Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

240
Vistas
Dependencias de la biblioteca OBJECT anidadas de CMake

Creé un proyecto con algunas dependencias de bibliotecas anidadas usando el tipo de biblioteca OBJECT . La motivación para esto es evitar problemas de orden de enlace con bibliotecas estáticas.

Tengo una estructura de directorio simple de la siguiente manera:

 ├── bar │ ├── bar.c │ └── bar.h ├── foo │ ├── foo.c │ └── foo.h ├── main.c └── CMakeLists.txt

foo depende de bar , y main depende de foo . Por ejemplo,

bar.c

 #include "bar.h" #include <stdio.h> void bar(void) { printf("woot woot\n"); }

foo.c

 #include "foo.h" #include "bar.h" void foo(void) { bar(); }

C Principal

 #include "foo.h" int main() { foo(); return 0; }

El archivo CMakeLists.txt

 cmake_minimum_required(VERSION 3.18) project(myproj) enable_language(C ASM) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS OFF) # build bar add_library(bar OBJECT ${PROJECT_SOURCE_DIR}/bar/bar.c) target_include_directories(bar PUBLIC ${PROJECT_SOURCE_DIR}/bar) # build foo, depends on bar add_library(foo OBJECT ${PROJECT_SOURCE_DIR}/foo/foo.c) target_include_directories(foo PUBLIC ${PROJECT_SOURCE_DIR}/foo) target_link_libraries(foo PUBLIC bar) # build executable, depends on foo add_executable(myexe ${PROJECT_SOURCE_DIR}/main.c) target_link_libraries(myexe PUBLIC foo)

Mi expectativa es que myexe herede la dependencia de la bar de foo cuando se vincula a ella. Sin embargo, este no es el caso que parece. Cuando se compila el código, main.o solo se vincula a foo.o y, por lo tanto, hay una referencia indefinida a bar . Sin embargo, si cambio los tipos de biblioteca de OBJECT a STATIC , todo funciona bien. ¿Por qué pasó esto?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Las bibliotecas de objetos no se pueden encadenar de esta manera. Debe vincular directamente (no transitivamente) a una biblioteca de objetos para adquirir sus archivos de objetos. Como dice en la documentación ,

Las bibliotecas de objetos pueden "vincularse" a otras bibliotecas de objetos para obtener los requisitos de uso, pero dado que no tienen un paso de enlace, no se hace nada con sus archivos de objetos. [...] En otras palabras, cuando las bibliotecas de objetos aparecen en la propiedad INTERFACE_LINK_LIBRARIES de un objetivo, se tratarán como bibliotecas de interfaz, pero cuando aparecen en la propiedad LINK_LIBRARIES de un objetivo, sus archivos de objetos también se incluirán en el enlace.

Sin embargo, estoy de acuerdo en que desafía toda razón.


Sin embargo, puede propagar manualmente los archivos de objeto a través target_link_libraries(INTERFACE) y la expresión del generador $<TARGET_OBJECTS> de la versión 3.21 (hacerlo tenía errores en versiones anteriores, y las fuentes de destino de incluso hackers target_sources se pueden usar en versiones anteriores).

Tenga en cuenta que esto es un truco, ya que hay algunos casos que se romperán. En particular, si un destino de biblioteca se vincula a dicho destino públicamente, los archivos de objeto se propagarán nuevamente . Así que ten cuidado.

Aún así, aquí hay una versión corregida de su compilación de ejemplo:

 cmake_minimum_required(VERSION 3.21) project(myproj LANGUAGES C ASM) set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use") option(CMAKE_C_STANDARD_REQUIRED "Enforce strict C standard selection" ON) option(CMAKE_C_EXTENSIONS "Allow compiler-specific C extensions" OFF) # build bar add_library(bar OBJECT bar/bar.c) target_include_directories( bar PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/bar>" ) # build foo, depends on bar add_library(foo OBJECT foo/foo.c) target_include_directories( foo PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/foo>" ) target_link_libraries(foo PUBLIC bar "$<TARGET_OBJECTS:bar>") # build executable, depends on foo add_executable(myexe main.c) target_link_libraries(myexe PRIVATE foo)

En la línea de comando:

 $ cmake -G Ninja -S . -B build ... $ cmake --build build -- -nv [1/4] /usr/bin/cc -I/path/to/bar -std=c11 -MD -MT CMakeFiles/bar.dir/bar/bar.co -MF CMakeFiles/bar.dir/bar/bar.cod -o CMakeFiles/bar.dir/bar/bar.co -c /path/to/bar/bar.c [2/4] /usr/bin/cc -I/path/to/foo -I/path/to/bar -std=c11 -MD -MT CMakeFiles/foo.dir/foo/foo.co -MF CMakeFiles/foo.dir/foo/foo.cod -o CMakeFiles/foo.dir/foo/foo.co -c /path/to/foo/foo.c [3/4] /usr/bin/cc -I/path/to/foo -I/path/to/bar -std=c11 -MD -MT CMakeFiles/myexe.dir/main.co -MF CMakeFiles/myexe.dir/main.cod -o CMakeFiles/myexe.dir/main.co -c /path/to/main.c [4/4] : && /usr/bin/cc CMakeFiles/foo.dir/foo/foo.co CMakeFiles/myexe.dir/main.co -o myexe CMakeFiles/bar.dir/./bar/bar.co && :
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda