From my own search, I'm not exactly sure what the "normal" behaviour is: Does CMake normally rebuild .obj-files when a header included in the associated source file changes? Because it doesn't do that in my project at all. Here's my top-level CMakeLists.txt:
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# project and binary name
project("myProjectName")
# compiler specific warnings
# and warnings are treated as errors
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(warnings "-Wall -Wextra -Werror")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(warnings "/W4 /WX /EHsc")
endif()
if (NOT CONFIGURED_ONCE)
set(CMAKE_CXX_FLAGS "${warnings}"
CACHE STRING "Flags used by the compiler during all build types." FORCE)
set(CMAKE_C_FLAGS "${warnings}"
CACHE STRING "Flags used by the compiler during all build types." FORCE)
endif()
# default build-type is Debug:
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
endif()
# =============================
# libraries
# =============================
# external
# eigen numerics library
find_package (Eigen3 3.3 REQUIRED NO_MODULE)
set( EIGEN Eigen3::Eigen )
# some internal libraries here
set( LIB_NAME_1 lib1 )
set( LIB_NAME_2 lib2 )
# =============================
# directory configuration
# =============================
# for finding libraries and such in the project's subdirectories
# all paths are prepended with the project's root directory
set(CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR})
# specifiying output directories
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# the last one is disabled to allow for tests in a different directory
# include paths
include_directories(
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/lib # I put header-only libraries there
${CMAKE_SOURCE_DIR}/src # for template definitions
)
# =============================
# unit test configuration
# =============================
# enable_testing() sets the internal flag "CMAKE_TESTING_ENABLED" to 1
# add_test() commands are only run when enable_testing() has executed.
# here, it is only executed in debug mode
if(CMAKE_BUILD_TYPE MATCHES Debug)
enable_testing()
endif()
# the unit test framework used here is "Catch2" (single header file "catch.hpp")
# (https://github.com/catchorg/Catch2)
if ( ${CMAKE_TESTING_ENABLED} )
message( "-- Tests are enabled" )
set( UNIT_TEST_LIB catch2 )
endif()
# =============================
# subdir calls
# =============================
# the second parameter specifies the output path for binaries.
# however, the respective CMAKE_XYZ_OUTPUT_DIRECTORY takes precedence
add_subdirectory(lib)
add_subdirectory(src bin)
if ( ${CMAKE_TESTING_ENABLED} )
add_subdirectory(tests tests)
endif()
and then I have another CMakeLists.txt in lib, src and tests. These contain only addLibrary
, addExecutable
and targetLinkLibraries
commands using the appropriate source files. Except in "tests", where there's also addTest
and addCustomCommand
to make the unit test executable run after building.
Here's the question: Did I miss something and it should be rebuilding when a header changes (1)? Or is this the normal behaviour (2)?
Possibly related questions:
Rebuilding object files when a header changes
Make doesn't rebuild headers when changed
GCC included header (using -include
) changes not detected by CMake