我想知道如何在没有任何FIND_PACKAGE的情况下查找/链接库.
假设我们有一个名为testlib的"个人"库:
/perso/testlib/include/testlib1.h
/perso/testlib/include/testlib2.h
/perso/testlib/lib/testlib1.a
/perso/testlib/lib/testlib2.a
Run Code Online (Sandbox Code Playgroud)
如何将其与CMake链接?
1)在CMakeLists.txt的代码中直接链接它的功能是什么?
2)如何让用户选择文件的位置?
3)我很难理解CMake解释什么和不解释什么.例如,如果您定义变量$ {MYVARIABLE_INCLUDE_DIR}或$ {MYVARIABLE_LIBRARIES}是"INCLUDE_DIR"或"LIBRARIES"由CMake解释的扩展名,或者如果我调用此变量$ {MYVARIABLE_INCDIR}没有区别?
4)如果在lib目录中有一个包含十个或更多库文件的库,如何执行相同的过程(包括"个人"库)?
5)最后,当你输入时TARGET_LINK_LIBRARIES(myexecutable gmp),你怎么知道这个库的名字是"gmp".为什么不"Gmp"或"GMP"?放入此函数的库的名称是否等于.a文件减去"lib"和".a"?比如libgmp.a - > gmp?如果我想链接一个名为libtestlolexample.a的库,我是否需要输入TARGET_LINK_LIBRARIES(myexecutable testlolexample)?
非常感谢你.
tre*_*nki 15
您可以使用target_link_libraries(myexecutable mylib)链接到库"mylib".编译器将使用其默认方式来查找指定的库(例如,它将在Linux上查找libmylib.a).编译器只会查看link_directories(directory1 directory2 ...),因此您可以尝试使用该命令将所需目录添加到搜索路径中.
当"mylib"也用CMake编译时,这将被识别,一切都应该自动工作.
如果希望用户指定目录,可以使用缓存的CMake变量.set(MYPATH "NOT-DEFINED" CACHE PATH "docstring").
对于更复杂的东西,建议编写一个可以使用的CMake查找模块find_package.我建议你看看FindALSA.cmake哪个可以作为一个很好的起点.
有趣的部分是在最后:
if(ALSA_FOUND)
set( ALSA_LIBRARIES ${ALSA_LIBRARY} )
set( ALSA_INCLUDE_DIRS ${ALSA_INCLUDE_DIR} )
endif()
mark_as_advanced(ALSA_INCLUDE_DIR ALSA_LIBRARY)
Run Code Online (Sandbox Code Playgroud)
在ALSA_LIBRARY和ALSA_INCLUDE_DIR变量是用户可配置的,并存储在缓存中,而ALSA_LIBRARIES和ALSA_INCLUDE_DIRS以及ALSA_FOUND得到计算,并是查找模块的用户应该使用的.
通常会使用find模块,如下所示:
find_package(ALSA REQUIRED)
include_directories(${ALSA_INCLUDE_DIRS})
target_link_libraries(myexe ${ALSA_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)
我相信你可以适应你的个人图书馆.
通常,当您想要链接到没有 find_package 模块的库(例如,它是一个不常见的库,或者它是您自己的库)时,您可以使用基本命令(find_X 命令)来设置变量与您的路径需要。include_directories然后您可以像 find_package ( , )一样使用这些变量target_link_libraries。
如果您要从多个包中使用此库,您可能需要创建一个 find_package 模块;基本上它使用具有某些约定的相同命令。
其中任何一个都允许您指定要查找的路径(在 CMake 模块中),并且它们允许用户覆盖路径(变量显示为ccmake/中的选项cmake-gui)。
我很乐意添加其中一种或两种方法的示例,只需让我知道您在寻找什么即可。
如果你只是想要一个快速而肮脏的解决方案,你可以这样做,但我不推荐它:
include_directories(/perso/testlib/include)
add_executable(myexecutable myexecutable.cpp)
target_link_libraries(myexecutable
/perso/testlib/lib/testlib1.a
/perso/testlib/lib/testlib2.a)
Run Code Online (Sandbox Code Playgroud)
关于您关于target_link_libraries(#5)的问题,您可以通过多种方式实现。如果您愿意,您可以提供全名(例如target_link_libraries(myexe libfoo.a)),但我认为使用短名称(例如 )更好(我想更便携)target_link_libraries(myexe foo。您还可以包含链接器标志;我不确定我在哪里读到它,但我认为它可能会翻译不同链接器的 -L 和 -l 标志。
例如,如果我在同一目录中有一堆库,并且我知道名称,我可能会找到该目录,将其存储在变量中,然后执行以下操作:
# First, find and set TESTLIB_LIBRARY_DIR, e.g. with find_path
# ...
# This assumes the libraries are e.g. 'libtestlib1.a' and 'libtestlib2.a'
set(TESTLIB_LIBRARIES
-L${TESTLIB_LIBRARY_DIR)
-l testlib1
-l testlib2)
add_executable(myexecutable myexecutable.cpp)
target_link_libraries(myexecutable ${TESTLIB_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)
如果你想制作自己的 find_package 模块(就像 trenki 提到的那样,FindALSA.cmake似乎是一个很好的起点),你可以通过将目录添加到CMAKE_MODULE_PATH;来使用它。例如,如果您将模块放在子目录中cmake/modules/:
# Look for extra CMake modules in a subdirectory of this project
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/" ${CMAKE_MODULE_PATH})
Run Code Online (Sandbox Code Playgroud)
一个可能的问题是FindALSA.cmake:我不确定CMAKE_CURRENT_LIST_DIR是否可行。所以我认为你应该做出这个改变(我编写的模块中的第二项工作):
# Change this line
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
# To this (with no path/extension it will search the CMake modules path):
include(FindPackageHandleStandardArgs)
Run Code Online (Sandbox Code Playgroud)
要了解 的用法FIND_PACKAGE_HANDLE_STANDARD_ARGS,请查看FindPackageHandleStandardArgs.cmakeCMake Modules 目录。
| 归档时间: |
|
| 查看次数: |
30200 次 |
| 最近记录: |