背景
我有一个项目,它使用其他较小的项目。这些项目本身由其他项目组成。大部分是传统遗留代码或由管理人员规定排列的,因此将所有内容合并到一个项目中不是选项。一些库在远程共享上进行预编译。
我有两个主要的子项目让我头疼:
Foo 项目 是一个可执行文件和库,链接了几个静态子项目 (
foo_subproject_1
,foo_subproject_n
)。这些子项目进一步链接到远程位置的静态库 (some_lib
,some_other_lib
)。Foo 项目的可执行文件可以正确地编译、链接和运行Bar 项目 是一个可执行文件,链接了几个其他项目,包括 libFoo。链接失败,显示“undefined reference to”
foo_subproject
函数
据我所知,这两个项目的链接指令类似。在 Stack Overflow 上查看后,发现静态库与静态库链接不应该工作,但是我对如何成功编译 Project Foo 感到困惑。
编译器是 gcc 和 g++ 4.9.2(已经检查了一些部分使用 C,一些部分使用 C++ 的 extern "C" 问题)
问题
我对 CMake add_subdirectory 的工作方式或链接器的工作方式中的一个或两个方面存在误解。有人能否请解释一下 Project Foo 如何成功运行以及 Project Bar (未能)按预期工作的原因?
更新 我仔细查看了 foo_lib.a 和 foo_runtime。
我应该从一开始就确定有些问题,因为 foo_runtime 的大小接近 100MB,而 foo_lib 只有 10KB。
nm
显示 foo_lib.a 引用了几十个符号,其中大多数未定义。与此同时,foo_runtime 引用了 所有 符号。
同样令人困惑的是,foo_subproject_1.a 同样大部分未定义。再次强调,这是我所期望看到的;但我不明白如何从中构建 foo_runtime?
我仍然不清楚为什么 some_library -> subproject -> foo_runtime
成功,但 some_library -> subproject -> foo_lib -> bar
不成功。在我的调查阶段,我期望这两个命令都会失败。
Project Foo 使用 CMake 排列如下:
cmake_minimum_required(VERSION 2.6)
project(foo)
set(FOO_SRCS
# source and headers for main foo project
)
# Project Foo libraries are subdirectories within this project
add_subdirectory(subs/foo_subproject_1)
add_subdirectory(subs/foo_subproject_2)
# Runtime executable
add_executable(foo_runtime main.c ${FOO_SRCS})
target_link_libraries(foo_runtime foo_subproject_1 foo_subproject_2)
# Library version (static library)
add_library(foo_lib STATIC ${FOO_SRCS})
target_link_libraries(foo_lib foo_subproject_1 foo_subproject_2)
Foo项目的子目录大致具有以下结构:
cmake_minimum_required(VERSION 2.6)
project(foo_subproject_<n>)
set(FOO_SUBPROJECT_<N>_SRCS
# source and headers for subproject
)
# foo_subproject's remote libraries are all static
add_library(some_lib STATIC IMPORTED)
set_target_properties(some_lib PROPERTIES IMPORTED_LOCATION /path/to/libsome_lib.a)
add_library(some_other_lib STATIC IMPORTED)
set_target_properties(some_other_lib PROPERTIES IMPORTED_LOCATION /path/to/libsome_other_lib.a)
include_directories(/paths/to/libs/include/)
# Static library for foo_subproject_N, links against static libs above
add_library(foo_subproject_<N> STATIC ${FOO_SUBPROJECT_<N>_SRCS})
target_link_libraries(foo_subproject_<N> some_library some_other_library)
Project Bar 的排列方式如下:
cmake_minimum_required(VERSION 2.6)
project(bar)
set(BAR_SRCS
# source and headers for main bar project
)
# Project Bar libraries are remote from Bar's perspective
add_library(foo_lib STATIC IMPORTED)
set_target_properties(foo_lib PROPERTIES IMPORTED_LOCATION /path/to/foo/libfoo_lib.a)
include_directories(/path/to/foo/include/)
# Runtime executable
add_executable(bar main.c ${BAR_SRCS} foo_lib)
项目栏与多个错误无法链接(编译正常),错误形式如下:
bar_frobulator.cpp:123: undefined reference to 'foo_subproject_1_init_frobulation'
foo_subproject_1_init_frobulation
位于foo_subproject_1中。