# Here CC and CXX are variables CC := clang CXX := clang++
# .PHONY means that `all` is not a real file to be generated, instead a fake target # Assume hello is the executable we want to get .PHONY: all all: hello
# Assume hello depends on all of the files in objects # We only need to add new depeneds to objects to make this Makefile work on them objects := main.o
# Here `$@` is the name of the target being generated hello: $(objects) $(CXX) -o $@$(objects) main.o: main.cpp $(CXX) -c main.cpp # clean is used to clean up the temporary files used. It is a fake target as well .PHONY: clean clean: rm -f hello $(objects)
For example, when we need another dependence answer.hpp,
we will have:
# Minimum version required cmake_minimum_required(VERSION 3.9) # Project name project(answer)
#[[ All the target, similar to the following in Makefile: answer: main.o answer.o main.o: main.cpp answer.hpp answer.o: answer.cpp answer.hpp CMake will find the depended header automatically #]] add_executable(answer main.cpp answer.cpp)
#[[ Use the following command to build: cmake -B build # generate build directory cmake --build build # build ./build/answer # run the executable #]]
Build with library
If we need a library several times, we can make it a separate library
to be linked.
And within the directory answer, we have another
CMakeLists.txt file:
1 2 3 4 5 6 7
add_library(libanswer STATIC answer.cpp) #[[ Put `libanswer` library to `include` directory and makes it PUBLIC When the `libanswer` library is used, this `include` directory will be automatically used #]] target_include_directories(libanswer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
To find
already installed third party library in OS
API keys and private ID should not be inside the source code, instead
a configurable option to be sent in. This can be done with the cache
variable:
1 2 3 4 5 6 7 8 9
set(API_KEY "" CACHE STRING"PRIVATE API_KEY")
if(API_KEY STREQUAL"") message(SEND_ERROR "The API_KEY must not be empty") endif()
target_compile_definitions(libanswer PRIVATE MACRO_NAME="${API_KEY}") # If we need a integer, we can write: target_compile_definitions(libanswer PRIVATE ANOTHER_MACRO_NAME=42)
To run certain CMake script multiple times, we can use macros:
1 2 3 4 5 6 7 8 9 10
macro(answer_add_test TEST_NAME) # Here ${ARGN} is similar to __VA_ARGS__ in C add_executable(${TEST_NAME}${ARGN}) add_test(NAME answer.${TEST_NAME}COMMAND${TEST_NAME}) target_link_libraries(${TEST_NAME} PRIVATE libanswer) target_link_libraries(${TEST_NAME} PRIVATE Catch2::Catch2WithMain) endmacro()