cmake中target_link_libraries()使用问题动态库使用绝对路径没问题,但是使用相对路径就矬了?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cmake中target_link_libraries()使用问题动态库使用绝对路径没问题,但是使用相对路径就矬了?相关的知识,希望对你有一定的参考价值。
小弟最近在做一个小项目,需要用到cmake的target_link_libraries()来链接一个已经存在的动态库文件,就像这样 myproject/libs/libcurl.so(libcurl.so是直接下载的)。我把CmakeList.txt和qiproject.xml放在另一个文件夹下,就像这样 myproject/build/cmakelist.txt. 编辑cmakelist.txt的时候使用target_link_libraries()来链接动态库 ,在make的时候发现,只有使用动态库的绝对路径才行得通,换成相对路径就不行。在此问一下大家,可能是哪里出了问题?
使用相对路径的时候,你要让cmake能够搜索到找到你动态库,就像直接使用gcc/g++来链接的时候一样,要使用-L来指定第三方库所在路径。cmake可以使用 LINK_DIRECTORIES 命令来指定第三方库所在路径,比如,你的动态库在/home/myproject/libs这个路径下,则通过命令:LINK_DIRECTORIES(/home/myproject/libs),把该路径添加到第三方库搜索路径中,这样就可以使用相对路径了,使用TARGET_LINK_LIBRARIES的时候,只需要给出动态链接库的名字就行了。
拓展:
1、CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。
2、只是 CMake 的组态档取名为 CMakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。
参考技术A 使用相对路径的时候,你要让cmake能够搜索到找到你动态库,就像直接使用gcc/g++来链接的时候一样,要使用-L来指定第三方库所在路径。cmake可以使用 LINK_DIRECTORIES 命令来指定第三方库所在路径,比如,你的动态库在
/home/myproject/libs
这个路径下,则通过命令:
LINK_DIRECTORIES(/home/myproject/libs)
把该路径添加到第三方库搜索路径中,这样就可以使用相对路径了,使用TARGET_LINK_LIBRARIES的时候,只需要给出动态链接库的名字就行了,比如:
TARGET_LINK_LIBRARIES(MyApp -lcurl ) 参考技术B 程序执行时的当前路径可能不是你存放list的路径
在CMake中如何使`TARGET_LINK_LIBRARIES'禁止第三方库代码发出警告?
在CMake中,您可以将TARGET_INCLUDE_DIRECTORIES()
添加包含目录作为系统包含目录(即使用-isystem
),以便不会弹出以第3方代码为根的警告:
TARGET_INCLUDE_DIRECTORIES(mytarget
SYSTEM
${3rdPartyLib_INCLUDE_DIR})
我更喜欢使用TARGET_LINK_LIBRARIES
,它也包括来自第三方库的目录。据我所知,TARGET_LINK_LIBRARIES
不支持SYSTEM
修饰符将这些目录添加为系统包含目录。
我弄错了吗?
有没有办法:
TARGET_LINK_LIBRARIES(mytarget
${3rdPartyLib_INCLUDE_DIR})
使用-isystem
? (或任何其他方式来抑制来自3rdPartyLib
的警告)。
我建议你创建一个名为myproject_thirdparty.h
的标题,如下所示:
#ifndef myproject_thirdparty_h
#define myproject_thirdparty_h
#include "myprojectMacros.h"
CLANG_PRAGMA_PUSH
CLANG_SUPPRESS_Wfloat_equal
CLANG_PRAGMA_POP
#endif
其中myprojectMacros.h
将定义有用的宏,如CLANG_PRAGMA_PUSH
,CLANG_PRAGMA_POP
,GCC_PRAGMA_PUSH
,GCC_PRAGMA_POP
,...
然后,在项目代码中,每次要使用库时都会包含myproject_thirdparty_h
,这将有效地关闭警告而不会影响项目的剩余部分。
我有一个similar question,我用自定义函数解决了:
function(target_link_libraries_system target)
set(libs ${ARGN})
foreach(lib ${libs})
get_target_property(lib_include_dirs ${lib} INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(${target} SYSTEM PRIVATE ${lib_include_dirs})
target_link_libraries(${target} ${lib})
endforeach(lib)
endfunction(target_link_libraries_system)
我现在可以调用target_link_libraries_system(myapp lib::lib)
,并从目标的属性中读取include目录。
现在可以将其扩展为指定PUBLIC|PRIVATE|INTERFACE
范围,但由于我在可执行文件上使用它,现在就足够了。
以上是关于cmake中target_link_libraries()使用问题动态库使用绝对路径没问题,但是使用相对路径就矬了?的主要内容,如果未能解决你的问题,请参考以下文章
cmake中target_link_libraries()使用问题动态库使用绝对路径没问题,但是使用相对路径就矬了?
添加不存在的目标时强制 CMake target_link_libraries 失败
C++学习(四一零)cmake的target_link_libraries
[cmake][转载]cmake中的link_directories, LINK_LIBRARIES, target_link_libraries的区别
调用 `target_link_libraries(target_name, library_name_without_postfix)` 时,`Cmake` 更喜欢链接到哪个库?