Skip to content

Commit

Permalink
Merge pull request #103 from MOLAorg/master
Browse files Browse the repository at this point in the history
Modernize cmake; make cmake compatible with git submoduling
  • Loading branch information
pomerlef authored Sep 17, 2020
2 parents d4f45e2 + b448838 commit 99e58e4
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 66 deletions.
148 changes: 100 additions & 48 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,33 @@ execute_process(
)
if (NOT GREP_VERSION_RESULT EQUAL 0)
message(SEND_ERROR "Cannot grep version number: ${GREP_VERSION_RESULT}")
endif (NOT GREP_VERSION_RESULT EQUAL 0)
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 (NOT CMAKE_BUILD_TYPE)
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 (CMAKE_BUILD_TYPE STREQUAL "Debug")
endif (NOT CMAKE_BUILD_TYPE)
endif ()
endif ()

if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-O3)
endif(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
endif()

# Documentation
set(DOXYFILE_LATEX false)
include(UseDoxygen)
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")
Expand All @@ -56,17 +59,17 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "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 (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
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 (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
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 (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
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")
Expand All @@ -87,19 +90,6 @@ else ()
set (CMAKE_CXX_STANDARD 11)
endif ()

# 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)
add_definitions(-fopenmp -DHAVE_OPENMP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
if (CMAKE_COMPILER_IS_GNUCC)
set(EXTRA_LIBS ${EXTRA_LIBS} gomp)
endif(CMAKE_COMPILER_IS_GNUCC)
endif(OPENMP_FOUND)
endif (USE_OPEN_MP)

# eigen 2 or 3
find_path(EIGEN_INCLUDE_DIR Eigen/Core
/usr/local/include/eigen3
Expand All @@ -123,10 +113,10 @@ if (USE_OPEN_CL)
find_library(OPENCL_LIBRARIES opencl64)
if (!OPENCL_LIBRARIES)
find_library(OPENCL_LIBRARIES opencl32)
endif (!OPENCL_LIBRARIES)
else (WIN32)
endif ()
else ()
find_library(OPENCL_LIBRARIES OpenCL ENV LD_LIBRARY_PATH)
endif (WIN32)
endif ()
if (OPENCL_INCLUDE_DIR AND OPENCL_LIBRARIES)
add_definitions(-DHAVE_OPENCL)
set(EXTRA_LIBS ${OPENCL_LIBRARIES} ${EXTRA_LIBS})
Expand All @@ -135,13 +125,11 @@ if (USE_OPEN_CL)
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 (OPENCL_INCLUDE_DIR AND OPENCL_LIBRARIES)
else (USE_OPEN_CL)
endif ()
else ()
message("OpenCL disabled, not looking for it")
endif (USE_OPEN_CL)
endif ()

# include all libs so far
include_directories(${CMAKE_SOURCE_DIR} ${EIGEN_INCLUDE_DIR})

# main nabo lib
set(NABO_SRC
Expand All @@ -154,13 +142,35 @@ 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 (SHARED_LIBS)
add_library(${LIB_NAME} ${NABO_SRC})
add_definitions(-fPIC)
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 (SHARED_LIBS)
endif ()
set_target_properties(${LIB_NAME} PROPERTIES VERSION "${PROJECT_VERSION}" SOVERSION 1)

target_include_directories(${LIB_NAME} PUBLIC
${EIGEN_INCLUDE_DIR}
$<INSTALL_INTERFACE:>
$<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)
Expand All @@ -172,21 +182,33 @@ endif (DOXYGEN_FOUND)

enable_testing()

add_subdirectory(examples)
add_subdirectory(tests)
add_subdirectory(python)

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})
# find_package(libnabo)
# include_directories(${libnabo_INCLUDE_DIRS})
# target_link_libraries(executableName ${libnabo_LIBRARIES})
# ...

Expand All @@ -197,6 +219,34 @@ install(FILES package.xml DESTINATION share/libnabo)
# Register the local build in case one doesn't use "make install"
export(PACKAGE libnabo)

include(GNUInstallDirs)

# '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}>)

Expand Down Expand Up @@ -237,10 +287,12 @@ install(FILES
#=============================================
# Add uninstall target
#=============================================
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)
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)
endif()
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Under Unix, assuming that [Eigen] and [Boost] are installed system-wide, you can
BUILD_DIR=${SRC_DIR}/build
mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR}
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ${SRC_DIR}
# if Eigen or Boost are not available system-wide, run at that point:
# if Eigen or Boost are not available system-wide, run at that point:
# cmake-gui .
# cmake-gui allows you to tell the location of Eigen or Boost
make
Expand All @@ -78,11 +78,11 @@ libnabo is easy to use. For example, assuming that you are working with floats a
using namespace Eigen;
...
NNSearchF* nns = NNSearchF::createKDTreeLinearHeap(M);

const int K = 5;
VectorXi indices(K);
VectorXf dists2(K);

nns->knn(q, indices, dists2, K);

In this example, `M` is an [Eigen] (refering to the software, not to the math) matrix (column major, float) and `q` is an [Eigen] vector (float). Note that `M` **must stay alive** throughout the use of libnabo, otherwise the results of `knn` are undefined.
Expand All @@ -92,6 +92,10 @@ See `examples/trivial.cpp` for a compilable version of this example, and `exampl
Running `make doc` in your build directory will generate a browsable documentation in `doc/html`.
The main page `doc/html/index.html` contains a detailed overview of the usage of libnabo.

You can find a complete CMake integration
example in [examples/libnabo-cmake-example](examples/libnabo-cmake-example) to
see how to look for, and link against this library.

Python bindings
===============

Expand Down Expand Up @@ -119,7 +123,7 @@ The distribution of libnabo integrates a unit test module, based on CTest.
Just type:

make test

...in the build directory to run the tests.
Their outputs are available in the `Testing` directory.
These consist of validation and benchmarking tests.
Expand Down
11 changes: 11 additions & 0 deletions examples/libnabo-cmake-example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.0)
project(libnabo-cmake-example)

# This looks for the libnabo-config.cmake file, which in turns
# includes libnabo-targets.cmake:
find_package(libnabo REQUIRED)

add_executable(${PROJECT_NAME} trivial.cpp)

# This sets both the include directories and link library:
target_link_libraries(${PROJECT_NAME} libnabo::nabo)
28 changes: 28 additions & 0 deletions examples/libnabo-cmake-example/trivial.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// This example is in the public domain

#include "nabo/nabo.h"

int main()
{
using namespace Nabo;
using namespace Eigen;

// 100 points in 3D
MatrixXf M = MatrixXf::Random(3, 100);
// 1 query points
VectorXf q = VectorXf::Random(3);

// create a kd-tree for M, note that M must stay valid during the lifetime of the kd-tree
NNSearchF* nns = NNSearchF::createKDTreeLinearHeap(M);

// look for the 5 nearest neighbour of a the single-point query
const int K = 5;
VectorXi indices(K);
VectorXf dists2(K);
nns->knn(q, indices, dists2, K);

// cleanup kd-tree
delete nns;

return 0;
}
13 changes: 1 addition & 12 deletions libnaboConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
# - Config file for the libnabo package
# It defines the following variables
# libnabo_INCLUDE_DIRS - include directories for libnabo
# libnabo_LIBRARIES - libraries to link against

# Compute paths
get_filename_component(libnabo_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(libnabo_INCLUDE_DIRS "@libnabo_include_dirs@")

if(CMAKE_COMPILER_IS_GNUCC)
set(libnabo_LIBRARIES @libnabo_library@ gomp)
else(CMAKE_COMPILER_IS_GNUCC)
set(libnabo_LIBRARIES @libnabo_library@)
endif(CMAKE_COMPILER_IS_GNUCC)
include(${CMAKE_CURRENT_LIST_DIR}/libnabo-targets.cmake)

# This causes catkin_simple to link against these libraries
set(libnabo_FOUND_CATKIN_PROJECT true)
5 changes: 3 additions & 2 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ if (PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND)
if (SHARED_LIBS)
python_add_module(pynabo SHARED nabo.cpp)
target_link_libraries(pynabo ${LIB_NAME} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
else (SHARED_LIBS)
else ()
set(PYTHON_SRC "nabo.cpp")
foreach(file ${NABO_SRC})
set(PYTHON_SRC ${PYTHON_SRC} "../${file}")
endforeach(file)
python_add_module(pynabo ${PYTHON_SRC})
target_link_libraries(pynabo ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
endif (SHARED_LIBS)
target_include_directories(pynabo PRIVATE ${EIGEN_INCLUDE_DIR})
endif ()
# fix for old python_add_module
set_target_properties(pynabo PROPERTIES PREFIX "")
if (PYTHON_CUSTOM_TARGET)
Expand Down

0 comments on commit 99e58e4

Please sign in to comment.