Skip to content

Commit a5ef1b3

Browse files
authored
Merge pull request #6 from saxbophone/josh/target-based-usage-requirements
Major structure changes for more neat project:
2 parents 5ee98d6 + 569aa7d commit a5ef1b3

File tree

21 files changed

+1113
-18244
lines changed

21 files changed

+1113
-18244
lines changed

.github/workflows/build-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,5 @@ jobs:
5555
- name: Upload
5656
uses: actions/upload-artifact@v2
5757
with:
58-
name: build_${{ github.run_number }}_${{ matrix.platform_name }}
58+
name: project_build_${{ github.run_number }}_${{ matrix.platform_name }}
5959
path: ${{github.workspace}}/artifacts

.github/workflows/continuous-integration.yml

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ on:
55
branches:
66
- master
77
pull_request:
8+
types: [opened, synchronize]
89

910
jobs:
1011
build:
1112
runs-on: ${{ matrix.os }}
1213
env:
1314
BUILD_TYPE: Debug
1415
strategy:
15-
fail-fast: false
16+
fail-fast: true
1617
matrix:
1718
os: [macos-10.15, ubuntu-20.04]
1819
cxx: [g++-10, clang++]
@@ -23,6 +24,42 @@ jobs:
2324
steps:
2425
- uses: actions/checkout@v2
2526

