c++ - Linux C++ 对 main 进行 undefined reference

标签 c++ linux makefile

我正在开发一个 C++ 项目,以便让自己重新熟悉一下该语言,但在使用 make 构建时遇到了一个(对我来说)相当奇怪的问题。

我的项目设置如下结构:

 bin/
 include/
 src/
 Makefile
 build.sh

I'n src 我当前有 2 个文件,loggerConfig.cpp 和 proxy.cpp。主要方法位于 proxy.cpp 中。我的 Makefile 包含以下内容,取自 this post :

CC := g++
SRCDIR := src
BUILDDIR := build
TARGET := bin/proxy

SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -iname *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))

LINKFLAGS = -pthread -std=c++11
CFLAGS := -g -Wall -pedantic -std=c++11 -pthread
LIB := -lconfig++
INC := -I include


$(TARGET): $(OBJECTS)
    @echo " Linking..."
    @echo " $(CC) $^ -o $(TARGET) $(LIB)"; $(CC) $^ -o $(TARGET) $(LIB) $(LINKFLAGS)

$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
    @echo " Building..."
    @mkdir -p $(BUILDDIR)
    @echo " $(CC) $(CFLAGS) $(INC) -c -o $@ $<"; $(CC) $(CFLAGS) $(INC) -c -o $@ $<

clean:
    @echo " Cleaning..."; 
    @echo " $(RM) -r $(BUILDDIR) $(TARGET)"; $(RM) -r $(BUILDDIR) $(TARGET)

..PHONY: clean

除非我的 Makefile 所在目录中有一个 .cpp 文件,否则一切都会按预期工作。因为我目前正在玩游戏,所以在将某些内容放入项目之前,我将在 test.cpp 文件中创建一个小型独立应用程序。当我这样做并切换回使用 make 时,我会收到以下错误:

$ make clean ; make
 Cleaning...
 rm -f -r build bin/proxy
 Linking...
 g++  -o bin/proxy -lconfig++
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [bin/proxy] Error 1

只需将 test.cpp 文件移到一个目录即可解决问题并全部编译。谁能解释为什么?我对 make 的理解相当简单,所以我不知道 Google 的目的是什么......

[编辑]

直接在 shell 中运行 SOURCES 列表的 find 命令后,我发现当 test.cpp 文件存在时,它不会返回任何结果。

$ ls
bin  build.sh  include  log  Makefile  src  test.cpp
$ find src -type f -iname *.cpp
$ mv test.cpp ../
$ find src -type f -iname *.cpp
src/proxy.cpp
src/loggerConfig.cpp

最佳答案

这是一个非常奇特的 Makefile,您可能会因为它过于复杂而给自己带来麻烦。

我会写得更像下面这样:

TARGET=bin/proxy
SOURCES=loggerConfig proxy

$(TARGET): $(SOURCES:%=build/%.o)
    @echo " Linking..."
    $(CC) $^ -o $(TARGET) $(LIB) $(LINKFLAGS)

build/%.o: src/%.cpp
    @echo " Building..."
    test -d build || mkdir -p build
    $(CC) $(CFLAGS) $(INC) -c -o $@ $<

也许我只是有点老派,但是玩带有花哨的变量替换的游戏很有趣,直到有人受伤,当我屈服于那里的诱惑时,我通常会在事后后悔,并简化 Makefile。

特别是,这里有两个进一步的观察结果。

源集似乎不太可能如此非常动态,以至于值得动态生成SOURCES变量。添加文件时,无需将名称添加到 Makefile 中,并且由于如果不这样做,程序将无法构建,因此不存在忘记的危险。

@echo foo 栏; foo bar 模式肯定只是自找麻烦!在某些时候,您必须调整 foo bar 的一个部分而不调整另一个部分,并且您会变得非常感到困惑。 Make 会回显它执行的行,除非您使用 @ 前缀来停止它,因此您似乎是通过迂回路线综合了默认行为。

关于c++ - Linux C++ 对 main 进行 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32648362/

相关文章:

c++ - 如何使用 QTextEdit 模拟类似 shell 的脚本环境?

c++ - 如何在 C++ 中打印出 BST

linux - 如何在 (arch) linux 中删除 dkms 模块?

php - UTF-8贯穿始终

Android makefile 链接两次

c - 学习makefile

c++ - QQuickView 新删除类型不匹配

c++ - 可以在字符串上使用 htonl

linux - 如何在不离开当前 shell 的情况下在当前 shell 中间脚本中设置 sudo?

c - 未定义对 `yylval' 和 `yyerror` 的引用