summaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake')
-rw-r--r--cmake/ModulePackage.cmake98
-rw-r--r--cmake/StrictAbi.cmake46
2 files changed, 119 insertions, 25 deletions
diff --git a/cmake/ModulePackage.cmake b/cmake/ModulePackage.cmake
index 3a4eb9b9..d51607df 100644
--- a/cmake/ModulePackage.cmake
+++ b/cmake/ModulePackage.cmake
@@ -51,45 +51,123 @@ function(pkg_use_module mod pkg)
51 endif() 51 endif()
52endfunction() 52endfunction()
53 53
54macro(add_submodule super lib)
55 add_module(${lib} ${ARGN})
56 set(${super}_SUBLIBS ${${super}_SUBLIBS} ${lib})
57 set(${super}_SOURCES ${${super}_SOURCES} ${${lib}_SOURCES})
58endmacro()
59
54function(add_module lib) 60function(add_module lib)
55 set_source_language(${ARGN}) 61 set_source_language(${ARGN})
62 set(${lib}_SOURCES ${ARGN} PARENT_SCOPE)
56 63
57 if(ENABLE_SHARED) 64 if(ENABLE_SHARED)
58 add_library(${lib}_shared SHARED ${ARGN}) 65 add_library(${lib}_shared SHARED ${ARGN})
66 set_target_properties(${lib}_shared PROPERTIES OUTPUT_NAME ${lib})
67 endif()
68 if(ENABLE_STATIC)
69 add_library(${lib}_static STATIC ${ARGN})
70 set_target_properties(${lib}_static PROPERTIES OUTPUT_NAME ${lib})
71 endif()
72
73 # ${lib}_PKGCONFIG_LIBS is what's added to the Libs: line in ${lib}.pc. It
74 # needs to contain all the libraries a program using ${lib} should link against
75 # if it's statically linked. If it's dynamically linked, there is no need to
76 # explicitly link against all the dependencies, but it doesn't harm much(*)
77 # either.
78 #
79 # (*) It allows client code to use symbols from our dependencies without
80 # explicitly linking against them.
81 set(${lib}_PKGCONFIG_LIBS PARENT_SCOPE)
82 # Requires: in pkg-config file.
83 set(${lib}_PKGCONFIG_REQUIRES PARENT_SCOPE)
84endfunction()
85
86function(install_module lib)
87 if(ENABLE_SHARED)
59 set_target_properties(${lib}_shared PROPERTIES 88 set_target_properties(${lib}_shared PROPERTIES
60 OUTPUT_NAME ${lib}
61 VERSION ${SOVERSION} 89 VERSION ${SOVERSION}
62 SOVERSION ${SOVERSION_MAJOR} 90 SOVERSION ${SOVERSION_MAJOR}
63 ) 91 )
64 install(TARGETS ${lib}_shared DESTINATION "lib") 92 install(TARGETS ${lib}_shared DESTINATION "lib")
65 endif() 93 endif()
66 if(ENABLE_STATIC) 94 if(ENABLE_STATIC)
67 add_library(${lib}_static STATIC ${ARGN})
68 set_target_properties(${lib}_static PROPERTIES OUTPUT_NAME ${lib})
69 install(TARGETS ${lib}_static DESTINATION "lib") 95 install(TARGETS ${lib}_static DESTINATION "lib")
70 endif() 96 endif()
97
98 string(REPLACE ";" " " ${lib}_PKGCONFIG_LIBS "${${lib}_PKGCONFIG_LIBS}")
99 string(REPLACE ";" " " ${lib}_PKGCONFIG_REQUIRES "${${lib}_PKGCONFIG_REQUIRES}")
100
101 configure_file(
102 "${${lib}_SOURCE_DIR}/other/pkgconfig/${lib}.pc.in"
103 "${CMAKE_BINARY_DIR}/${lib}.pc"
104 @ONLY
105 )
106
107 install(FILES
108 ${CMAKE_BINARY_DIR}/${lib}.pc
109 DESTINATION "lib/pkgconfig")
110
111 foreach(sublib ${${lib}_API_HEADERS})
112 string(REPLACE "^" ";" sublib ${sublib})
113 list(GET sublib 0 header)
114
115 install(FILES ${header} ${ARGN})
116 endforeach()
71endfunction() 117endfunction()
72 118
73function(target_link_modules target) 119function(target_link_modules target)
120 # If the target we're adding dependencies to is a shared library, add it to
121 # the set of targets.
74 if(TARGET ${target}_shared) 122 if(TARGET ${target}_shared)
75 set(_targets ${_targets} ${target}_shared) 123 set(_targets ${_targets} ${target}_shared)
124 # Shared libraries should first try to link against other shared libraries.
125 set(${target}_shared_primary shared)
126 # If that fails (because the shared target doesn't exist), try linking
127 # against the static library. This requires the static library's objects to
128 # be PIC.
129 set(${target}_shared_secondary static)
76 endif() 130 endif()
131 # It can also be a static library at the same time.
77 if(TARGET ${target}_static) 132 if(TARGET ${target}_static)
78 set(_targets ${_targets} ${target}_static) 133 set(_targets ${_targets} ${target}_static)
134 # Static libraries aren't actually linked, but their dependencies are
135 # recorded by "linking" them. If we link an executable to a static library,
136 # we want to also link statically against its transitive dependencies.
137 set(${target}_static_primary static)
138 # If a dependency doesn't exist as static library, we link against the
139 # shared one.
140 set(${target}_static_secondary shared)
79 endif() 141 endif()
142 # If it's neither, then it's an executable.
80 if(NOT _targets) 143 if(NOT _targets)
81 set(_targets ${_targets} ${target}) 144 set(_targets ${_targets} ${target})
145 # Executables preferrably link against static libraries, so they are
146 # standalone and can be shipped without any external dependencies. As a
147 # frame of reference: nTox becomes an 1.3M binary instead of 139K on x86_64
148 # Linux.
149 set(${target}_primary static)
150 set(${target}_secondary shared)
82 endif() 151 endif()
83 152
84 foreach(target ${_targets}) 153 foreach(dep ${ARGN})
85 foreach(dep ${ARGN}) 154 foreach(_target ${_targets})
86 if(TARGET ${dep}_shared) 155 if(TARGET ${dep}_${${_target}_primary})
87 target_link_libraries(${target} ${dep}_shared) 156 target_link_libraries(${_target} ${dep}_${${_target}_primary})
88 elseif(TARGET ${dep}_static) 157 elseif(TARGET ${dep}_${${_target}_secondary})
89 target_link_libraries(${target} ${dep}_static) 158 target_link_libraries(${_target} ${dep}_${${_target}_secondary})
90 else() 159 else()
91 target_link_libraries(${target} ${dep}) 160 # We record the modules linked to this target, so that we can collect
161 # them later when linking a composed module.
162 list(FIND LINK_MODULES ${dep} _index)
163 if(_index EQUAL -1)
164 set(LINK_MODULES ${LINK_MODULES} ${dep})
165 endif()
166
167 target_link_libraries(${_target} ${dep})
92 endif() 168 endif()
93 endforeach() 169 endforeach()
94 endforeach() 170 endforeach()
171
172 set(${target}_LINK_MODULES ${${target}_LINK_MODULES} ${LINK_MODULES} PARENT_SCOPE)
95endfunction() 173endfunction()
diff --git a/cmake/StrictAbi.cmake b/cmake/StrictAbi.cmake
index fdf3664b..5a646d77 100644
--- a/cmake/StrictAbi.cmake
+++ b/cmake/StrictAbi.cmake
@@ -9,26 +9,42 @@
9# 9#
10################################################################################ 10################################################################################
11 11
12function(make_version_script header ns lib) 12find_program(SHELL NAMES sh dash bash zsh fish)
13 execute_process(
14 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"
15 OUTPUT_VARIABLE ${lib}_SYMS
16 OUTPUT_STRIP_TRAILING_WHITESPACE)
17 string(REPLACE "\n" ";" ${lib}_SYMS ${${lib}_SYMS})
18 13
19 set(${lib}_VERSION_SCRIPT "${CMAKE_BINARY_DIR}/${lib}.ld") 14macro(make_version_script)
15 if(STRICT_ABI AND SHELL AND ENABLE_SHARED)
16 _make_version_script(${ARGN})
17 endif()
18endmacro()
20 19
21 file(WRITE ${${lib}_VERSION_SCRIPT} 20function(_make_version_script target)
21 set(${target}_VERSION_SCRIPT "${CMAKE_BINARY_DIR}/${target}.ld")
22
23 file(WRITE ${${target}_VERSION_SCRIPT}
22 "{ global:\n") 24 "{ global:\n")
23 foreach(sym ${${lib}_SYMS}) 25
24 file(APPEND ${${lib}_VERSION_SCRIPT} 26 foreach(sublib ${ARGN})
25 "${sym};\n") 27 string(REPLACE "^" ";" sublib ${sublib})
26 endforeach(sym) 28 list(GET sublib 0 header)
27 file(APPEND ${${lib}_VERSION_SCRIPT} 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}
28 "local: *; };\n") 44 "local: *; };\n")
29 45
30 set_target_properties(${lib}_shared PROPERTIES 46 set_target_properties(${target}_shared PROPERTIES
31 LINK_FLAGS -Wl,--version-script,${${lib}_VERSION_SCRIPT}) 47 LINK_FLAGS -Wl,--version-script,${${target}_VERSION_SCRIPT})
32endfunction() 48endfunction()
33 49
34option(STRICT_ABI "Enforce strict ABI export in dynamic libraries" OFF) 50option(STRICT_ABI "Enforce strict ABI export in dynamic libraries" OFF)