CMake Lists
CMake Lists
CMake Lists
5)
project(networkit CXX)
# BUILD OPTIONS
option(NETWORKIT_BUILD_CORE "Build NetworKit core library" ON)
option(NETWORKIT_BUILD_TESTS "Build NetworKit C++ tests" OFF)
option(NETWORKIT_QUIET_LOGGING "Set log level to QUIET by default (can still be
changed at run time)" OFF)
option(NETWORKIT_STATIC "Build static libraries" OFF)
option(NETWORKIT_MONOLITH "Build single library (and tests is requested; required
for shared lib)" ON)
option(NETWORKIT_NATIVE "Optimize for native architecture (often better
performance)" OFF)
option(NETWORKIT_WARNINGS "Issue more warnings" OFF)
option(NETWORKIT_WARNINGS_AS_ERRORS "Treat warnings as errors (except deprecated)"
OFF)
option(NETWORKIT_FLATINSTALL "Install into a flat directory structure (useful when
building a Python package)" OFF)
option(NETWORKIT_COVERAGE "Build with support for coverage" OFF)
set(NETWORKIT_PYTHON "" CACHE STRING "Directory containing Python.h. Implies
MONOLITH=TRUE")
set(NETWORKIT_PYTHON_SOABI "" CACHE STRING "Platform specific file extension.
Implies MONOLITH=TRUE")
set(NETWORKIT_WITH_SANITIZERS "" CACHE STRING "Uses sanitizers during the
compilation")
set(NETWORKIT_RELEASE_LOGGING "AUTO" CACHE STRING "Do not compile log messages at
levels TRACE or DEBUG (AUTO|ON|OFF)")
set(NETWORKIT_PYTHON_RPATH "" CACHE STRING "Build specific rpath references.")
set(NETWORKIT_EXT_TLX "" CACHE STRING "Absolute path for external tlx-library. If
not set, extlibs/tlx is used")
set(NETWORKIT_INSTALL_BIN_DIR "bin"
CACHE PATH "Installation directory for executables")
set(NETWORKIT_INSTALL_LIB_DIR "lib"
CACHE PATH "Installation directory for libraries")
set(NETWORKIT_INSTALL_INCLUDE_DIR "include"
CACHE PATH "Installation directory for header files")
set(NETWORKIT_INSTALL_PKGCONFIG_DIR "lib/pkgconfig"
CACHE PATH "Installation directory for pkg-config file")
if (NETWORKIT_PYTHON)
if (NOT NETWORKIT_MONOLITH)
message(FATAL_ERROR "When building NetworKit as a Python module,
NETWORKIT_MONOLITH=ON is required")
endif()
if(NOT NETWORKIT_PYTHON_SOABI)
message(WARNING "No platform-specific file extension provided. Do not
distribute library.")
endif()
endif()
if (NOT CMAKE_BUILD_TYPE)
message("Use Release Build Type as default")
set(CMAKE_BUILD_TYPE "Release")
endif()
################################################################################
# Compilation Flags
set(NETWORKIT_CXX_FLAGS "")
set(NETWORKIT_LINK_FLAGS "")
if (NETWORKIT_QUIET_LOGGING)
set(NETWORKIT_CXX_FLAGS "-DNETWORKIT_QUIET_LOGGING")
endif()
elseif (MSVC)
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} /DNETWORKIT_OMP2 /MP
/DNETWORKIT_WINDOWS")
# TTMath requires running an ASM for MSVC which we disable here at the cost
of worse performance
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} /DTTMATH_NOASM=1")
else()
message(WARNING "Support only GCC, Clang, MSVC and AppleClang. Your compiler
may or may not work.")
endif()
# finding or creating OpenMP target. This is likely to fail for CMake Version <
3.12.
find_package(OpenMP)
# FindOpenMP.cmake does not reliably find a user installed openmp library for
clang/llvm on
# both Linux- and macOS-systems (even for CMake Version >= 3.12). The following
section
# manually sets the required fields for clang-like compiler.
if(NOT OpenMP_FOUND)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
# This will find default libomp-installations for homebrew/MacPorts
find_library(LIBOMP_PATH NAMES omp PATHS "/usr/local/opt/libomp/lib"
"/opt/local/lib/libomp")
find_path(LIBOMP_INCLUDE NAMES omp.h PATHS
"/usr/local/opt/libomp/include" "/opt/local/include/libomp")
if(LIBOMP_PATH AND LIBOMP_INCLUDE)
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I$
{LIBOMP_INCLUDE}" CACHE STRING "Manually set" FORCE)
endif()
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if(DEFINED ENV{CONDA_PREFIX})
find_library(LIBOMP_PATH NAMES omp HINTS "$ENV{CONDA_PREFIX}/lib"
PATHS "/usr/lib" "/usr/lib64")
find_path(LIBOMP_INCLUDE NAMES omp.h HINTS
"$ENV{CONDA_PREFIX}/include"
PATHS "/usr/include")
else()
find_library(LIBOMP_PATH NAMES omp PATHS "/usr/lib" "/usr/lib64")
find_path(LIBOMP_INCLUDE NAMES omp.h PATHS "/usr/include")
endif()
if(LIBOMP_PATH AND LIBOMP_INCLUDE)
set(OpenMP_CXX_FLAGS "-fopenmp -I${LIBOMP_INCLUDE}" CACHE STRING
"Manually set" FORCE)
endif()
endif()
# Set OpenMP-folders in case they are found with the aid of additional hints
if(LIBOMP_PATH AND LIBOMP_INCLUDE)
set(OpenMP_CXX_LIB_NAMES "omp" CACHE STRING "Manually set" FORCE)
set(OpenMP_omp_LIBRARY "${LIBOMP_PATH}" CACHE STRING "Manually set"
FORCE)
else()
message(FATAL_ERROR "libomp was not found, but necessary to run
NetworKit with ${CMAKE_CXX_COMPILER_ID}")
endif()
if (CMAKE_SIZEOF_VOID_P LESS 8)
if (MSVC)
message(FATAL_ERROR "NetworKit supports only 64bit builds.
Make sure to select a x64 target rather than x86,
e.g. when invoking cmake with -G")
else()
message(FATAL_ERROR "NetworKit supports only 64bit builds")
endif()
endif()
if(NOT NETWORKIT_BUILD_CORE)
find_library(EXTERNAL_NETWORKIT_CORE NAMES networkit DOC "External NetworKit
core library")
endif()
if(NETWORKIT_FLATINSTALL)
set(NETWORKIT_LIB_DEST ".")
else()
set(NETWORKIT_LIB_DEST "lib/")
endif()
################################################################################
# Use TLX as a CMake submodule
if(NOT NETWORKIT_EXT_TLX)
if(EXISTS "${PROJECT_SOURCE_DIR}/extlibs/tlx/CMakeLists.txt")
add_subdirectory(extlibs/tlx)
else()
message(FATAL_ERROR
"Missing TLX library in extlibs/tlx "
"Please run `git submodule update --init` to fetch the
submodule.")
endif()
else()
add_library(tlx STATIC IMPORTED)
set_target_properties(tlx PROPERTIES
IMPORTED_LOCATION "${NETWORKIT_EXT_TLX}/lib/libtlx.a"
INTERFACE_INCLUDE_DIRECTORIES "${NETWORKIT_EXT_TLX}/include/")
endif()
################################################################################
# NETWORKIT MODULES
if(NETWORKIT_BUILD_CORE AND NETWORKIT_MONOLITH)
if(NETWORKIT_STATIC)
add_library(networkit networkit/cpp/networkit.cpp)
else()
add_library(networkit SHARED networkit/cpp/networkit.cpp)
endif()
set_target_properties(networkit PROPERTIES
CXX_STANDARD ${NETWORKIT_CXX_STANDARD}
COMPILE_FLAGS "${NETWORKIT_CXX_FLAGS}"
LINK_FLAGS "${NETWORKIT_LINK_FLAGS}")
install(TARGETS networkit
LIBRARY DESTINATION ${NETWORKIT_LIB_DEST}
ARCHIVE DESTINATION ${NETWORKIT_LIB_DEST})
if(NETWORKIT_PYTHON)
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/networkit/_NetworKit.cpp")
message(FATAL_ERROR "networkit/_NetworKit.cpp is missing. Invoke Cython
manually.")
endif()
if(NOT NETWORKIT_BUILD_CORE)
if(NOT EXTERNAL_NETWORKIT_CORE)
message(FATAL_ERROR "Core build is disabled but no external core
library was found.")
endif()
target_link_libraries(_NetworKit PRIVATE ${EXTERNAL_NETWORKIT_CORE})
else()
target_link_libraries(_NetworKit PRIVATE networkit)
endif()
set_target_properties(_NetworKit PROPERTIES
CXX_STANDARD ${NETWORKIT_CXX_STANDARD}
COMPILE_FLAGS "${NETWORKIT_CXX_FLAGS}"
LINK_FLAGS "${NETWORKIT_LINK_FLAGS}"
PREFIX ""
OUTPUT_NAME "_NetworKit.${NETWORKIT_PYTHON_SOABI}")
# If rpath-content is set explicitly, omit the dynamic binary path
if(NETWORKIT_PYTHON_RPATH)
set_target_properties(_NetworKit PROPERTIES
INSTALL_RPATH "${NETWORKIT_PYTHON_RPATH}")
else()
# DSOs on Apple OSes use different conventions for RPATH.
if(APPLE)
set_target_properties(_NetworKit PROPERTIES
INSTALL_RPATH "@loader_path")
else()
set_target_properties(_NetworKit PROPERTIES
INSTALL_RPATH "$ORIGIN")
endif()
endif()
install(TARGETS _NetworKit
LIBRARY DESTINATION ${NETWORKIT_LIB_DEST})
endif()
if(NETWORKIT_MONOLITH)
# in case we are building a monolith, no submodule are registered
# and we simple add the source file to the networkkit target
set(MODULE_TARGET "networkit")
else()
set(MODULE_TARGET "networkit_${modname}")
add_library(${MODULE_TARGET}
${PROJECT_SOURCE_DIR}/networkit/cpp/networkit.cpp)
set_target_properties(${MODULE_TARGET} PROPERTIES
CXX_STANDARD ${NETWORKIT_CXX_STANDARD}
COMPILE_FLAGS "${NETWORKIT_CXX_FLAGS}"
LINK_FLAGS "${NETWORKIT_LINK_FLAGS}")
# All tests added to this module will will also become a dependency
# of networkit_tests_MODNAME. This target hence allows to build all
# tests associated with this module
if (NETWORKIT_BUILD_TESTS)
add_custom_target(networkit_tests_${modname})
endif()
endif()
if(NOT NETWORKIT_BUILD_CORE)
return()
endif()
if(NOT NETWORKIT_MONOLITH)
target_link_libraries(networkit_${modname}
PRIVATE ${NMLL_PRIVATE}
PUBLIC ${NMLL_PUBLIC})
endif()
endfunction()
if(NOT NETWORKIT_MONOLITH)
foreach(dep IN LISTS ARGN)
target_link_libraries(networkit_${modname} PUBLIC networkit_$
{dep})
endforeach()
endif()
endfunction()
################################################################################
# TESTING and BENCHMARKING
if (NETWORKIT_BUILD_TESTS)
enable_testing()
if(EXISTS "${PROJECT_SOURCE_DIR}/extlibs/googletest/CMakeLists.txt")
if (MSVC)
# While by default MSVC projects link against the shared runtime
library
# (and hence also NetworKit), GTest defaults to the static
runtime lib.
# Both must not be mix, so we request GTest here to also use the
shared CRT.
set( gtest_force_shared_crt ON CACHE BOOL "Always use msvcrt.dll"
FORCE)
endif()
option(BUILD_GTEST "Builds the googletest subproject" ON)
option(BUILD_GMOCK "Builds the googlemock subproject" OFF)
add_subdirectory(extlibs/googletest)
else()
message(FATAL_ERROR
"Missing GoogleTest and GoogleMock in extlibs/googletest. "
"Please run `git submodule update --init` to fetch the
submodule.")
endif()
if (NETWORKIT_MONOLITH)
add_executable(networkit_tests networkit/cpp/Unittests-X.cpp)
target_link_libraries(networkit_tests
PRIVATE
gtest
networkit
tlx
OpenMP::OpenMP_CXX
)
set_target_properties(networkit_tests PROPERTIES
CXX_STANDARD ${NETWORKIT_CXX_STANDARD}
COMPILE_FLAGS "${NETWORKIT_CXX_FLAGS}"
LINK_FLAGS "${NETWORKIT_LINK_FLAGS}")
add_test(
NAME networkit_tests
COMMAND networkit_tests -t --srcloc
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
add_test(
NAME networkit_tests_no_assertions
COMMAND networkit_tests -r --srcloc
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
else()
add_library(networkit_gtest_main STATIC networkit/cpp/Unittests-X.cpp)
set_target_properties(networkit_gtest_main PROPERTIES
CXX_STANDARD ${NETWORKIT_CXX_STANDARD}
COMPILE_FLAGS "${NETWORKIT_CXX_FLAGS}"
LINK_FLAGS "${NETWORKIT_LINK_FLAGS}")
target_link_libraries(networkit_gtest_main
PUBLIC
gtest
PRIVATE
tlx
networkit_auxiliary
OpenMP::OpenMP_CXX
)
endif()
endif()
if (NETWORKIT_MONOLITH)
target_sources(networkit_tests PRIVATE ${TEST_SOURCE})
else()
if (NOT TARGET networkit_${MOD})
MESSAGE(FATAL_ERROR "Unknown NetworKit module '${MOD}'")
endif()
set(TARGET_NAME "networkit_${MOD}_${NAME}")
add_executable(${TARGET_NAME} ${TEST_SOURCE})
target_link_libraries(${TARGET_NAME}
PRIVATE
gtest networkit_gtest_main
PRIVATE
networkit_${MOD}
tlx
OpenMP::OpenMP_CXX
)
set_target_properties(${TARGET_NAME} PROPERTIES
CXX_STANDARD ${NETWORKIT_CXX_STANDARD}
COMPILE_FLAGS "${NETWORKIT_CXX_FLAGS}"
LINK_FLAGS "${NETWORKIT_LINK_FLAGS}")
if (${IS_TEST})
add_dependencies(networkit_tests_${MOD} ${TARGET_NAME})
add_test(
NAME "${MOD}/${NAME}"
COMMAND ${TARGET_NAME} -t --srcloc
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
add_test(
NAME "${MOD}/${NAME}_no_assertions"
COMMAND ${TARGET_NAME} -r --srcloc
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
endif()
endif()
endif()
endfunction()
################################################################################
# Benchmarks
target_link_libraries(networkit_benchmarks
PRIVATE
benchmark_main benchmark
networkit
)
set_target_properties(networkit_tests PROPERTIES
CXX_STANDARD ${NETWORKIT_CXX_STANDARD}
COMPILE_FLAGS "${NETWORKIT_CXX_FLAGS}"
LINK_FLAGS "${NETWORKIT_LINK_FLAGS}")
endif()
if (NETWORKIT_MONOLITH)
target_sources(networkit_benchmarks PRIVATE ${BENCH_SOURCE})
else()
if (NOT TARGET networkit_${MOD})
MESSAGE(FATAL_ERROR "Unknown NetworKit module '${MOD}'")
endif()
set(TARGET_NAME "networkit_${MOD}_${NAME}")
add_executable(${TARGET_NAME} ${BENCH_SOURCE})
message("${TARGET_NAME}: ${BENCH_SOURCE}")
target_link_libraries(${TARGET_NAME}
PRIVATE
benchmark_main benchmark
networkit_${MOD})
set_target_properties(${TARGET_NAME} PROPERTIES
CXX_STANDARD ${NETWORKIT_CXX_STANDARD}
COMPILE_FLAGS "${NETWORKIT_CXX_FLAGS}"
LINK_FLAGS "${NETWORKIT_LINK_FLAGS}")
################################################################################
# Documentation
find_program(SPHINX_EXECUTABLE
NAMES
sphinx-build sphinx-build.exe
PATHS
/usr/bin
/usr/local/bin
/opt/local/bin
DOC "Sphinx documentation generator")
if (NOT SPHINX_EXECUTABLE)
message(STATUS "sphinx-build not found. Disable documentation targets")
else()
message(STATUS "Found sphinx-build: ${SPHINX_EXECUTABLE}")
add_custom_target(general_docs
COMMAND rm -rf htmldocs
COMMAND ${SPHINX_EXECUTABLE} ${CMAKE_SOURCE_DIR}/docs htmldocs)
################################################################################
# Subdirectories
add_subdirectory(networkit/cpp)
################################################################################
# Prepare pkg-config file
set(NETWORKIT_LIBNAME networkit)
execute_process(COMMAND python3 -c "from version import version; print(version,
end='')"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE NETWORKIT_VERSION)
configure_file(networkit.pc
"${PROJECT_BINARY_DIR}/${NETWORKIT_LIBNAME}.pc" @ONLY)
if(NETWORKIT_INSTALL_PKGCONFIG_DIR)
INSTALL(FILES ${PROJECT_BINARY_DIR}/${NETWORKIT_LIBNAME}.pc
DESTINATION ${NETWORKIT_INSTALL_PKGCONFIG_DIR})
endif()