【问题标题】:Getting undefined symbols for architecture arm64 error获取架构 arm64 错误的未定义符号
【发布时间】:2021-12-28 21:04:04
【问题描述】:

我在 M1 Pro Mac (CLion) 上构建,编译时出现以下错误:

FAILED: tree 
: && /Library/Developer/CommandLineTools/usr/bin/c++ -g -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX12.0.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/tree.dir/main.cpp.o CMakeFiles/tree.dir/Node.cpp.o CMakeFiles/tree.dir/Tree.cpp.o CMakeFiles/tree.dir/Unit.cpp.o -o tree   && :
Undefined symbols for architecture arm64:
  "Node<Unit>::addRoot(Unit)", referenced from:
      _main in main.cpp.o
  "Node<Unit>::Node()", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

我有三个班级,Node、Tree 和 Unit。我遇到的大多数帖子都表明其中一个文件不包含在项目中(例如Undefined symbols for architecture arm64 using g++ compiler)。我怀疑这是问题所在,因为它们似乎都包含在编译器行中。

我的CMakeLists.txt 看起来像这样:

cmake_minimum_required(VERSION 3.21)
project(tree)

set(CMAKE_CXX_STANDARD 14)

add_executable(tree main.cpp Node.cpp Node.h Tree.cpp Tree.h Unit.cpp Unit.h)

我正在为Unit 类添加头文件,因为这似乎是冒犯编译器的那个,但是我怀疑这就是问题所在。猜是一些make文件设置?


#include <iostream>
#include <vector>

using namespace std;

template <class T>
class Node {
    weak_ptr<Node> parent;
    vector<shared_ptr<shared_ptr<Node>>> children;
    T data;

public:
    Node();
    Node(weak_ptr<Node> parent, T &data);

    void addRoot(T node_data);
};

这篇文章可能过于冗长,这里是CMakeError.log 输出:

Compiling the C compiler identification source file "CMakeCCompilerId.c" failed.
Compiler: /Library/Developer/CommandLineTools/usr/bin/cc 
Build flags: 
Id flags:  

The output was:
1
ld: library not found for -lSystem
clang: error: linker command failed with exit code 1 (use -v to see invocation)


Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" failed.
Compiler: /Library/Developer/CommandLineTools/usr/bin/c++ 
Build flags: 
Id flags:  

The output was:
1
ld: library not found for -lc++
clang: error: linker command failed with exit code 1 (use -v to see invocation)

如果我运行c++ main.cpp Node.cpp Tree.cpp Unit.cpp,则输出:

In file included from main.cpp:3:
./Node.h:16:38: error: a space is required between consecutive right angle brackets (use '> >')
    vector<shared_ptr<shared_ptr<Node>>> children;
                                     ^~
                                     > > 
main.cpp:7:5: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
    auto unit = std::make_unique<Unit>(1, "Test Unit");
    ^
main.cpp:7:22: error: no member named 'make_unique' in namespace 'std'
    auto unit = std::make_unique<Unit>(1, "Test Unit");
                ~~~~~^
main.cpp:7:34: error: 'Unit' does not refer to a value
    auto unit = std::make_unique<Unit>(1, "Test Unit");
                                 ^
./Unit.h:11:7: note: declared here
class Unit {
      ^
main.cpp:7:40: warning: expression result unused [-Wunused-value]
    auto unit = std::make_unique<Unit>(1, "Test Unit");
                                       ^
main.cpp:8:20: error: expected ';' at end of declaration
    Node<Unit> node {};
                   ^
                   ;
2 warnings and 4 errors generated.
In file included from Node.cpp:5:
./Node.h:16:38: error: a space is required between consecutive right angle brackets (use '> >')
    vector<shared_ptr<shared_ptr<Node>>> children;
                                     ^~
                                     > > 
1 error generated.

我是 C++ 的新手,所以我发现这个问题有点难以追踪。

【问题讨论】:

  • 尝试手工编译。只需c++ main.cpp Node.cpp Tree.cpp Unit.cpp 告诉我会发生什么。
  • 我什至会说一个 xtools 问题。你能编译一个简单的 hello world 示例吗?
  • @wobr,是的,如果我在main.cpp 中删除对Unit 构造函数的调用,所有编译都会很好。
  • 哦,当然你必须在命令行中添加-std=c++14。如果你回到 cmake,你可以在调试模式下运行 make VERBOSE=1 来查看命令行。
  • 你在哪里定义 Node::Node() ?如果类是模板化的,您必须 (1) 在头文件中包含模板化代码的实现,或者 (2) 在正文 (cpp) 文件中明确专门化具体模板类。

标签: c++ templates linker-errors


【解决方案1】:

您的模板似乎有问题。在模板类中,您必须将方法的实现全部放在头文件中,或者在定义它的 cpp 主体中对具体类进行显式模板实例化。

举个例子更容易理解。在以下情况下,我将在标题中添加构造函数的主体,因此我不必做任何其他事情


/////////////////////////////////////////
// In Node.h
/////////////////////////////////////////
template< typename T >
struct Node {
    Node();
};

template< typename T >
Node<T>::Node() {
}

/////////////////////////////////////////
// In Node.cpp
/////////////////////////////////////////
// (nothing)

/////////////////////////////////////////
// Int main.cpp
/////////////////////////////////////////
#include "Node.h"
int main() {
   Node<int> n;
}

在第二种情况下,我将在 Node.cpp 的主体中对具体类 Node&lt;int&gt; 进行显式模板实例化,这样我就不需要公开模板类的实现。

/////////////////////////////////////////
// In Node.h
/////////////////////////////////////////
template< typename T >
struct Node {
    Node();
};

/////////////////////////////////////////
// In Node.cpp
/////////////////////////////////////////

template< typename T >
Node<T>::Node() {}

// Explicit initialization 
template struct Node<int>;

/////////////////////////////////////////
// Int main.cpp
/////////////////////////////////////////
#include "Node.h"
int main() {
   Node<int> n;
}

我更喜欢使用第二种方法,因为它显着降低了构建时间。

【讨论】:

  • 是的,就是这样。太棒了。
猜你喜欢
  • 2015-11-18
  • 2014-01-22
  • 2016-09-08
  • 2013-10-13
  • 1970-01-01
  • 2021-12-31
相关资源
最近更新 更多