无法链接 CMake 中的本地库
Cannot link local libraries in CMake
我正在Visual Studio上开发一个C++程序,该程序将部署在Linux上,并通过ssh在Linux上进行调试。目前,这是我的文件夹的结构:
ANT
-xscommon
--xscommon_config.h
-xscontroller
-xstypes
ANT.cpp
ANT.h
CMakeLists.txt
CMakeSettings.json
hashes.h
quaternionic.h
stars.h
目前,我认为必须链接到的所有.h, .cpp, .o, .cpp.o, .a
文件都保存在三个xs-------目录中。我对 cmake 很陌生,这种链接到这些库给我带来了麻烦;我能够正确链接到包含,但是当我不进行链接时会抛出未定义的引用错误,并且当我尝试链接时,它会抛出错误。这是我当前的CMakeLists.txt文件:
# CMakeList.txt : CMake project for ANT, include source and define
# project specific logic h"ere.
#
cmake_minimum_required (VERSION 3.8)
project ("ANT")
link_directories(${ANT_SOURCE_DIR}/xscommon xscontroller xstypes)
add_executable(
ANT
"ANT.cpp"
"ANT.h"
"quaternionic.h"
"stars.h"
"hashes.h"
)
target_include_directories(ANT PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(ANT PUBLIC xscommon_config)
当我运行它时,构建器会说以下内容:
/usr/bin/ld: cannot find -lxscommon_config
我需要在 ANT.cpp 所在的目录中查找这些库,因为这是保存它们的地方,但是我所做的任何事情(我已经弄乱了几个小时的配置)不会告诉 camke 在 src 文件夹中查找这些库。 它总是去/usr/bin/ld
.
我真的只需要知道要告诉 CMake 什么,以便它会在每个文件的正确位置查找,也就是说,如果我告诉它查找正确的文件(我相当确定我是)。
%%%%%
更新
%%%%%
所以我将 CMakeLists.txt 文件重新制作为:
# CMakeList.txt : CMake project for ANT, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.15)
project ("ANT")
#[STATIC | SHARED | MODULE]
#[STATIC | SHARED | MODULE]
#[STATIC | SHARED | MODULE]
add_library(xscommon SHARED IMPORTED)
add_library(xscontroller SHARED IMPORTED)
add_library(xstypes SHARED IMPORTED)
add_executable(
ANT
"ANT.cpp"
"ANT.h"
)
target_include_directories(ANT PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
并且仍然获得未定义的引用。我将尝试构建库。此外,我已经联系了使用此SDK的IMU制造商,因为同事也无法解决此问题。
问题是您链接到尚未构建的库。 这
# link to this directory
target_link_libraries(ANT PRIVATE xscommon)
尝试将名为 xscommon 的库链接到目标 ANT,但您尚未在项目中的任何位置构建 xscommon。
如果 xscommon 是一个预构建库,而你只想导入它,那么添加库并设置 IMPORTED 的目标属性:
add_library(xscommon [STATIC | SHARED | MODULE] IMPORTED)
如果你想在你的根CMakeList中构建xscommon.txt。将 xscommon 添加为库,并包括标头的位置。
add_library(xscommon [STATIC | SHARED | MODULE]
xxx/xxx.cpp #list all source files that build the library - use relative path
)
target_include_directories(xscommon PRIVATE
xxx/xxx #path to the location of library header files
)
此外,添加可执行文件时无需添加头文件。所以这个
add_executable(
ANT
"ANT.cpp"
"ANT.h"
"quaternionic.h"
"stars.h"
"hashes.h"
)
可以简化为
add_executable(
ANT
"ANT.cpp"
)
假设你的目录是这样的:
ANT
-xscommon
--xscommon_config.h
--xscommon_config.cpp
...
首先添加一个CMakeLists.txt
文件到xscommon/
:
ANT
-xscommon
--CMakeLists.txt
--xscommon_config.h
--xscommon_config.cpp
...
现在在xscommon/CMakeLists.txt
我们将创建一个库,该库将被导入并链接到主CMakeLists.txt文件中:
xscommon/CMakeLists.txt:
#define another target, let's name it 'xscommon'
add_library(xscommon
xscommon_config.h
xscommon_config.cpp
#more sources if you want
)
现在在主CMakeLists.txt
文件中:
cmake_minimum_required (VERSION 3.8)
project ("ANT")
#remove this line
#link_directories(${ANT_SOURCE_DIR}/xscommon xscontroller xstypes)
add_executable(
ANT
"ANT.cpp"
"ANT.h"
"quaternionic.h"
"stars.h"
"hashes.h"
)
# add the xscommon directory, this will make the library target defined there available here
add_subdirectory(xscommon)
# link to this directory
target_link_libraries(ANT PRIVATE xscommon)
# use PUBLIC if the xscommon library will be part of the public interface of your
# library. But since it is an executable, PRIVATE is better here.
target_include_directories(ANT PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
使用上述方法,您可以创建更多库并链接到它们。
请注意,没有必要为每个子目录创建单独的 cmake 文件,但这被认为是一种很好的做法,并且可以模块化您的代码。如果要在主 cmake 文件中执行此操作而不是创建子目录,请将其添加到主 cmake 中:
add_library(xscommon
xscommon/xscommon_config.h
xscommon/xscommon_config.cpp
#more sources if you want
)
根据相关更改进行更新
您当前CMakeLists.txt
:
下面这三行什么都没做,绝对不是你想的那样。 我知道add_library()
命令中有"add"这个词,但它没有添加任何库,就像add_executable
没有添加任何可执行文件一样。它创建一个库。
add_library(xscommon SHARED IMPORTED)
add_library(xscontroller SHARED IMPORTED)
add_library(xstypes SHARED IMPORTED)
如何在cmake中创建两个文件a.cpp
和a.h
库:
add_library(myALib "a.cpp")
就是这样。如果您有更多来源,您当然会相应地包含它们。在您的情况下,您必须相应地添加xscommon
和其他来源。
创建库后,需要将它们链接到可执行文件。否则,将出现未定义的引用错误,因为编译器可以在头文件中找到声明,但不能找到存在于.cpp
文件中的代码定义。
那么,你如何链接?简单:
target_link_libraries(TARGET_NAME PUBLIC | PRIVATE LIBRARY_NAME)
# TARGET_NAME: can be `executable` or `library`
# PUBLIC or PRIVATE (for exe, it is usually private)
# LIBRARY_NAME: Name of library you want to link to TARGET_NAME
# So if you wanted to link "myALib" which I created above to ANT, you would do:
target_link_libraries(ANT PRIVATE myALib)
# Note: You need to add this line **after** add_executable() because target "ANT" will be created after that. You can do the linking after the "target_include_directories" command.
- CMake-按正确顺序将项目与C运行时对象文件链接
- 无法链接 CMake 中的本地库
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- Cmake 链接问题:未定义对 Button::mousePressEvent(QGraphicsSceneMouseE
- 在 CMake 中为每个目标设置编译器/链接器标志
- 链接 cmake 时出现未定义的引用错误
- 如何将GTest与CMake一起使用?遵循谷歌指南时的链接问题
- 将 SDL2 与 CMake 链接起来
- CMake 库链接使用两个不同的编译器版本
- CMake 无法链接外部库
- CMake - 更改共享库链接选项
- CMake 3.5 中的链接器标志位置
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 如何避免在 cmake 中自动链接 Qt5 库?
- 将源中的 GLEW 与 cmake 静态链接
- CMake 错误:链接器命令失败,退出代码为 1 和 cpp.o 文件
- 找不到 CMake 链接的库
- Opencv 链接 CMAKE 不起作用 Ubuntu 16.04 Docker
- 如何在没有外部脚本的情况下链接CMake和SQLite
- 链接CMake的Openscenegraph库