Skip to content

Commit

Permalink
Refactor CMake and add missing API
Browse files Browse the repository at this point in the history
  • Loading branch information
borrrden committed Mar 12, 2019
1 parent ee5b9ef commit b123563
Show file tree
Hide file tree
Showing 16 changed files with 363 additions and 181 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -5,3 +5,4 @@ build_cmake
python/CouchbaseLite/libcouchbase_lite.dylib
python/CouchbaseLite/PyCBL.c
.vscode
empty.cpp
230 changes: 60 additions & 170 deletions CMakeLists.txt
Expand Up @@ -16,189 +16,102 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 11)
option(CODE_COVERAGE_ENABLED "Set whether or not code coverage information should be generated" OFF)
option(BUILD_ENTERPRISE "Set whether or not to build enterprise edition" OFF)

add_definitions(-DCMAKE # Let the source know this is a CMAKE build
-D__STDC_LIMIT_MACROS # Ensure the presence of UINT64_MAX, etc
-DNOMINMAX # Get rid of pesky Windows macros for min and max
-DHAVE_LOCALTIME_R
-DHAVE_USLEEP
-DHAVE_UTIME)

if(BUILD_ENTERPRISE)
add_definitions(-DCOUCHBASE_ENTERPRISE) # Tells CBL it's an EE build
endif()

add_definitions("-DCMAKE")
include(CheckIncludeFile)
include (CheckFunctionExists)
check_include_file(unistd.h CBL_HAVE_UNISTD_H)
check_include_file(direct.h CBL_HAVE_DIRECT_H)
check_function_exists(vasprintf, CBL_HAVE_VASPRINTF)

configure_file(
"${PROJECT_SOURCE_DIR}/include/cbl/cbl_config.h.in"
"${PROJECT_BINARY_DIR}/include/cbl/cbl_config.h"
)
if(MSVC)
if(WINDOWS_STORE)
add_definitions(-D_WIN32_WINNT=0x0602) # Support back to Windows 8 for Windows Store
else()
add_definitions(-D_WIN32_WINNT=0x0601 # Support back to Windows 7 for Windows desktop
-DINCL_EXTRA_HTON_FUNCTIONS)# Make sure htonll is defined for WebSocketProtocol.hh
endif()
include("cmake/platform_win.cmake")
elseif(ANDROID)
# See: https://github.com/android-ndk/ndk/issues/477
# The issue is also applicable for other areas like fseeko
add_definitions(-D_FILE_OFFSET_BITS=32)
include("cmake/platform_android.cmake")
elseif(APPLE)
include("cmake/platform_apple.cmake")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
include("cmake/platform_linux.cmake")
else()
message(FATAL_ERROR "Unknown platform")
endif()

init_vars()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CBL_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CBL_CXX_FLAGS}")
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
$<$<CONFIG:Debug>:DEBUG>
)

