CMakeLists.txt 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #
  2. # Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
  3. #
  4. cmake_minimum_required(VERSION 2.8)
  5. if(DEFINED CMAKE_BUILD_TYPE)
  6. set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Debug Release RelWithDebInfo MinSizeRel")
  7. else()
  8. set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Debug Release RelWithDebInfo MinSizeRel")
  9. endif()
  10. # Detecting whether we need to add debug targets
  11. string(TOLOWER "${CMAKE_BUILD_TYPE}" build_type_lower)
  12. if (build_type_lower STREQUAL "debug")
  13. set(DEBUG_BUILD 1)
  14. message(STATUS "Debug build")
  15. else ()
  16. set(DEBUG_BUILD 0)
  17. endif ()
  18. project(libuavcan)
  19. find_program(PYTHON python)
  20. if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
  21. set(COMPILER_IS_GCC_COMPATIBLE 1)
  22. else ()
  23. set(COMPILER_IS_GCC_COMPATIBLE 0)
  24. endif ()
  25. #
  26. # DSDL compiler invocation
  27. # Probably output files should be saved into CMake output dir?
  28. #
  29. execute_process(COMMAND ${PYTHON} setup.py build WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dsdl_compiler OUTPUT_QUIET)
  30. set(DSDLC_INPUTS "test/dsdl_test/root_ns_a" "test/dsdl_test/root_ns_b" "${CMAKE_CURRENT_SOURCE_DIR}/../dsdl/uavcan")
  31. set(DSDLC_OUTPUT "include/dsdlc_generated")
  32. set(DSDLC_INPUT_FILES "")
  33. foreach(DSDLC_INPUT ${DSDLC_INPUTS})
  34. file(GLOB_RECURSE DSDLC_NEW_INPUT_FILES ${CMAKE_CURRENT_SOURCE_DIR} "${DSDLC_INPUT}/*.uavcan")
  35. set(DSDLC_INPUT_FILES ${DSDLC_INPUT_FILES} ${DSDLC_NEW_INPUT_FILES})
  36. endforeach(DSDLC_INPUT)
  37. add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/libuavcan_dsdlc_run.stamp
  38. COMMAND ${PYTHON} ${CMAKE_CURRENT_SOURCE_DIR}/dsdl_compiler/libuavcan_dsdlc ${DSDLC_INPUTS} -O${DSDLC_OUTPUT}
  39. COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/libuavcan_dsdlc_run.stamp
  40. DEPENDS ${DSDLC_INPUT_FILES}
  41. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  42. COMMENT "Running dsdl compiler")
  43. add_custom_target(libuavcan_dsdlc DEPENDS ${CMAKE_BINARY_DIR}/libuavcan_dsdlc_run.stamp)
  44. include_directories(${DSDLC_OUTPUT})
  45. #
  46. # Compiler flags
  47. #
  48. if (COMPILER_IS_GCC_COMPATIBLE)
  49. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wundef")
  50. if (UAVCAN_USE_CPP03)
  51. message(STATUS "Using C++03")
  52. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03 -Wno-variadic-macros -Wno-long-long")
  53. else ()
  54. message(STATUS "Using C++11 (pass UAVCAN_USE_CPP03=1 to override)")
  55. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
  56. endif ()
  57. endif ()
  58. if (DEBUG_BUILD)
  59. add_definitions(-DUAVCAN_DEBUG=1)
  60. endif ()
  61. include_directories(include)
  62. #
  63. # libuavcan
  64. #
  65. file(GLOB_RECURSE LIBUAVCAN_CXX_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
  66. add_library(uavcan STATIC ${LIBUAVCAN_CXX_FILES})
  67. add_dependencies(uavcan libuavcan_dsdlc)
  68. install(TARGETS uavcan DESTINATION lib)
  69. install(DIRECTORY include/uavcan DESTINATION include)
  70. install(DIRECTORY include/dsdlc_generated/uavcan DESTINATION include) # Generated and lib's .hpp
  71. install(CODE "execute_process(COMMAND ${PYTHON} setup.py install --record installed_files.log
  72. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dsdl_compiler)")
  73. #
  74. # Tests and static analysis - only for debug builds
  75. #
  76. function(add_libuavcan_test name library flags) # Adds GTest executable and creates target to execute it every build
  77. find_package(Threads REQUIRED)
  78. include_directories(${GTEST_INCLUDE_DIRS})
  79. file(GLOB_RECURSE TEST_CXX_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "test/*.cpp")
  80. add_executable(${name} ${TEST_CXX_FILES})
  81. add_dependencies(${name} ${library})
  82. if (flags)
  83. set_target_properties(${name} PROPERTIES COMPILE_FLAGS ${flags})
  84. endif ()
  85. target_link_libraries(${name} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
  86. target_link_libraries(${name} ${library})
  87. target_link_libraries(${name} rt)
  88. # Tests run automatically upon successful build
  89. # If failing tests need to be investigated with debugger, use 'make --ignore-errors'
  90. if (CONTINUOUS_INTEGRATION_BUILD)
  91. # Don't redirect test output, and don't run tests suffixed with "RealTime"
  92. add_custom_command(TARGET ${name} POST_BUILD
  93. COMMAND ./${name} --gtest_filter=-*RealTime
  94. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  95. else ()
  96. add_custom_command(TARGET ${name} POST_BUILD
  97. COMMAND ./${name} 1>"${name}.log" 2>&1
  98. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  99. endif()
  100. endfunction()
  101. if (DEBUG_BUILD)
  102. message(STATUS "Debug build (note: requires gtest)")
  103. if (COMPILER_IS_GCC_COMPATIBLE)
  104. # No such thing as too many warnings
  105. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -pedantic -Wfloat-equal -Wconversion")
  106. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsign-conversion -Wcast-align -Wmissing-declarations -Wlogical-op")
  107. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdouble-promotion -Wswitch-enum -Wtype-limits -Wno-error=array-bounds")
  108. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wzero-as-null-pointer-constant -Wnon-virtual-dtor")
  109. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual -Wsign-promo -Wold-style-cast")
  110. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-declarations")
  111. #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weffc++ -Wno-error=effc++") # Produces heaps of useless warnings
  112. set(cpp03_flags "-std=c++03 -Wno-variadic-macros -Wno-long-long -Wno-zero-as-null-pointer-constant")
  113. set(optim_flags "-O3 -DNDEBUG -g0")
  114. else ()
  115. message(STATUS "Compiler ID: ${CMAKE_CXX_COMPILER_ID}")
  116. message(FATAL_ERROR "This compiler cannot be used to build tests; use release build instead.")
  117. endif ()
  118. # Additional flavours of the library
  119. add_library(uavcan_cpp03 STATIC ${LIBUAVCAN_CXX_FILES})
  120. set_target_properties(uavcan_cpp03 PROPERTIES COMPILE_FLAGS ${cpp03_flags})
  121. add_dependencies(uavcan_cpp03 libuavcan_dsdlc)
  122. add_library(uavcan_optim STATIC ${LIBUAVCAN_CXX_FILES})
  123. set_target_properties(uavcan_optim PROPERTIES COMPILE_FLAGS ${optim_flags})
  124. add_dependencies(uavcan_optim libuavcan_dsdlc)
  125. # GTest executables
  126. find_package(GTest)
  127. if (GTEST_FOUND)
  128. message(STATUS "GTest found, tests will be built and run [${GTEST_INCLUDE_DIRS}] [${GTEST_BOTH_LIBRARIES}]")
  129. add_libuavcan_test(libuavcan_test uavcan "") # Default
  130. add_libuavcan_test(libuavcan_test_cpp03 uavcan_cpp03 "${cpp03_flags}") # C++03
  131. add_libuavcan_test(libuavcan_test_optim uavcan_optim "${optim_flags}") # Max optimization
  132. else (GTEST_FOUND)
  133. message(STATUS "GTest was not found, tests will not be built")
  134. endif (GTEST_FOUND)
  135. else ()
  136. message(STATUS "Release build type: " ${CMAKE_BUILD_TYPE})
  137. endif ()
  138. # vim: set et ft=cmake fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :