Skip to content

Commit

Permalink
♻️ Use FetchContent and revamp CMake structure (#81)
Browse files Browse the repository at this point in the history
This PR brings some updates to the overall CMake project organization.
  • Loading branch information
burgholzer authored Feb 8, 2024
2 parents dd1e02f + 0ac646b commit 89634f9
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 93 deletions.
10 changes: 0 additions & 10 deletions .gitmodules

This file was deleted.

4 changes: 1 addition & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ repos:

# Handling unwanted unicode characters
- repo: https://github.com/sirosen/texthooks
rev: 0.6.3
rev: 0.6.4
hooks:
- id: fix-ligatures
- id: fix-smartquotes
Expand Down Expand Up @@ -63,8 +63,6 @@ repos:
hooks:
- id: cmake-format
additional_dependencies: [pyyaml]
- id: cmake-lint
additional_dependencies: [pyyaml]

# Format configuration files with prettier
- repo: https://github.com/pre-commit/mirrors-prettier
Expand Down
56 changes: 25 additions & 31 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# set required cmake version
cmake_minimum_required(VERSION 3.19...3.27)
cmake_minimum_required(VERSION 3.19...3.28)

project(
logicblocks
Expand All @@ -13,9 +13,29 @@ configure_file("${${PROJECT_NAME}_SOURCE_DIR}/cmake/version.hpp.in"
# enable organization of targets into folders
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE
Release
CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui, ccmake
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel"
"RelWithDebInfo")
endif()

# Require C++ standard
set_property(GLOBAL PROPERTY CMAKE_CXX_STANDARD_REQUIRED ON)
set_property(GLOBAL PROPERTY CXX_EXTENSIONS OFF)

# configuration options
option(ENABLE_COVERAGE "Configure for coverage report generation")
option(GENERATE_POSITION_INDEPENDENT_CODE "Generate position independent code")
option(GENERATE_POSITION_INDEPENDENT_CODE "Generate position independent code" ON)

# Generate compile_commands.json to make it easier to work with clang based tools
set(CMAKE_EXPORT_COMPILE_COMMANDS
ON
CACHE BOOL "Export compile commands" FORCE)

option(DEPLOY "Configure for deployment")
if(DEFINED ENV{DEPLOY})
Expand All @@ -38,42 +58,16 @@ if(DEPLOY)
CACHE STRING "" FORCE)
endif()

# check whether the submodule ``modulename`` is correctly cloned in the ``/extern`` directory.
macro(CHECK_SUBMODULE_PRESENT modulename)
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/${modulename}/CMakeLists.txt")
message(
FATAL_ERROR
"${modulename} submodule not cloned properly. \
Please run `git submodule update --init --recursive` \
from the main project directory")
endif()
endmacro()

# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE
Release
CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui, ccmake
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel"
"RelWithDebInfo")
endif()

check_submodule_present(plog)

# Add path for custom modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# search for Z3
if(NOT Z3_FOUND)
find_package(Z3 4.8.15)
endif()
option(BUILD_LB_TESTS "Also build tests for LogicBlocks project" ON)

include(cmake/ExternalDependencies.cmake)

add_subdirectory(src)

# add test code
option(BUILD_LB_TESTS "Also build tests for LogicBlocks project" ON)
if(BUILD_LB_TESTS)
enable_testing()
include(GoogleTest)
Expand Down
51 changes: 51 additions & 0 deletions cmake/ExternalDependencies.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Declare all external dependencies and make sure that they are available.

include(FetchContent)
set(FETCH_PACKAGES "")

# search for Z3
find_package(Z3 4.8.15)
if(NOT Z3_FOUND)
message(WARNING "Did not find Z3. Some targets will not be available")
endif()