if(CODE_COVERAGE_ENABLED)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug" AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -O0")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -O0")
elseif(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
message(WARN " Code coverage not supported for non-debug builds")
else()
message(WARN " Code coverage only supported on Clang")
endif()
endif()


if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8 /EHsc /wd4068 /wd4244 /wd4018 /wd4819 /wd4800 -D_CRT_SECURE_NO_WARNINGS=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8 -D_CRT_SECURE_NO_WARNINGS=1")
endif()

if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
add_definitions(-DLITECORE_USES_ICU=1)

# Enable relative RPATHs for installed bits
set (CMAKE_INSTALL_RPATH "\$ORIGIN")

if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
message(FATAL_ERROR "${CMAKE_CXX_COMPILER_ID} is not supported for building!")
endif()
find_library(LIBCXX_LIB c++)
if (NOT LIBCXX_LIB)
message(FATAL_ERROR "libc++ not found")
endif()
message("Found libc++ at ${LIBCXX_LIB}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")

find_library(LIBCXXABI_LIB c++abi)
if (NOT LIBCXXABI_LIB)
message(FATAL_ERROR "libc++abi not found")
endif()
message("Found libc++abi at ${LIBCXXABI_LIB}")
find_path(LIBCXX_INCLUDE c++/v1/string
HINTS "${CMAKE_BINARY_DIR}/tlm/deps/libcxx.exploded"
PATH_SUFFIXES include)
if (NOT LIBCXX_INCLUDE)
message(FATAL_ERROR "libc++ header files not found")
endif()
message("Using libc++ header files in ${LIBCXX_INCLUDE}")
include_directories("${LIBCXX_INCLUDE}/c++/v1")
if(NOT EXISTS "/usr/include/xlocale.h")
include_directories("${LIBCXX_INCLUDE}/c++/v1/support/xlocale") # this fixed path is here to avoid compilation on Ubuntu 17.10 where xlocale.h is searched by some header(s) in libc++ as <xinclude.h> but not found from search path without this modification. However, only do it if the original xlocale.h does not exist since this will get searched before /usr/include and override a valid file with an empty one.
endif()
include_directories("/usr/include/libcxxabi") # this fixed path is here to avoid Clang issue noted at http://lists.alioth.debian.org/pipermail/pkg-llvm-team/2015-September/005208.html
endif()
find_library(ICU4C_COMMON icuuc)
if (NOT ICU4C_COMMON)
message(FATAL_ERROR "libicuuc not found")
endif()
message("Found libicuuc at ${ICU4C_COMMON}")
find_library(ICU4C_I18N icui18n)
if (NOT ICU4C_I18N)
message(FATAL_ERROR "libicui18n not found")
endif()
message("Found libicui18n at ${ICU4C_I18N}")
find_path(LIBICU_INCLUDE unicode/ucol.h
HINTS "${CMAKE_BINARY_DIR}/tlm/deps/icu4c.exploded"
PATH_SUFFIXES include)
if (NOT LIBICU_INCLUDE)
message(FATAL_ERROR "libicu header files not found")
endif()
message("Using libicu header files in ${LIBICU_INCLUDE}")
include_directories("${LIBICU_INCLUDE}")
endif()

if(WIN32 OR ANDROID)
if(ANDROID)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libgcc.a")
endif()
endif()

### SUBMODULES:

include_directories("vendor/couchbase-lite-core/C/include"
"vendor/couchbase-lite-core/vendor/fleece/API"
"vendor/couchbase-lite-core/vendor/fleece/Fleece/Support")

if(WIN32)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /ignore:4099 /ignore:4221")
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221")
endif()

add_subdirectory(vendor/couchbase-lite-core EXCLUDE_FROM_ALL)

### MORE BUILD SETTINGS:

# Generate file repo_version.h containing Git repo information, and add it to #include path:
set(GENERATED_HEADERS_DIR "${CMAKE_BINARY_DIR}/generated_headers")
file(MAKE_DIRECTORY "${GENERATED_HEADERS_DIR}")
if (UNIX)
execute_process(COMMAND /bin/bash "${PROJECT_SOURCE_DIR}/build_cmake/scripts/get_repo_version.sh"
"${GENERATED_HEADERS_DIR}/repo_version.h")
else()
execute_process(COMMAND powershell "${PROJECT_SOURCE_DIR}/build_cmake/scripts/get_repo_version.ps1"
"${GENERATED_HEADERS_DIR}/repo_version.h")
endif()
include_directories(${GENERATED_HEADERS_DIR})


### SOURCE FILES:

include_directories(include/cbl src)

# TODO: CMake docs say it's better to list the source files explicitly than use aux_source_directory
aux_source_directory(src SRC_FILES)

if(!MSVC)
set_source_files_properties(${C_SRC} PROPERTIES COMPILE_FLAGS -Wno-return-type-c-linkage)
endif()

### BUILDING THE LIBRARY:

set(ALL_SRC_FILES
${SRC_FILES})

if(MSVC)
include_directories("vendor/fleece/MSVC")
endif()

if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
# libc++ is special - clang will introduce an implicit -lc++ when it is used.
# That means we need to tell the linker the path to the directory containing
# libc++.so rather than just linking the .so directly. This must be done
# *before* the target declaration as it affects all subsequent targets.
get_filename_component (LIBCXX_LIBDIR "${LIBCXX_LIB}" DIRECTORY)
link_directories (${LIBCXX_LIBDIR})
endif()
set_platform_source_files(RESULT PLATFORM_SRC)
set(
ALL_SRC_FILES
src/CBLBase.cc
src/CBLBlob.cc
src/CBLDatabase.cc
src/CBLDocument.cc
src/CBLLog.cc
src/CBLQuery.cc
src/CBLReplicator.cc
src/Listener.cc
src/Util.cc
${PLATFORM_SRC}
)

add_library(CouchbaseLiteCStatic STATIC ${ALL_SRC_FILES})
target_include_directories(CouchbaseLiteCStatic PUBLIC include/cbl)
set_platform_include_directories(RESULT PLATFORM_INCLUDE)
target_include_directories(
CouchbaseLiteCStatic
PRIVATE
src
vendor/couchbase-lite-core/C
${PROJECT_BINARY_DIR}/include/cbl/
${PLATFORM_INCLUDE}
)

if(WIN32)
add_library(CouchbaseLiteC SHARED MSVC/SQLiteTempDirectory.cc) #No-op for non-UWP
else()
file(WRITE empty.cpp)
add_library(CouchbaseLiteC SHARED empty.cpp)
endif()
file(WRITE empty.cpp)
add_library(CouchbaseLiteC SHARED empty.cpp)
target_include_directories(CouchbaseLiteC PUBLIC include/cbl)
target_include_directories(
CouchbaseLiteC
PRIVATE
src
vendor/couchbase-lite-core/C
${PROJECT_BINARY_DIR}/include/cbl/
${PLATFORM_INCLUDE}
)

install (TARGETS CouchbaseLiteC
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib)

if(UNIX AND NOT APPLE)
set(WHOLE_LIBRARY_FLAG "-Wl,--whole-archive")
set(NO_WHOLE_LIBRARY_FLAG "-Wl,--no-whole-archive")
endif()
LIBRARY DESTINATION lib
PUBLIC_HEADER DESTINATION include)

