Фон
У меня есть проект, который использует другие небольшие проекты. Эти проекты сами сделаны из других проектов. Многое из этого является наследием или имеет иные управленческие причины для того, чтобы все было организовано как есть, поэтому объединить все в один проект невозможно. Некоторые библиотеки предварительно скомпилированы на удаленных общих ресурсах.
У меня есть 2 основных подпроекта, которые вызывают у меня головную боль:
Project Foo - это исполняемый файл и библиотека, которая связывает несколько статических подпроектов (foo_subproject_1
, foo_subproject_n
). Эти подпроекты также связаны со статическими библиотеками в удаленных местах (some_lib
, some_other_lib
). Исполняемый файл Project Foo компилируется, связывается и работает правильно
Панель проекта - исполняемый файл, который связывает несколько других проектов, включая libFoo. Сбой связывания с «неопределенной ссылкой на» foo_subproject
функции
Насколько я могу судить, оба проекта организованы аналогично инструкциям по связыванию. Глядя на SO, я обнаружил, что связывание статических библиотек со статическими библиотеками не должно работать , но потом я запутался в том, как Project Foo успешно компилируется.
gcc и g ++ 4.9.2 являются компиляторами (внешние проблемы "C" из-за наличия некоторых частей в C, а некоторых в C ++ уже проверены)
Вопрос
Я неправильно понял что-либо о том, как работает CMake add_subdirectory, или о том, как работает компоновщик . Может кто-нибудь объяснить, как Project Foo работает успешно, а Project Bar (не) работает как положено?
Обновление Я посмотрел ближе на foo_lib.a и foo_runtime.
Я должен был определить, что что-то не так, чтобы начать, потому что foo_runtime имеет размер почти 100 МБ, а foo_lib всего 10 КБ.
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)
Подкаталоги Project 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)
Панель проекта устроена так:
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)
Project Bar не удается связать (компилируется нормально) с несколькими ошибками в форме:
bar_frobulator.cpp:123: undefined reference to 'foo_subproject_1_init_frobulation'
где foo_subproject_1_init_frobulation
живет в foo_subproject_1