Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding CMake to manage the build process #774

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ test/clustertest/testplugin/testplugin.so
test/bedrocktest_*
test/clustertest/cluster_node_?_bedrocktest*
bedrock
build
.build
libbedrock.a
libstuff.a
Expand Down
7 changes: 6 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
language: c++
sudo: false
env:
- GXX=g++-9 CC=gcc-9
- BUILD_PROCESS=make GXX=g++-9 CC=gcc-9
- BUILD_PROCESS=cmake CXX=g++-9 CC=gcc-9
addons:
apt:
sources:
Expand All @@ -11,6 +13,9 @@ addons:
notifications:
email:
on_success: never
cache:
directories:
- ${HOME}/.local
before_install:
script: ./travis.sh
dist: xenial
Expand Down
160 changes: 160 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
cmake_minimum_required(VERSION 3.16) # Minimum required for precompiled headers
project(Bedrock)

if(WIN32)
message(FATAL_ERROR "Windows platform is not currently supported")
elseif(DEFINED ENV{WSL_DISTRO_NAME})
message(WARNING "Windows subsystem for linux is not fully supported")
endif()

# Handle submodule initialization if necessary
find_package(Git QUIET)
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_SHORT_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Bedrock revision: ${GIT_SHORT_REVISION}")
option(GIT_SUBMODULE "Check submodules during build" ON)
if(GIT_SUBMODULE AND NOT EXISTS "${PROJECT_SOURCE_DIR}/mbedtls/CMakeLists.txt")
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE GIT_SUBMODULE_RESULT
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT GIT_SUBMODULE_RESULT EQUAL "0")
message(FATAL_ERROR "git submodule update --init failed: ${GIT_SUBMODULE_RESULT}")
endif()
endif()
endif()

if(NOT EXISTS "${PROJECT_SOURCE_DIR}/mbedtls/CMakeLists.txt")
message(FATAL_ERROR "Third party library mbedtls is missing")
endif()

# Ensure additional CMake modules are made available
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules)
include(ExternalProject)

# Default to release builds
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()

option(ENABLE_TESTING "Build Bedrock tests" Off)
option(ENABLE_MBEDTLS_PROGRAMS "Build libmedtls programs" Off)
option(ENABLE_PRODUCTION "Build Bedrock in production mode" Off)

# Ensure required dependencies are available
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(DL REQUIRED)
find_package(PCRECPP REQUIRED)
find_package(Threads REQUIRED)
find_package(ZLIB REQUIRED)

# Define common CXX flags for libraries and executables
set(CMAKE_CXX_FLAGS "$ENV{BEDROCK_OPTIM_COMPILE_FLAG} \
-Wall \
-Werror \
-Wformat-security \
-DGIT_REVISION=${GIT_SHORT_REVISION} \
-MMD")
set(CMAKE_POSITION_INDEPENDENT_CODE ON) # -fPIC
set(CMAKE_CXX_STANDARD 14) # -std=c++14
set(CMAKE_CXX_STANDARD_REQUIRED On)
set(CMAKE_CXX_EXTENSIONS Off) # Ensure -std=gnu++14 is disabled
set(BEDROCK_LINKER_FLAGS "-rdynamic")
set(CMAKE_SHARED_LINKER_FLAGS "${BEDROCK_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${BEDROCK_LINKER_FLAGS}")

# Place all external project build files in their own directory within the build
set_directory_properties(PROPERTIES EP_BASE "${PROJECT_BINARY_DIR}/external")

