Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 28 additions & 240 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@
### ---[ PCL global CMake
cmake_minimum_required(VERSION 3.16.3 FATAL_ERROR)

# Set target C++ standard and required compiler features
set(CMAKE_CXX_STANDARD 17 CACHE STRING "The target C++ standard. PCL requires C++14 or higher.")
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if("${CMAKE_CXX_STANDARD}" GREATER_EQUAL 17)
set(PCL_CXX_COMPILE_FEATURES cxx_std_17)
set(PCL__cplusplus 201703L)
set(PCL_REQUIRES_MSC_VER 1912)
elseif("${CMAKE_CXX_STANDARD}" EQUAL 14)
set(PCL_CXX_COMPILE_FEATURES cxx_std_14)
set(PCL__cplusplus 201402L)
set(PCL_REQUIRES_MSC_VER 1900)
else()
message(FATAL_ERROR "Unknown or unsupported C++ standard specified")
endif()

set(CMAKE_CUDA_STANDARD 17 CACHE STRING "The target CUDA/C++ standard. PCL requires CUDA/C++ 14 or higher.")
set(CMAKE_CUDA_STANDARD_REQUIRED ON)

set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "possible configurations" FORCE)

# In case the user does not setup CMAKE_BUILD_TYPE, assume it's RelWithDebInfo
Expand All @@ -30,10 +11,6 @@ endif()
project(PCL VERSION 1.15.1.99)
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)

if(MSVC AND ("${MSVC_VERSION}" LESS 1910))
message(FATAL_ERROR "The compiler versions prior to Visual Studio version 2017 are not supported. Please upgrade to a newer version or another compiler!")
endif()

### ---[ Find universal dependencies
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/" ${CMAKE_MODULE_PATH})

Expand All @@ -52,211 +29,49 @@ set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)

# Compiler identification
# Define a variable CMAKE_COMPILER_IS_X where X is the compiler short name.
# Note: CMake automatically defines one for GNUCXX, nothing to do in this case.
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_COMPILER_IS_CLANG 1)
elseif(__COMPILER_PATHSCALE)
set(CMAKE_COMPILER_IS_PATHSCALE 1)
elseif(MSVC)
set(CMAKE_COMPILER_IS_MSVC 1)
elseif(MINGW)
set(CMAKE_COMPILER_IS_MINGW 1)
endif()

# Ensure try_compile sets the include paths (e.g. for Eigen3)
set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})

