Probablemente a ninguno de nosotros nos gusta esperar mucho para completar el montaje del proyecto, cuando cada segundo es como siempre. Y es bueno si son horas de trabajo, y puedes pasar el tiempo con un vaso de café, discutiendo todas las deficiencias de la recolección automática de basura.
A veces, se puede lograr cierto éxito realizando la optimización de CMake. La técnica considerada aquí se basa en una idea simple: dos bibliotecas estáticas que usan las funciones de cada una pueden ensamblarse simultáneamente.
Un poco de anatomia
Para comenzar, considere los pasos básicos para construir una biblioteca estática:
- preprocesador : elimina todos los comentarios de los archivos de origen, inserta los archivos de encabezado y reemplaza las macros con valores calculados.
- compilador : convierte los archivos procesados por el preprocesador en código ensamblador.
- ensamblador : traduce el código de ensamblaje en código de máquina; El resultado se guarda como archivos de objeto.
- archivador : recopila archivos de objetos en un único archivo.
Gráficamente, estos pasos se muestran en el diagrama:
, . , . . , , .
, , 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
, , .
También en el metapaquete puede agregar una dependencia en forma de comando para generar archivos de encabezado, y las propiedades son rutas correctas.