2016-06-14 42 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/libblah/lib/osx?我可以改变软件包的结构,但是我不想修改它的设计方式。

我知道答案与PROPERTIES或默认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} 
) 

对于实际的库:

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 

另外的问题:

下面的答案帮助我ü了解lib文件夹和实际lib名称之间的区别。但是,仍然有一个问题回答了:如何让CMake接受并链接任意lib名称?

在上面的问题中,库被称为只是与他们的名字,例如,openFrameworks.a应该被称为libopenFrameworks.a为了被链接器拿起,但它不是。那我会问一个不同的问题。

+0

This [question](http://stackoverflow.com/questions/14077611/how-do-i-tell-cmake-to-link-in-a-static-library-in-the-source-directory)似乎覆盖类似的地面?解决方案(s)也适用于你的情况? – 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.ayour_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) 

将导致链接来寻找每个link_directorieslibfoo.{so|a}

+0

道歉,我跳过了一些我正在执行的步骤,并且忽略了这些问题,因此这个问题可能有点混乱。我刚刚更新了内容,使问题更加清晰,涵盖了我正在使用的所有阶段。我想我正在按照你在答案中描述的内容来做,对吗? – symbolix

+0

@symbolix查看更新。 –

+0

当我这样做,我的意思是当我通过文件夹,我得到这个:'警告:目标“3DPrimitiveExample”请求链接到目录“/Users/me/packages/builds/x86_64/of-0.9.3-osx-release /库/ openFrameworksCompiled/lib中/”。目标可能只能链接到图书馆。 CMake正在删除该项目。' – symbolix