# https://github.com/fish-shell/fish-shell/issues/5865
include(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES("
#include <atomic>
struct big { int foo[64]; };
std::atomic<big> x;
int main() {
return x.load().foo[13];
}"
LIBATOMIC_NOT_NEEDED)
IF (NOT LIBATOMIC_NOT_NEEDED)
SET(ATOMIC_LIBRARY "atomic")
ENDIF()

# Create a variable with expected default CXX flags
# This will be used further down the road to check if the user explicitly provided CXX flags
if(CMAKE_COMPILER_IS_MSVC)
set(CMAKE_CXX_FLAGS_DEFAULT ${CMAKE_CXX_FLAGS_INIT})
string(STRIP ${CMAKE_CXX_FLAGS_DEFAULT} CMAKE_CXX_FLAGS_DEFAULT)
else()
set(CMAKE_CXX_FLAGS_DEFAULT "")
endif()
# Check if we need to link against libatomic (armel)
include("${PCL_SOURCE_DIR}/cmake/pcl_check_atomic.cmake")

include("${PCL_SOURCE_DIR}/cmake/pcl_verbosity.cmake")
include("${PCL_SOURCE_DIR}/cmake/pcl_targets.cmake")
include("${PCL_SOURCE_DIR}/cmake/pcl_options.cmake")
include("${PCL_SOURCE_DIR}/cmake/clang-format.cmake")
include("${PCL_SOURCE_DIR}/cmake/pcl_utils.cmake")
DISSECT_VERSION()
GET_OS_INFO()
SET_INSTALL_DIRS()
Comment on lines +43 to +45
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would appreciate adopting lower-case commands in new/moved CMake code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind, do you have any pointers that this is "good practice or examples where this is done" 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just glanced at methods at VTK - and indeed they are seemingly all lowercase - I'll keep it in mind.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically it is done in all modern CMake code, including reference documentation. I believe lower-case is widely accepted as more readable for humans.
The transition is facilitated by the fact that command names are case-insensitive.

(Variable names are case-sensitive, and I don't have a strong opinion about them. Also keywords like PUBLIC are case-sensitive. This makes them stand out nicely. Don't discussion build types 🤦)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just glanced at methods at VTK - and indeed they are seemingly all lowercase - I'll keep it in mind.

VTK... It is maintained by Kitware as is CMake. It is probably an old CMake code base, and it tells me that Kitware should ... have a lot of early awareness of shortcomings in CMake.
(Coincidentally I'm trying to fix issues in the vtk port in vcpkg.)


if(${PCL_ENABLE_CCACHE})
include (UseCompilerCache)
UseCompilerCache(ccache REQUIRED)
endif()
# Check/Set compiler settings
include("cmake/pcl_set_compiler_settings.cmake")
message(STATUS "PCL public Options: ${PCL_PUBLIC_COMPILER_OPTIONS}")
message(STATUS "PCL private Options: ${PCL_PRIVATE_COMPILER_OPTIONS}")
message(STATUS "PCL public Definitions: ${PCL_PUBLIC_COMPILER_DEFINITIONS}")
message(STATUS "PCL private Definitions: ${PCL_PRIVATE_COMPILER_DEFINITIONS}")
message(STATUS "PCL public Compile Features: ${PCL_PUBLIC_COMPILER_FEATURES}")
message(STATUS "PCL private Compile Features: ${PCL_PRIVATE_COMPILER_FEATURES}")
message(STATUS "PCL private Link Options: ${PCL_PRIVATE_LINK_OPTIONS}")

# Enable verbose timing display?
if(CMAKE_TIMING_VERBOSE AND UNIX)
set_property(GLOBAL PROPERTY RULE_MESSAGES OFF)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_SOURCE_DIR}/cmake/custom_output.sh")
endif()

# check for allocation functions that return aligned memory
include("${PCL_SOURCE_DIR}/cmake/pcl_alignment.cmake")
PCL_CHECK_FOR_ALIGNMENT()

# check for SSE flags
include("${PCL_SOURCE_DIR}/cmake/pcl_find_sse.cmake")
if(PCL_ENABLE_SSE AND "${CMAKE_CXX_FLAGS}" STREQUAL "${CMAKE_CXX_FLAGS_DEFAULT}")
PCL_CHECK_FOR_SSE()
endif()

# check for AVX flags
if(PCL_ENABLE_AVX AND "${CMAKE_CXX_FLAGS}" STREQUAL "${CMAKE_CXX_FLAGS_DEFAULT}")
include("${PCL_SOURCE_DIR}/cmake/pcl_find_avx.cmake")
PCL_CHECK_FOR_AVX()
endif()

# Cuda
option(WITH_CUDA "Build NVIDIA-CUDA support" TRUE)
if(WITH_CUDA)
include("${PCL_SOURCE_DIR}/cmake/pcl_find_cuda.cmake")
endif()


# ---[ Unix/Darwin/Windows specific flags
if(CMAKE_COMPILER_IS_GNUCXX)
if("${CMAKE_CXX_FLAGS}" STREQUAL "${CMAKE_CXX_FLAGS_DEFAULT}")
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7)
string(APPEND CMAKE_CXX_FLAGS " -Wabi=18")
else()
string(APPEND CMAKE_CXX_FLAGS " -Wabi")
endif()
string(APPEND CMAKE_CXX_FLAGS " -Wall -Wextra -fno-strict-aliasing ${SSE_FLAGS} ${AVX_FLAGS}")
endif()

