好的,我正在尝试构建一个 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/