- Preprocessing is the first step in C/C++ compilation, handling macro replacement, file inclusion, and conditional compilation.
#define: Defines macros.#include: Includes header files.#ifdef,#ifndef,#endif: Conditional compilation.#pragma: Passes special instructions to the compiler (often for platform-specific optimizations).
- Converts preprocessed source code into assembly code, generating
.sfiles.
- Translates assembly code into machine code, producing
.ofiles. These are not executable yet (missing library links).
- Combines object files into final executables or libraries. Two types:
- Occurs at compile time. Embeds all code/data into a single executable.
- Example:
add_library(pipeline STATIC pipeline.cpp)generatespipeline.lib, embedded intomain.exe. - Drawback: Redundant copies if multiple programs use the same library.
- Example:
- Links shared libraries (
.so/.dll) at runtime.
Library Types
- Output:
.a(Linux) /.lib(Windows). - Fully copied into executables. Increases file size but no runtime dependencies.
add_library(mylib STATIC src/file1.cpp src/file2.cpp)- Output:
.so(Linux) /.dll(Windows). - Dynamically loaded at runtime. Saves memory via shared access.
add_library(mylib SHARED src/file1.cpp src/file2.cpp)- Similar to shared libraries but loaded dynamically via
dlopen()(Linux) orLoadLibrary()(Windows).
add_library(mymodule MODULE src/module.cpp)- Compiles sources to
.o/.objfiles without creating a full library. Reusable across targets.
add_library(myobjects OBJECT src/file1.cpp src/file2.cpp)
add_executable(myapp $<TARGET_OBJECTS:myobjects> src/main.cpp)- Dynamic libraries generate two files:
- Import Library (
.libor.dll.a): Contains function definitions. - Dynamic Library (
.dll): Holds complete function code.
- Import Library (
- Most third-party libraries use this format.
- Loads the DLL at program startup. Requires:
- Header files (
.h). - Import library (
.lib). - DLL in the executable's directory or
PATH.
- Header files (
- Manually load/unload libraries using system APIs:
# include <windows.h>
# include <iostream>
typedef int (*AddFunc)(int, int);
int main() {
HINSTANCE hDll = LoadLibrary("MathLib.dll");
if (hDll) {
AddFunc add = (AddFunc)GetProcAddress(hDll, "add");
if (add) {
std::cout << add(2, 3) << std::endl; // Outputs 5
}
FreeLibrary(hDll);
}
return 0;
}
${CMAKE_SOURCE_DIR}: Root directory of the project (contains top-levelCMakeLists.txt).${CMAKE_BINARY_DIR}: Build directory (e.g.,./build).${CMAKE_CURRENT_SOURCE_DIR}: Directory of the currentCMakeLists.txt.${CMAKE_CURRENT_BINARY_DIR}: Build directory for the currentCMakeLists.txt.${CMAKE_MODULE_PATH}: Paths for custom CMake modules.${CMAKE_INSTALL_PREFIX}: Installation root directory.${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_RUNTIME_OUTPUT_DIRECTORY}: Output paths for libraries/executables.${CMAKE_BUILD_TYPE}: Build configuration (e.g.,Debug,Release).EXECUTABLE_OUTPUT_PATH: Output path for executables.LIBRARY_OUTPUT_PATH: Output path for libraries.
- Implicit: Defined via
PROJECT()(e.g.,<project>_BINARY_DIR). - Explicit: Defined via
SET()(e.g.,SET(HELLO_SRC main.c)→${HELLO_SRC}).
find_program: Locates executables.CMAKE_CXX_COMPILER: Path to the C++ compiler.CMAKE_BUILD_TYPE: Sets optimization/debug levels (override via-DCMAKE_BUILD_TYPE=<type>).
# Basic usage
add_library(pipeline STATIC pipeline.cpp)
# Customize output name
set_target_properties(pipeline PROPERTIES OUTPUT_NAME "pipeline")
# Custom output paths
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) # Shared libs
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/static) # Static libstarget_link_libraries(main PUBLIC pipeline) # Links 'pipeline' to 'main'find_package(OpenCV REQUIRED) # Finds OpenCV
target_include_directories(main PUBLIC ${OpenCV_INCLUDE_DIRS})
target_link_libraries(main PUBLIC ${OpenCV_LIBRARIES})target_link_directories(main PRIVATE /opt/opencv/lib)
target_link_libraries(main PUBLIC libcore.lib)
# Link all .lib files in a directory
file(GLOB WIN_LIBS "${CMAKE_SOURCE_DIR}/lib/*.lib")
target_link_libraries(main PRIVATE ${WIN_LIBS})- Specifies header search paths for a target.
PUBLIC: Path visible to the target and its dependents.
PRIVATE: Path visible only to the target.
target_include_directories(main PUBLIC include)Note: Only affects #include paths, not library linking.
# Rename output
set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello")
# Set version
set_target_properties(hello PROPERTIES VERSION 1.2 SOVERSION 1)
# Custom output paths
set_target_properties(mul PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/build/lib
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/build/bin
)
# Debug suffix
set_target_properties(hello PROPERTIES DEBUG_POSTFIX _d)
# Add elements
list(APPEND my_list "item1" "item2")
list(PREPEND my_list "item0")
# Remove elements
list(REMOVE_ITEM my_list "item0.5")
list(REMOVE_AT my_list 0)
# Transform elements
list(TRANSFORM SOURCES PREPEND "src/") # Adds "src/" prefix
list(TRANSFORM PATHS REPLACE "/old/" "/new/") # Replaces paths
# Utilities
list(LENGTH my_list list_length) # Get length
list(JOIN my_list ";" joined_str) # Join into a string