Подтвердить что ты не робот

CMake: связать библиотеку с библиотекой

У меня проблема с cmake. У меня есть, скажем, CMakeLists1, у которого есть подкаталог, где есть CMakeLists2.

В CMakeLists2 моя цель - статическая библиотека. И я хочу связать его с внешней библиотекой. Я сделал это так:

link_directories ("path_to_library")
add_library (project2 ${sources})
target_link_libraries (project2 "name_of_external_lib")

Затем я хочу использовать класс из этого проекта2 в моем проекте1. Я сделал так:

add_executable (project1 ${sources})
target_link_libraries (project1 project2)

Но это не работает вообще. Прежде всего, project2 не ссылался на внешнюю библиотеку. Просто для проверки, я добавил эту библиотеку через свойства проекта vs10, и размеры были разными. И второе, как-то project1 видит, что внешняя библиотека (она находится в библиотечных зависимостях этого проекта) и, конечно, не может ее найти.

В чем проблема?

4b9b3361

Ответ 1

Я думаю, что CMakes по умолчанию не связывает project2 со внешней библиотекой, но связать обе библиотеки с исполняемым файлом. Из книги "Освоение CMake":

Since static labriries do not link to the libraries on which they depend, it is 
important for CMake to keep track of the libraries so they can be specified on the
link line of the executable being created. 

Вы можете попытаться использовать абсолютный путь в вашем CMakeLists2:

add_library (project2 ${sources})
target_link_libraries (project2 "path to ext lib"/"name of ext lib")

или вы можете добавить

link_directories ("path_to_library")

в файл CMakeLists проекта1.

Если вы действительно хотите сделать что-то вроде Visual Studio, вы могли бы, вероятно, использовать команду, приведенную в этом , чтобы создать команду custom_ в команде CMake. Вероятно, это будет выглядеть примерно так (я его не тестировал).

set(EXT_LIB "path_to_library/name_of_external_lib") 
set(BIG_LIB "path_to_big_lib/name_of_big_lib")
add_library (project2 ${sources})
get_property(PROJ2_LOC TARGET project2 PROPERTY LOCATION)

add_custom_command(OUTPUT ${BIG_LIB} 
                   DEPENDS ${EXT_LIB} project2
                   COMMAND "lib.exe /OUT:${BIG_LIB} ${EXT_LIB} ${PROJ2_LOC} )

Затем вы можете связать свой исполняемый файл с ${BIG_LIB}.

Некоторые вещи, которые вы должны учитывать:

  • Возможно, вам нужно использовать LOCATION_CONFIG (Документы CMake, я нашел команду get_property в этот ответ)
  • link.exe должен быть на вашем пути
  • просмотрите область действия BIG_LIB, если вы хотите использовать ее в другом CMakeLists.txt

Ответ 2

Я предполагаю, что проблема скорее всего будет заключаться в том, что * name_of_external_lib * неверен, поэтому он не может его найти.

Я бы пошел с:

find_library(
    LIB_I_NEED name_of_external_lib
    HINTS "path_to_library"
)

if(${LIB_I_NEED} STREQUAL "LIB_I_NEED-NOTFOUND")
    message(FATAL_ERROR "Couldn't find the 'external_lib' library)
endif()

message(STATUS "Found 'external_lib' at: ${LIB_I_NEED}")

add_library (project2 ${sources})
target_link_libraries (project2 ${LIB_I_NEED})

Если это не помогает, быстро прочитайте пример в документах cmake:

http://www.cmake.org/cmake/help/v2.8.8/cmake.html#command:target_link_libraries

Одна вещь, о которой он упоминает, есть:

В то время как одного повторения обычно достаточно, файл патологического объекта и схемы символов могут потребовать больше. Такие случаи можно обрабатывать вручную повторять компонент в последних target_link_libraries вызов

Итак, я бы сказал, что другая вещь, которую можно попробовать, может быть в проекте2:

set(PROJECT_2_LIBS project2 "name_of_external_lib" PARENT_SCOPE)

то в exe:

target_link_libraries (project1 ${PROJECT_2_LIBS})

Это приведет к тому, что ссылка "external_lib" повторится в двух местах и ​​даст вам больше шансов на ее работу;)