Probably none of us like to wait long for the completion of the project assembly, when every second is like an eternity. And itโs good if itโs working hours, and you can pass the time with a glass of coffee, discussing all the shortcomings of automatic garbage collection.
Sometimes, certain success can be achieved by performing CMake optimization. The technique considered here is based on a simple idea: two static libraries that use each other's functions can be assembled simultaneously.
A bit of anatomy
To begin, consider the basic steps of building a static library:
- preprocessor - removes all comments from source files, inserts header files and replaces macros with calculated values.
- compiler - converts the files processed by the preprocessor into assembler code.
- assembler - translates assembly code into machine code; The result is saved as object files.
- archiver - collect object files into a single archive.
Graphically, these steps are shown in the diagram:
, . , . . , , .
, , CMake target_link_libraries. :
target_link_libraries(staticC PRIVATE staticB)
, โ staticC
staticB
. , , , staticC
, staticB
.
, CoherentDeps, :
, staticC
staticB
, .
, , , ( , ) INTERFACE
, -meta ( , ). , -, .
target_link_libraries
.
, :
: NonCoherentDeps.
:
NonCoherentDeps
.
staticB
staticA
, staticC
staticB
, NonCoherentDeps
staticC
. :
CMake- staticA
- :
add_library(staticA-meta INTERFACE)
target_include_directories(staticA-meta INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
, :
target_link_libraries(staticA PUBLIC staticA-meta)
staticB
CMake
target_link_libraries(staticB PRIVATE staticA)
:
target_link_libraries(staticB PRIVATE staticA-meta)
staticA
staticB
, . staticB
staticA
.
:
โ :
add_executable(NonCoherentDeps main.cpp)
target_link_libraries(NonCoherentDeps PRIVATE staticC staticB staticA )
, .
, staticA
, target_include_directories. NonCoherentDeps, :
target_include_directories(staticB PRIVATE "${path_to_headers_in_staticA}")
:
target_link_libraries(staticB PRIVATE staticA-meta)
, staticB
staticA
, staticC
:
target_include_directories(staticC PRIVATE "${path_to_headers_in_staticB}" "${path_to_headers_in_staticA}")
. :
target_link_libraries(staticB-meta INTERFACE staticA-meta)
staticC
:
target_link_libraries(staticC INTERFACE staticB-meta)
staticB
, , .
Also in the meta-package you can add a dependency in the form of a command to generate header files, and the properties are correct paths.