2016-06-14 2 views
2

У меня есть несколько библиотек, которые находятся в нестандартных местах. Это из OpenFrameworks и ЛИЭС внутри:Как подключиться к библиотеке в нестандартном местоположении с помощью CMake?

/Users/me/packages/builds/x86_64/of-0.9.3-osx-release/libs/openFrameworksCompiled/lib/osx/openFrameworks.a 
... 
/Users/me/packages/builds/x86_64/of-0.9.3-osx-release/libs/boost/lib/osx/boost_system.a 
... 
etc. 

При связывании тех, кто в моем CMake, я использую следующий подход:

set(LIB_OF ${OF_DIRECTORY}/libs/openFrameworksCompiled/lib/osx/openFrameworks.a) 
... 
set(LIB_BOOST_MAIN ${OF_DIRECTORY}/libs/boost/lib/osx/boost.a) 
... 
set(LIB_CAIRO1 ${OF_DIRECTORY}/libs/cairo/lib/osx/cairo-script-interpreter.a) 
... 
set(LIB_FREETYPE ${OF_DIRECTORY}/libs/freetype/lib/osx/freetype.a) 
... 

Затем я объединить эти переменные в одну большую переменную:

set(OF_CORE_LIBS 
    ${LIB_OF} 
    ... 
    ${LIB_BOOST_MAIN} 
    ... 
    ${LIB_CAIRO1} 
    ... 
    ${LIB_FREETYPE} 
    ... 
) 

Так в конце концов все ЛИЭС объединяются и передаются в линкер:

link_directories (${OF_CORE_LIBS}) 

Затем я использую:

target_link_libraries(${APP_NAME} ${OF_CORE_LIBS}) 

, чтобы связать их.

Однако, я получаю следующее предупреждение на этапе связующей:

Linking CXX executable ../bin/3DPrimitiveExample 
ld: warning: -L path '/Users/me/packages/builds/x86_64/of-0.9.3-osx-release/libs/openFrameworksCompiled/lib/osx/openFrameworks.a' is not a directory 
... 
(All the libs are listed in this way) 

Как я могу сказать, CMake заглянуть в эти каталоги, даже если они не называются blah/lib но blah/lib/osx? Я мог бы изменить структуру пакета, но тогда я не хочу изменять способ его разработки.

Я знаю, что ответ имеет какое-то отношение к или по умолчанию CMAKE переменным, но помощь по-прежнему немного загадочна для меня. Я предполагаю, что это set_target_properties(), но не уверен в синтаксисе. (Я на CMake 2.8.12)

UPDATE (1): Так что я изменил свой подход следующим образом:

set(LIB_OF ${OF_DIRECTORY}/libs/openFrameworksCompiled/lib/) 
set(LIB_FREEIMAGE ${OF_DIRECTORY}/libs/FreeImage/lib/) 
set(LIB_BOOST ${OF_DIRECTORY}/libs/boost/lib/) 
set(LIB_CAIRO ${OF_DIRECTORY}/libs/cairo/lib/) 
set(LIB_FMODEX ${OF_DIRECTORY}/libs/fmodex/lib/) 
set(LIB_FREETYPE ${OF_DIRECTORY}/libs/freetype/lib/) 
set(LIB_GLEW ${OF_DIRECTORY}/libs/glew/lib/) 
set(LIB_OPENSSL ${OF_DIRECTORY}/libs/openssl/lib/) 
set(LIB_POCO ${OF_DIRECTORY}/libs/poco/lib/) 
set(LIB_RTAUDIO ${OF_DIRECTORY}/libs/rtAudio/lib/) 
set(LIB_TESS ${OF_DIRECTORY}/libs/tess2/lib/) 

После того, как эти переменные местоположения созданы, они объединены один раз снова:

set(OF_CORE_LIBS 
    ${LIB_OF} 
    ${LIB_FREEIMAGE} 
    ${LIB_BOOST} 
    ${LIB_CAIRO} 
    ${LIB_FMODEX} 
    ${LIB_FREETYPE} 
    ${LIB_GLEW} 
    ${LIB_GLFW} 
    ${LIB_OPENSS} 
    ${LIB_POCO} 
    ${LIB_RTAUDIO} 
    ${LIB_TESS} 
) 

Так что, когда я слишком разговорчивым, я получаю следующее:

OF_CORE_LIBS: /Users/me/packages/builds/x86_64/of-0.9.3-osx-release/libs/openFrameworksCompiled/lib/;/Users/me/packages/builds/x86_64/of- 0.9.3-osx-release/libs/FreeImage/lib/;/Users/me/packages/builds/x86_64/of-0.9.3-osx-release/libs/boost/lib/; (etc) 

Затем я передаю эти папки линкера:

link_directories (${OF_CORE_LIBS}) 

Теперь та часть, которая неправильно это:

target_link_libraries(${APP_NAME} ${OF_CORE_LIBS}) 

Очевидно, что я не могу передать папки прямо здесь? Мне нужны имена lib. Мне нужен еще один список с именами lib на этом этапе?

UPDATE (2):

Для Lib папки поиска:

