forked from networkit/networkit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCMakeLists.txt
729 lines (609 loc) · 25.5 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
cmake_minimum_required(VERSION 3.14)
project(networkit CXX)
if("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
message(SEND_ERROR "In-source builds are not allowed.")
endif("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
# 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" OFF)
option(NETWORKIT_CLANG_TIDY "Check code with clang-tidy" 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)
option(NETWORKIT_SANITY_CHECKS "Algorithms will perform further (expensive) checks" OFF)
set(NETWORKIT_PYTHON "" CACHE STRING "Directory containing Python.h. Implies MONOLITH=TRUE")
set(NETWORKIT_NUMPY "" CACHE STRING "Directory containing Numpy.h.")
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_CXX_STANDARD "20" CACHE STRING "CXX Version to compile with. Currently fixed to 20")
# Allow user to set installation paths relative to CMAKE_INSTALL_PREFIX
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()
if (NETWORKIT_RELEASE_LOGGING STREQUAL "AUTO")
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
set(NETWORKIT_RELEASE_LOGGING "ON")
else()
set(NETWORKIT_RELEASE_LOGGING "OFF")
endif()
endif()
if (NETWORKIT_RELEASE_LOGGING STREQUAL "ON")
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} -DNETWORKIT_RELEASE_LOGGING")
elseif(NOT NETWORKIT_RELEASE_LOGGING STREQUAL "OFF")
message(FATAL_ERROR "Unsupported setting ${NETWORKIT_RELEASE_LOGGING} for NETWORKIT_RELEASE_LOGGING")
endif()
if (("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") OR
("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") OR
("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang"))
if (NETWORKIT_NATIVE)
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} -march=native")
endif()
if (NETWORKIT_WARNINGS)
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} -Wall -Wextra -Wpedantic")
endif()
if (NETWORKIT_WARNINGS_AS_ERRORS)
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} -Werror")
endif()
elseif (MSVC)
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} /DNETWORKIT_OMP2 /MP /DNETWORKIT_WINDOWS /permissive-")
# 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")
if (NETWORKIT_NATIVE)
message(WARNING "Compiling NetworKit with native instructions is not yet supported by MSVC. Activating AVX2-support if possible.")
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("/arch:AVX2" COMPILER_OPT_ARCH_AVX_SUPPORTED)
if(COMPILER_OPT_ARCH_AVX_SUPPORTED)
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} /arch:AVX2")
endif()
endif()
else()
message(WARNING "Support only GCC, Clang, MSVC and AppleClang. Your compiler may or may not work.")
endif()
# Checking sanitizer options; in both cases we include 'undefined'
set(NETWORKIT_CXX_SANITIZERS "")
if ("${NETWORKIT_WITH_SANITIZERS}" STREQUAL "address")
set(NETWORKIT_CXX_SANITIZERS "address,undefined")
elseif ("${NETWORKIT_WITH_SANITIZERS}" STREQUAL "leak")
set(NETWORKIT_CXX_SANITIZERS "address,leak,undefined")
elseif(NOT "${NETWORKIT_WITH_SANITIZERS}" STREQUAL "")
message(FATAL_ERROR "Unsupported option ${NETWORKIT_WITH_SANITIZERS}")
endif()
if (NOT "${NETWORKIT_CXX_SANITIZERS}" STREQUAL "")
set(NETWORKIT_CXX_FLAGS "-fsanitize=${NETWORKIT_CXX_SANITIZERS} ${NETWORKIT_CXX_FLAGS}")
set(NETWORKIT_LINK_FLAGS "-fsanitize=${NETWORKIT_CXX_SANITIZERS} ${NETWORKIT_LINK_FLAGS}")
endif()
# Check if coverage support is enabled
if (NETWORKIT_COVERAGE)
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} --coverage")
set(NETWORKIT_LINK_FLAGS "${NETWORKIT_LINK_FLAGS} --coverage")
endif()
################################################################################
# ENABLE ADDITIONAL SANITY CHECKS
if (NETWORKIT_SANITY_CHECKS)
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} -DNETWORKIT_SANITY_CHECKS")
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" "/opt/homebrew/opt/libomp/lib")
find_path(LIBOMP_INCLUDE NAMES omp.h PATHS "/usr/local/opt/libomp/include" "/opt/local/include/libomp" "/opt/homebrew/opt/libomp/include")
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()
# After setting basic OpenMP-folders, run find_package again to set everything. Also acts as a final sanity check.
find_package(OpenMP REQUIRED)
endif()
if(NOT TARGET OpenMP::OpenMP_CXX)
message("Creating custom OpenMP target for CMake Version < 3.12. Current CMake Version ${CMAKE_VERSION}")
find_package(Threads REQUIRED)
add_library(OpenMP::OpenMP_CXX IMPORTED INTERFACE)
set_property(TARGET OpenMP::OpenMP_CXX
PROPERTY INTERFACE_COMPILE_OPTIONS ${OpenMP_CXX_FLAGS})
set_property(TARGET OpenMP::OpenMP_CXX
PROPERTY INTERFACE_LINK_LIBRARIES ${OpenMP_CXX_FLAGS} Threads::Threads)
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()
# specify linking flags for MacOS
if (APPLE)
set(NETWORKIT_LINK_FLAGS "-undefined dynamic_lookup ${NETWORKIT_LINK_FLAGS}")
endif()
if(NOT NETWORKIT_BUILD_CORE)
if(WIN32)
message(FATAL_ERROR "Make sure to enable NETWORKIT_BUILD_CORE. NetworKit on Windows does not support Python-builds with external core-libs.")
endif()
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/${CMAKE_SHARED_LIBRARY_PREFIX}tlx${CMAKE_STATIC_LIBRARY_SUFFIX}"
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()
if(WIN32)
message(FATAL_ERROR
"Windows does only support static builds. Call cmake with '-DNETWORKIT_STATIC=ON'.")
endif()
add_library(networkit SHARED networkit/cpp/networkit.cpp)
endif()
if(WIN32)
# For Windows all global shared variables have to be exported additionally as dll
add_library(networkit_state SHARED networkit/cpp/GlobalState.cpp)
set_target_properties(networkit_state PROPERTIES
CXX_STANDARD ${NETWORKIT_CXX_STANDARD}
COMPILE_FLAGS "${NETWORKIT_CXX_FLAGS} /DNETWORKIT_BUILDING_STATELIB"
LINK_FLAGS "${NETWORKIT_LINK_FLAGS}")
install(TARGETS networkit_state
LIBRARY DESTINATION "${NETWORKIT_LIB_DEST}/networkit"
ARCHIVE DESTINATION "${NETWORKIT_LIB_DEST}/networkit"
RUNTIME DESTINATION "${NETWORKIT_LIB_DEST}/networkit")
target_link_libraries(networkit PUBLIC networkit_state)
target_link_libraries(networkit_state PUBLIC tlx)
target_include_directories(networkit_state BEFORE PUBLIC "${PROJECT_SOURCE_DIR}/include")
endif()
target_link_libraries(networkit PRIVATE OpenMP::OpenMP_CXX PUBLIC tlx)
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}
RUNTIME DESTINATION ${NETWORKIT_LIB_DEST})
target_include_directories(networkit BEFORE PUBLIC "${PROJECT_SOURCE_DIR}/include")
target_include_directories(networkit PUBLIC "${PROJECT_SOURCE_DIR}/extlibs/ttmath/")
endif()
################################################################################
# ENABLE CLANG-TIDY
if (NETWORKIT_CLANG_TIDY)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set_target_properties(networkit PROPERTIES CXX_CLANG_TIDY clang-tidy)
else()
message(FATAL_ERROR "clang-tidy is only supported when compiling with clang")
endif()
endif()
if(NETWORKIT_PYTHON)
if(WIN32)
# Linking against Python3_libs is only neccessary on Windows. On other OSes
# this can lead to segmentation faults when importing NetworKit in Python.
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
FIND_PACKAGE(FindPythonLibs ${NETWORKIT_PYTHON_VERSION} EXACT REQUIRED)
else()
FIND_PACKAGE(Python3 ${NETWORKIT_PYTHON_VERSION} EXACT COMPONENTS Interpreter Development REQUIRED)
endif()
endif()
foreach (EXT base centrality clique coarsening community components correlation
distance dynamics dynbase embedding engineering flow generators globals graph graphio
graphtools helpers independentset linkprediction matching
randomization reachability scd simulation sparsification stats
structures traversal viz)
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/networkit/${EXT}.cpp")
message(FATAL_ERROR "networkit/${EXT}.cpp is missing. Invoke Cython manually.")
endif()
set(TARGET_LIB ${EXT})
add_library(${TARGET_LIB} MODULE networkit/${EXT}.cpp)
target_include_directories(${TARGET_LIB} BEFORE PUBLIC "${PROJECT_SOURCE_DIR}/include")
target_include_directories(${TARGET_LIB} PRIVATE "${PROJECT_SOURCE_DIR}/extlibs/ttmath/")
target_include_directories(${TARGET_LIB} PRIVATE "${NETWORKIT_PYTHON}")
target_include_directories(${TARGET_LIB} PUBLIC "${NETWORKIT_NUMPY}")
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(${TARGET_LIB} PRIVATE ${EXTERNAL_NETWORKIT_CORE})
else()
target_link_libraries(${TARGET_LIB} PRIVATE networkit)
endif()
set_target_properties(${TARGET_LIB} PROPERTIES
CXX_STANDARD ${NETWORKIT_CXX_STANDARD}
COMPILE_FLAGS "${NETWORKIT_CXX_FLAGS}"
LINK_FLAGS "${NETWORKIT_LINK_FLAGS}"
PREFIX ""
OUTPUT_NAME "${TARGET_LIB}.${NETWORKIT_PYTHON_SOABI}")
if (NETWORKIT_BUILD_TESTS)
target_compile_definitions(${TARGET_LIB} PRIVATE CYTHON_TRACE=1 CYTHON_TRACE_NOGIL=1)
endif()
if(WIN32)
set_target_properties(${TARGET_LIB} PROPERTIES SUFFIX .pyd)
target_link_libraries(${TARGET_LIB} PRIVATE ${Python3_LIBRARIES})
endif()
# If rpath-content is set explicitly, omit the dynamic binary path
if(NETWORKIT_PYTHON_RPATH)
set_target_properties(${TARGET_LIB} PROPERTIES
INSTALL_RPATH "${NETWORKIT_PYTHON_RPATH}")
else()
# DSOs on Apple OSes use different conventions for RPATH.
if(APPLE)
set_target_properties(${TARGET_LIB} PROPERTIES
INSTALL_RPATH "@loader_path/..")
else()
set_target_properties(${TARGET_LIB} PROPERTIES
INSTALL_RPATH "$ORIGIN/..")
endif()
endif()
target_link_libraries(${TARGET_LIB} PRIVATE OpenMP::OpenMP_CXX PUBLIC tlx)
install(TARGETS ${TARGET_LIB}
LIBRARY DESTINATION "${NETWORKIT_LIB_DEST}/networkit")
endforeach()
endif()
# Register a new NetworKit module named ${modname}
# Files additionally passed are interpreted as PUBLIC source files to this module
function(networkit_add_module modname)
if(NOT NETWORKIT_BUILD_CORE)
return()
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}")
target_link_libraries(${MODULE_TARGET} PRIVATE OpenMP::OpenMP_CXX PUBLIC tlx)
target_include_directories(${MODULE_TARGET} BEFORE PUBLIC "${PROJECT_SOURCE_DIR}/include")
target_include_directories(${MODULE_TARGET} PUBLIC "${PROJECT_SOURCE_DIR}/extlibs/ttmath/")
# 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()
# Add source files (it's important to mark them private; otherwise
# all targets linking to the lib, will recompile the objects from scratch)
foreach(file ${ARGN})
target_sources(${MODULE_TARGET}
PRIVATE ${CMAKE_CURRENT_LIST_DIR}/${file})
endforeach()
endfunction()
# Analogous to target_link_libraries with KEYWORDS.
# Use the module's name (without networkit_ prefix) for target.
# In case of monolithic builds, the call is ignored.
# To link against another module use networkit_module_link_modules
# Example: networkit_module_link_libraries(graph PRIVATE foobar_lib)
function(networkit_module_link_libraries modname)
set(options )
set(oneValueArgs )
set(multiValueArgs PRIVATE PUBLIC)
cmake_parse_arguments(NMLL
"${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT NETWORKIT_BUILD_CORE)
return()
endif()
if(NOT NETWORKIT_MONOLITH)
target_link_libraries(networkit_${modname}
PRIVATE ${NMLL_PRIVATE}
PUBLIC ${NMLL_PUBLIC})
endif()
endfunction()
# Specifiy inter-module dependencies. The function expects a list of at least
# two module names (without the networkit_ prefix). The first one add all following
# ones as dependencies. In case of monolith build, the function does nothing.
# Example: networkit_module_link_modules(io graph) # io depends on graph
function(networkit_module_link_modules modname)
if(NOT NETWORKIT_BUILD_CORE)
return()
endif()
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" ON)
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
gmock
networkit
tlx
OpenMP::OpenMP_CXX
)
if(WIN32)
target_link_libraries(networkit_tests
PRIVATE
networkit_state
)
endif()
if(WIN32)
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} /wd4996")
else()
set(NETWORKIT_CXX_FLAGS "${NETWORKIT_CXX_FLAGS} -Wno-deprecated-declarations")
endif()
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
gmock
PRIVATE
tlx
networkit_auxiliary
OpenMP::OpenMP_CXX
)
endif()
endif()
# internal use only
# IS_TEST indicates whether add_test should be invoked for executable
# an whether it should be assigned to the module's test target
# MOD Name of module the test/benchmark assigned to. It will
# join its namespace, assigned to its test target and linked
# TESTNAME Name of the CPP File (excluding its .cpp extension). Will
# also be used to derive the test's name
function(networkit_add_extra IS_TEST MOD NAME)
if (NETWORKIT_BUILD_TESTS)
set(TEST_SOURCE ${CMAKE_CURRENT_LIST_DIR}/${NAME}.cpp)
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}")
foreach(dep IN LISTS ARGN)
target_link_libraries(${TARGET_NAME} PRIVATE networkit_${dep})
endforeach()
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()
# Wrapper for networkit_add_extra with (IS_TEST=ON)
# Example: networkit_add_test(io SpecialIOGTest graph) compiles
# io/test/SpecialIOGTest.cpp, registers is as an test of networkit_tests_io
# and links it against io and graph.
function(networkit_add_test MOD NAME)
networkit_add_extra(ON ${MOD} ${NAME} ${ARGN})
endfunction(networkit_add_test)
# Wrapper for networkit_add_extra with (IS_TEST=OFF)
function(networkit_add_benchmark MOD NAME)
networkit_add_extra(OFF ${MOD} ${NAME} ${ARGN})
endfunction(networkit_add_benchmark)
################################################################################
# Benchmarks
# In case of monolithic builds we add the target networkit_benchmarks, and later add
# source files via networkit_add_gbenchmark. In case of non-monolithic builds, each
# networkit_add_test creates it own target.
if (NETWORKIT_BUILD_BENCHMARKS AND NETWORKIT_MONOLITH)
add_executable(networkit_benchmarks networkit/cpp/networkit.cpp)
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()
function(networkit_add_gbenchmark MOD NAME)
if (NETWORKIT_BUILD_BENCHMARKS)
set(BENCH_SOURCE ${CMAKE_CURRENT_LIST_DIR}/${NAME}.cpp)
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}")
foreach(dep IN LISTS ARGN)
target_link_libraries(${TARGET_NAME} PRIVATE networkit_${dep})
endforeach()
endif()
endif()
endfunction(networkit_add_gbenchmark)
################################################################################
# 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(prepare_docs
COMMAND mkdir -p ${CMAKE_SOURCE_DIR}/docs/input
COMMAND cp -r ${CMAKE_SOURCE_DIR}/input/* ${CMAKE_SOURCE_DIR}/docs/input
COMMAND mkdir -p ${CMAKE_SOURCE_DIR}/docs/notebooks
COMMAND cp -r ${CMAKE_SOURCE_DIR}/notebooks/* ${CMAKE_SOURCE_DIR}/docs/notebooks)
add_custom_target(general_docs
COMMAND rm -rf htmldocs
COMMAND ${SPHINX_EXECUTABLE} ${CMAKE_SOURCE_DIR}/docs htmldocs
DEPENDS prepare_docs)
add_custom_target(docs DEPENDS general_docs)
add_custom_command(TARGET docs
POST_BUILD
COMMAND rm -rf ${CMAKE_SOURCE_DIR}/docs/input
COMMAND rm -rf ${CMAKE_SOURCE_DIR}/docs/notebooks)
endif()
################################################################################
# Subdirectories
add_subdirectory(networkit/cpp)
# Install NetworKit header files
set(NETWORKIT_LIBRARIES networkit)
install(DIRECTORY include/networkit
DESTINATION ${NETWORKIT_INSTALL_INCLUDE_DIR}
FILES_MATCHING PATTERN "*.hpp")
# Install ttmath header files
install(DIRECTORY extlibs/ttmath/ttmath
DESTINATION ${NETWORKIT_INSTALL_INCLUDE_DIR}
FILES_MATCHING PATTERN "*.h")
################################################################################
# Prepare pkg-config file
set(NETWORKIT_LIBNAME networkit)
execute_process(COMMAND ${NETWORKIT_PYTHON_EXECUTABLE} -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()