如何解决使用来自不同头文件C ++和CMake的类和函数
我正在波恩大学学习现代C ++。
我已经在grass.h
文件中声明了一个类,并在相应的grass.cpp
文件中声明了其实现。类似地,在另一个tools.h
-tools.cpp
声明实现对中,是一个函数,该函数接受对上面定义的类对象的引用。最后,main.cpp
文件初始化了第一对中的Grass对象,并将其从第二对中传递给函数。我能够编译main.cpp
并从这些命令行指令中获得所需的输出:
c++ -std=c++11 -g -c grass.cpp -o grass.o
c++ -std=c++11 -g -c tools.cpp -o tools.o
c++ -std=c++11 -g main.cpp grass.o tools.o -o main
,但是无法使用CMake做到。我不知道命令行指令的名称(链接和编译?)。
这是代码示例“ grass.h”:
#include <string>
#pragma once
class Grass
{
private:
int green_;
std::string name_;
public:
Grass(int green,std::string name): green_{green},name_{name} {}
int get_green() const; // getter functions for
const std::string& get_green_name() const; // both private members
};
这些函数仅返回值,并在“ grass.cpp”中实现。
然后我有一个“ tools.h”:
#include <iostream>
#include "grass.h"
#pragma once
void PrintGrass(Grass& grObj);
此函数仅打印Grass的getter函数中的值。
最后,main.cpp包含:
int main ()
{
Grass grObj{10,"ABC"};
PrintGrass(grObj);
cout << endl;
return 0;
}
CMake错误发生在100%链接CXX可执行主文件上。错误在tools.cpp中:
undefined reference to `Grass::get_green_name[abi:cxx11]()'
和
undefined reference to `Grass::get_green()'
。
这意味着程序无法找到这些功能的定义,对吧? CMake文件如下所示:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "-Wall")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
add_library(grass grass.cpp)
add_library(tools tools.cpp)
add_executable(main main.cpp)
target_link_libraries(main grass tools)
我该如何使用CMake?非常感谢您的帮助。
解决方法
我也通过将包含文件也添加到add_library中来解决了类似的问题:
add_library(草grass.cpp grass.h)
尝试一下,看看是否有效
,我将总结注释部分,并根据@pptaszni的建议将整个代码和详细错误放在此处:
完整代码(依依顺序):
-
grass.h
和grass.cpp
:
#include <string>
#pragma once
class Grass
{
public:
Grass(int green,std::string name): green_{green},name_{name} {}
int get_green ();
std::string get_green_name ();
private:
int green_ = 100;
std::string name_ = "Joe";
};
和
#include "grass.h"
Grass::Grass(int green,name_{name}{}
int Grass::get_green() {
return green_;
}
std::string Grass::get_green_name() {
return name_;
}
-
tools.h
和tools.cpp
:
#include <iostream>
#include "grass.h"
#pragma once
void PrintGrass(Grass& grObj);
和
#include <iostream>
#include "grass.h"
#include "tools.h"
void PrintGrass(Grass& grObj)
{
std::cout << grObj.get_green_name() << "," << grObj.get_green() << " ";
}
-
main.cpp
#include <iostream>
#include "grass.h"
#include "tools.h"
#include <string>
using std::string;
using std::cout;
using std::endl;
int main ()
{
Grass grObj{10,"Jane"};
PrintGrass(grObj);
cout << endl;
return 0;
}
-
CMakeLists.txt
project(Grasses)
cmake_minimum_required(VERSION 3.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "-Wall")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
add_library(grass grass.cpp)
add_library(tools tools.cpp)
add_executable(main main.cpp)
target_link_libraries(main grass tools)
make VERBOSE=1
的错误output为详细,已粘贴到Github Gist中,以使该帖子的长度不超过其已有时间。
摘要
什么有效?写作
target_link_libraries(main tools grass)
代替
target_link_libraries(main grass tools).
@Yksisarvinen给出的解释中要带走的信息是,始终在最后放置没有任何依赖关系的库。这是因为,如果编译器在处理它们时没有发现任何用途,则可能会查看这些库并将其丢弃。
另一种可行的方法是仅使用add_executable(main main.cpp grass.cpp tools.cpp)
而不添加库,然后再链接它们。这是@molbdnilo和@Yksisarvinen提出的。
谢谢大家帮助我更好地理解C ++。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。