if(PCL_WARNINGS_ARE_ERRORS)
string(APPEND CMAKE_CXX_FLAGS " -Werror -fno-strict-aliasing")
endif()

if("${CMAKE_SHARED_LINKER_FLAGS}" STREQUAL "" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
endif()

if(WIN32)
if(PCL_SHARED_LIBS)
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -Wl,--export-all-symbols -Wl,--enable-auto-import")
if(MINGW)
add_definitions("-DBOOST_THREAD_USE_LIB")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -Wl,--allow-multiple-definition")
endif()
else()
add_definitions("-DBOOST_LIB_DIAGNOSTIC -DBOOST_THREAD_USE_LIB")
endif()
endif()
endif()

if(CMAKE_COMPILER_IS_MSVC)
add_definitions("-DBOOST_ALL_NO_LIB -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -DNOMINMAX ${SSE_DEFINITIONS}")

if("${CMAKE_CXX_FLAGS}" STREQUAL "${CMAKE_CXX_FLAGS_DEFAULT}")

string(APPEND CMAKE_CXX_FLAGS " /fp:precise ${SSE_FLAGS} ${AVX_FLAGS}")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=/bigobj")

set(PCL_USE_GLOBAL_OPTIMIZATION TRUE)
if(CUDA_FOUND)
if(${CUDA_VERSION_STRING} VERSION_GREATER_EQUAL "10.0" AND ${CUDA_VERSION_STRING} VERSION_LESS "12.0")
set(PCL_USE_GLOBAL_OPTIMIZATION FALSE)
message("Global optimizations /GL has been turned off, as it doesn't work with nvcc/thrust in CUDA 10 and 11.")
endif()
endif()

# Add extra code generation/link optimizations
if(CMAKE_MSVC_CODE_LINK_OPTIMIZATION AND PCL_USE_GLOBAL_OPTIMIZATION)
string(APPEND CMAKE_CXX_FLAGS_RELEASE " /GL")
string(APPEND CMAKE_SHARED_LINKER_FLAGS_RELEASE " /LTCG /OPT:REF")
string(APPEND CMAKE_EXE_LINKER_FLAGS_RELEASE " /LTCG")
endif()
# /MANIFEST:NO") # please, don't disable manifest generation, otherwise crash at start for vs2008

# Disable some warnings
string(APPEND CMAKE_CXX_FLAGS " /wd4800 /wd4521 /wd4251 /wd4275 /wd4305 /wd4355")

# Enable warnings, which are disabled by default (see https://learn.microsoft.com/de-de/cpp/preprocessor/compiler-warnings-that-are-off-by-default)
string(APPEND CMAKE_CXX_FLAGS " /w34265")

if(PCL_WARNINGS_ARE_ERRORS)
# MSVC supports external includes only since Visual Studio 2019 version 16.10.0.
# CMake supports external includes since 3.22.0 using the Ninja generator or NMake files (see https://gitlab.kitware.com/cmake/cmake/-/merge_requests/4766)
# CMake supports external includes for Visual Studio also since 3.24.0 (see https://gitlab.kitware.com/cmake/cmake/-/merge_requests/7238)
if(CMAKE_C_COMPILER_VERSION VERSION_LESS "19.29.30036.3" OR CMAKE_VERSION VERSION_LESS 3.22.0 OR (CMAKE_VERSION VERSION_LESS 3.24.0 AND CMAKE_GENERATOR MATCHES "Visual Studio"))
message(WARNING "With the used combination of compiler and CMake version it is not recommended to activate PCL_WARNINGS_ARE_ERRORS, "
"because also warnings from 3rd party components are marked as errors. It is recommended to upgrade to "
"Visual Studio 2019 version 16.10.0 and CMake 3.24.0 (or CMake 3.22.0 if using Ninja or NMake files).")
endif()
string(APPEND CMAKE_CXX_FLAGS " /WX")
endif()

include(ProcessorCount)
ProcessorCount(CPUCores)
set(MSVC_MP ${CPUCores} CACHE STRING "Number of simultaneously running compilers (0 = automatic detection by MSVC). See documentation of /MP flag.")

if(MSVC_MP EQUAL 0)
# MSVC_MP is 0 in case the information cannot be determined by ProcessorCount => fallback
# Generator expression is necessary to limit /MP flag to C/CXX, so flag will be not set to e.g. CUDA (see https://gitlab.kitware.com/cmake/cmake/issues/17535)
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/MP>)
elseif(MSVC_MP GREATER 1)
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/MP${MSVC_MP}>)
endif()
endif()
string(APPEND CMAKE_CXX_FLAGS " /bigobj")

