-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support multiple build systems such as pure make, catkin, ament, etc #109
base: master
Are you sure you want to change the base?
Changes from all commits
f8fdd06
3cc0712
89d1da7
c9414bb
0b57425
641f177
3177e0f
4bbfee9
be08549
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,298 +1,28 @@ | ||
cmake_minimum_required(VERSION 2.6) | ||
cmake_minimum_required(VERSION 2.8.12) | ||
project(libnabo) | ||
|
||
if (NOT CMAKE_VERSION VERSION_LESS "3.1") | ||
cmake_policy(SET CMP0054 NEW) | ||
endif () | ||
|
||
set(LIB_NAME nabo) | ||
project("lib${LIB_NAME}") | ||
|
||
# Extract version from header | ||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) | ||
execute_process( | ||
COMMAND grep "NABO_VERSION " nabo/nabo.h | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} | ||
RESULT_VARIABLE GREP_VERSION_RESULT | ||
OUTPUT_VARIABLE PROJECT_VERSION | ||
OUTPUT_STRIP_TRAILING_WHITESPACE | ||
) | ||
if (NOT GREP_VERSION_RESULT EQUAL 0) | ||
message(SEND_ERROR "Cannot grep version number: ${GREP_VERSION_RESULT}") | ||
endif () | ||
string(REGEX REPLACE ".*\"(.*)\".*" "\\1" PROJECT_VERSION "${PROJECT_VERSION}" ) | ||
|
||
if (NOT CMAKE_BUILD_TYPE) | ||
message("-- No build type specified; defaulting to CMAKE_BUILD_TYPE=Release.") | ||
set(CMAKE_BUILD_TYPE Release CACHE STRING | ||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." | ||
FORCE) | ||
else () | ||
if (CMAKE_BUILD_TYPE STREQUAL "Debug") | ||
message("\n=================================================================================") | ||
message("\n-- Build type: Debug. Performance will be terrible!") | ||
message("-- Add -DCMAKE_BUILD_TYPE=Release to the CMake command line to get an optimized build.") | ||
message("\n=================================================================================") | ||
endif () | ||
endif () | ||
|
||
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") | ||
add_definitions(-O3) | ||
endif() | ||
|
||
# Documentation | ||
option(LIBNABO_BUILD_DOXYGEN "Build libnabo doxygen documentation" ON) | ||
if (LIBNABO_BUILD_DOXYGEN) | ||
set(DOXYFILE_LATEX false) | ||
include(UseDoxygen) | ||
endif() | ||
|
||
# Switch on warnings. | ||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wall") | ||
else () | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") | ||
endif () | ||
|
||
# Check the compiler version as we need C++11 support. | ||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") | ||
# using Clang | ||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.3") | ||
message(FATAL_ERROR "Your clang compiler has version ${CMAKE_CXX_COMPILER_VERSION}, while version 3.3 or later is required") | ||
endif () | ||
elseif () | ||
# using AppleClang | ||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.1") | ||
message(FATAL_ERROR "Your XCode environment has version ${CMAKE_CXX_COMPILER_VERSION}, while version 5.1 or later is required") | ||
endif () | ||
elseif () | ||
# using GCC | ||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8.2") | ||
message(FATAL_ERROR "Your g++ compiler has version ${CMAKE_CXX_COMPILER_VERSION}, while version 4.8.2 or later is required") | ||
endif () | ||
elseif () | ||
# using MSVC | ||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.0.23506") | ||
message(FATAL_ERROR "Your Microsoft Visual C++ compiler has version ${CMAKE_CXX_COMPILER_VERSION}, while version MSVC 2015 Update 1+ is required") | ||
endif () | ||
endif () | ||
|
||
# enable C++11 support. | ||
if (CMAKE_VERSION VERSION_LESS "3.1") | ||
if (MSVC) | ||
message(FATAL_ERROR "CMake version 3.1 or later is required to compile ${PROJECT_NAME} with Microsoft Visual C++") | ||
endif () | ||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") | ||
set (CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}") | ||
else () | ||
set (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") | ||
endif () | ||
else () | ||
set (CMAKE_CXX_STANDARD 11) | ||
endif () | ||
|
||
include(GNUInstallDirs) | ||
|
||
# eigen 2 or 3 | ||
find_path(EIGEN_INCLUDE_DIR Eigen/Core | ||
/usr/local/include/eigen3 | ||
/usr/local/include/eigen2 | ||
/usr/local/include/eigen | ||
/usr/include/eigen3 | ||
/usr/include/eigen2 | ||
/usr/include/eigen | ||
/opt/local/include/eigen3 | ||
) | ||
|
||
# optionally, opencl | ||
# OpenCL disabled as its code is not up-to-date with API | ||
set(USE_OPEN_CL FALSE CACHE BOOL "Set to TRUE to look for OpenCL") | ||
if (USE_OPEN_CL) | ||
find_path(OPENCL_INCLUDE_DIR CL/cl.h | ||
/usr/local/include | ||
/usr/include | ||
) | ||
if (WIN32) | ||
find_library(OPENCL_LIBRARIES opencl64) | ||
if (!OPENCL_LIBRARIES) | ||
find_library(OPENCL_LIBRARIES opencl32) | ||
endif () | ||
else () | ||
find_library(OPENCL_LIBRARIES OpenCL ENV LD_LIBRARY_PATH) | ||
endif () | ||
if (OPENCL_INCLUDE_DIR AND OPENCL_LIBRARIES) | ||
add_definitions(-DHAVE_OPENCL) | ||
set(EXTRA_LIBS ${OPENCL_LIBRARIES} ${EXTRA_LIBS}) | ||
include_directories(${OPENCL_INCLUDE_DIR}) | ||
add_definitions(-DOPENCL_SOURCE_DIR=\"${CMAKE_SOURCE_DIR}/nabo/opencl/\") | ||
message("OpenCL enabled and found, enabling CL support") | ||
else (OPENCL_INCLUDE_DIR AND OPENCL_LIBRARIES) | ||
message("OpenCL enabled but not found, disabling CL support") | ||
endif () | ||
else () | ||
message("OpenCL disabled, not looking for it") | ||
endif () | ||
|
||
|
||
# main nabo lib | ||
# Source and header files. | ||
set(NABO_SRC | ||
nabo/nabo.cpp | ||
nabo/brute_force_cpu.cpp | ||
nabo/kdtree_cpu.cpp | ||
nabo/kdtree_opencl.cpp | ||
nabo/nabo.cpp | ||
nabo/brute_force_cpu.cpp | ||
nabo/kdtree_cpu.cpp | ||
nabo/kdtree_opencl.cpp | ||
) | ||
set(SHARED_LIBS FALSE CACHE BOOL "Set to TRUE to build shared library") | ||
if (SHARED_LIBS) | ||
add_library(${LIB_NAME} SHARED ${NABO_SRC}) | ||
install(TARGETS ${LIB_NAME} LIBRARY DESTINATION lib) | ||
else () | ||
add_library(${LIB_NAME} STATIC ${NABO_SRC}) | ||
if (NOT MSVC) | ||
target_compile_options(${LIB_NAME} PRIVATE -fPIC) | ||
endif() | ||
install(TARGETS ${LIB_NAME} ARCHIVE DESTINATION lib) | ||
endif () | ||
set_target_properties(${LIB_NAME} PROPERTIES VERSION "${PROJECT_VERSION}" SOVERSION 1) | ||
|
||
target_include_directories(${LIB_NAME} PUBLIC | ||
${EIGEN_INCLUDE_DIR} | ||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> | ||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> | ||
) | ||
|
||
# openmp | ||
set(USE_OPEN_MP TRUE CACHE BOOL "Set to FALSE to not use OpenMP") | ||
if (USE_OPEN_MP) | ||
find_package(OpenMP) | ||
if (OPENMP_FOUND) | ||
target_compile_options(${LIB_NAME} PRIVATE -fopenmp ${OpenMP_CXX_FLAGS}) | ||
target_compile_definitions(${LIB_NAME} PRIVATE HAVE_OPENMP) | ||
if (CMAKE_COMPILER_IS_GNUCC) | ||
target_link_libraries(${LIB_NAME} PUBLIC gomp) | ||
endif() | ||
endif() | ||
endif () | ||
|
||
|
||
# create doc before installing | ||
set(DOC_INSTALL_TARGET "share/doc/${PROJECT_NAME}/api" CACHE STRING "Target where to install doxygen documentation") | ||
install(FILES nabo/nabo.h DESTINATION include/nabo) | ||
install(FILES nabo/third_party/any.hpp DESTINATION include/nabo/third_party) | ||
install(FILES README.md DESTINATION share/doc/${PROJECT_NAME}) | ||
if (DOXYGEN_FOUND) | ||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION ${DOC_INSTALL_TARGET}) | ||
endif (DOXYGEN_FOUND) | ||
|
||
enable_testing() | ||
|
||
|
||
option(LIBNABO_BUILD_EXAMPLES "Build libnabo examples" ON) | ||
if (LIBNABO_BUILD_EXAMPLES) | ||
add_subdirectory(examples) | ||
endif() | ||
|
||
option(LIBNABO_BUILD_TESTS "Build libnabo tests" ON) | ||
if(LIBNABO_BUILD_TESTS) | ||
add_subdirectory(tests) | ||
endif() | ||
|
||
option(LIBNABO_BUILD_PYTHON "Build libnabo python" ON) | ||
if(LIBNABO_BUILD_PYTHON) | ||
add_subdirectory(python) | ||
endif() | ||
|
||
# Install catkin package.xml | ||
install(FILES package.xml DESTINATION share/libnabo) | ||
|
||
#============================================= | ||
# to allow find_package() on libnabo | ||
#============================================= | ||
# | ||
# the following case be used in an external project requiring libnabo: | ||
# ... | ||
# find_package(libnabo) | ||
# include_directories(${libnabo_INCLUDE_DIRS}) | ||
# target_link_libraries(executableName ${libnabo_LIBRARIES}) | ||
# ... | ||
|
||
# NOTE: the following will support find_package for 1) local build (make) and 2) for installed files (make install) | ||
|
||
# 1- local build # | ||
|
||
# Register the local build in case one doesn't use "make install" | ||
export(PACKAGE libnabo) | ||
|
||
# 'make install' to the correct locations (provided by GNUInstallDirs). | ||
install(TARGETS ${LIB_NAME} EXPORT ${PROJECT_NAME}-targets | ||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) # This is for Windows | ||
#install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) | ||
|
||
add_library(${PROJECT_NAME}::${LIB_NAME} ALIAS ${LIB_NAME}) | ||
|
||
# This makes the project importable from the install directory | ||
# Put config file in per-project dir (name MUST match), can also | ||
# just go into 'cmake'. | ||
install( | ||
EXPORT ${PROJECT_NAME}-targets | ||
DESTINATION share/${PROJECT_NAME}/cmake | ||
NAMESPACE ${PROJECT_NAME}:: | ||
) | ||
|
||
# This makes the project importable from the build directory | ||
export( | ||
TARGETS ${LIB_NAME} | ||
FILE ${PROJECT_NAME}-targets.cmake | ||
NAMESPACE ${PROJECT_NAME}:: | ||
) | ||
|
||
|
||
# Create variable with the library location | ||
set(libnabo_library $<TARGET_FILE:${LIB_NAME}>) | ||
|
||
# Create variable for the local build tree | ||
get_property(libnabo_include_dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) | ||
# Configure & generate config file for local build tree | ||
configure_file(libnaboConfig.cmake.in | ||
"${PROJECT_BINARY_DIR}/libnaboConfig.cmake.conf" @ONLY) | ||
file(GENERATE | ||
OUTPUT "${PROJECT_BINARY_DIR}/libnaboConfig.cmake" | ||
INPUT "${PROJECT_BINARY_DIR}/libnaboConfig.cmake.conf") | ||
|
||
# 2- installation build # | ||
|
||
# Change the library location for an install location | ||
set(libnabo_library ${CMAKE_INSTALL_PREFIX}/lib/$<TARGET_FILE_NAME:${LIB_NAME}>) | ||
|
||
# Change the include location for the case of an install location | ||
set(libnabo_include_dirs ${CMAKE_INSTALL_PREFIX}/include) | ||
|
||
# We put the generated file for installation in a different repository (i.e., ./CMakeFiles/) | ||
configure_file(libnaboConfig.cmake.in | ||
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/libnaboConfig.cmake.conf" @ONLY) | ||
file(GENERATE | ||
OUTPUT "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/libnaboConfig.cmake" | ||
INPUT "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/libnaboConfig.cmake.conf") | ||
|
||
# The same versioning file can be used for both cases | ||
configure_file(libnaboConfigVersion.cmake.in | ||
"${PROJECT_BINARY_DIR}/libnaboConfigVersion.cmake" @ONLY) | ||
|
||
install(FILES | ||
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/libnaboConfig.cmake" | ||
"${PROJECT_BINARY_DIR}/libnaboConfigVersion.cmake" | ||
DESTINATION share/libnabo/cmake COMPONENT dev) | ||
|
||
|
||
#============================================= | ||
# Add uninstall target | ||
#============================================= | ||
if (NOT TARGET uninstall) | ||
configure_file( | ||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" | ||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" | ||
IMMEDIATE @ONLY) | ||
|
||
add_custom_target(uninstall | ||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) | ||
file(GLOB_RECURSE NABO_HEADERS "nabo/*.h") | ||
|
||
# Global compiler flags. | ||
add_compile_options(-Wall -Wextra -Wpedantic) | ||
|
||
# Build type options: | ||
# * catkin. | ||
# * cmake. | ||
# * ament (future). | ||
set(BUILD_TYPE "cmake") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stephanemagnenat Related to your comment, I would keep the default build type to cmake, so support for non-ROS users is kept as before. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this rather check a CMake variable and fill in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest also testing if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Can you give an example?
I thought about something similar, but I think it's better to just allow the user to be explicit about the build type. I also don't know if e.g. the ethz-asl CI is already packaging libnabo as a sort-of ROS package with pure cmake build. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changing the build type requires editing the CMakeLists.txt (if this isn't some black magic that would turn this local variable into cached option). So at least expose the build type as an option, the same way USE_OPEN_MP and others do. And, when introducing the option, please, give it a unique name to prevent collisions with other packages - e.g. NABO_BUILD_TYPE. I would still be happier if libnabo detected it is built using catkin and autoselected catkin build in that case. But I agree that can break some older setups that expect the pure CMake package. These could continue building using catkin and set NABO_BUILD_TYPE=cmake explicitly. Without the autodetection, all users who want the catkin package, would need to explicitly set the build type. It is doable, but not convenient. But this is more a political decision, you have to properly weigh all pros and cons. |
||
if (BUILD_TYPE STREQUAL "catkin") | ||
include(cmake/CatkinBuild.cmake) | ||
else() | ||
# For a pure-cmake build, follow the instructions on the package.xml file, which | ||
# specify how to set the buildtool to cmake and export the package accordingly. | ||
include(cmake/PureCMakeBuild.cmake) | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In modern CMake, you should use target_compile_options (since CMake 2.8.12).