set(PLOG_VERSION
1.1.10
CACHE STRING "Plog version")
set(PLOG_URL https://github.com/SergiusTheBest/plog/archive/refs/tags/${PLOG_VERSION}.tar.gz)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
FetchContent_Declare(plog URL ${PLOG_URL} FIND_PACKAGE_ARGS ${PLOG_VERSION})
list(APPEND FETCH_PACKAGES plog)
else()
find_package(plog ${PLOG_VERSION} QUIET)
if(NOT plog_FOUND)
FetchContent_Declare(plog URL ${PLOG_URL})
list(APPEND FETCH_PACKAGES plog)
endif()
endif()

if(BUILD_LB_TESTS)
set(gtest_force_shared_crt
ON
CACHE BOOL "" FORCE)
set(GTEST_VERSION
1.14.0
CACHE STRING "Google Test version")
set(GTEST_URL https://github.com/google/googletest/archive/refs/tags/v${GTEST_VERSION}.tar.gz)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
FetchContent_Declare(googletest URL ${GTEST_URL} FIND_PACKAGE_ARGS ${GTEST_VERSION} NAMES GTest)
list(APPEND FETCH_PACKAGES googletest)
else()
find_package(googletest ${GTEST_VERSION} QUIET NAMES GTest)
if(NOT googletest_FOUND)
FetchContent_Declare(googletest URL ${GTEST_URL})
list(APPEND FETCH_PACKAGES googletest)
endif()
endif()
endif()

# Make all declared dependencies available.
FetchContent_MakeAvailable(${FETCH_PACKAGES})

set_target_properties(plog PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
$<TARGET_PROPERTY:plog,INTERFACE_INCLUDE_DIRECTORIES>)
52 changes: 34 additions & 18 deletions cmake/FindZ3.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,41 @@ include(FindPackageHandleStandardArgs)

# Function to check Z3's version
function(check_z3_version z3_include z3_lib)
if(z3_include AND EXISTS "${z3_include}/z3_version.h")
file(STRINGS "${z3_include}/z3_version.h" z3_version_str
REGEX "^#define[\t ]+Z3_MAJOR_VERSION[\t ]+.*")
string(REGEX REPLACE "^.*Z3_MAJOR_VERSION[\t ]+([0-9]*).*$" "\\1" Z3_MAJOR "${z3_version_str}")

file(STRINGS "${z3_include}/z3_version.h" z3_version_str
REGEX "^#define[\t ]+Z3_MINOR_VERSION[\t ]+.*")
string(REGEX REPLACE "^.*Z3_MINOR_VERSION[\t ]+([0-9]*).*$" "\\1" Z3_MINOR "${z3_version_str}")

file(STRINGS "${z3_include}/z3_version.h" z3_version_str
REGEX "^#define[\t ]+Z3_BUILD_NUMBER[\t ]+.*")
string(REGEX REPLACE "^.*Z3_BUILD_NUMBER[\t ]+([0-9]*).*$" "\\1" Z3_BUILD "${z3_version_str}")

set(z3_version_string ${Z3_MAJOR}.${Z3_MINOR}.${Z3_BUILD})
endif()
try_run(
Z3_RUN_RESULT Z3_COMPILE_RESULT ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/try_z3.cpp
CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${z3_include} LINK_LIBRARIES ${z3_lib}
COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
RUN_OUTPUT_VARIABLE RUN_OUTPUT)

if(NOT Z3_COMPILE_RESULT)
message(STATUS "Could not compile test program for Z3 version check. Output: "
${COMPILE_OUTPUT})
if(z3_include AND EXISTS "${z3_include}/z3_version.h")
file(STRINGS "${z3_include}/z3_version.h" z3_version_str
REGEX "^#define[\t ]+Z3_MAJOR_VERSION[\t ]+.*")
string(REGEX REPLACE "^.*Z3_MAJOR_VERSION[\t ]+([0-9]*).*$" "\\1" Z3_MAJOR
"${z3_version_str}")

file(STRINGS "${z3_include}/z3_version.h" z3_version_str
REGEX "^#define[\t ]+Z3_MINOR_VERSION[\t ]+.*")
string(REGEX REPLACE "^.*Z3_MINOR_VERSION[\t ]+([0-9]*).*$" "\\1" Z3_MINOR
"${z3_version_str}")

file(STRINGS "${z3_include}/z3_version.h" z3_version_str
REGEX "^#define[\t ]+Z3_BUILD_NUMBER[\t ]+.*")
string(REGEX REPLACE "^.*Z3_BUILD_NUMBER[\t ]+([0-9]*).*$" "\\1" Z3_BUILD "${z3_version_str}")

set(z3_version_string ${Z3_MAJOR}.${Z3_MINOR}.${Z3_BUILD})
endif()

if(NOT z3_version_string)
message(STATUS "Could not determine Z3 version")
return()
if(NOT z3_version_string)
message(STATUS "Could not determine Z3 version from z3_version.h")
return()
endif()
else()
string(REGEX MATCH "(Z3 )?([0-9]+.[0-9]+.[0-9]+.[0-9]+)" Z3_VERSION_STRING ${RUN_OUTPUT})
set(z3_version_string ${CMAKE_MATCH_2})
endif()

find_package_check_version(${z3_version_string} suitable_version RESULT_MESSAGE_VARIABLE reason)
Expand Down
7 changes: 7 additions & 0 deletions cmake/try_z3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <iostream>
#include <z3.h>

int main() {
std::cout << Z3_get_full_version();
return 0;
}
1 change: 0 additions & 1 deletion extern/googletest
Submodule googletest deleted from f8d7d7
1 change: 0 additions & 1 deletion extern/plog
Submodule plog deleted from 199734
22 changes: 2 additions & 20 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
# add logging library target
add_subdirectory("${PROJECT_SOURCE_DIR}/extern/plog" "extern/plog")
# the following sets the SYSTEM flag for the include dirs of the plog libs to suppress warnings
# cmake-lint: disable=C0307
set_target_properties(plog PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
$<TARGET_PROPERTY:plog,INTERFACE_INCLUDE_DIRECTORIES>)

add_library(
LogicTerm_lib
${CMAKE_CURRENT_SOURCE_DIR}/LogicTerm/TermImpl.cpp
Expand All @@ -24,11 +17,10 @@ add_library(
target_include_directories(LogicTerm_lib PUBLIC ${PROJECT_SOURCE_DIR}/include)

# add logging library
target_link_libraries(LogicTerm_lib PUBLIC plog)
target_link_libraries(LogicTerm_lib PUBLIC plog::plog)

# set required C++ standard and disable compiler specific extensions
target_compile_features(LogicTerm_lib PUBLIC cxx_std_17)
set_target_properties(LogicTerm_lib PROPERTIES CMAKE_CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF)

# enable interprocedural optimization if it is supported
include(CheckIPOSupported)
Expand All @@ -42,11 +34,7 @@ endif()
if(MSVC)
target_compile_options(LogicTerm_lib PUBLIC /utf-8)
else()
target_compile_options(LogicTerm_lib PUBLIC -Wall -Wextra $<$<CONFIG:DEBUG>:-Og>)
if(BINDINGS)
# adjust visibility settings for building Python bindings
target_compile_options(LogicTerm_lib PUBLIC -fvisibility=hidden)
endif()
target_compile_options(LogicTerm_lib PUBLIC -Wall -Wextra -g)
if(NOT DEPLOY)
# only include machine-specific optimizations when building for the host machine
include(CheckCXXCompilerFlag)
Expand All @@ -70,12 +58,6 @@ if(ENABLE_COVERAGE)
target_link_libraries(LogicTerm_lib PUBLIC --coverage)
endif()

if(BINDINGS)
include(CheckPIESupported)
check_pie_supported()
set_target_properties(LogicTerm_lib PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE ON)
endif()

add_library(
SMTLibLogic
${${PROJECT_NAME}_SOURCE_DIR}/include/LogicBlock/LogicBlock.hpp
Expand Down
9 changes: 0 additions & 9 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
if(NOT TARGET gtest OR NOT TARGET gmock)
# Prevent overriding the parent project's compiler/linker settings on Windows
set(gtest_force_shared_crt # cmake-lint: disable=C0103
ON
CACHE BOOL "" FORCE)
add_subdirectory("${PROJECT_SOURCE_DIR}/extern/googletest" "extern/googletest" EXCLUDE_FROM_ALL)
set_target_properties(gtest gtest_main gmock gmock_main PROPERTIES FOLDER extern)
endif()

# macro to add a test executable for one of the project libraries
macro(PACKAGE_ADD_TEST testname linklibs)
# create an executable in which the tests will be stored
Expand Down

0 comments on commit 89634f9

Please sign in to comment.