Skip to content

Commit

Permalink
Modern CMake for CPU code
Browse files Browse the repository at this point in the history
Use an interface library for compiler flags instead of populating
variable CMAKE_CXX_FLAGS with global scope that CMake will inject
in the compilation of all libraries. Document CMake policies and
add CMP0025 to distinguish between Clang and AppleClang. Replace
simple if/else blocks by generator expressions.
  • Loading branch information
jngrad committed Apr 11, 2020
1 parent 8ea5f0d commit b6a485c
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 116 deletions.
138 changes: 66 additions & 72 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,21 @@

cmake_minimum_required(VERSION 3.10)
message(STATUS "CMake version: ${CMAKE_VERSION}")
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.13)
if(POLICY CMP0076)
# make target_sources() convert relative paths to absolute
cmake_policy(SET CMP0076 NEW)
endif()
if(POLICY CMP0025)
# make CXX_COMPILER_ID return "AppleClang" instead of "Clang" for Apple Clang
cmake_policy(SET CMP0025 NEW)
endif()
include(FeatureSummary)
include(GNUInstallDirs)
project(ESPResSo)
include(cmake/FindPythonModule.cmake)
include(cmake/option_enum.cmake)
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.12")
if(POLICY CMP0074)
# make find_package() use <PackageName>_ROOT variables
cmake_policy(SET CMP0074 NEW)
endif()

Expand All @@ -52,8 +58,8 @@ option_enum(
varname "CMAKE_BUILD_TYPE" help_text "build type" default_value "Release"
possible_values
"Debug;Release;RelWithDebInfo;MinSizeRel;Coverage;RelWithAssert")
set(CMAKE_CXX_FLAGS_COVERAGE "-Og -g")
set(CMAKE_CXX_FLAGS_RELWITHASSERT "-O3 -g")
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -Og -g")
set(CMAKE_CXX_FLAGS_RELWITHASSERT "${CMAKE_CXX_FLAGS_RELWITHASSERT} -O3 -g")

# On Mac OS X, first look for other packages, then frameworks
set(CMAKE_FIND_FRAMEWORK LAST)
Expand All @@ -71,16 +77,16 @@ option(WITH_SCAFACOS "Build with Scafacos support" OFF)
option(WITH_BENCHMARKS "Enable benchmarks" OFF)
option(WITH_VALGRIND_INSTRUMENTATION
"Build with valgrind instrumentation markers" OFF)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
option(WITH_CLANG_TIDY "Run Clang-Tidy during compilation" OFF)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL
"GNU")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL
"GNU")
option(WITH_COVERAGE "Generate code coverage report" OFF)
option(WITH_ASAN "Build with address sanitizer" OFF)
option(WITH_UBSAN "Build with undefined behavior sanitizer" OFF)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT APPLE)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE)
option(
WITH_MSAN
"Build with memory sanitizer (experimental; requires a memory-sanitized Python interpreter)"
Expand Down Expand Up @@ -148,7 +154,7 @@ if(WITH_CUDA)
set(ROCM_HOME "/opt/rocm" CACHE FILEPATH "Path to AMD ROCm")
list(APPEND CMAKE_MODULE_PATH "${ROCM_HOME}/hip/cmake")
find_package(HIP 1.5.18494 MODULE REQUIRED)
# patch HCC_PATH environment variable and reload HIP (for ROCm 3.0/3.1)
# patch HCC_PATH environment variable and reload HIP
if(HIP_VERSION VERSION_LESS "3.1")
set(HCC_PATH "${HIP_ROOT_DIR}")
else()
Expand Down Expand Up @@ -328,70 +334,55 @@ set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTDIR}/espressomd")
# drop 'lib' prefix from all libraries
set(CMAKE_SHARED_LIBRARY_PREFIX "")

if(WARNINGS_ARE_ERRORS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif(WARNINGS_ARE_ERRORS)

add_library(coverage_interface INTERFACE)
target_compile_options(
coverage_interface
INTERFACE
"$<$<BOOL:${WITH_COVERAGE}>:-g>"
"$<$<AND:$<BOOL:${WITH_COVERAGE}>,$<CXX_COMPILER_ID:Clang>>:-fprofile-instr-generate>"
"$<$<AND:$<BOOL:${WITH_COVERAGE}>,$<CXX_COMPILER_ID:Clang>>:-fcoverage-mapping>"
"$<$<AND:$<BOOL:${WITH_COVERAGE}>,$<NOT:$<CXX_COMPILER_ID:Clang>>>:--coverage>"
"$<$<AND:$<BOOL:${WITH_COVERAGE}>,$<NOT:$<CXX_COMPILER_ID:Clang>>>:-fprofile-arcs>"
"$<$<AND:$<BOOL:${WITH_COVERAGE}>,$<NOT:$<CXX_COMPILER_ID:Clang>>>:-ftest-coverage>"
)

set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-sign-compare -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-missing-braces"
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_PROCESSOR MATCHES
"arm")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi")
if(WITH_COVERAGE)
list(
APPEND
coverage_interface_flags
-g
$<IF:$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>,-fprofile-instr-generate;-fcoverage-mapping,--coverage;-fprofile-arcs;-ftest-coverage>
)
target_compile_options(coverage_interface
INTERFACE ${coverage_interface_flags})
target_link_libraries(
coverage_interface
INTERFACE
${coverage_interface_flags}
$<$<NOT:$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>>:gcov>
)
endif()
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Intel"
AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION
VERSION_LESS "7.0.0"))
# disable warnings from -Wextra
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-implicit-fallthrough")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# disable warnings from -Wextra
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wno-clobbered -Wno-cast-function-type")

