如何使 cmakelists.txt 编译使用在其他地方声明和实现的函数和类的 cpp
Posted
技术标签:
【中文标题】如何使 cmakelists.txt 编译使用在其他地方声明和实现的函数和类的 cpp【英文标题】:how to make cmakelists.txt compile cpp that uses functions and classes declared and implemented in some other place 【发布时间】:2019-12-17 14:21:29 【问题描述】:我在 2 个头文件中定义了一些函数类,并在某个文件夹的 cpp 文件中实现。我将它们用于位于同一目录中的一些 cpp 程序(我们称之为 cpp1.cpp)。我们称之为 dir1。
现在我的问题是: 我在 dir1 的同一级别上有另一个 dir2 有它自己的 CMakeLists.txt 我正在尝试在其中编译另一个 cpp 文件(让我们称它为 cpp2.cpp) 位于 dir2。这个新的 cpp 使用或者应该使用在 dir1 头文件和 cpp 文件中声明和定义的一些函数和类。 在我的 cpp2.cpp 中,我正在做:
#include "header1_from_dir1.h"
#include "header2_from_dir1.h"
这给了我这个错误: 错误:“func_name”未在此范围内声明 func_name(param1) ^~~~~~~~~~~~~~~
当我尝试将它包含在相对路径中时,它可以编译并正常工作:
#include "../dir1/header1_from_dir1.h"
#include "../dir1/header2_from_dir1.h"
为什么会这样?如何修改 CMakelists.txt 以正确“查看”在 dir1 中定义的函数?
简而言之,在 CMakeLists 中:
include_directories(../dir1)
add_executable(cpp2 cpp2.cpp ../dir1/cpp_header1.cpp ../dir1/cpp_header2.cpp)
target_include_directories(cpp2 PUBLIC ./dir1)
target_link_libraries(some_library_from_another_place)
install(TARGETS cpp2 DESTINATION $CMAKE_SOURCE_DIR/bin/$TARGET_LOCATION)
目录结构:
.
|-- dir1
| |-- bin
| |-- build
| |-- header1_from_dir1.h
| |-- header2_from_dir1.h
| |-- cpp_header1.cpp
| |-- cpp_header1.cpp
| |-- cpp1.cpp // this uses functions and clases from above files
| `-- CMakeLists.txt // this is for above cpp1.cpp
|-- dir2
| |-- bin
| |-- build
| |-- cpp2.cpp // this uses functions and clases from
// dir1/cpp_header1.cpp
| `-- CMakeLists.txt // this is for above cpp2.cpp and have briefly
// described its contents
【问题讨论】:
target_include_directories(cpp2 PUBLIC ./dir1)
- 你不是说要target_include_directories(cpp2 PUBLIC ../dir1)
还是更好的target_include_directories(cpp2 PUBLIC $CMAKE_CURRENT_SOURCE_DIR/../dir1)
我会说 ../dir1 是正确的,因为我有一个用于编译/构建的脚本,并且我尝试使用 $CMAKE_CURRENT_SOURCE_DIR/../dir1 并显示相同的错误消息
你的目录/文件结构是什么?你能展示/画出来吗? dir1
在哪里(或者有两个dir1
?) Trytarget_include_directories(cpp2 PUBLIC $CMAKE_CURRENT_SOURCE_DIR/dir1)
这个 CMakeLists.txt 在哪里?是在 dir1 里面还是在 dir2 里面还是在 root 里面?
你为什么要给*include_directories()
打两次电话?在本例中,这些调用是多余的。
@squareskittles 是的,您是对的,尽管删除并不能解决主要问题。我应该说我在 cmake 使用艺术方面并不像您可能已经看到的那样先进。
【参考方案1】:
来自target_include_directories 文档:
INSTALL_INTERFACE 表达式中允许使用相对路径,并且相对于安装前缀进行解释。
所以相对路径不是你想要的。您需要为其指定绝对路径才能正确解释以进行编译。使用CMAKE_CURRENT_SOURCE_DIR
指定当前源目录的相对路径。
【讨论】:
我已经切换到使用CMAKE_CURRENT_SOURCE_DIR,但结果是一样的。消息调用显示了任何一种使用方式的正确路径。另一方面,从 include_directories 中删除所需的文件确实会打印出我找不到包含的头文件,正如预期的那样。我看到的错误我只是将其解释为它找不到具有该功能的对象...这听起来对吗?it could not find the object that has the function
- 你没有来源cpp1.cpp
,检查目标文件。老实说,你为什么不从 dir1 链接库?我只想 target_link_libraries(cpp2 PUBLIC cpp1)
假设 dir1/CMakeLists.txt
以与 dir2 中类似的方式执行 add_library(cpp1)
..【参考方案2】:
如何修改 CMakelists.txt 以正确“查看”dir1 中定义的函数?
您可以通过以下方式修改项目:
项目结构:
┣ ?dir1
┃ ┣ ?test.cpp
┃ ┗ ?test.h
┣ ?dir2
┃ ┣ ?CMakeLists.txt
┃ ┗ ?cpp2.cpp
┗ ?CMakeLists.txt
根
CMakeLists.txt:
project(test)
add_subdirectory(dir2)
目录1
测试.h
#pragma once
void hello();
test.cpp
#include "test.h"
#include <iostream>
void hello()
std::cout << "hello" << std::endl;
目录2
CMakeLists.txt:
add_executable(cpp2)
target_sources(cpp2 PRIVATE cpp2.cpp $CMAKE_CURRENT_SOURCE_DIR/../dir1/test.cpp)
target_include_directories(cpp2 PRIVATE $CMAKE_CURRENT_SOURCE_DIR/../dir1)
cpp2.cpp:
#include <test.h>
int main()
hello();
更好的方法是从dir1
创建一个库,将其导出,然后导入dir2/CMakeLists.txt
。
希望这会有所帮助。
【讨论】:
不幸的是,我不得不将 CmakeLists.txt 保留在 dir1 和 dir2 中,因为它们都在构建不同的应用程序。这是一个更大的项目的一部分。我也在想创建一个库会是更好的方法 您可以将文件保存在两个目录中。只是为了确保将dir2/CMakeLists.txt
中的新目标cpp2
添加到现有目标。
是的,我将新目标添加为: add_executable(cpp2 cpp2.cpp ../dir1/cpp_header1.cpp ../dir1/cpp_header2.cpp) 那个命令 target_sources 是什么?我似乎很难在 cmake doc 网站上找到它。
cmake.org/cmake/help/latest/command/target_sources.html以上是关于如何使 cmakelists.txt 编译使用在其他地方声明和实现的函数和类的 cpp的主要内容,如果未能解决你的问题,请参考以下文章
如何将 NSIS 的 RequestExecutionLevel 选项添加到 CMakeLists.txt