27+
- name: Cache CMake dependency source code
28+
uses: actions/cache@v2
29+
env:
30+
cache-name: cache-cmake-dependency-sources
31+
with:
32+
# CMake cache is at ${{github.workspace}}/build/_deps but we only will cache folders ending in '-src' to cache source code
33+
path: ${{github.workspace}}/build/_deps/*-src
34+
# Cache hash is dependent on CMakeLists files anywhere as these can change what's in the cache, as well as cmake modules files
35+
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
36+
# it's acceptable to reuse caches for different CMakeLists content if exact match is not available and unlike build caches, we
37+
# don't need to restrict these by OS or compiler as it's only source code that's being cached
38+
restore-keys: |
39+
${{ env.cache-name }}-
40+
41+
- name: Cache CMake dependency build objects
42+
uses: actions/cache@v2
43+
env:
44+
cache-name: cache-cmake-dependency-builds
45+
with:
46+
# CMake cache is at ${{github.workspace}}/build/_deps but we only care about the folders ending in -build or -subbuild
47+
path: |
48+
${{github.workspace}}/build/_deps/*-build
49+
${{github.workspace}}/build/_deps/*-subbuild
50+
# Cache hash is dependent on CMakeLists files anywhere as these can change what's in the cache, as well as cmake modules files
51+
key: ${{ env.cache-name }}-${{ matrix.os }}-${{ matrix.cxx }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
52+
# it's acceptable to reuse caches for different CMakeLists content if exact match is not available
53+
# as long as the OS and Compiler match exactly
54+
restore-keys: |
55+
${{ env.cache-name }}-${{ matrix.os }}-${{ matrix.cxx }}-
56+
57+
# when building on master branch and not a pull request, build and test in release mode (optimised build)
58+
- name: Set Build Mode to Release
59+
shell: bash
60+
if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/master' }}
61+
run: echo "BUILD_TYPE=Release" >> $GITHUB_ENV
62+
2663
- name: Configure CMake
2764
env:
2865
CXX: ${{ matrix.cxx }}
@@ -33,7 +70,7 @@ jobs:
3370
# Note the current convention is to use the -S and -B options here to specify source
3471
# and build directories, but this is only available with CMake 3.13 and higher.
3572
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
36-
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX:PATH=$GITHUB_WORKSPACE/artifacts
73+
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX:PATH=$GITHUB_WORKSPACE/test_install -DENABLE_TESTS=ON
3774

3875
- name: Build
3976
working-directory: ${{github.workspace}}/build
@@ -46,10 +83,10 @@ jobs:
4683
shell: bash
4784
# Execute tests defined by the CMake configuration.
4885
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
49-
run: ctest -C $BUILD_TYPE
86+
run: ctest -C $BUILD_TYPE --no-tests=error
5087

5188
- name: Test Install
5289
working-directory: ${{github.workspace}}/build
5390
shell: bash
54-
# Test install with CMake to the "artifacts" directory
91+
# Test install with CMake to the "test_install" directory
5592
run: cmake --install . --config $BUILD_TYPE

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# WARNING: The Travis-CI build config is unmaintained and may not work
2+
# This project needs CMake3.15+, but at the time of writing (2021-03-10),
3+
# Travis-CI provided CMake3.12 on Linux instances.
4+
15
dist: bionic # this is the most recent Ubuntu image available
26
language: cpp
37
cache: ccache

CMakeLists.txt

Lines changed: 105 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,121 @@
11
# begin basic metadata
22
# minimum CMake version required for C++20 support, among other things
3-
cmake_minimum_required(VERSION 3.12)
3+
cmake_minimum_required(VERSION 3.15)
4+
5+
# detect if Project is being used as a sub-project of another CMake project
6+
if(NOT DEFINED PROJECT_NAME)
7+
set(PROJECT_SUBPROJECT OFF)
8+
else()
9+
set(PROJECT_SUBPROJECT ON)
10+
endif()
11+
12+
project(project VERSION 0.3.0 LANGUAGES CXX)
413

514
find_program(CCACHE_PROGRAM ccache)
615
if(CCACHE_PROGRAM)
716
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
817
endif()
918

10-
project(proj VERSION 0.0.0 LANGUAGES CXX)
19+
# Set a default build type if none was specified
20+
set(DEFAULT_BUILD_TYPE "Debug")
21+
22+
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
23+
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE STRING "Choose the type of build." FORCE)
24+
# Set the possible values of build type for cmake-gui
25+
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
26+
endif()
27+
28+
# set some handy custom variables to detect Release-type builds from Debug-type ones
29+
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
30+
set(PROJECT_BUILD_DEBUG ON)
31+
set(PROJECT_BUILD_RELEASE OFF)
32+
else()
33+
set(PROJECT_BUILD_DEBUG OFF)
34+
set(PROJECT_BUILD_RELEASE ON)
35+
endif()
36+
37+
message(STATUS "[project] Build Mode: ${CMAKE_BUILD_TYPE}")
1138

1239
# set the C++ standard to use to C++20 always
13-
set(PROJ_CXX_STANDARD "20")
14-
message(STATUS "[proj] C++ Standard set to C++${PROJ_CXX_STANDARD}")
15-
set(CMAKE_CXX_STANDARD ${PROJ_CXX_STANDARD})
40+
set(PROJECT_CXX_STANDARD "20")
41+
message(STATUS "[project] C++ Standard set to C++${PROJECT_CXX_STANDARD}")
42+
set(CMAKE_CXX_STANDARD ${PROJECT_CXX_STANDARD})
1643
set(CMAKE_CXX_STANDARD_REQUIRED ON)
1744

45+
include(CMakeDependentOption)
46+
# if building in Release mode, provide an option to explicitly enable tests if desired (always ON for other builds, OFF by default for Release builds)
47+
cmake_dependent_option(ENABLE_TESTS "Build the unit tests in release mode?" OFF PROJECT_BUILD_RELEASE ON)
48+
49+
# Premature Optimisation causes problems. Commented out code below allows detection and enabling of LTO.
50+
# It's not being used currently because it seems to cause linker errors with Clang++ on Ubuntu if the library
51+
# is compiled with LTO but the unit tests are not. This suggests LTO may force some downstream software into
52+
# using LTO also if it's enabled. The plan is to reënable LTO as an option in the future, possibly done much
53+
# more optionally (and probably not by default).
54+
55+
# include(CheckIPOSupported)
56+
# check_ipo_supported(RESULT IPO_SUPPORTED)
57+
# # If we're in Release mode, set PROJECT_USE_IPO to ON by default if it's detected as supported (user can always explicitly enable it in Release mode)
58+
# cmake_dependent_option(PROJECT_USE_IPO "Use Link-Time/Inter-Procedural Optimisation?" ${IPO_SUPPORTED} PROJECT_BUILD_RELEASE OFF)
59+
# if(PROJECT_USE_IPO)
60+
# message(STATUS "[project] Link-Time-Optimisation Enabled")
61+
# endif()
62+
1863
set(
19-
PROJ_VERSION_STRING
64+
PROJECT_VERSION_STRING
2065
"${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
2166
)
22-
set(PROJ_ESCAPED_VERSION_STRING "\"${PROJ_VERSION_STRING}\"")
67+
set(PROJECT_ESCAPED_VERSION_STRING "\"${PROJECT_VERSION_STRING}\"")
2368
# end basic metadata
2469

25-
# pass in version of project as preprocessor definitions
26-
add_definitions(-DPROJ_VERSION_MAJOR=${PROJECT_VERSION_MAJOR})
27-
add_definitions(-DPROJ_VERSION_MINOR=${PROJECT_VERSION_MINOR})
28-
add_definitions(-DPROJ_VERSION_PATCH=${PROJECT_VERSION_PATCH})
29-
add_definitions(-DPROJ_VERSION_STRING=${PROJ_ESCAPED_VERSION_STRING})
70+
# This is a special target which only exists to capture compilation options
71+
# used for project and its tests. This is to avoid setting global compiler
72+
# options which would be inherited by dependencies as well, which is bad
73+
# because project uses strict compiler warning options which not all other
74+
# projects can build successfully with.
75+
# Any target linked with this one will inherit the compiler options used for
76+
# project.
77+
add_library(project-compiler-options INTERFACE)
3078

3179
# used for enabling additional compiler options if supported
3280
include(CheckCXXCompilerFlag)
3381

3482
function(enable_cxx_compiler_flag_if_supported flag)
35-
message(STATUS "[proj] Checking if compiler supports warning flag '${flag}'")
36-
string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_already_set)
37-
if(flag_already_set EQUAL -1)
38-
check_cxx_compiler_flag("${flag}" flag_supported)
39-
if(flag_supported)
40-
message(STATUS "[proj] Enabling warning flag '${flag}'")
41-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE)
42-
endif()
83+
message(STATUS "[project] Checking if compiler supports warning flag '${flag}'")
84+
check_cxx_compiler_flag("${flag}" flag_supported)
85+
if(flag_supported)
86+
message(STATUS "[project] Enabling warning flag '${flag}'")
87+
target_compile_options(project-compiler-options INTERFACE "${flag}")
4388
endif()
44-
unset(flag_already_set CACHE)
4589
unset(flag_supported CACHE)
4690
endfunction()
4791

48-
# enable extra flags (warnings) if we're not in release mode
49-
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "")
50-
message(STATUS "[proj] Warnings Enabled")
51-
if (MSVC) # MSVC supports different warning options to GCC/Clang
52-
add_compile_options(/WX /W3) # treat all warnings as errors, set warning level 3
53-
else() # GCC/Clang warning option
54-
# NOTE: GCC and Clang support most of the same options, but neither supports all
55-
# of the others'. By only enabling them if supported, we get graceful failure
56-
# when trying to enable unsupported flags
57-
# e.g. at the time of writing, GCC does not support -Wdocumentation
58-
#
59-
# enable all warnings about 'questionable constructs'
60-
enable_cxx_compiler_flag_if_supported("-Wall")
61-
# issue 'pedantic' warnings for strict ISO compliance
62-
enable_cxx_compiler_flag_if_supported("-pedantic")
63-
# enable 'extra' strict warnings
64-
enable_cxx_compiler_flag_if_supported("-Wextra")
65-
# enable sign conversion warnings
66-
enable_cxx_compiler_flag_if_supported("-Wsign-conversion")
67-
# enable warnings about mistakes in Doxygen documentation
68-
enable_cxx_compiler_flag_if_supported("-Wdocumentation")
69-
# convert all warnings into errors
92+
# enable a large amount of extra warnings, regardless of build mode
93+
if (MSVC) # MSVC supports different warning options to GCC/Clang
94+
# add_compile_options(/W4) # set warning level 4
95+
enable_cxx_compiler_flag_if_supported("/W4")
96+
# if in debug mode, enable converting all warnings to errors too
97+
if (PROJECT_BUILD_DEBUG)
98+
# add_compile_options(/WX)
99+
enable_cxx_compiler_flag_if_supported("/WX")
100+
endif()
101+
else() # GCC/Clang warning option
102+
# NOTE: GCC and Clang support most of the same options, but neither supports all
103+
# of the others'. By only enabling them if supported, we get graceful failure
104+
# when trying to enable unsupported flags
105+
# e.g. at the time of writing, GCC does not support -Wdocumentation
106+
#
107+
# enable all warnings about 'questionable constructs'
108+
enable_cxx_compiler_flag_if_supported("-Wall")
109+
# issue 'pedantic' warnings for strict ISO compliance
110+
enable_cxx_compiler_flag_if_supported("-pedantic")
111+
# enable 'extra' strict warnings
112+
enable_cxx_compiler_flag_if_supported("-Wextra")
113+
# enable sign conversion warnings
114+
enable_cxx_compiler_flag_if_supported("-Wsign-conversion")
115+
# enable warnings about mistakes in Doxygen documentation
116+
enable_cxx_compiler_flag_if_supported("-Wdocumentation")
117+
# if in debug mode, enable converting all warnings to errors too
118+
if (PROJECT_BUILD_DEBUG)
70119
enable_cxx_compiler_flag_if_supported("-Werror")
71120
# exclude the following kinds of warnings from being converted into errors
72121
# unknown-pragma is useful to have as a warning but not as an error, if you have
@@ -76,86 +125,21 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "")
76125
enable_cxx_compiler_flag_if_supported("-Wno-error=unused-function")
77126
enable_cxx_compiler_flag_if_supported("-Wno-error=unused-variable")
78127
enable_cxx_compiler_flag_if_supported("-Wno-error=unused-parameter")
128+
enable_cxx_compiler_flag_if_supported("-Wno-error=unused-private-field")
79129
endif()
80130
endif()
81131

82-
83132
# add custom dependencies directory
84-
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
85-
86-
# begin dependencies
87-
88-
# ...Add additional dependencies here...
89-
90-
# end dependencies
91-
92-
# C++ library source files
93-
file(GLOB PROJ_SOURCES "proj/*.cpp")
94-
# C++ program source file
95-
set(PROJ_CLI_SOURCE "main.cpp")
96-
# C++ source files for unit tests
97-
file(GLOB TEST_SOURCES "tests/*.cpp")
98-
# Header files
99-
set(PROJ_HEADERS "proj/proj.hpp")
100-
101-
# if project is a library
102-
add_library(proj ${PROJ_SOURCES})
103-
# set up version for library objects
104-
set_target_properties(
105-
proj PROPERTIES VERSION ${PROJ_VERSION_STRING}
106-
SOVERSION ${PROJECT_VERSION_MAJOR}
107-
)
108-
# link proj with C math library if we're on Linux
109-
if (UNIX AND NOT APPLE)
110-
target_link_libraries(proj m)
133+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
134+
135+
# a better way to load dependencies
136+
include(CPM)
137+
138+
# library
139+
add_subdirectory(project)
140+
# unit tests --only enable if requested AND we're not building as a sub-project
141+
if(ENABLE_TESTS AND NOT PROJECT_SUBPROJECT)
142+
message(STATUS "[project] Unit Tests Enabled")
143+
add_subdirectory(tests)
144+
enable_testing()
111145
endif()
112-
113-
# the proj executable --this is the command-line program
114-
add_executable(proj-cli ${PROJ_CLI_SOURCE})
115-
# link the program with the library
116-
target_link_libraries(proj-cli proj)
117-
# set output name property so it will be called proj despite target name being different
118-
set_target_properties(proj-cli PROPERTIES OUTPUT_NAME proj)
119-
120-
# build unit tests
121-
add_executable(unit_tests ${TEST_SOURCES})
122-
target_link_libraries(unit_tests proj)
123-
enable_testing()
124-
125-
# auto-discover and add Catch2 tests from unit tests program
126-
include(CTest)
127-
include(Catch)
128-
129-
catch_discover_tests(unit_tests)
130-
131-
install(
132-
TARGETS proj
133-
ARCHIVE DESTINATION lib
134-
LIBRARY DESTINATION lib
135-
)
136-
install(
137-
TARGETS proj-cli
138-
RUNTIME DESTINATION bin
139-
)
140-
141-
# Generate rough (nearest major) version-dependent header installation folder
142-
set(
143-
PROJ_ROUGH_HEADER_DESTINATION
144-
"proj-${PROJECT_VERSION_MAJOR}"
145-
)
146-
# Generate precise (major and minor) version-dependent header installation folder
147-
set(
148-
PROJ_PRECISE_HEADER_DESTINATION
149-
"proj-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
150-
)
151-
152-
# Install main library header files, both to rough and precise install locations
153-
install(
154-
FILES ${PROJ_HEADERS}
155-
DESTINATION "include/${PROJ_ROUGH_HEADER_DESTINATION}"
156-
)
157-
158-
install(
159-
FILES ${PROJ_HEADERS}
160-
DESTINATION "include/${PROJ_PRECISE_HEADER_DESTINATION}"
161-
)

Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ WARN_LOGFILE =
771771
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
772772
# Note: If this tag is empty the current directory is searched.
773773

774-
INPUT = proj
774+
INPUT = project
775775

776776
# This tag can be used to specify the character encoding of the source files
777777
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

0 commit comments

Comments
 (0)