【问题标题】:g++ isn't compiling all of the files in my projectg++ 没有编译我项目中的所有文件
【发布时间】:2021-05-13 11:46:00
【问题描述】:

我正在尝试在 VS Code 中构建一个 c++ 项目,但是当我尝试构建它时,g++ 会抛出一个错误:

g++ -std=c++17 -ggdb -Iinclude src/main.cpp -o bin/main 
Undefined symbols for architecture x86_64:
  "MessageBus::MessageBus()", referenced from:
      _main in main-244f95.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [bin/main] Error 1
The terminal process "/bin/zsh '-c', 'make'" terminated with exit code: 2.

以下是我认为导致问题的文件:

MessageBus.h

#pragma once
#include "../Utils/Queue.h"
#include "../Utils/SimpleList.h"
#include "Messages/Message.h"

class System;

class MessageBus
{
public:
    MessageBus();
    ~MessageBus();

    void addReciever(System* system);
    void postMessage(Message* msg);
    void notify();

private:
    Queue<Message> msgQueue;
    SimpleList<System*> systems;
};

MessageBus.cpp

#include "MessageBus.h"
#include "System.h"

MessageBus::MessageBus() {}
MessageBus::~MessageBus() {}

void MessageBus::postMessage(Message* msg) {
    msgQueue.add(msg);
}

void MessageBus::addReciever(System* system) {
    systems.add(system);
}

void MessageBus::notify() {
    int queueLength = msgQueue.getLength();
    for (int i = 0; i < queueLength; i++) {
        Message msg = msgQueue.pop();
        for (int j = 0; j < systems.getLength(); j++) {
            System* system = systems.get(j);
            system->handleMessage(&msg);
        }
    }
}

ma​​in.cpp

#include "EventSystem/MessageBus.h"

int main(int argc, char* argv[])
{
   MessageBus* msgBus = new MessageBus();
}

生成文件

CXX       := g++
CXX_FLAGS := -std=c++17 -ggdb

BIN     := bin
SRC     := src
INCLUDE := include

LIBRARIES   :=
EXECUTABLE  := main


all: $(BIN)/$(EXECUTABLE)

run: clean all
    clear
    ./$(BIN)/$(EXECUTABLE)

$(BIN)/$(EXECUTABLE): $(SRC)/*.cpp
    $(CXX) $(CXX_FLAGS) -I$(INCLUDE) $^ -o $@ $(LIBRARIES)

clean:
    -rm $(BIN)/*

但是当我尝试使用终端编译这些文件时:

g++ main.cpp EventSystem/MessageBus.cpp -o maintest

它工作得很好,所以我认为问题是我的文件没有一起编译。我认为这可能与链接器无法找到正确的文件有关,并且可能与我的项目结构有关? This is my current structure

如您所见,头文件与源代码位于一起。我应该将头文件与 cpp 文件分开还是将它们放在子目录中?还是完全是别的东西?我对 c++ 和 Makefiles 有点陌生,我似乎无法理解导致问题的原因。

编辑:

解决方案:

正如@MadScientist 所建议的,我将Makefile 中的$(SRC)/*.cpp 替换为$(shell find $(SRC) -name \*.cpp -print),从而解决了问题。但正如@WhozCraig 提到的,我可能应该切换到 cmake 以避免将来使用 Makefile。

【问题讨论】:

  • 请在您的问题中显示调用的链接命令。这是我们需要看到的最关键的事情,而你没有展示出来。
  • 或者使用 cmake 并停止使用 makefile 杀死自己。不要误会我的意思;学习 makefile 是一项巨大的资产;随着更现代的项目管理工具的出现,它也越来越少被使用。
  • 停止使用 Makefiles? CMake 的结果是什么?生成文件

标签: c++ visual-studio-code makefile g++ linker-errors


【解决方案1】:

您将“工作”命令列为:

g++ main.cpp EventSystem/MessageBus.cpp -o maintest

但你的食谱是:

$(BIN)/$(EXECUTABLE): $(SRC)/*.cpp

glob 表达式 $(SRC)/*.cpp 与文件 main.cpp 不匹配。

如果我们能看到您的链接行,我们可能会发现main.cpp 不见了。

【讨论】:

  • 那么我应该更改 glob 表达式吗?我虽然 $(SRC)/*.cpp 将包含 src 目录中的所有源文件。我应该把它改成什么?
  • 它将包含src目录中的所有源文件。但是在您的示例链接行中,main.cppsrc 目录中是 NOT 的。如果这是真的,那是你的问题。如果只是您的示例中的拼写错误,那么请注意示例并使用所有命令行、错误等的剪切和粘贴,而不是手动重新输入。
  • 另外,您的其他文件在目录EventSystem 中,而不是在目录src 中。所以这也不匹配。
  • 哦,我想我明白了。您的目录结构是src/EventSystem,并且您有文件src/main.cppsrc/EventSystem/MessageBus.cpp,并且您的示例链接行是从src 目录中调用的。所以,这真的完全不同。
  • glob 行src/*.cpp 将匹配src 目录中的所有.cpp 文件。如果您从 shell 提示符运行 ls src/*.cpp,它与打印的文件完全相同。它不会匹配src 目录的所有子目录中的所有源文件。为此,您需要使用$(SRC)/*/*.cpp 或者您需要使用类似$(shell find $(SRC) -name \*.cpp -print)
猜你喜欢
  • 2019-08-15
  • 2018-02-02
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-21
  • 2015-01-16
相关资源
最近更新 更多