#c #gcc #cmake #linker-errors #undefined-reference
#c #ссагпз #cmake #компоновщик -ошибки #не определено-ссылка
Вопрос:
Я пытаюсь включить проект в проект. Соответствующая структура как таковая:
projectA
/CMakeLists.txt (PA1)
/src
/main.cpp
/req/projectB
/CMakeLists.txt (PB1)
/src
/projb.hpp
/projb.cpp
/CMakeLists.txt (PB2)
После компиляции связывание ЗАВЕРШИТСЯ УСПЕШНО, если я закомментирую все в projb.cpp , (и определите его в заголовке), но СБОЙ с неопределенной ссылкой (на любую функцию, определенную в projb.cpp ).
— (PA1)-
add_subdirectory("req/projectB")
include_directories(${PROJECT_NAME} "req/projectB/src")
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} INTERFACE projectB)
— (РБ1)-
add_subdirectory(src)
— (PB2)-
add_library(projectB projb.hpp projb.cpp)
main.cpp
int main() {
project_b::doStuff();
return 1;
}
projb.hpp
namespace project_b {
void doStuff(); // fails
void doStuff() {} // works if nothing defined in .cpp
// (only one or the other version is declared not both)
} // end namespace
projb.cpp
namespace project_b {
void doStuff() {} // fails with undefined reference error when called from main
} // end namespace
Комментарии:
1. Компоновщик вообще не просматривает .cpp-файлы. Запустите
make VERBOSE=1
, чтобы увидеть фактические команды компиляции.2. вот как я запускал make
3. Это не видно из вашего сообщения. Если
projb.cpp
не компилируется, почему удивительно, что материал, определенный в нем, не определен?4. когда я проверяю папку сборки, библиотеки для ProjectB находятся там.
5. Но они не используются для сборки исполняемого файла
Ответ №1:
Оказывается, что другая часть ProjectA, которую я считал неактуальной, на самом деле была очень актуальной.
Таким образом, мне просто нужно было добавить эту строку:
# projAadep is included by main.cpp from projectA
target_link_libraries(projAdep PRIVATE projectB)
перед этой строкой:
target_link_libraries(${PROJECT_NAME} PUBLIC projectB)
Мое понимание заключалось в том, что с помощью:
target_link_libraries(${PROJECT_NAME} list of all used libs here)
было все, что необходимо.
Как это было обнаружено, когда я комментировал различные вещи, чтобы получить вывод make VERBOSE=1
, содержащий только наиболее релевантные части, он успешно скомпилирован и связан. Затем это заставило меня провести дополнительное тестирование, чтобы выяснить, почему он успешно связан, и так далее.
Ответ №2:
Библиотеки, следующие за ИНТЕРФЕЙСОМ, добавляются к интерфейсу ссылки и не используются для компоновки .
смотрите: https://cmake.org/cmake/help/latest/command/target_link_libraries.html
Итак, я предлагаю изменить ИНТЕРФЕЙС на ОБЩЕДОСТУПНЫЙ или ЧАСТНЫЙ
Комментарии:
1. пробовал использовать ОБЩЕДОСТУПНЫЕ и ЧАСТНЫЕ, но все равно не работает
2. @R.Smyth Работает на меня, возможно, раскомментирует projb.cpp ?
3. так оно и есть. все еще терпит неудачу.
4. @R.Smyth пожалуйста, опубликуйте полный вывод
make VERBOSE=1
.5. Кроме того, удалите
CMakeCache.txt
и выполнитеmake clean
перед сборкой.