# Gather all the files for the Bedrock library
file(GLOB BEDROCKH *.h)
file(GLOB BEDROCK_PLUGINSH plugins/*.h)
file(GLOB BEDROCK_SQLITECLUSTERH sqlitecluster/*.h)
file(GLOB BEDROCKCPP *.cpp)
list(REMOVE_ITEM BEDROCKCPP "${PROJECT_SOURCE_DIR}/main.cpp")
file(GLOB BEDROCK_PLUGINSCPP plugins/*.cpp)
file(GLOB BEDROCK_SQLITECLUSTERCPP sqlitecluster/*.cpp)

# Gather the header files used by the Bedrock library
file(GLOB BEDROCK_LIBSTUFFH libstuff/*.h)

# Allow for folders to be used (IDEs)
set_property(GLOBAL PROPERTY USE_FOLDERS On)

# Group the header and source files for the Bedrock library (IDE)
source_group("Header Files" FILES ${BEDROCKH})
source_group("Header Files\\plugins" FILES ${BEDROCK_PLUGINSH})
source_group("Header Files\\sqlitecluster" FILES ${BEDROCK_SQLITECLUSTERH})
source_group("Source Files" FILES ${BEDROCKCPP})
source_group("Source Files\\plugins" FILES ${BEDROCK_PLUGINSCPP})
source_group("Source Files\\sqlitecluster" FILES ${BEDROCK_SQLITECLUSTERCPP})

# Group the libstuff headers used by the Bedrock library (IDE)
source_group("Header Files\\stuff" FILES ${BEDROCK_LIBSTUFFH})

# Ensure the proper includes are made available for all libraries and executables
include_directories(${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_SOURCE_DIR}/mbedtls/include)

# Establish an external project for in source dependency build of libmedtls
externalproject_add(libmbedtls
SOURCE_DIR ${PROJECT_SOURCE_DIR}/mbedtls
INSTALL_DIR ${PROJECT_BINARY_DIR}/libmedtls
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/libmedtls
-DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_POSITION_INDEPENDENT_CODE=On
-DENABLE_PROGRAMS=${ENABLE_MBEDTLS_PROGRAMS}
-DENABLE_TESTING=Off)
ExternalProject_Get_Property(libmbedtls INSTALL_DIR)
link_directories(${INSTALL_DIR}/lib)

# Add libstuff to the build
add_subdirectory(libstuff)

# Add libbedrock to the build
# Note: Header files are included for IDEs
add_library(bedrock STATIC ${BEDROCKCPP}
${BEDROCK_PLUGINSCPP}
${BEDROCK_SQLITECLUSTERCPP}
${BEDROCKH}
${BEDROCK_PLUGINSH}
${BEDROCK_SQLITECLUSTERH}
${BEDROCK_LIBSTUFFH})
target_precompile_headers(bedrock PRIVATE libstuff/libstuff.h)
set_target_properties(bedrock PROPERTIES FOLDER "Libraries")

# Create a common list of libraries for Bedrock
list(APPEND BEDROCK_LIBRARIES bedrock stuff
mbedtls mbedx509 mbedcrypto
DL::DL
PCRECPP::PCRECPP
Threads::Threads
ZLIB::ZLIB)

# Add bedrock executable to the build
# Note: Header files are included for IDEs
add_executable(bedrock-bin main.cpp
${BEDROCKH}
${BEDROCK_PLUGINSH}
${BEDROCK_SQLITECLUSTERH}
${BEDROCK_LIBSTUFFH})
add_dependencies(bedrock-bin bedrock
libmbedtls
stuff)
target_link_libraries(bedrock-bin ${BEDROCK_LIBRARIES})
set_target_properties(bedrock-bin PROPERTIES OUTPUT_NAME bedrock
FOLDER "Applications")

if(ENABLE_TESTING)
# Add tests to the build
add_subdirectory(test)
endif()
32 changes: 32 additions & 0 deletions cmake/modules/FindDL.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# DL_FOUND - Dynamic linking interface available
# DL_INCLUDE_DIR - Where dlfcn.h is located.
# DL_LIBRARY - Libraries needed to use dlopen
include(CheckFunctionExists)

find_path(DL_INCLUDE_DIR NAMES dlfcn.h)
find_library(DL_LIBRARY NAMES dl)
if(DL_LIBRARY)
set(DL_FOUND TRUE)
else(DL_LIBRARY)
check_function_exists(dlopen DL_FOUND)
# If dlopen can be found without linking in dl then dlopen is part
# of libc, so don't need to link extra libs.
set(DL_LIBRARY "")
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DL FOUND_VAR DL_FOUND
REQUIRED_VARS DL_INCLUDE_DIR)
mark_as_advanced(DL_INCLUDE_DIR DL_LIBRARY)

if(DL_FOUND AND NOT TARGET DL::DL)
if(DL_LIBRARY)
add_library(DL::DL UNKNOWN IMPORTED)
set_target_properties(DL::DL PROPERTIES
IMPORTED_LOCATION "${DL_LIBRARY}")
else()
add_library(DL::DL INTERFACE IMPORTED )
endif()
set_target_properties(DL::DL PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${DL_INCLUDE_DIR}")
endif()
25 changes: 25 additions & 0 deletions cmake/modules/FindPCRECPP.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# PCRECPP_FOUND - Perl Compatible Regular Expressions available
# PCRECPP_INCLUDE_DIR - Where pcrecpp.h is located.
# PCRECPP_LIBRARY - Libraries needed to use PCRE
include(CheckFunctionExists)

find_path(PCRECPP_INCLUDE_DIR NAMES pcrecpp.h)
find_library(PCRECPP_LIBRARY NAMES pcrecpp)
if(PCRECPP_LIBRARY)
set(PCRECPP_FOUND TRUE)
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PCRECPP FOUND_VAR PCRECPP_FOUND
REQUIRED_VARS PCRECPP_INCLUDE_DIR)
mark_as_advanced(PCRECPP_INCLUDE_DIR DL_LIBRARY)

if(PCRECPP_FOUND AND NOT TARGET PCRECPP::PCRECPP)
if(PCRECPP_LIBRARY)
add_library(PCRECPP::PCRECPP UNKNOWN IMPORTED)
set_target_properties(PCRECPP::PCRECPP PROPERTIES
IMPORTED_LOCATION "${PCRECPP_LIBRARY}")
endif()
set_target_properties(PCRECPP::PCRECPP PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${DL_INCLUDE_DIR}")
endif()
44 changes: 44 additions & 0 deletions libstuff/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Gather all the files for the stuff library
file(GLOB LIBSTUFFH *.h)
file(GLOB LIBSTUFFCPP *.cpp)
file(GLOB LIBSTUFFC *.c)

# Group the header and source files for the stuff library (IDE)
source_group("Header Files" FILES ${LIBSTUFFH})
source_group("Source Files" FILES ${LIBSTUFFCPP} ${LIBSTUFFC})

# Gather and group the headers for the mbedtls library (IDE)
file(GLOB LIBMBEDTLSH ${PROJECT_SOURCE_DIR}/mbedtls/include/mbedtls/*.h)
source_group("Header Files\\mbedtls" FILES ${LIBMBEDTLSH})

# Define the C flags for the c files within the stuff library
# Note: This is basically just for sqlite, so we don't bother with dependencies
# for it. SQLITE_MAX_MMAP_SIZE is set to 16TB
set(LIBSTUFF_C_FLAGS "$ENV{BEDROCK_OPTIM_COMPILE_FLAG} \
-Wno-unused-but-set-variable \
-DSQLITE_ENABLE_STAT4 \
-DSQLITE_ENABLE_JSON1 \
-DSQLITE_ENABLE_SESSION \
-DSQLITE_ENABLE_PREUPDATE_HOOK \
-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT \
-DSQLITE_ENABLE_NOOP_UPDATE \
-DSQLITE_MUTEX_ALERT_MILLISECONDS=20 \
-DSQLITE_MAX_MMAP_SIZE=17592186044416ull \
-DSQLITE_SHARED_MAPPING \
-DSQLITE_ENABLE_NORMALIZE")
check_function_exists("usleep" HAVE_USLEEP)
if(HAVE_USLEEP)
set(LIBSTUFF_C_FLAGS "${LIBSTUFF_C_FLAGS} -DHAVE_USLEEP=1")
else()
message(FATAL_ERROR "usleep is required")
endif()
set(CMAKE_C_FLAGS "${LIBSTUFF_C_FLAGS}")

# Add libstuff to the build
# Note: Header files are included for IDEs
ADD_LIBRARY(stuff STATIC
${LIBSTUFFCPP}
${LIBSTUFFC}
${LIBSTUFFH}
${LIBMBEDTLSH})
set_target_properties(stuff PROPERTIES FOLDER "Libraries")
58 changes: 58 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Ensure required dependencies are available
# Note: This action is performed again to allow for module property availability
find_package(DL REQUIRED)
find_package(PCRECPP REQUIRED)
find_package(Threads REQUIRED)
find_package(ZLIB REQUIRED)

# Gather all the files for the test executable
file(GLOB TEST_TESTS_JOBSH tests/jobs/*.h)
file(GLOB TESTCPP main.cpp)
file(GLOB TEST_TESTSCPP tests/*.cpp)
file(GLOB TEST_TESTS_JOBSCPP tests/jobs/*.cpp)

# Gather the headers for the test framework library
file(GLOB TEST_TPUNITH lib/*.h)

# Group the header and source for the test executable (IDE)
source_group("Header Files\\tests\\jobs" FILES ${TEST_TESTS_JOBSH})
source_group("Source Files" FILES ${TESTCPP})
source_group("Source Files\\tests" FILES ${TEST_TESTSCPP})
source_group("Source Files\\tests\\jobs" FILES ${TEST_TESTS_JOBSCPP})

# Group the headers used by the test executable (IDE)
source_group("Header Files\\tpunit" FILES ${TEST_TPUNITH})
source_group("Header Files\\bedrock" FILES ${BEDROCKH})
source_group("Header Files\\bedrock\\plugins" FILES ${BEDROCK_PLUGINSH})
source_group("Header Files\\bedrock\\sqlitecluster" FILES ${BEDROCK_SQLITECLUSTERH})
source_group("Header Files\\bedrock\\stuff" FILES ${BEDROCK_LIBSTUFFH})

# Add test executable to the build
# Note: Header files are included for IDEs
add_executable(test ${TESTCPP}
${TEST_TESTSCPP}
${TEST_TESTS_JOBSCPP}
${TEST_TESTS_JOBSH}
${TEST_TPUNITH}
${BEDROCKH}
${BEDROCK_PLUGINSH}
${BEDROCK_SQLITECLUSTERH}
${BEDROCK_LIBSTUFFH})
add_dependencies(test bedrock-bin
tpunit
testplugin)
target_link_libraries(test tpunit
${BEDROCK_LIBRARIES})
set_target_properties(test PROPERTIES FOLDER "Tests")

# Add a post action to the test executable build
# Note: This copies the sample_data directory for proper execution of the
# test executable
add_custom_target(copy-sample_data ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/sample_data ${CMAKE_CURRENT_BINARY_DIR}/sample_data
DEPENDS test)
set_target_properties(copy-sample_data PROPERTIES FOLDER "Tests/Post Build Actions")

# Add clustertest, test plugin and test framework to the build
add_subdirectory(clustertest)
add_subdirectory(lib)
Loading