Skip to content

Commit ca9813d

Browse files
committed
build: add a cmake based build system
This is far from complete, but is sufficient to build a Linux version of libdispatch. It shows what a potential cmake based build system could look like, and if desired can be completed to build all the various flavours with cmake.
1 parent 787dd92 commit ca9813d

File tree

9 files changed

+811
-0
lines changed

9 files changed

+811
-0
lines changed

CMakeLists.txt

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
2+
cmake_minimum_required(VERSION 3.4.3)
3+
4+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
5+
6+
project(dispatch C CXX)
7+
enable_testing()
8+
9+
set(CMAKE_C_VISIBILITY_PRESET hidden)
10+
set(CMAKE_CXX_STANDARD 11)
11+
12+
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
13+
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
14+
find_package(Threads REQUIRED)
15+
16+
include(GNUInstallDirs)
17+
include(ExternalProject)
18+
if(BUILD_SHARED_LIBS)
19+
set(CMAKE_LIBRARY_TYPE SHARED)
20+
else()
21+
set(CMAKE_LIBRARY_TYPE STATIC)
22+
endif()
23+
24+
set(WITH_KQUEUE "" CACHE PATH "Path to kqueue headers")
25+
set(WITH_BLOCKS_RUNTIME "" CACHE PATH "Path to blocks runtime")
26+
set(WITH_PTHREAD_WORKQUEUES "" CACHE PATH "Path to pthread-workqueues")
27+
28+
# TODO(compnerd) consider adding a flag for USE_GOLD_LINKER. Currently, we
29+
# expect the user to specify `-fuse-ld=gold`
30+
31+
include(DispatchAppleOptions)
32+
33+
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
34+
set(ENABLE_DISPATCH_INIT_CONSTRUCTOR_DEFAULT ON)
35+
else()
36+
set(ENABLE_DISPATCH_INIT_CONSTRUCTOR_DEFAULT OFF)
37+
endif()
38+
option(ENABLE_DISPATCH_INIT_CONSTRUCTOR "enable libdispatch_init as a constructor"
39+
${ENABLE_DISPATCH_INIT_CONSTRUCTOR_DEFAULT})
40+
41+
if(CMAKE_SYSTEM_NAME STREQUAL Linux)
42+
set(ENABLE_THREAD_LOCAL_STORAGE_DEFAULT ON)
43+
else()
44+
set(ENABLE_THREAD_LOCAL_STORAGE_DEFAULT OFF)
45+
endif()
46+
option(ENABLE_THREAD_LOCAL_STORAGE "enable usage of thread local storage via __thread"
47+
${ENABLE_THREAD_LOCAL_STORAGE_DEFAULT})
48+
49+
if(EXISTS "${CMAKE_SOURCE_DIR}/libkqueue/CMakeLists.txt")
50+
ExternalProject_Add(kqueue
51+
SOURCE_DIR
52+
"${CMAKE_SOURCE_DIR}/libkqueue"
53+
CMAKE_ARGS
54+
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
55+
-DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
56+
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
57+
BUILD_BYPRODUCTS
58+
<INSTALL_DIR>/${CMAKE_INSTALL_LIBDIR}/${CMAKE_${CMAKE_LIBRARY_TYPE}_LIBRARY_PREFIX}kqueue${CMAKE_${CMAKE_LIBRARY_TYPE}_LIBRARY_SUFFIX})
59+
ExternalProject_Get_Property(kqueue install_dir)
60+
add_library(KQUEUE::kqueue UNKNOWN IMPORTED)
61+
set_property(TARGET KQUEUE::kqueue
62+
PROPERTY IMPORTED_LOCATION
63+
${install_dir}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_${CMAKE_LIBRARY_TYPE}_LIBRARY_PREFIX}kqueue${CMAKE_${CMAKE_LIBRARY_TYPE}_LIBRARY_SUFFIX})
64+
set(WITH_KQUEUE "${install_dir}" CACHE PATH "Path to kqueue headers" FORCE)
65+
else()
66+
# TODO(compnerd) support system installed kqueue
67+
# find_package(kqueue REQUIRED)
68+
endif()
69+
70+
if(EXISTS "${CMAKE_SOURCE_DIR}/libpwq/CMakeLists.txt")
71+
ExternalProject_Add(pwq
72+
SOURCE_DIR
73+
"${CMAKE_SOURCE_DIR}/libpwq"
74+
CMAKE_ARGS
75+
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
76+
-DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
77+
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
78+
BUILD_BYPRODUCTS
79+
<INSTALL_DIR>/${CMAKE_INSTALL_LIBDIR}/${CMAKE_${CMAKE_LIBRARY_TYPE}_LIBRARY_PREFIX}pthread_workqueue${CMAKE_${CMAKE_LIBRARY_TYPE}_LIBRARY_SUFFIX})
80+
ExternalProject_Get_Property(pwq install_dir)
81+
add_library(PTHREAD::workqueue UNKNOWN IMPORTED)
82+
set_property(TARGET PTHREAD::workqueue
83+
PROPERTY IMPORTED_LOCATION
84+
${install_dir}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_${CMAKE_LIBRARY_TYPE}_LIBRARY_PREFIX}pthread_workqueue${CMAKE_${CMAKE_LIBRARY_TYPE}_LIBRARY_SUFFIX})
85+
set(WITH_PTHREAD_WORKQUEUES "${install_dir}" CACHE PATH "Path to pthread-workqueues" FORCE)
86+
else()
87+
# TODO(compnerd) support system installed pthread-workqueues
88+
# find_package(pthread_workqueues REQUIRED)
89+
endif()
90+
91+
if(CMAKE_SYSTEM_NAME STREQUAL Linux)
92+
add_library(BlocksRuntime
93+
STATIC
94+
${CMAKE_SOURCE_DIR}/src/BlocksRuntime/data.c
95+
${CMAKE_SOURCE_DIR}/src/BlocksRuntime/runtime.c)
96+
# TODO(compnerd) check if libdl is required on the target
97+
set_target_properties(BlocksRuntime
98+
PROPERTIES
99+
POSITION_INDEPENDENT_CODE TRUE
100+
INTERFACE_LINK_LIBRARIES dl)
101+
set(WITH_BLOCKS_RUNTIME "${CMAKE_SOURCE_DIR}/src/BlocksRuntime" CACHE PATH "Path to blocks runtime" FORCE)
102+
else()
103+
# TODO(compnerd) support system installed BlocksRuntime
104+
# find_package(BlocksRuntime REQUIRED)
105+
endif()
106+
107+
if(ENABLE_DISPATCH_INIT_CONSTRUCTOR)
108+
add_definitions(-DUSE_LIBDISPATCH_INIT_CONSTRUCTOR=1)
109+
endif()
110+
if(ENABLE_THREAD_LOCAL_STORAGE)
111+
add_definitions(-DDISPATCH_USE_THREAD_LOCAL_STORAGE=1)
112+
endif()
113+
114+
include(CheckCSourceCompiles)
115+
include(CheckFunctionExists)
116+
include(CheckIncludeFiles)
117+
include(CheckLibraryExists)
118+
include(CheckSymbolExists)
119+
120+
check_c_source_compiles(
121+
"
122+
#include <features.h>
123+
#if defined(__GNU_LIBRARY__)
124+
int main() { return 0; }
125+
#endif
126+
"
127+
_GNU_SOURCE)
128+
if(_GNU_SOURCE)
129+
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE)
130+
add_definitions(-D_GNU_SOURCE)
131+
endif()
132+
133+
find_library(HAVE_LIBRT NAMES rt)
134+
if(HAVE_LIBRT)
135+
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} rt)
136+
endif()
137+
138+
check_function_exists(_pthread_workqueue_init HAVE__PTHREAD_WORKQUEUE_INIT)
139+
check_function_exists(getprogname HAVE_GETPROGNAME)
140+
check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME)
141+
check_function_exists(mach_port_construct HAVE_MACH_PORT_CONSTRUCT)
142+
check_function_exists(malloc_create_zone HAVE_MALLOC_CREATE_ZONE)
143+
check_function_exists(pthread_key_init_np HAVE_PTHREAD_KEY_INIT_NP)
144+
check_function_exists(pthread_main_np HAVE_PTHREAD_MAIN_NP)
145+
check_function_exists(pthread_workqueue_setdispatch_np HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP)
146+
check_function_exists(strlcpy HAVE_STRLCPY)
147+
check_function_exists(sysconf HAVE_SYSCONF)
148+
149+
if(NOT HAVE_STRLCPY AND NOT HAVE_GETPROGNAME)
150+
include(FindPkgConfig)
151+
pkg_check_modules(BSD_OVERLAY libbsd-overlay)
152+
if(BSD_OVERLAY_FOUND)
153+
set(HAVE_STRLCPY 1 CACHE INTERNAL "Have function strlcpy" FORCE)
154+
set(HAVE_GETPROGNAME 1 CACHE INTERNAL "Have function getprogname" FORCE)
155+
endif()
156+
endif()
157+
158+
find_package(Threads REQUIRED)
159+
160+
check_include_files("TargetConditionals.h" HAVE_TARGETCONDITIONALS_H)
161+
check_include_files("dlfcn.h" HAVE_DLFCN_H)
162+
check_include_files("fcntl.h" HAVE_FCNTL_H)
163+
check_include_files("inttypes.h" HAVE_INTTYPES_H)
164+
check_include_files("libkern/OSAtomic.h" HAVE_LIBKERN_OSATOMIC_H)
165+
check_include_files("libkern/OSCrossEndian.h" HAVE_LIBKERN_OSCROSSENDIAN_H)
166+
check_include_files("libproc_internal.h" HAVE_LIBPROC_INTERNAL_H)
167+
check_include_files("mach/mach.h" HAVE_MACH)
168+
if(HAVE_MACH)
169+
set(__DARWIN_NON_CANCELABLE 1)
170+
set(USE_MACH_SEM 1)
171+
else()
172+
set(__DARWIN_NON_CANCELABLE 0)
173+
set(USE_MACH_SEM 0)
174+
endif()
175+
check_include_files("malloc/malloc.h" HAVE_MALLOC_MALLOC_H)
176+
check_include_files("memory.h" HAVE_MEMORY_H)
177+
check_include_files("pthread/qos.h" HAVE_PTHREAD_QOS_H)
178+
check_include_files("pthread/workqueue_private.h" HAVE_PTHREAD_WORKQUEUE_PRIVATE_H)
179+
check_include_files("pthread_machdep.h" HAVE_PTHREAD_MACHDEP_H)
180+
check_include_files("pthread_np.h" HAVE_PTHREAD_NP_H)
181+
check_include_files("pthread_workqueue.h" HAVE_PTHREAD_WORKQUEUE_H)
182+
check_include_files("stdint.h" HAVE_STDINT_H)
183+
check_include_files("stdlib.h" HAVE_STDLIB_H)
184+
check_include_files("string.h" HAVE_STRING_H)
185+
check_include_files("strings.h" HAVE_STRINGS_H)
186+
check_include_files("sys/cdefs.h" HAVE_SYS_CDEFS_H)
187+
check_include_files("sys/guarded.h" HAVE_SYS_GUARDED_H)
188+
check_include_files("sys/stat.h" HAVE_SYS_STAT_H)
189+
check_include_files("sys/types.h" HAVE_SYS_TYPES_H)
190+
check_include_files("unistd.h" HAVE_UNISTD_H)
191+
192+
check_library_exists(pthread sem_init "" USE_POSIX_SEM)
193+
194+
check_symbol_exists(CLOCK_UPTIME "time.h" HAVE_DECL_CLOCK_UPTIME)
195+
check_symbol_exists(CLOCK_MONOTONIC "time.h" HAVE_DECL_CLOCK_MONOTONIC)
196+
check_symbol_exists(FD_COPY "sys/select.h" HAVE_DECL_FD_COPY)
197+
check_symbol_exists(NOTE_NONE "sys/event.h" HAVE_DECL_NOTE_NONE)
198+
check_symbol_exists(NOTE_REAP "sys/event.h" HAVE_DECL_NOTE_REAP)
199+
check_symbol_exists(NOTE_REVOKE "sys/event.h" HAVE_DECL_NOTE_REVOKE)
200+
check_symbol_exists(NOTE_SIGNAL "sys/event.h" HAVE_DECL_NOTE_SIGNAL)
201+
check_symbol_exists(SIGEMT "signal.h" HAVE_DECL_SIGEMT)
202+
check_symbol_exists(VQ_QUOTA "sys/mount.h" HAVE_DECL_VQ_QUOTA)
203+
check_symbol_exists(VQ_UPDATE "sys/mount.h" HAVE_DECL_VQ_UPDATE)
204+
check_symbol_exists(VQ_VERYLOWDISK "sys/mount.h" HAVE_DECL_VQ_VERYLOWDISK)
205+
206+
check_symbol_exists(program_invocation_name "errno.h" HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
207+
208+
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
209+
add_definitions(-DDISPATCH_USE_DTRACE=1)
210+
else()
211+
add_definitions(-DDISPATCH_USE_DTRACE=0)
212+
endif()
213+
214+
configure_file("${CMAKE_SOURCE_DIR}/cmake/config.h.in"
215+
"${CMAKE_BINARY_DIR}/config/config.h")
216+
217+
add_subdirectory(dispatch)
218+
add_subdirectory(man)
219+
add_subdirectory(os)
220+
add_subdirectory(private)
221+
add_subdirectory(src)
222+
if(ENABLE_TESTING)
223+
add_subdirectory(tests)
224+
endif()
225+

0 commit comments

Comments
 (0)