set(OF_CORE_LIB_DIRS 
    ${LIB_OF} 
    ${LIB_FREEIMAGE} 
    ${LIB_BOOST} 
    ${LIB_CAIRO} 
    ${LIB_FMODEX} 
    ${LIB_FREETYPE} 
    ${LIB_GLEW} 
    ${LIB_GLFW} 
    ${LIB_OPENSS} 
    ${LIB_POCO} 
    ${LIB_RTAUDIO} 
    ${LIB_TESS} 
) 

Для реальных LIBS:

set(OF_CORE_LIBS 
    openFrameworks 
    freeimage 
    boost_system 
    boost_filesyste 
    freeimage 
    cairo-script-interpreter 
    cairo 
    pixman-1 
    fmodex 
    freetype 
    glew 
    ssl 
    crypto 
    PocoCrypto 
    PocoData 
    PocoDataSQLite 
    PocoJSON 
    PocoMongoDB 
    PocoXML 
    PocoNet 
    PocoNetSSL 
    PocoUtil 
    PocoZip 
    PocoFoundation 
    rtAudio 
    tess2 
) 

И связывающей стадии:

link_directories (${OF_CORE_LIB_DIRS}) 
add_executable(${APP_NAME} ${SOURCE_FILES}) 
target_link_libraries(${APP_NAME} ${OF_CORE_LIBS}) 

Теперь я получаю следующее сообщение об ошибке:

Linking CXX executable ../bin/3DPrimitiveExample.app/Contents/MacOS/3DPrimitiveExample 
ld: library not found for -lopenFrameworks 

Это немного каталога:

set(LIB_OF ${OF_DIRECTORY}/libs/openFrameworksCompiled/lib/osx) 

и файл там:

openFrameworks.a 

Дальнейшие вопросы:

Ответ ниже помог мне nderstand разница между папками lib и фактическими именами lib. Однако есть еще один вопрос: как сообщить CMake принять и связать произвольные имена lib?

В вопросе выше, libs вызывается только с их именами, например, openFrameworks.a следует называть libopenFrameworks.a, чтобы его подхватил компоновщик, но это не так. Это, я спрошу по другому вопросу. не

+0

Этот [вопрос] (http://stackoverflow.com/questions/14077611/how-do-i-tell-cmake-to-link-in-a-static-library-in-the-source-directory) похоже, покрывает аналогичную почву? Решение (ы) может работать и в вашем случае? – Wuggy

+0

Спасибо. Но это не помогает мне. Я делаю то же самое, и я получаю эти предупреждения, описанные выше. Я хотел бы знать, как исправить предупреждение и передать папку компоновщику, а не фактический файл lib. – symbolix

+3

Нет, проблема в том, что вы передаете полный путь к библиотеке. Вам необходимо передать путь к папке, в которой находится библиотека. Тогда вы можете просто добавить свой типичный -l alfalfasprout

ответ

1

So eventually all the libs are concatenated and passed into the linker:

link_directories (${OF_CORE_LIBS}) 

Нет, они не. От the manual

link_directories

Specify directories in which the linker will look for libraries.

link_directories(directory1 directory2 ...)

Specify the paths in which the linker should search for libraries.

Так вы указали каталоги, в которых компоновщик должен искать библиотеки, которые вы хотите связать. Теперь вы хотите указать, что компоновщик должен связать библиотеку, скажем, libfoo.a с your_executable.

Опять the manual:

target_link_libraries(your_executable foo) 

Вы говорите компоновщик где искать, а также , что искать.

Позже

I think I am doing exactly what you have described in your answer, right?

Нет, это не так.

Вы даете список файлы (по-видимому, они являются статическими библиотеками, хотя они не имеют префикс обычного lib) в link_directories.Для этого требуется список каталогов , в котором компоновщик должен искать библиотеки, заданные с помощью target_link_libraries.

Вот почему линкер говорит:

ld: warning: -L path '/Users/me/packages/builds/x86_64/of-0.9.3-osx-release/\ 
libs/openFrameworksCompiled/lib/osx/openFrameworks.a' is not a directory 

Это файл. Исправьте это, а затем:

target_link_libraries(your_executable foo) 

заставит компоновщик искать библиотеку libfoo.{so|a} в каждом из link_directories.

+0

Извинения, я пропустил некоторые шаги, которые я выполняю, и опустил их из вопроса, поэтому вопрос может быть немного запутанным, как есть. Я только что обновил содержание, так что вопрос яснее, и он охватывает все этапы, которые я использую. Думаю, я делаю именно то, что вы описали в своем ответе, верно? – symbolix

+0

@symbolix См. Обновление. –

+0

Когда я это делаю, я имею в виду, когда я передаю папки, я получаю следующее: «ПРЕДУПРЕЖДЕНИЕ: целевые« 3DPrimitiveExample »запросы, ссылающиеся на каталог» /Users/me/packages/builds/x86_64/of-0.9.3-osx-release/ЛИЭС/openFrameworksCompiled/Библиотека /». Цели могут связываться только с библиотеками. CMake отбрасывает элемент. ' – symbolix

Смежные вопросы