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

♻️ Use FetchContent and revamp CMake structure #81

Merged
merged 9 commits into from
Feb 8, 2024
Merged
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
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
Loading