if(CMAKE_SYSTEM_PROCESSOR MATCHES "[xX]86")
set(ARCH_X86 TRUE)
else()
set(ARCH_X86 FALSE)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
list(
APPEND
cxx_interface_flags
-Wall
-Wextra
$<$<BOOL:${WARNINGS_ARE_ERRORS}>:-Werror>
# disable warnings from -Wextra
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd592")
endif()
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_ID
STREQUAL "Intel")
# G++ and Intel don't know this flag
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-private-field")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wno-gnu-zero-variadic-macro-arguments")
endif()
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_VERSION
VERSION_GREATER "4.8.5")
# older versions don't support -Wno-pedantic which we need in src/python
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND CMAKE_CXX_COMPILER_VERSION
VERSION_LESS "16.0")
-Wno-sign-compare
-Wno-unused-function
-Wno-unused-variable
-Wno-unused-parameter
-Wno-missing-braces
$<$<AND:$<CXX_COMPILER_ID:GNU>,$<STREQUAL:${CMAKE_SYSTEM_PROCESSOR},arm>>:-Wno-psabi>
$<$<AND:$<NOT:$<CXX_COMPILER_ID:Intel>>,$<NOT:$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7.0.0>>>>:-Wno-implicit-fallthrough>
$<$<CXX_COMPILER_ID:GNU>:-Wno-clobbered;-Wno-cast-function-type>
$<$<CXX_COMPILER_ID:Intel>:-wd592>
$<$<AND:$<NOT:$<CXX_COMPILER_ID:GNU>>,$<NOT:$<CXX_COMPILER_ID:Intel>>>:-Wno-unused-private-field>
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-gnu-zero-variadic-macro-arguments>
# older GCC versions don't support -Wno-pedantic which we need in src/python
$<$<NOT:$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_LESS_EQUAL:$<CXX_COMPILER_VERSION>,4.8.5>>>:-pedantic>
# workaround for compiler crash related to decltype() and variadic template
# usage inside Boost
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_NO_CXX11_VARIADIC_TEMPLATES")
endif()

# prevent 80-bit arithmetic on old Intel processors
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_SIZEOF_VOID_P EQUAL 4
AND CMAKE_SYSTEM_PROCESSOR MATCHES "[xX]86")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffloat-store")
endif()
$<$<AND:$<CXX_COMPILER_ID:Intel>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,16.0>>:-DBOOST_NO_CXX11_VARIADIC_TEMPLATES>
# prevent 80-bit arithmetic on old Intel processors
$<$<AND:$<CXX_COMPILER_ID:GNU>,$<EQUAL:${CMAKE_SIZEOF_VOID_P},4>,$<BOOL:${ARCH_X86}>>:-ffloat-store>
)

set(CMAKE_MACOSX_RPATH TRUE)