if(CMAKE_GENERATOR STREQUAL "Ninja")
string(APPEND CMAKE_C_FLAGS " /FS")
string(APPEND CMAKE_CXX_FLAGS " /FS")
endif()
endif()

if(CMAKE_COMPILER_IS_PATHSCALE)
if("${CMAKE_CXX_FLAGS}" STREQUAL "${CMAKE_CXX_FLAGS_DEFAULT}")
set(CMAKE_CXX_FLAGS "-Wno-uninitialized -zerouv -mp")
endif()
if("${CMAKE_SHARED_LINKER_FLAGS}" STREQUAL "")
set(CMAKE_SHARED_LINKER_FLAGS "-mp")
endif()
endif()

if(CMAKE_COMPILER_IS_CLANG)
if("${CMAKE_C_FLAGS}" STREQUAL "${CMAKE_CXX_FLAGS_DEFAULT}")
string(APPEND CMAKE_C_FLAGS " -Wall -Wextra")
endif()
if("${CMAKE_CXX_FLAGS}" STREQUAL "")
set(CMAKE_CXX_FLAGS "-ftemplate-depth=1024 -Wno-invalid-offsetof ${SSE_FLAGS} ${AVX_FLAGS}") # Unfortunately older Clang versions do not have this: -Wno-unnamed-type-template-args
if(APPLE AND WITH_CUDA AND CUDA_FOUND)
string(APPEND CMAKE_CXX_FLAGS " -stdlib=libstdc++")
endif()
string(APPEND CMAKE_CXX_FLAGS " -Wall -Wextra")
endif()
set(CLANG_LIBRARIES "stdc++")
endif()

include("${PCL_SOURCE_DIR}/cmake/pcl_utils.cmake")
DISSECT_VERSION()
GET_OS_INFO()
SET_INSTALL_DIRS()

if(WIN32)
set(PCL_RESOURCES_DIR "${PCL_SOURCE_DIR}/resources")
set(PCL_POINTCLOUDS_DIR "${PCL_RESOURCES_DIR}/pointclouds")
endif()

#Set up output directory for builds
set(PCL_OUTPUT_LIB_DIR "${PCL_BINARY_DIR}/${LIB_INSTALL_DIR}")
set(PCL_OUTPUT_BIN_DIR "${PCL_BINARY_DIR}/${BIN_INSTALL_DIR}")
file(MAKE_DIRECTORY "${PCL_OUTPUT_LIB_DIR}")
Expand Down Expand Up @@ -285,6 +100,7 @@ if(CMAKE_GENERATOR_IS_IDE)
else()
set(UNINSTALL_TARGET_NAME uninstall)
endif()

configure_file("${PCL_SOURCE_DIR}/cmake/uninstall_target.cmake.in"
"${PCL_BINARY_DIR}/uninstall_target.cmake" IMMEDIATE @ONLY)
add_custom_target(${UNINSTALL_TARGET_NAME} "${CMAKE_COMMAND}" -P
Expand All @@ -304,44 +120,6 @@ set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}")
endif()