set(CBL_LIBRARIES_PRIVATE ${WHOLE_LIBRARY_FLAG}
CouchbaseLiteCStatic
Expand All @@ -213,30 +126,7 @@ set(CBL_LIBRARIES_PRIVATE ${WHOLE_LIBRARY_FLAG}

target_link_libraries(CouchbaseLiteC PRIVATE ${CBL_LIBRARIES_PRIVATE})

# Mac/iOS stuff
if (APPLE)
set_target_properties(CouchbaseLiteC PROPERTIES LINK_FLAGS
"-exported_symbols_list ${PROJECT_SOURCE_DIR}/src/CBL.exp")
target_link_libraries(CouchbaseLiteC PUBLIC "-framework CoreFoundation"
"-framework Foundation"
"-framework CFNetwork"
"-framework Security"
z)
elseif(UNIX AND NOT ANDROID)
target_link_libraries(CouchbaseLiteC PUBLIC z ${ICU4C_COMMON} ${ICU4C_I18N})
elseif(ANDROID)
target_compile_definitions(CouchbaseLiteCStatic PUBLIC -D_CRYPTO_MBEDTLS)
target_link_libraries(CouchbaseLiteC PRIVATE "atomic" "log" zlibstatic)
else()
if(WINDOWS_STORE)
target_compile_definitions(CouchbaseLiteCStatic PUBLIC -DMBEDTLS_NO_PLATFORM_ENTROPY)
set_target_properties(CouchbaseLiteC PROPERTIES COMPILE_FLAGS /ZW)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /nodefaultlib:kernel32.lib /nodefaultlib:ole32.lib")
endif()
set_target_properties(CouchbaseLiteC PROPERTIES LINK_FLAGS
"/def:${PROJECT_SOURCE_DIR}/C/c4.def")
target_link_libraries(CouchbaseLiteC PRIVATE zlibstatic Ws2_32)
endif()
set_dylib_properties()

### TESTS:

Expand Down
18 changes: 18 additions & 0 deletions cmake/platform_android.cmake
@@ -0,0 +1,18 @@
include("${CMAKE_CURRENT_LIST_DIR}/platform_linux.cmake")

function(set_platform_source_files)
# No-op
endfunction()

function(set_platform_include_directories)
# No-op
endfunction()

function(init_vars)
init_vars_linux()
endfunction()

function(set_dylib_properties)
target_compile_definitions(CouchbaseLiteCStatic PRIVATE -D_CRYPTO_MBEDTLS)
target_link_libraries(CouchbaseLiteC PRIVATE atomic log zlibstatic)
endfunction()
31 changes: 31 additions & 0 deletions cmake/platform_apple.cmake
@@ -0,0 +1,31 @@
function(set_platform_source_files)
set(oneValueArgs RESULT)
cmake_parse_arguments(PLATFORM "" ${oneValueArgs} "" ${ARGN})
if(NOT DEFINED PLATFORM_RESULT)
message(FATAL_ERROR set_platform_include_directories needs to be called with RESULT)
endif()

set(
${PLATFORM_RESULT}
src/dylib_main.cc
PARENT_SCOPE
)
endfunction()

function(set_platform_include_directories)
# No-op
endfunction()

function(init_vars)
# No-op
endfunction()

function(set_dylib_properties)
set_target_properties(CouchbaseLiteC PROPERTIES LINK_FLAGS
"-exported_symbols_list ${PROJECT_SOURCE_DIR}/src/CBL.exp")
target_link_libraries(CouchbaseLiteC PUBLIC "-framework CoreFoundation"
"-framework Foundation"
"-framework CFNetwork"
"-framework Security"
z)
endfunction()
6 changes: 6 additions & 0 deletions cmake/platform_linux.cmake
@@ -0,0 +1,6 @@


function(init_vars_linux)
set(WHOLE_LIBRARY_FLAG "-Wl,--whole-archive" CACHE INTERNAL "")
set(NO_WHOLE_LIBRARY_FLAG "-Wl,--no-whole-archive" CACHE INTERNAL "")
endfunction()
17 changes: 17 additions & 0 deletions cmake/platform_linux_desktop.cmake
@@ -0,0 +1,17 @@
include("${CMAKE_CURRENT_LIST_DIR}/platform_linux.cmake")

function(set_platform_source_files)
# No-op
endfunction()

function(set_platform_include_directories)
# No-op
endfunction()

function(init_vars)
init_vars_linux()
endfunction()

function(set_dylib_properties)
target_link_libraries(CouchbaseLiteC PUBLIC z ${ICU4C_COMMON} ${ICU4C_I18N})
endfunction()

0 comments on commit b123563

Please sign in to comment.