1CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
2PROJECT(Platform LANGUAGES C CXX)
3
4INCLUDE(CheckFunctionExists)
5INCLUDE(CheckIncludeFile)
6INCLUDE(CheckIncludeFileCXX)
7INCLUDE(CheckSymbolExists)
8INCLUDE(CTest)
9INCLUDE(GenerateExportHeader)
10INCLUDE(check_unit_test_enabled)
11
12OPTION(PLATFORM_ENABLE_CBSOCKET "Build cbsocket support" ON)
13
14check_unit_test_enabled(platform COUCHBASE_PLATFORM_BUILD_UNIT_TESTS)
15if (COUCHBASE_PLATFORM_BUILD_UNIT_TESTS)
16    ENABLE_CODE_COVERAGE_REPORT()
17endif (COUCHBASE_PLATFORM_BUILD_UNIT_TESTS)
18
19CMAKE_PUSH_CHECK_STATE(RESET)
20  FIND_LIBRARY(EXECINFO_LIBRARY NAMES execinfo)
21  IF (EXECINFO_LIBRARY)
22    SET(CMAKE_REQUIRED_LIBRARIES "${EXECINFO_LIBRARY}")
23    LIST(APPEND PLATFORM_LIBRARIES "${EXECINFO_LIBRARY}")
24  ENDIF(EXECINFO_LIBRARY)
25  CHECK_SYMBOL_EXISTS(backtrace execinfo.h HAVE_BACKTRACE)
26CMAKE_POP_CHECK_STATE()
27
28CMAKE_PUSH_CHECK_STATE(RESET)
29  SET(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
30  FIND_LIBRARY(DL_LIBRARY NAMES dl)
31  IF (DL_LIBRARY)
32    SET(CMAKE_REQUIRED_LIBRARIES "${DL_LIBRARY}")
33    LIST(APPEND PLATFORM_LIBRARIES "${DL_LIBRARY}")
34  ENDIF (DL_LIBRARY)
35  CHECK_SYMBOL_EXISTS(dladdr dlfcn.h HAVE_DLADDR)
36CMAKE_POP_CHECK_STATE()
37
38CMAKE_PUSH_CHECK_STATE(RESET)
39SET(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
40SET(CMAKE_REQUIRED_LIBRARIES "pthread")
41CHECK_SYMBOL_EXISTS(pthread_setname_np pthread.h HAVE_PTHREAD_SETNAME_NP)
42CHECK_SYMBOL_EXISTS(pthread_getname_np pthread.h HAVE_PTHREAD_GETNAME_NP)
43CHECK_SYMBOL_EXISTS(sched_getaffinity sched.h HAVE_SCHED_GETAFFINITY)
44CHECK_SYMBOL_EXISTS(sched_getcpu sched.h HAVE_SCHED_GETCPU)
45CMAKE_POP_CHECK_STATE()
46
47CMAKE_PUSH_CHECK_STATE(RESET)
48
49CHECK_CXX_SOURCE_COMPILES("
50    #include <memory>
51    int main() {
52        return *std::make_unique<int>(0);
53    }" HAVE_MAKE_UNIQUE)
54CMAKE_POP_CHECK_STATE()
55
56CHECK_SYMBOL_EXISTS(gethrtime sys/time.h CB_DONT_NEED_GETHRTIME)
57CHECK_SYMBOL_EXISTS(htonll arpa/inet.h CB_DONT_NEED_BYTEORDER)
58CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H)
59CONFIGURE_FILE (${CMAKE_CURRENT_SOURCE_DIR}/src/config.cmake.h
60                ${CMAKE_CURRENT_BINARY_DIR}/src/config.h)
61
62CONFIGURE_FILE (${CMAKE_CURRENT_SOURCE_DIR}/include/platform/dynamic.in.h
63                ${CMAKE_CURRENT_BINARY_DIR}/include/platform/dynamic.h)
64
65#
66# Set the include path
67#
68INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/external)
69
70IF (MEMORY_ALLOCATOR)
71  INCLUDE_DIRECTORIES(AFTER ${MALLOC_INCLUDE_DIR})
72ENDIF (MEMORY_ALLOCATOR)
73
74ADD_LIBRARY(cJSON SHARED
75            include/cJSON.h
76            include/cJSON_utils.h
77            src/cJSON.cc
78            src/cJSON_utils.cc)
79SET_TARGET_PROPERTIES(cJSON PROPERTIES SOVERSION 1.1.0)
80GENERATE_EXPORT_HEADER(cJSON
81                       EXPORT_MACRO_NAME CJSON_PUBLIC_API
82                       EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/include/platform/cJSON-visibility.h)
83TARGET_INCLUDE_DIRECTORIES(cJSON INTERFACE include)
84TARGET_LINK_LIBRARIES(cJSON PRIVATE gsl_lite)
85
86ADD_LIBRARY(JSON_checker SHARED src/JSON_checker.cc include/JSON_checker.h)
87SET_TARGET_PROPERTIES(JSON_checker PROPERTIES SOVERSION 1.0.0)
88TARGET_LINK_LIBRARIES(JSON_checker PRIVATE platform_headers)
89GENERATE_EXPORT_HEADER(JSON_checker
90                       EXPORT_MACRO_NAME JSON_CHECKER_PUBLIC_API
91                       EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/include/platform/JSON_checker-visibility.h)
92
93IF (WIN32)
94   INCLUDE_DIRECTORIES(AFTER ${CMAKE_CURRENT_SOURCE_DIR}/include/win32)
95   ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
96   SET(PLATFORM_FILES src/sockets.c
97                      src/cb_win32.cc
98                      src/winrandom.c
99                      src/memorymap_win32.cc
100                      include/win32/getopt.h
101                      include/win32/strings.h
102                      include/win32/unistd.h)
103
104   # Allow to build on unsupported platorms (currently with MSVC 2017CE)
105   # and the FindCouchbaseDbgHelp macro didn't pick it up in the new location
106   # stuff has been moved around for the CE version. The library is only used
107   # for backtrace support which we can live without
108   CB_GET_SUPPORTED_PLATFORM(_supported_platform)
109   if (_supported_platform)
110       ADD_DEFINITIONS(-DHAVE_BACKTRACE_SUPPORT=1)
111       INCLUDE(FindCouchbaseDbgHelp)
112       LIST(APPEND PLATFORM_LIBRARIES "${DBGHELP_LIBRARY}")
113   endif ()
114ELSE (WIN32)
115   SET(PLATFORM_FILES src/cb_pthreads.cc src/urandom.c src/memorymap_posix.cc)
116   SET_SOURCE_FILES_PROPERTIES(src/crc32c_sse4_2.cc PROPERTIES COMPILE_FLAGS -msse4.2)
117   LIST(APPEND PLATFORM_LIBRARIES "pthread")
118
119   IF (NOT APPLE)
120      LIST(APPEND PLATFORM_LIBRARIES "rt")
121   ENDIF(NOT APPLE)
122
123   SET(LIB_M m)
124ENDIF (WIN32)
125
126TARGET_LINK_LIBRARIES(cJSON PRIVATE platform ${LIB_M})
127
128IF (NOT DEFINED COUCHBASE_NETWORK_LIBS)
129   IF (WIN32)
130      SET(COUCHBASE_NETWORK_LIBS "Ws2_32")
131   ELSEIF ("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
132      SET(COUCHBASE_NETWORK_LIBS socket nsl)
133   ENDIF (WIN32)
134ENDIF (NOT DEFINED COUCHBASE_NETWORK_LIBS)
135
136IF ("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
137    # The implementation you get with chrono on a default FreeBSD 10
138    # is dead slow and considered useless...
139    SET(HAVE_DEAD_SLOW_CHRONO true)
140ENDIF ("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
141
142IF (CB_DONT_NEED_GETHRTIME OR HAVE_DEAD_SLOW_CHRONO)
143   SET(PLATFORM_FILES ${PLATFORM_FILES} src/gethrtime.c)
144ELSE (CB_DONT_NEED_GETHRTIME OR HAVE_DEAD_SLOW_CHRONO)
145   SET(PLATFORM_FILES ${PLATFORM_FILES} src/cxxtime.cc)
146ENDIF (CB_DONT_NEED_GETHRTIME OR HAVE_DEAD_SLOW_CHRONO)
147
148CHECK_FUNCTION_EXISTS(malloc_usable_size HAVE_MALLOC_USABLE_SIZE)
149if(HAVE_MALLOC_USABLE_SIZE)
150  ADD_DEFINITIONS(-DHAVE_MALLOC_USABLE_SIZE)
151endif()
152#
153# Add all of the libraries
154#
155
156# 'platform_headers' - header-only part of platform.
157#
158# This should typically only be used for tests / benchmarks which want the
159# definitions of platform functions; but don't want to link against the
160# complete library. For example, a unit test might want to just link against
161# the single .cc file for the code it is testing, but needs the prototype(s)
162# of that .cc file.
163ADD_LIBRARY(platform_headers INTERFACE)
164TARGET_INCLUDE_DIRECTORIES(platform_headers INTERFACE
165        include
166        # "config.h" (which resides in ${Platform_BINARY_DIR}/src) is needed
167        # indirectly by any targets linking against platform_headers (because
168        # a number of platform's public headers include it).
169        ${Platform_BINARY_DIR}/src
170        ${Platform_BINARY_DIR}/include)
171
172# platform_so - the 'real' platform shared library containing our various
173# platform abstraction functionality.
174# Note that in general external users should link 'platform' and not
175# 'platform_so' - see below.
176ADD_LIBRARY(platform_so SHARED ${PLATFORM_FILES}
177                            ${CMAKE_CURRENT_BINARY_DIR}/src/config.h
178                            src/base64.cc
179                            src/getpid.c
180                            src/random.cc
181                            src/backtrace.c
182                            src/byte_buffer_dump.cc
183                            src/byteorder.c
184                            src/cb_malloc.cc
185                            src/cb_mktemp.cc
186                            src/cb_time.cc
187                            src/cbassert.c
188                            src/checked_snprintf.cc
189                            src/crc32c.cc
190                            src/crc32c_sse4_2.cc
191                            src/crc32c_private.h
192                            src/getopt.cc
193                            src/global_new_replacement.cc
194                            src/histogram.cc
195                            src/interrupt.cc
196                            src/processclock.cc
197                            src/strerror.cc
198                            src/string.cc
199                            src/strnstr.cc
200                            src/sysinfo.cc
201                            src/thread.cc
202                            src/timeutils.cc
203                            src/uuid.cc
204                            include/platform/atomic_duration.h
205                            include/platform/backtrace.h
206                            include/platform/base64.h
207                            include/platform/bitset.h
208                            include/platform/byte_buffer_dump.h
209                            include/platform/cacheline_padded.h
210                            include/platform/cb_malloc.h
211                            include/platform/cbassert.h
212                            include/platform/checked_snprintf.h
213                            include/platform/corestore.h
214                            include/platform/crc32c.h
215                            include/platform/getopt.h
216                            include/platform/interrupt.h
217                            include/platform/make_unique.h
218                            include/platform/memorymap.h
219                            include/platform/non_negative_counter.h
220                            include/platform/platform.h
221                            include/platform/pipe.h
222                            include/platform/processclock.h
223                            include/platform/random.h
224                            include/platform/ring_buffer.h
225                            include/platform/rwlock.h
226                            include/platform/sized_buffer.h
227                            include/platform/strerror.h
228                            include/platform/string.h
229                            include/platform/sysinfo.h
230                            include/platform/thread.h
231                            include/platform/timeutils.h
232                            include/platform/uuid.h
233                            ${Platform_BINARY_DIR}/include/platform/visibility.h)
234GENERATE_EXPORT_HEADER(platform_so
235                       EXPORT_MACRO_NAME PLATFORM_PUBLIC_API
236                       EXPORT_FILE_NAME ${Platform_BINARY_DIR}/include/platform/visibility.h)
237
238LIST(APPEND PLATFORM_LIBRARIES "phosphor")
239LIST(REMOVE_DUPLICATES PLATFORM_LIBRARIES)
240TARGET_LINK_LIBRARIES(platform_so PRIVATE
241        platform_headers
242        gsl_lite
243        ${MALLOC_LIBRARIES}
244        ${PLATFORM_LIBRARIES})
245
246# Link publically with COUCHBASE_NETWORK_LIBS - strictly speaking this
247# shouldn't be necessary, however a number of downstream components
248# (e.g. couchstore targets) rely on platform to make available
249# htons/htonl (via Ws2_32) etc when building on Windows.
250# Until all such targets are # updated to link directly to Ws2_32, we
251# link publically.
252TARGET_LINK_LIBRARIES(platform_so PUBLIC
253        ${COUCHBASE_NETWORK_LIBS})
254
255TARGET_INCLUDE_DIRECTORIES(platform_so PUBLIC include)
256# TODO: Add a TARGET_INCLUDE_DIRECTORIES(PUBLIC) to phosphor; then the
257# following line can be removed:
258TARGET_INCLUDE_DIRECTORIES(platform_so PRIVATE ${phosphor_SOURCE_DIR}/include)
259
260# 'platform' - the library clients should normally link to.
261#
262# 'platform' is a static library, which itself links to the main platform_so
263# shared library. This is to ensure that any clients of platform always link
264# in the C++ global operator new/delete replacements if they use platform at
265# all. If they didn't then this would cause problems:
266# 1) Memory usage from the client will not be tracked.
267# 2) If a C++ object allocated in platform (using cbmalloc via new) is
268#    delete'd in the client (using default free) then we have a mismatched
269#    new/delete pair.
270# By giving all clients of platform the global new/delete automatically we
271# avoid these problems.
272ADD_LIBRARY(platform STATIC src/global_new_replacement.cc)
273SET_TARGET_PROPERTIES(platform PROPERTIES POSITION_INDEPENDENT_CODE true)
274TARGET_LINK_LIBRARIES(platform platform_headers platform_so)
275
276# On OS X 10.11 we need to remove the default rpath settings in order to all
277# us to load the platform library from Python scripts that are run out of
278# /usr/bin/python. We can remove this once we ship our own Python.
279IF (APPLE)
280    SET_TARGET_PROPERTIES(platform_so
281                          PROPERTIES
282                          INSTALL_RPATH "")
283ENDIF ()
284
285SET_TARGET_PROPERTIES(platform_so PROPERTIES SOVERSION 0.1.0)
286
287# TODO: Given dirutils now links with platform (for cbmalloc &
288# global_new_replacement) we can probably just merge it into platform.
289ADD_LIBRARY(dirutils SHARED
290            src/dirutils.cc
291            include/platform/dirutils.h)
292SET_TARGET_PROPERTIES(dirutils PROPERTIES SOVERSION 0.1.0)
293TARGET_LINK_LIBRARIES(dirutils platform)
294GENERATE_EXPORT_HEADER(dirutils
295                       EXPORT_MACRO_NAME DIRUTILS_PUBLIC_API
296                       EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/include/platform/dirutils-visibility.h)
297
298IF (BREAKPAD_FOUND)
299   ADD_DEFINITIONS(-DHAVE_BREAKPAD)
300   INCLUDE_DIRECTORIES(AFTER ${BREAKPAD_INCLUDE_DIR})
301   # Breakpad has headers (which are dependencies for our breakpad integration
302   # code) that don't compile cleanly as C++11, so the GNU standard is
303   # used instead.
304   IF (UNIX)
305      set_source_files_properties(src/breakpad_wrapper.cc PROPERTIES COMPILE_FLAGS ${CB_GNU_CXX11_OPTION})
306   ENDIF (UNIX)
307ENDIF (BREAKPAD_FOUND)
308
309# To simplify usage we always build breakpad_wrapper; it'll just
310# do nothing on targets which don't have Breakpad.
311ADD_LIBRARY(breakpad_wrapper SHARED
312            src/breakpad_wrapper.cc
313            include/breakpad_wrapper/breakpad_wrapper.h)
314SET_TARGET_PROPERTIES(breakpad_wrapper PROPERTIES COMPILE_FLAGS "-Dplatform_so_EXPORTS")
315TARGET_LINK_LIBRARIES(breakpad_wrapper
316                      ${BREAKPAD_LIBRARIES} platform_headers)
317
318INSTALL(TARGETS breakpad_wrapper cJSON JSON_checker platform_so dirutils
319        RUNTIME DESTINATION bin
320        LIBRARY DESTINATION lib
321        ARCHIVE DESTINATION lib)
322
323ADD_SUBDIRECTORY(cbcompress)
324
325IF (PLATFORM_ENABLE_CBSOCKET)
326   ADD_SUBDIRECTORY(cbsocket)
327ENDIF (PLATFORM_ENABLE_CBSOCKET)
328
329if (COUCHBASE_PLATFORM_BUILD_UNIT_TESTS)
330    ADD_SUBDIRECTORY(tests)
331endif (COUCHBASE_PLATFORM_BUILD_UNIT_TESTS)
332