Hi, I am about 3 days old to Cmake, lol. I have read the relevant chapters in Professional Cmake book but have not found the answer to my question.
Here is my CMakeList.txt
cmake_minimum_required(VERSION 3.21)
include(cmake/prelude.cmake)
include(cmake/macros.cmake)
message(NOTICE " " CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE})
message(NOTICE " " CMAKE_CURRENT_BINARY_DIR = ${CMAKE_CURRENT_BINARY_DIR})
project(
c_template_two
VERSION 0.1.0
DESCRIPTION "A simple C template made using `cmake-init`."
HOMEPAGE_URL "https://example.com/"
LANGUAGES C
)
include(cmake/variables.cmake)
# Find all source files under each subdirectory of source/libs and add each of them as a library named after the name of the directory
# ADD_LIBRARY_FOR_EACH_SUB_DIR("source/libs")
# Use the macro `GET_SUB_DIRS_NAMES` to get a list of Library Directories Names => `SUB_DIR_NAMES` = GCDUtilitiesPrimalityUtilities
GET_SUB_DIRS_NAMES(LIBRARIES_NAMES "source/libs")
MESSAGE(NOTICE "`LIBRARIES_NAMES` = " ${LIBRARIES_NAMES})
FOREACH(libname ${LIBRARIES_NAMES})
FILE(GLOB library_source_files source/libs/${libname}/*.c)
add_library(${libname} STATIC ${library_source_files})
target_include_directories(
${libname} ${warning_guard}
PUBLIC
"\$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source/libs/${libname}>"
)
target_compile_features(${libname} PUBLIC c_std_17)
ENDFOREACH()
# target_include_directories(
# PrimalityUtilities ${warning_guard}
# PUBLIC
# "\$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source/libs/PrimalityUtilities>"
# )
# target_include_directories(
# GCDUtilities ${warning_guard}
# PUBLIC
# "\$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source/libs/GCDUtilities>"
# )
# target_compile_features(PrimalityUtilities PUBLIC c_std_17)
# target_compile_features(GCDUtilities PUBLIC c_std_17)
# ---- Declare executable ----
GET_SUB_DIRS_NAMES(EXECUTABLE_NAMES "source/bin")
MESSAGE(NOTICE "`EXECUTABLE_NAMES` = " ${EXECUTABLE_NAMES})
FOREACH(executable_name ${EXECUTABLE_NAMES})
FILE(GLOB executable_source_files source/bin/${executable_name}/*.c)
add_executable(${executable_name} source/bin/${executable_name}/main.c)
add_executable(${executable_name}::exe ALIAS ${executable_name})
set_property(TARGET ${executable_name} PROPERTY OUTPUT_NAME ${executable_name})
target_compile_features(${executable_name} PRIVATE c_std_17)
FOREACH(libname ${LIBRARIES_NAMES})
target_link_libraries(${executable_name} PRIVATE ${libname})
ENDFOREACH()
ENDFOREACH()
# add_executable(primetest source/bin/primetest/main.c)
# add_executable(primetest::exe ALIAS primetest)
# set_property(TARGET primetest PROPERTY OUTPUT_NAME primetest)
# target_compile_features(primetest PRIVATE c_std_17)
# target_link_libraries(primetest PRIVATE PrimalityUtilities)
# target_link_libraries(primetest PRIVATE GCDUtilities)
# ---- Declare executable ----
# add_executable(gcd source/bin/gcd/main.c)
# add_executable(gcd::exe ALIAS gcd)
# set_property(TARGET gcd PROPERTY OUTPUT_NAME gcd)
# target_compile_features(gcd PRIVATE c_std_17)
# target_link_libraries(gcd PRIVATE PrimalityUtilities)
# target_link_libraries(gcd PRIVATE GCDUtilities)
# ---- Tests ----
# https://honeytreelabs.com/posts/cmake-unity-integration/
# use Unity
include(FetchContent)
FetchContent_Declare(
unity
URL https://github.com/ThrowTheSwitch/Unity/archive/refs/tags/v2.6.0.zip
)
FetchContent_MakeAvailable(unity)
enable_testing()
add_executable(
test_isprime
test/source/test_isprime.c
)
target_link_libraries(
test_isprime
unity
PrimalityUtilities
GCDUtilities
)
# ---- Install rules ----
if(NOT CMAKE_SKIP_INSTALL_RULES)
include(cmake/install-rules.cmake)
endif()
# ---- Developer mode ----
if(NOT c_template_two_DEVELOPER_MODE)
return()
elseif(NOT PROJECT_IS_TOP_LEVEL)
message(
AUTHOR_WARNING
"Developer mode is intended for developers of c_template_two"
)
endif()
include(cmake/dev-mode.cmake)
Basically, what this project is doing is that it has two executables, gcd
(calculate the greatest common divisor) and isprime
(calculates if a number is prime or not). I am building the test_isprime
binary to do unit testing with the Unity Testing Framework.
The issue is, each time I run to commands
cmake -S . -Bbuild/test
cmake --build build/test
to build the test binary (test_isprime
), it also builds the other binaries (gcd
and isprime
).
What would be the best practice in this situation?
In some situations, perhaps my tests will involve executing the actual release binaries, e.g. ./build/release/isprime 12
, but it can also be the case where all I want is to build only the test binaries for unit testing.
Should I create a new Configuration named ‘Test’ and set up a guard (using If() .... ENDIF()
) to only build the binaries that I need for testing, e.g. isprime
and test_isprime
while neglecting say gcd
? Again, what would be the best practice?