【发布时间】:2021-06-14 18:20:46
【问题描述】:
我在编译项目时遇到了一点麻烦,使用Conan.io 和CMake。
我正在构建一个基于 OpenGL 的小型项目。我使用 MVC 架构。我希望 CMake 产生两个不同的 .exe :
-
main.exe是一个带有简单 OpenGL 上下文的小 GLFW 窗口。它使用 conan.io 来管理所使用的库,运行良好。 -
pentest.exe是一个简单的测试可执行文件,我想用它来测试我模型中的一些基本功能。当我调用make命令时,这个不会被编译。
这是我简化的项目架构:
├───build
│ ├───.cmake
│ │
│ ├───bin
│ │ └─── // .exe files are here
│ │
│ ├───CMakeFiles
│ │ └─── // Cmake files are here
│ │
│ └─── // ...
│
├───include
│ ├───GL
│ │ └─── GLU.h
│ │
│ └───model
│ ├───Block.hpp
│ └───GameGrid.hpp
│
├───src
│ ├───model
│ │ ├───Block.hpp
│ │ └───GameGrid.hpp
│ │
│ ├───main.cpp
│ └───pentest.cpp
│
├───CMakeLists.txt
└───conanfile.txt
请注意:
-
pentest.cpp不依赖任何外部库。 - 尽管我的
GameGrid类是一个模板类,但我还是让标题在末尾包含了实现文件(在this StackOverflow question 之后)。 - 我对 CMake 非常非常不满意。
- CMake 命令运行良好,当
make命令为pentest.exe调用链接器 时出现错误。
这是我的CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.12)
project(TheEndless)
add_definitions("-std=c++17")
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
include_directories(
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/model
)
link_directories(${CMAKE_SOURCE_DIR}/lib)
add_executable(main src/main.cpp)
add_executable(pentest src/pentest.cpp)
target_link_libraries(main ${CONAN_LIBS})
target_link_libraries(pentest ${CONAN_LIBS})
这是我的pentest.cpp:
#include <iostream>
#include <string>
#include "model/Block.hpp"
#include "model/GameGrid.hpp"
int main(int argc, char const *argv[]) {
theendless::model::Block b;
theendless::model::GameGrid<1, 1> g;
g(0, 0) = b;
std::string s(g(0, 0).get_name());
std::cout << s << std::endl;
return 0;
}
这是我的model/Block.hpp:
#ifndef THEENDLESS_MODEL_BLOCK_HPP
#define THEENDLESS_MODEL_BLOCK_HPP
#include <string>
namespace theendless::model {
class Block {
private:
std::string name;
public:
Block();
Block(std::string name);
std::string get_name() const;
void set_name(const std::string newName);
};
}
#endif
这是我的model/Block.cpp:
#include "model/Block.hpp"
#include <string>
namespace theendless::model {
Block::Block() : name("default_name") {}
Block::Block(std::string name) : name(name) {}
std::string Block::get_name() const { return this->name; }
void Block::set_name(const std::string newName) { this->name = newName; }
}
这是make 显示的错误:
PS C:\projects\TheEndless\build> make
Scanning dependencies of target pentest
[ 75%] Building CXX object CMakeFiles/pentest.dir/src/pentest.cpp.obj
[100%] Linking CXX executable bin/pentest.exe
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/pentest.dir/objects.a(pentest.cpp.obj): in function `main':
C:/projects/TheEndless/src/pentest.cpp:9: undefined reference to `theendless::model::Block::Block()'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/projects/TheEndless/src/pentest.cpp:13: undefined reference to `theendless::model::Block::get_name[abi:cxx1c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/pentest.dir/objects.a(pentest.cpp.obj): in function `std::array<theendless::model::Block, 1ull>::array()':
c:/mingw/include/c++/9.2.0/array:94: undefined reference to `theendless::model::Block::Block()'
collect2.exe: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/pentest.dir/build.make:107: bin/pentest.exe] Error 1
make[1]: *** [CMakeFiles/Makefile2:124: CMakeFiles/pentest.dir/all] Error 2
make: *** [Makefile:103: all] Error 2
请注意,将model/Block.cpp 包含到pentest.cpp 会使问题消失,但我有点想让项目变得干净,所以我不想这样做。
其他信息:
- 我使用的是 Windows 10。
- 我正在使用VSCode 编辑我的文件,并通过在集成的*PowerShell 终端中键入
make进行编译。 - 我正在使用Mingw distro 进行编译。
任何帮助将不胜感激! :)
【问题讨论】:
-
我自己不是 CMake 英雄,但编译器似乎连 Block 都没有编译。您是否尝试将 Block.cpp 添加到 CMakeLists.txt 中的 add_executable 中?
-
@TobiasBrösamle 我刚刚做了,但它告诉我有一个
undefined reference to 'WinMain'。我的看法是,这是因为它试图创建一个 'block.exe' 文件,但由于 'Block.cpp' 没有任何主要功能而失败 -
你能具体说明你做了什么吗?您是将其添加到现有的 add_executable 语句中还是创建了一个新语句?
-
在我的情况下,如果我将 .cpp 文件添加到 add_executable(pentest ...),它就可以工作。在这种情况下,将创建一个包含 .cpp 文件的 visualstudio 解决方案(我现在在 Windows 上)。如果您还希望解决方案中的 .hpp 文件,也必须添加它们。
-
所以,我首先添加了一个新的
add_executable(block src/model/block.cpp)语句。它没有用。然后,我刚刚阅读了您的评论并将src/model/block.cpp添加到现有的 pentest 评论中。它仍然停止链接,告诉我有多个定义到我的Block::Block()(以及其他与我的Block类相关的)方法。
标签: c++ cmake include mingw undefined-reference