Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

235
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda