如何解决如何在 CMAKE 项目上正确添加子文件夹而不会收到链接器错误
我在 CMAKE
项目中包含子文件夹时遇到了一些问题。
简而言之,下面是我拥有的 CMAKE
树的摘要。第一层工作正常,但第二层不能正常工作,抛出一个 linker error
:
错误:
src/ROstemplatesMsgs/CMakeLists.txt 中的 CMake 错误:17 (add_executable): 找不到源文件:
actionlib_msgs/goalID/dbGoalID.cpp
尝试扩展 .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp .hxx .in .txx
CMake 错误:CMake 无法确定目标的链接器语言: goalID CMake 错误:无法确定目标的链接语言 “目标 ID”。生成完成
项目树如下图所示:
.
+-- Project-DriveAll[master]
+-- CMakeLists.txt
+-- src
| +-- projectA
| +-- projectB
| +-- ROstemplatesMsgs
| +-- CMakeLists.txt
| +-- main
| +-- geometry_msgs.h
| +-- main.cpp
| +-- pointField.h
| +-- ros_headers.h
| +-- src
| +-- actionlib_msgs
| +-- goalID
| +-- dbGoalID.cpp
| +-- dbGoalID.h
| +-- goalIDItem.cpp
| +-- goalIDItem.h
| +-- goalStatus
| +-- dbGoalStatus.cpp
| +-- dbGoalStatus.h
| +-- goalStatusItem.cpp
| +-- goalStatusItem.h
| +-- sensor_msgs
| +-- laserscan
| ........
要获得更好的可视化效果,另请参阅:
cmake_minimum_required(VERSION 3.1)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(INCLUDE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/include)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g")
project(Project-DriveAll)
add_subdirectory(src/projectA)
add_subdirectory(src/projectB)
add_subdirectory(src/ROstemplatesMsgs)
但是,以下是未正确编译的项目 CMakeLists.txt
下的 src/ROstemplatesMsgs
:
cmake_minimum_required (VERSION 3.1)
project(ROstemplatesMsgs)
find_package(Qt5Widgets required)
set (OpenCV_DIR /home/to/opencv/build)
set (BOOST_LIBRARYDIR /usr/lib/x86_64-linux-gnu)
find_package( OpenCV required )
find_package(Boost COMPONENTS system thread filesystem required)
find_package(Qt5PrintSupport required)
find_package(Qt5 required COMPONENTS Core Quick sql)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
include_directories(${OpenCV_INCLUDE_Dirs})
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDE_Dirs})
file(GLOB SRCS
"src/*.h"
"src/*.cpp"
"src/*.hpp"
"src/actionlib_msgs/goalID/dbGoalID.cpp"
"src/actionlib_msgs/goalID/dbGoalID.h"
"src/actionlib_msgs/goalID/dbGoalIDItem.cpp"
"src/actionlib_msgs/goalID/dbGoalIDItem.h"
"src/actionlib_msgs/goalStatusArray/dbGoalStatusArray.cpp"
"src/actionlib_msgs/goalStatusArray/dbGoalStatusArray.h"
"src/actionlib_msgs/goalStatusArray/goalStatusArrayItem.cpp"
"src/actionlib_msgs/goalStatusArray/goalStatusArrayItem.h"
"src/sensor_msgs/laserscan/*.h"
"src/sensor_msgs/laserscan/*.cpp"
"src/sensor_msgs/laserscan/*.hpp"
"src/visualization_msgs/marker/*.h"
"src/visualization_msgs/marker/*.cpp"
"src/visualization_msgs/marker/*.hpp"
"src/visualization_msgs/markerarray/*.h"
"src/visualization_msgs/markerarray/*.cpp"
"src/visualization_msgs/markerarray/*.hpp"
"src/sensor_msgs/pointcloud2/*.h"
"src/sensor_msgs/pointcloud2/*.cpp"
"src/sensor_msgs/pointcloud2/*.hpp"
"src/sensor_msgs/pointcloud/*.h"
"src/sensor_msgs/pointcloud/*.cpp"
"src/sensor_msgs/pointcloud/*.hpp"
"main/*.h"
"main/*.cpp"
"main/*.hpp"
)
file(GLOB UI_SRCS
"ui/*.h"
"ui/*.cpp"
"ui/*.hpp"
)
add_executable(ROstemplatesMsgs main/main.cpp ${SRCS})
target_link_libraries (ROstemplatesMsgs Qt5::Widgets ${Boost_LIBRARIES} ${OpenCV_LIBS} Qt5::PrintSupport Qt5::Core Qt5::Quick Qt5::sql)
add_library(ROstemplatesMsgs_lib SHARED ${SRCS} ${UI_HDRS} ${UI_SRCS})
target_include_directories (ROstemplatesMsgs_lib PUBLIC "src/actionlib_msgs/" )
target_include_directories (ROstemplatesMsgs_lib PUBLIC "src/sensor_msgs/" )
target_link_libraries (ROstemplatesMsgs_lib Qt5::Widgets ${Boost_LIBRARIES} ${OpenCV_LIBS} Qt5::PrintSupport Qt5::Core Qt5::Quick Qt5::sql)
我查阅了很多资源,例如 this one 和 this one,但是就我而言,我没有使用 TARGET
选项,因为 CMAKE
文档中并不总是建议这样做。
但是,我也尝试按照这篇文章中的建议使用 set_target_properties,但没有任何改变。
我浏览了 this post,但没有帮助找出问题所在。
我也尝试通过以下方式add_subdirectory按照这篇文章的建议,但也没有奏效:
add_subdirectory(src/actionlib_msgs)
add_subdirectory(src/sensor_msgs)
我咨询的另一个来源是 this one,它实际上有助于理解处理复杂项目和处理复杂项目时的不同用途。如问题开头所示,我的项目还有其他子项目,其中包含多个 CMakeLists.txt
,但项目 ROstemplatesMsgs
是具有多个子文件夹并且使树复杂化的项目。
root 有 add_subdirectory()
命令,实际上运行良好。
ProjectA 和 ProjectB 有自己的 CMakeLists.txt
并且没问题(但它们也没有多个子文件夹)。
当涉及到最后一个项目(带有子文件夹的项目)时,有些事情无法正常工作,我的想法已经用完了。
编辑
构建项目后的其他信息可以在下面的终端错误中看到:
在包含的文件中 /home/build-ultrasound_mapper-Desktop_Qt_5_12_2_GCC_64bit-Debug/src/ROstemplatesMsgs/ROstemplatesMsgs_autogen/mocs_compilation.cpp:3:0: /home/build-ultrasound_mapper-Desktop_Qt_5_12_2_GCC_64bit-Debug/src/ROstemplatesMsgs/ROstemplatesMsgs_autogen/WKFP3Z6SYI/moc_dbGoalStatus.cpp:57:6: 错误:“dbGoalStatus”尚未声明为无效 dbGoalStatus::qt_static_Metacall(QObject *_o,QMetaObject::Call _c,int _id,void **_a)
/home/build-ultrasound_mapper-Desktop_Qt_5_12_2_GCC_64bit-Debug/src/ROstemplatesMsgs/ROstemplatesMsgs_autogen/WKFP3Z6SYI/moc_dbGoalStatus.cpp:65:38: 错误:“dbGoalStatus”尚未声明 QT_INIT_MetaOBJECT const QMetaObject dbGoalStatus::staticMetaObject = { { ^~~~~~~~~~~~~
/home/labrat/build-ultrasound_mapper-Desktop_Qt_5_12_2_GCC_64bit-Debug/src/ROstemplatesMsgs/ROstemplatesMsgs_autogen/WKFP3Z6SYI/moc_dbGoalStatus.cpp:75:20: 错误:“dbGoalStatus”尚未声明为 const QMetaObject *dbGoalStatus::MetaObject() const ^~~~~~~~~~~~~
/home/build-ultrasound_mapper-Desktop_Qt_5_12_2_GCC_64bit-Debug/src/ROstemplatesMsgs/ROstemplatesMsgs_autogen/WKFP3Z6SYI/moc_dbGoalStatus.cpp:75:47: 错误:非成员函数‘const QMetaObject* MetaObject()’不能 有 cv 限定符 const QMetaObject *dbGoalStatus::MetaObject() const ^~~~~
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。