Expand All @@ -402,18 +393,21 @@ if(WITH_ASAN AND WITH_MSAN)
endif()
if(WITH_ASAN)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -O1")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
list(APPEND cxx_interface_flags -fsanitize=address -fno-omit-frame-pointer)
endif()
if(WITH_MSAN)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -O1")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -fsanitize=memory -fno-omit-frame-pointer")
list(APPEND cxx_interface_flags -fsanitize=memory -fno-omit-frame-pointer)
endif()
if(WITH_UBSAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
list(APPEND cxx_interface_flags -fsanitize=undefined)
endif()

add_library(cxx_interface INTERFACE)
target_compile_options(cxx_interface INTERFACE ${cxx_interface_flags})
target_link_libraries(cxx_interface INTERFACE ${cxx_interface_flags})
target_link_libraries(cxx_interface INTERFACE coverage_interface)

#
# Testing
# ##############################################################################
Expand Down
2 changes: 1 addition & 1 deletion cmake/unit_test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function(UNIT_TEST)
# Build tests only when testing
set_target_properties(${TEST_NAME} PROPERTIES EXCLUDE_FROM_ALL ON)
target_link_libraries(${TEST_NAME} PRIVATE Boost::unit_test_framework)
target_link_libraries(${TEST_NAME} PUBLIC coverage_interface)
target_link_libraries(${TEST_NAME} PRIVATE cxx_interface)
if(TEST_DEPENDS)
target_link_libraries(${TEST_NAME} PRIVATE ${TEST_DEPENDS})
endif()
Expand Down
17 changes: 6 additions & 11 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ set(EspressoCore_SRC
PartCfg.cpp)

if(CUDA)
list(APPEND EspressoCore_SRC
cuda_init.cpp
cuda_interface.cpp
list(APPEND EspressoCore_SRC cuda_init.cpp cuda_interface.cpp
grid_based_algorithms/electrokinetics.cpp
grid_based_algorithms/lbgpu.cpp)
set(EspressoCuda_SRC
Expand Down Expand Up @@ -78,12 +76,10 @@ target_link_libraries(
EspressoCore
PRIVATE EspressoConfig shapes Profiler
"$<$<BOOL:${FFTW3_FOUND}>:${FFTW3_LIBRARIES}>"
"$<$<BOOL:${SCAFACOS}>:Scafacos>"
PUBLIC
coverage_interface utils MPI::MPI_CXX Random123 Boost::serialization
Boost::mpi "$<$<BOOL:${H5MD}>:${HDF5_LIBRARIES}>"
"$<$<BOOL:${H5MD}>:Boost::filesystem>" "$<$<BOOL:${H5MD}>:h5xx>"
"$<$<AND:$<BOOL:${WITH_COVERAGE}>,$<NOT:$<CXX_COMPILER_ID:Clang>>>:gcov>")
$<$<BOOL:${SCAFACOS}>:Scafacos> cxx_interface
PUBLIC utils MPI::MPI_CXX Random123 Boost::serialization Boost::mpi
"$<$<BOOL:${H5MD}>:${HDF5_LIBRARIES}>"
$<$<BOOL:${H5MD}>:Boost::filesystem> $<$<BOOL:${H5MD}>:h5xx>)

target_include_directories(
EspressoCore
Expand All @@ -92,8 +88,7 @@ target_include_directories(
PUBLIC "$<$<BOOL:${H5MD}>:${HDF5_INCLUDE_DIRS}>" SYSTEM
PRIVATE "$<$<BOOL:${FFTW3_FOUND}>:${FFTW3_INCLUDE_DIR}>")

target_compile_definitions(EspressoCore
PUBLIC "$<$<BOOL:${H5MD}>:H5XX_USE_MPI>")
target_compile_definitions(EspressoCore PUBLIC $<$<BOOL:${H5MD}>:H5XX_USE_MPI>)

if(CUDA)
target_link_libraries(EspressoCuda PRIVATE EspressoConfig shapes utils)
Expand Down
2 changes: 1 addition & 1 deletion src/core/cluster_analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ install(TARGETS core_cluster_analysis
LIBRARY DESTINATION ${PYTHON_INSTDIR}/espressomd)
set_target_properties(core_cluster_analysis PROPERTIES MACOSX_RPATH TRUE)
target_link_libraries(core_cluster_analysis PUBLIC EspressoCore
PRIVATE EspressoConfig)
PRIVATE EspressoConfig cxx_interface)

if(GSL)
target_link_libraries(core_cluster_analysis PRIVATE GSL::gsl GSL::gslcblas)
Expand Down
3 changes: 2 additions & 1 deletion src/core/io/mpiio/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_library(mpiio SHARED mpiio.cpp)
target_include_directories(mpiio PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(mpiio PRIVATE EspressoConfig EspressoCore MPI::MPI_CXX)
target_link_libraries(mpiio PRIVATE EspressoConfig EspressoCore MPI::MPI_CXX
cxx_interface)
install(TARGETS mpiio LIBRARY DESTINATION ${PYTHON_INSTDIR}/espressomd)
42 changes: 16 additions & 26 deletions src/python/espressomd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ add_subdirectory(io)
list(APPEND cython_SRC ${CMAKE_CURRENT_BINARY_DIR}/code_info.pyx)
list(REMOVE_DUPLICATES cython_SRC)

list(
APPEND
pyx_interface_flags
$<$<CXX_COMPILER_ID:GNU>:-Wno-pedantic;-Wno-cpp;-Wno-strict-aliasing;-Wno-maybe-uninitialized;-Wno-unused-variable>
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-pedantic;-Wno-\#warnings;-Wno-sometimes-uninitialized;-Wno-unused-variable>
$<$<CXX_COMPILER_ID:Intel>:-wd1224>
$<$<NOT:$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Intel>>>:-Wno-pedantic;-Wno-unused-variable>
)
add_library(pyx_interface INTERFACE)
target_compile_options(pyx_interface INTERFACE ${pyx_interface_flags})
target_link_libraries(pyx_interface INTERFACE ${pyx_interface_flags}
cxx_interface)

# Configure, compile and install Cython files
foreach(cython_file ${cython_SRC})
get_filename_component(basename ${cython_file} NAME_WE)
Expand All @@ -79,9 +92,8 @@ foreach(cython_file ${cython_SRC})
add_custom_command(
OUTPUT ${outputpath}
COMMAND
${CYTHON_EXECUTABLE}
"$<$<BOOL:${WARNINGS_ARE_ERRORS}>:--warning-errors>" -3 --cplus
--directive embedsignature=True --directive binding=True -I
${CYTHON_EXECUTABLE} $<$<BOOL:${WARNINGS_ARE_ERRORS}>:--warning-errors>
-3 --cplus --directive embedsignature=True --directive binding=True -I
${CMAKE_CURRENT_SOURCE_DIR} -I ${CMAKE_CURRENT_BINARY_DIR}
${cython_file} -o ${outputpath}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..
Expand All @@ -100,32 +112,10 @@ foreach(cython_file ${cython_SRC})
${target} PROPERTIES SUFFIX ".so" LINK_FLAGS
"-undefined dynamic_lookup")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set_source_files_properties(
${outputpath}
PROPERTIES
COMPILE_FLAGS
"-Wno-pedantic -Wno-cpp -Wno-strict-aliasing -Wno-maybe-uninitialized -Wno-unused-variable"
)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID
STREQUAL "AppleClang")
set_source_files_properties(
${outputpath}
PROPERTIES
COMPILE_FLAGS
"-Wno-pedantic -Wno-#warnings -Wno-sometimes-uninitialized -Wno-unused-variable"
)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
set_source_files_properties(${outputpath} PROPERTIES COMPILE_FLAGS
"-wd1224")
else()
set_source_files_properties(
${outputpath} PROPERTIES COMPILE_FLAGS
"-Wno-pedantic -Wno-unused-variable")
endif()
set_target_properties(${target} PROPERTIES CXX_CLANG_TIDY "")
target_link_libraries(${target} PRIVATE EspressoConfig EspressoCore
ScriptInterface)
target_link_libraries(${target} PRIVATE pyx_interface)
target_include_directories(${target} SYSTEM PRIVATE ${PYTHON_INCLUDE_DIRS}
${NUMPY_INCLUDE_DIR})
add_dependencies(espressomd ${target})
Expand Down
2 changes: 1 addition & 1 deletion src/scafacos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ add_library(Scafacos SHARED ${Scafacos_SRC})
target_include_directories(Scafacos PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
${SCAFACOS_INCLUDE_DIRS})
target_link_libraries(Scafacos PRIVATE ${SCAFACOS_LDFLAGS})
target_link_libraries(Scafacos PUBLIC MPI::MPI_CXX)
target_link_libraries(Scafacos PUBLIC MPI::MPI_CXX PRIVATE cxx_interface)

install(TARGETS Scafacos DESTINATION ${PYTHON_INSTDIR}/espressomd)
3 changes: 2 additions & 1 deletion src/script_interface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ install(TARGETS ScriptInterface

target_link_libraries(
ScriptInterface PRIVATE EspressoConfig EspressoCore
PUBLIC mpiio utils MPI::MPI_CXX shapes core_cluster_analysis)
PUBLIC mpiio utils MPI::MPI_CXX shapes core_cluster_analysis
PRIVATE cxx_interface)

target_include_directories(ScriptInterface PUBLIC ${CMAKE_SOURCE_DIR}/src)
2 changes: 1 addition & 1 deletion src/shapes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set(SOURCE_FILES
src/SpheroCylinder.cpp src/Stomatocyte.cpp src/Torus.cpp src/Wall.cpp)

add_library(shapes SHARED ${SOURCE_FILES})
target_link_libraries(shapes PUBLIC utils PRIVATE Boost::boost)
target_link_libraries(shapes PUBLIC utils PRIVATE Boost::boost cxx_interface)
target_include_directories(
shapes PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
Expand Down
2 changes: 1 addition & 1 deletion src/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
add_library(utils INTERFACE)
target_include_directories(
utils INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
$<INSTALL_INTERFACE:include> Boost::serialization Boost::mpi)

install(TARGETS utils LIBRARY DESTINATION ${PYTHON_INSTDIR}/espressomd)

Expand Down

0 comments on commit b6a485c

Please sign in to comment.