Skip to content

Commit 861d452

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 272e818 commit 861d452

File tree

9 files changed

+829
-0
lines changed

9 files changed

+829
-0
lines changed

CMakeLists.txt

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

0 commit comments

Comments
 (0)