Я работаю над Windows в Eclipse C++. У меня есть эта структура в моем проекте:
subProject A
-> creates a static library (works fine)
subProject B encapsulating subproject A
-> creates a static library (works fine)
subProject TestA
-> creates an executable (works fine)
subProject TestB
|dev
|src
| CmakeList.txt
|CmakeList.txt
-> creates an executable (doesn't work)
Это CmakeList.txt в каталоге dev для исполняемого файла TestB:
set(${PROJECT_NAME}_INCLUDE_DIRS
$(CMAKE_CURRENT_SOURCE_DIR}/src
CACHE STRING "" FORCE)
include_directories(${${PROJECT_NAME}_INCLUDE_DIRS})
file(GLOB_RECURSE ${PROJECT_NAME}_HEADER_FILES FOLLOW_SYMLINKS
./*.hpp
./*.h)
file(GLOB_RECURSE ${PROJECT_NAME}_SORUCE_FILES FOLLOW_SYMLINKS
./*.cpp
./*.c)
set(${PROJECT_NAME}_FILES ${${PROJECT_NAME}_HEADER_FILES}
${${PROJECT_NAME}_SOURCE_FILES})
# Additional includes and link directories and dependencies
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../install/${CMAKE_BUILD_TYPE}/A/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../install/${CMAKE_BUILD_TYPE}/B/include)
if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
set(${PROJECT_NAME}_EXTRA_LIBRARIES ${${PROJECT_NAME}_EXTRA_LIBRARIES}
A
B
pthread)
elseif(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(${PROJECT_NAME}_EXTRA_LIBRARIES ${${PROJECT_NAME}_EXTRA_LIBRARIES}
A
B
pthread)
endif()
# Add a library to the project
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../install/${CMAKE_BUILD_TYPE}/A/lib)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../install/${CMAKE_BUILD_TYPE}/B/lib)
add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_FILES})
target_link_libraries(${PROJECT_NAME} ${${PROJECT_NAME}_EXTRA_LIBRARIES})
install(FILES ${${PROJECT_NAME}_HEADER_FILES}
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/
PERSMISSIONS OWNER_READ GROUP_READ WORLD_READ)
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
В моем подпроекте B в файле у меня есть следующее:
#include "A.hpp"
...
A algo;
A.method(parameters)
Когда я создаю свой TestB, у меня есть эта странная ошибка, появляющаяся в проекте B на двух строках выше, из-за чего моя сборка завершилась неудачей:
undefined reference to A::A()
undefined reference to A::method(parameter)
Когда я комментирую эти строки и перестраиваю проект B и проект TestB, он отлично работает, у меня есть библиотека в проекте B и.exe в TestB.
Я не понимаю, где моя проблема.
B
зависит от A
, поэтому добавьте зависимость в B
CMakeLists.txt к A с target_link_libraries
. Даже если это статическая библиотека, и при создании B
не будет никакой реальной привязки, это в любом случае даст подсказку CMake, что каждый раз, когда вы связываете B
с исполняемым файлом, вам также необходимо связать потом с A
A
должен прийти после B
в командной строке ссылки, так что символы, необходимые B
, известны, когда вы получаете ссылку на A
Подробнее см. Здесь.
Если вы ищете быстрое решение, просто измените:
set(${PROJECT_NAME}_EXTRA_LIBRARIES ${${PROJECT_NAME}_EXTRA_LIBRARIES}
A
B
pthread)
к этому
set(${PROJECT_NAME}_EXTRA_LIBRARIES ${${PROJECT_NAME}_EXTRA_LIBRARIES}
B
A
pthread)
A
, вам нужно связать статическую библиотеку, которую создает проект A.link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../install/${CMAKE_BUILD_TYPE}/A/lib)
уже не связывает ее?