【问题标题】:Makefile linking errorMakefile 链接错误
【发布时间】:2018-01-15 10:55:39
【问题描述】:

我的 Makefile:

CXX = g++
CXXFLAGS = -g -Wall -std=c++14
LDFLAGS = -lboost_system -lcrypto -lssl -lcpprest -lpthread

SRC := $(shell find . -name *.cpp)
OBJ = $(SRC:%.cpp=%.o)
BIN = run

all: $(BIN)

$(BIN): $(OBJ)
    $(CXX) $(LDFLAGS)

%.o: %.cpp
    $(CXX) -c $(CXXFLAGS) $< -o $@

clean:
    find . -name *.o -delete
    rm -f $(BIN)

它扫描所有子目录中的所有文件*.cpp文件并创建相应的*.o文件。然后它尝试将所有内容链接到最终的二进制文件中,但出现以下错误。我不知道如何解决这个问题。

/usr/lib/gcc/x86_64-pc-linux-gnu/7.2.1/../../../../lib/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'

目录结构:

Makefile
sources/
    directory1
        ...cpp
    directory2
        ...cpp
    ...
    main.cpp

main.cpp 内容:

#include <iostream>

#include <signal.h>

#include "application/application_launcher.hpp"

Alastriona::Application::Launcher launcher;

void shutdown(int signal);

int main(int argc, const char * argv[])
{
    struct sigaction sa;
    sa.sa_handler = &::shutdown;
    sa.sa_flags = SA_RESTART;
    sigfillset(&sa.sa_mask);

    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGQUIT, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);

    launcher.loadArguments(argc, argv);
    launcher.loadConfiguration();
    launcher.startApplication();
}

void shutdown(int signal)
{
    launcher.stopApplication();
}

【问题讨论】:

  • 你在某处有主函数吗?如果是这种情况,请在您的问题中包含其签名
  • @UmNyobe 我做到了。
  • int main(int argc, char * argv[]) 也许?
  • 可能偏离主题,但是......在你的find 命令中,名称模式几乎肯定应该用引号引起来——例如'*.cpp'。
  • @VTT 是的,这就是问题所在。但是有一些我无法理解:这个主要签名是 XCode 项目的直接端口,它在那里工作。不过它使用了 Clang。

标签: c++ makefile linker


【解决方案1】:
int main(int argc, const char * argv[])

由于 constness 导致过载,标准为 which is not allowed, and considered ill formed §2。您需要使用的签名是

int main(int argc, char * argv[])

编辑:您在尝试构建目标时没有使用任何先决条件。 你应该有

$(BIN): $(OBJ)
    $(CXX) $^ $(LDFLAGS)

【讨论】:

  • 但是为什么编译器一开始就允许它呢?
  • stackoverflow.com/tags/undefined-behavior/info。可能无法编译,可能编译但不链接,可能链接但产生意外结果,可能链接并产生预期结果是ub的可能场景
  • 标准不允许。该标准规定main 可以具有任何实现定义的签名,只要它返回int 并且任何实现必须 支持int main()int main(char**) 这两个签名。所以它没有被标准禁止,只是不可移植。
  • 我已经修复了主原型,但它仍然没有编译。 gist.github.com/CorellianAle/e1424bc1d16a08b4acbee17a94f4da55 很抱歉,但我仍然看不到我的错误。也许现在main.cpp 是正确的Makefile 有什么问题?
  • @Galik A program *shall* contain 是使用的术语。格式错误 - 程序有语法错误或可诊断的语义错误。需要符合标准的 C++ 编译器来发出诊断,即使它定义了为此类代码分配意义的语言扩展(例如使用可变长度数组)。标准使用的文本应、不应和格式错误地表明这些要求。 en.cppreference.com/w/cpp/language/ub
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多