summaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake')
-rw-r--r--cmake/ApiDsl.cmake44
-rw-r--r--cmake/CompileGTest.cmake62
-rw-r--r--cmake/Dependencies.cmake77
-rw-r--r--cmake/MacRpath.cmake24
-rw-r--r--cmake/ModulePackage.cmake143
-rw-r--r--cmake/StrictAbi.cmake76
6 files changed, 426 insertions, 0 deletions
diff --git a/cmake/ApiDsl.cmake b/cmake/ApiDsl.cmake
new file mode 100644
index 00000000..759f7f05
--- /dev/null
+++ b/cmake/ApiDsl.cmake
@@ -0,0 +1,44 @@
1################################################################################
2#
3# :: APIDSL regeneration
4#
5################################################################################
6
7find_program(APIDSL NAMES
8 apidsl
9 apidsl.native
10 apidsl.byte
11 ${CMAKE_SOURCE_DIR}/../apidsl/apigen.native)
12find_program(ASTYLE NAMES
13 astyle
14 $ENV{ASTYLE})
15
16function(apidsl)
17 if(APIDSL AND ASTYLE)
18 foreach(in_file ${ARGN})
19 # Get the directory component of the input file name.
20 if(CMAKE_VERSION VERSION_LESS 3.0)
21 execute_process(
22 COMMAND dirname ${in_file}
23 OUTPUT_VARIABLE dirname
24 OUTPUT_STRIP_TRAILING_WHITESPACE)
25 else()
26 get_filename_component(dirname ${in_file} DIRECTORY)
27 endif()
28
29 # Get the name without extension (i.e. without ".api.h").
30 get_filename_component(filename ${in_file} NAME_WE)
31
32 # Put them together, with the new extension that is ".h".
33 set(out_file ${CMAKE_SOURCE_DIR}/${dirname}/${filename}.h)
34
35 # Run apidsl.
36 add_custom_command(
37 OUTPUT ${out_file}
38 COMMAND "${APIDSL}" "${CMAKE_SOURCE_DIR}/${in_file}"
39 | "${ASTYLE}" --options="${CMAKE_SOURCE_DIR}/other/astyle/astylerc"
40 > "${out_file}"
41 DEPENDS ${in_file})
42 endforeach()
43 endif()
44endfunction()
diff --git a/cmake/CompileGTest.cmake b/cmake/CompileGTest.cmake
new file mode 100644
index 00000000..9aa4712f
--- /dev/null
+++ b/cmake/CompileGTest.cmake
@@ -0,0 +1,62 @@
1# Find and compile the GTest library.
2
3include(CheckCXXCompilerFlag)
4include(CheckIncludeFileCXX)
5
6message(STATUS "Checking for gtest")
7
8# Look for the sources.
9find_file(GTEST_ALL_CC gtest-all.cc PATHS
10 ${CMAKE_SOURCE_DIR}/third_party/googletest/googletest/src
11 /usr/src/gtest/src
12 NO_DEFAULT_PATH
13)
14
15if(GTEST_ALL_CC)
16 # ../.. from the source file is the source root.
17 get_filename_component(GTEST_SRC_DIR ${GTEST_ALL_CC} DIRECTORY)
18 get_filename_component(GTEST_SRC_ROOT ${GTEST_SRC_DIR} DIRECTORY)
19
20 # Look for the header file.
21 include(CheckIncludeFileCXX)
22 include_directories(SYSTEM ${GTEST_SRC_ROOT}/include)
23 check_include_file_cxx("gtest/gtest.h" HAVE_GTEST_GTEST_H)
24
25 if(HAVE_GTEST_GTEST_H)
26 message(STATUS "Found gtest: ${GTEST_SRC_ROOT}")
27
28 add_library(gtest
29 ${GTEST_SRC_DIR}/gtest-all.cc
30 ${GTEST_SRC_DIR}/gtest_main.cc)
31 target_include_directories(gtest PRIVATE ${GTEST_SRC_ROOT})
32
33 # Ignore all warnings for gtest. We don't care about their implementation.
34 check_cxx_compiler_flag("-w" HAVE_CXX_W QUIET)
35 if(HAVE_CXX_W)
36 set_target_properties(gtest PROPERTIES COMPILE_FLAGS "-w")
37 endif()
38
39 set(HAVE_GTEST TRUE)
40 set(TEST_CXX_FLAGS "")
41
42 check_cxx_compiler_flag("-Wno-global-constructors" HAVE_CXX_W_NO_GLOBAL_CONSTRUCTORS QUIET)
43 if(HAVE_CXX_W_NO_GLOBAL_CONSTRUCTORS)
44 set(TEST_CXX_FLAGS "${TEST_CXX_FLAGS} -Wno-global-constructors")
45 endif()
46
47 check_cxx_compiler_flag("-Wno-zero-as-null-pointer-constant" HAVE_CXX_W_NO_ZERO_AS_NULL_POINTER_CONSTANT QUIET)
48 if(HAVE_CXX_W_NO_ZERO_AS_NULL_POINTER_CONSTANT)
49 set(TEST_CXX_FLAGS "${TEST_CXX_FLAGS} -Wno-zero-as-null-pointer-constant")
50 endif()
51 endif()
52endif()
53
54function(unit_test subdir target)
55 if(HAVE_GTEST)
56 add_executable(unit_${target}_test ${subdir}/${target}_test.cc)
57 target_link_modules(unit_${target}_test toxcore gtest)
58 set_target_properties(unit_${target}_test PROPERTIES COMPILE_FLAGS "${TEST_CXX_FLAGS}")
59 add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} unit_${target}_test)
60 set_property(TEST ${target} PROPERTY ENVIRONMENT "LLVM_PROFILE_FILE=${target}.profraw")
61 endif()
62endfunction()
diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake
new file mode 100644
index 00000000..5970fde7
--- /dev/null
+++ b/cmake/Dependencies.cmake
@@ -0,0 +1,77 @@
1###############################################################################
2#
3# :: For UNIX-like systems that have pkg-config.
4#
5###############################################################################
6
7include(ModulePackage)
8
9find_package(Threads REQUIRED)
10
11find_library(NSL_LIBRARIES nsl )
12find_library(RT_LIBRARIES rt )
13find_library(SOCKET_LIBRARIES socket )
14
15# For toxcore.
16pkg_use_module(LIBSODIUM libsodium )
17
18# For toxav.
19pkg_use_module(OPUS opus )
20pkg_use_module(VPX vpx )
21
22# For tox-bootstrapd.
23pkg_use_module(LIBCONFIG libconfig )
24
25# For tox-spectest.
26pkg_use_module(MSGPACK msgpack )
27
28# For av_test.
29pkg_use_module(OPENCV opencv )
30pkg_use_module(PORTAUDIO portaudio-2.0)
31pkg_use_module(SNDFILE sndfile )
32
33###############################################################################
34#
35# :: For MSVC Windows builds.
36#
37# These require specific installation paths of dependencies:
38# - libsodium in third-party/libsodium/Win32/Release/v140/dynamic
39# - pthreads in third-party/pthreads-win32/Pre-built.2
40#
41###############################################################################
42
43if(MSVC)
44 # libsodium
45 # ---------
46 find_library(LIBSODIUM_LIBRARIES
47 NAMES sodium libsodium
48 PATHS
49 "third_party/libsodium/Win32/Release/v140/dynamic"
50 "third_party/libsodium/x64/Release/v140/dynamic"
51 )
52 if(LIBSODIUM_LIBRARIES)
53 include_directories("third_party/libsodium/include")
54 set(LIBSODIUM_FOUND TRUE)
55 message("libsodium: ${LIBSODIUM_LIBRARIES}")
56 else()
57 message(FATAL_ERROR "libsodium libraries not found")
58 endif()
59
60 # pthreads
61 # --------
62 if(CMAKE_USE_WIN32_THREADS_INIT)
63 find_library(CMAKE_THREAD_LIBS_INIT
64 NAMES pthreadVC2
65 PATHS
66 "third_party/pthreads-win32/Pre-built.2/lib/x86"
67 "third_party/pthreads-win32/Pre-built.2/lib/x64"
68 )
69 if(CMAKE_THREAD_LIBS_INIT)
70 include_directories("third_party/pthreads-win32/Pre-built.2/include")
71 add_definitions(-DHAVE_STRUCT_TIMESPEC)
72 message("libpthreads: ${CMAKE_THREAD_LIBS_INIT}")
73 else()
74 message(FATAL_ERROR "libpthreads libraries not found")
75 endif()
76 endif()
77endif()
diff --git a/cmake/MacRpath.cmake b/cmake/MacRpath.cmake
new file mode 100644
index 00000000..ae5429dc
--- /dev/null
+++ b/cmake/MacRpath.cmake
@@ -0,0 +1,24 @@
1# Taken from https://cmake.org/Wiki/CMake_RPATH_handling#Always_full_RPATH.
2#
3# In many cases you will want to make sure that the required libraries are
4# always found independent from LD_LIBRARY_PATH and the install location. Then
5# you can use these settings:
6
7# Use, i.e. don't skip the full RPATH for the build tree.
8set(CMAKE_SKIP_BUILD_RPATH FALSE)
9
10# When building, don't use the install RPATH already
11# (but later on when installing).
12set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
13
14set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
15
16# Add the automatically determined parts of the RPATH
17# which point to directories outside the build tree to the install RPATH.
18set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
19
20# The RPATH to be used when installing, but only if it's not a system directory.
21list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
22if("${isSystemDir}" STREQUAL "-1")
23 set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
24endif()
diff --git a/cmake/ModulePackage.cmake b/cmake/ModulePackage.cmake
new file mode 100644
index 00000000..77911b1d
--- /dev/null
+++ b/cmake/ModulePackage.cmake
@@ -0,0 +1,143 @@
1option(ENABLE_SHARED "Build shared (dynamic) libraries for all modules" ON)
2option(ENABLE_STATIC "Build static libraries for all modules" ON)
3
4if(NOT ENABLE_SHARED AND NOT ENABLE_STATIC)
5 message(WARNING
6 "Both static and shared libraries are disabled; "
7 "enabling only shared libraries. Use -DENABLE_SHARED or -DENABLE_STATIC to "
8 "select one manually.")
9 set(ENABLE_SHARED ON)
10endif()
11
12find_package(PkgConfig)
13
14function(pkg_use_module mod pkg)
15 if(PKG_CONFIG_FOUND)
16 pkg_search_module(${mod} ${pkg})
17 endif()
18 if(${mod}_FOUND)
19 link_directories(${${mod}_LIBRARY_DIRS})
20 include_directories(${${mod}_INCLUDE_DIRS})
21 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${${mod}_CFLAGS_OTHER}" PARENT_SCOPE)
22 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${mod}_CFLAGS_OTHER}" PARENT_SCOPE)
23
24 foreach(dir ${${mod}_INCLUDE_DIRS})
25 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isystem ${dir}" PARENT_SCOPE)
26 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${dir}" PARENT_SCOPE)
27 endforeach()
28 endif()
29endfunction()
30
31function(add_module lib)
32 set(${lib}_SOURCES ${ARGN} PARENT_SCOPE)
33
34 if(ENABLE_SHARED)
35 add_library(${lib}_shared SHARED ${ARGN})
36 set_target_properties(${lib}_shared PROPERTIES OUTPUT_NAME ${lib})
37 endif()
38 if(ENABLE_STATIC)
39 add_library(${lib}_static STATIC ${ARGN})
40 set_target_properties(${lib}_static PROPERTIES OUTPUT_NAME ${lib})
41 endif()
42endfunction()
43
44function(install_module lib)
45 if(ENABLE_SHARED)
46 set_target_properties(${lib}_shared PROPERTIES
47 VERSION ${SOVERSION}
48 SOVERSION ${SOVERSION_MAJOR}
49 )
50 install(TARGETS ${lib}_shared
51 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
52 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
53 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
54 endif()
55 if(ENABLE_STATIC)
56 install(TARGETS ${lib}_static
57 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
58 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
59 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
60 endif()
61
62 string(REPLACE ";" " " ${lib}_PKGCONFIG_LIBS "${${lib}_PKGCONFIG_LIBS}")
63 string(REPLACE ";" " " ${lib}_PKGCONFIG_REQUIRES "${${lib}_PKGCONFIG_REQUIRES}")
64
65 configure_file(
66 "${${lib}_SOURCE_DIR}/other/pkgconfig/${lib}.pc.in"
67 "${CMAKE_BINARY_DIR}/${lib}.pc"
68 @ONLY
69 )
70
71 configure_file(
72 "${toxcore_SOURCE_DIR}/other/rpm/${lib}.spec.in"
73 "${CMAKE_BINARY_DIR}/${lib}.spec"
74 @ONLY
75 )
76
77 install(FILES
78 ${CMAKE_BINARY_DIR}/${lib}.pc
79 DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
80
81 foreach(sublib ${${lib}_API_HEADERS})
82 string(REPLACE "^" ";" sublib ${sublib})
83 list(GET sublib 0 header)
84
85 install(FILES ${header} ${ARGN})
86 endforeach()
87endfunction()
88
89function(target_link_modules target)
90 # If the target we're adding dependencies to is a shared library, add it to
91 # the set of targets.
92 if(TARGET ${target}_shared)
93 set(_targets ${_targets} ${target}_shared)
94 # Shared libraries should first try to link against other shared libraries.
95 set(${target}_shared_primary shared)
96 # If that fails (because the shared target doesn't exist), try linking
97 # against the static library. This requires the static library's objects to
98 # be PIC.
99 set(${target}_shared_secondary static)
100 endif()
101 # It can also be a static library at the same time.
102 if(TARGET ${target}_static)
103 set(_targets ${_targets} ${target}_static)
104 # Static libraries aren't actually linked, but their dependencies are
105 # recorded by "linking" them. If we link an executable to a static library,
106 # we want to also link statically against its transitive dependencies.
107 set(${target}_static_primary static)
108 # If a dependency doesn't exist as static library, we link against the
109 # shared one.
110 set(${target}_static_secondary shared)
111 endif()
112 # If it's neither, then it's an executable.
113 if(NOT _targets)
114 set(_targets ${_targets} ${target})
115 # Executables preferably link against static libraries, so they are
116 # standalone and can be shipped without any external dependencies. As a
117 # frame of reference: tests become roughly 600-800K binaries instead of
118 # 50-100K on x86_64 Linux.
119 set(${target}_primary static)
120 set(${target}_secondary shared)
121 endif()
122
123 foreach(dep ${ARGN})
124 foreach(_target ${_targets})
125 if(TARGET ${dep}_${${_target}_primary})
126 target_link_libraries(${_target} ${dep}_${${_target}_primary})
127 elseif(TARGET ${dep}_${${_target}_secondary})
128 target_link_libraries(${_target} ${dep}_${${_target}_secondary})
129 else()
130 # We record the modules linked to this target, so that we can collect
131 # them later when linking a composed module.
132 list(FIND LINK_MODULES ${dep} _index)
133 if(_index EQUAL -1)
134 set(LINK_MODULES ${LINK_MODULES} ${dep})
135 endif()
136
137 target_link_libraries(${_target} ${dep})
138 endif()
139 endforeach()
140 endforeach()
141
142 set(${target}_LINK_MODULES ${${target}_LINK_MODULES} ${LINK_MODULES} PARENT_SCOPE)
143endfunction()
diff --git a/cmake/StrictAbi.cmake b/cmake/StrictAbi.cmake
new file mode 100644
index 00000000..2dc5c5e0
--- /dev/null
+++ b/cmake/StrictAbi.cmake
@@ -0,0 +1,76 @@
1################################################################################
2#
3# :: Strict ABI
4#
5# Enabling the STRICT_ABI flag will generate and use an LD version script.
6# It ensures that the dynamic libraries (libtoxcore.so, libtoxav.so) only
7# export the symbols that are defined in their public API (tox.h and toxav.h,
8# respectively).
9#
10################################################################################
11
12find_program(SHELL NAMES sh dash bash zsh fish)
13
14macro(make_version_script)
15 if(STRICT_ABI AND SHELL AND ENABLE_SHARED)
16 _make_version_script(${ARGN})
17 endif()
18endmacro()
19
20function(_make_version_script target)
21 set(${target}_VERSION_SCRIPT "${CMAKE_BINARY_DIR}/${target}.ld")
22
23 file(WRITE ${${target}_VERSION_SCRIPT}
24 "{ global:\n")
25
26 foreach(sublib ${ARGN})
27 string(REPLACE "^" ";" sublib ${sublib})
28 list(GET sublib 0 header)
29 list(GET sublib 1 ns)
30
31 execute_process(
32 COMMAND ${SHELL} -c "egrep '^\\w' ${header} | grep '${ns}_[a-z0-9_]*(' | grep -v '^typedef' | grep -o '${ns}_[a-z0-9_]*(' | egrep -o '\\w+' | sort -u"
33 OUTPUT_VARIABLE sublib_SYMS
34 OUTPUT_STRIP_TRAILING_WHITESPACE)
35 string(REPLACE "\n" ";" sublib_SYMS ${sublib_SYMS})
36
37 foreach(sym ${sublib_SYMS})
38 file(APPEND ${${target}_VERSION_SCRIPT}
39 "${sym};\n")
40 endforeach(sym)
41 endforeach(sublib)
42
43 file(APPEND ${${target}_VERSION_SCRIPT}
44 "local: *; };\n")
45
46 set_target_properties(${target}_shared PROPERTIES
47 LINK_FLAGS -Wl,--version-script,${${target}_VERSION_SCRIPT})
48endfunction()
49
50option(STRICT_ABI "Enforce strict ABI export in dynamic libraries" OFF)
51if(WIN32 OR APPLE)
52 # Windows and OSX don't have this linker functionality.
53 set(STRICT_ABI OFF)
54endif()
55
56if(STRICT_ABI)
57 if(AUTOTEST)
58 message("AUTOTEST option is incompatible with STRICT_ABI. Disabling AUTOTEST.")
59 endif()
60 set(AUTOTEST OFF)
61
62 if(BUILD_MISC_TESTS)
63 message("BUILD_MISC_TESTS option is incompatible with STRICT_ABI. Disabling BUILD_MISC_TESTS.")
64 endif()
65 set(BUILD_MISC_TESTS OFF)
66
67 if(BOOTSTRAP_DAEMON)
68 message("BOOTSTRAP_DAEMON option is incompatible with STRICT_ABI. Disabling BOOTSTRAP_DAEMON.")
69 endif()
70 set(BOOTSTRAP_DAEMON OFF)
71
72 if(DHT_BOOTSTRAP)
73 message("DHT_BOOTSTRAP option is incompatible with STRICT_ABI. Disabling DHT_BOOTSTRAP.")
74 endif()
75 set(DHT_BOOTSTRAP OFF)
76endif()