c++ - Makefile 有两次看不到 main.o

标签 c++ macos build makefile clang++

好的,我正在尝试构建一个 makefile,以便在不同的环境中编译程序。在 Linux (Mint) 上它工作得很好,但在 Mac OS 下我得到这个错误:

Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [build] Error 1

使用“-v”:

Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
 "/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.9.0 -w -o bin/Darwin/main ./cfprintf.o ./file.o ./inputmanager.o ./neditfile.o ./neditmanager.o ./neditscreen.o ./n_string.o ./sys_booter.o ./sys_display.o ./sys_manager.o ./sys_screen.o -lc++ -lSystem /Library/Developer/CommandLineTools/usr/bin/../lib/clang/5.1/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [build] Error 1

现在是生成文件:

CC = clang++
LIB = 
INC = -I src/
OPTIONS = -w

OBJS = $(shell find ./src/obj -name '*.cpp')
IO = $(shell find ./src/io -name '*.cpp')
SYS = $(shell find ./src/sys -name '*.cpp')
APPS = $(shell find ./src/apps -name '*.cpp')

EXEC = bin/$(shell uname)/main

.PHONY: dummy build all objects io sys apps incBC clear run

build: clear incBC objects io sys apps
    @echo "-> Compiling main... "
    @$(CC) -c src/main.cpp $(INC) $(OPTIONS)
    @echo "-> Building environment... "
    @$(CC) $(shell find . -name '*.o') $(LIB) $(OPTIONS) -o $(EXEC) -v
    @echo "-> Removing all objects file from compilation... "
    @rm *.o

objects:
    @echo "-> Building objects files and classes... "
    @$(CC) -c $(OBJS) $(INC) $(OPTIONS)

io:
    @echo "-> Building input/output files and classes..."
    @$(CC) -c $(IO) $(INC) $(OPTIONS)

sys:
    @echo "-> Building system files and classes..."
    @$(CC) -c $(SYS) $(INC) $(OPTIONS)

apps:
    @echo "-> Building all apps files and classes..."
    @$(CC) -c $(APPS) $(INC) $(OPTIONS)

incBC:
    @echo "-> Updated build count..."
    @./incBC.sh

clear:
    clear

run:
    cd bin/$(shell uname)/ && clear && ./main

现在(至少对我而言)真正奇怪的是,当我键入 make 时,它有两分之一的失败......实际上是二分之一!当它确实失败时,我会收到上面的错误消息。我从该消息中注意到,在 ld 命令中,没有 main.o,这可能是我得到 undefined reference 的原因。我的问题是:为什么?为什么特别是两次中的一次,我该如何解决这个问题?

最佳答案

这是一个奇怪的生成文件。为什么不直接写一个 shell 脚本呢?这个 makefile 中没有任何东西可以利用 make 本身的任何优势:它每次都会重建所有内容。编写 makefile 而不是 shell 脚本的目的是避免重建未更改的对象。

无论如何,您看到失败的原因是您正在使用 make 的 $(shell ...) 函数 inside 。这不是必需的,因为配方已经在 shell 中运行。这对您来说失败的原因是 make 将展开整个食谱(所有行)首先,然后再开始您的食谱(显然必须这样做)。这意味着因为您正在使用 $(shell ...) find 命令在配方运行之前运行,并且在配方运行之前您还没有编译您的main.o,因此 find 命令不会将其包含在找到的目标文件列表中。然后在您下次运行它时,main.o 存在于上一次运行中,因此 find 命令会找到它。

改变这一行:

@$(CC) $(shell find . -name '*.o') $(LIB) $(OPTIONS) -o $(EXEC) -v

为此:

@$(CC) `find . -name '*.o'` $(LIB) $(OPTIONS) -o $(EXEC) -v

它会起作用。

虽然它作为 makefile 仍然不是很有用。

关于c++ - Makefile 有两次看不到 main.o,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24454642/

相关文章:

c++ - 将元组分配给类成员变量

c++ - 大图像的 CUDA 内存分配问题

java - 我应该使用哪种键值数据结构?按值快速检索,按键快速检索

objective-c - Launch Daemon 可以运行哪些类型的文件?

ios - 从终端在模拟器中安装内置的 iOS 应用程序?

c++ - 与 std::vector 的元素进行组合

java - Android Studio - 找不到tools.jar。请检查 X 是否包含有效的 JDK 安装

java - 尝试运行使用 subversion 共享的 netbeans 项目时生成错误

android - 如何将 Kivy 应用部署到 Google 应用商店?

macos - 沙盒不允许在终端中打开文档