### ---[ Find universal dependencies

# OpenMP (optional)
option(WITH_OPENMP "Build with parallelization using OpenMP" TRUE)
option(USE_HOMEBREW_FALLBACK "(macOS-only) also look in 'brew --prefix' for libraries (e.g. OpenMP)" TRUE)
if(WITH_OPENMP)
find_package(OpenMP COMPONENTS C CXX)
if(APPLE AND NOT OpenMP_FOUND)
if(USE_HOMEBREW_FALLBACK)
# libomp 15.0+ from brew is keg-only, so have to search in other locations.
# See https://github.com/Homebrew/homebrew-core/issues/112107#issuecomment-1278042927.
execute_process(COMMAND brew --prefix libomp
OUTPUT_VARIABLE HOMEBREW_LIBOMP_PREFIX
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -I${HOMEBREW_LIBOMP_PREFIX}/include")
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I${HOMEBREW_LIBOMP_PREFIX}/include")
set(OpenMP_C_LIB_NAMES omp)
set(OpenMP_CXX_LIB_NAMES omp)
set(OpenMP_omp_LIBRARY ${HOMEBREW_LIBOMP_PREFIX}/lib/libomp.dylib)
find_package(OpenMP COMPONENTS C CXX)
endif()
endif()
endif()
if(OpenMP_FOUND)
string(APPEND CMAKE_C_FLAGS " ${OpenMP_C_FLAGS}")
string(APPEND CMAKE_CXX_FLAGS " ${OpenMP_CXX_FLAGS}")

# We could use OpenMP_CXX_VERSION starting from CMake 3.9, but this value is only available on first run of CMake (see https://gitlab.kitware.com/cmake/cmake/issues/19150),
# so we use always OpenMP_CXX_SPEC_DATE, which is available since CMake 3.7.
message(STATUS "Found OpenMP, spec date ${OpenMP_CXX_SPEC_DATE}")

if((MSVC_VERSION EQUAL 1900) OR (MSVC_VERSION MATCHES "^191[0-9]$"))
string(APPEND CMAKE_SHARED_LINKER_FLAGS_DEBUG " /DELAYLOAD:VCOMP140D.dll")
string(APPEND CMAKE_SHARED_LINKER_FLAGS_RELEASE " /DELAYLOAD:VCOMP140.dll")
endif()
else()
message(STATUS "Not found OpenMP")
endif()

# Threads (required)
find_package(Threads REQUIRED)

Expand Down Expand Up @@ -469,6 +247,8 @@ if(WITH_SYSTEM_CJSON)
endif()

set(CMAKE_REQUIRED_LIBRARIES Eigen3::Eigen) # so that Eigen/Core is found below
string(REPLACE ";" " " PCL_PUBLIC_COMPILE_OPTIONS_STR "${PCL_PUBLIC_COMPILER_OPTIONS}")
set(CMAKE_REQUIRED_FLAGS ${PCL_PUBLIC_COMPILE_OPTIONS_STR})
CHECK_CXX_SOURCE_COMPILES("
#include <Eigen/Core>
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
Expand All @@ -482,10 +262,11 @@ else()
set(PCL_USES_EIGEN_HANDMADE_ALIGNED_MALLOC 0)
endif()
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_FLAGS)

### --[ Set variables for pcl_config.h
if (BUILD_visualization)
set(PCL_VISUALIZATION_AVAILABLE TRUE)
set(visualization_AVAILABLE TRUE)
endif()

### ---[ Create the config.h file
Expand All @@ -504,6 +285,13 @@ foreach(subdir ${PCL_MODULES_DIRS})
add_subdirectory("${PCL_SOURCE_DIR}/${subdir}")
endforeach()


install(
EXPORT PCLTargets
NAMESPACE PCL::
DESTINATION cmake
)

### ---[ Documentation
add_subdirectory(doc)

Expand Down
Loading
Loading