首先,我应该说一下gcc和makefile是一个新手。
在我最近开始使用的Ubuntu机器上,我发现在运行gcc时,我放置源文件和库/头文件的顺序有所不同。在另一台我可以做的机器上:
gcc -I../include -L../lib myProgram.c -o myProgram
但是在新机器上,这不会链接库,我必须这样做:
gcc myProgram.c -o myProgram -I../include -L../lib
现在,我有以下makefile:
SHELL = /bin/sh
CC = gcc -O3
CFLAGS = -I../include
LDFLAGS = -L../lib
PROGS = myProgram
all: $(PROGS)
$(all): $(PROGS).o
$(CC) -o $@ $@.o $(LIBS) $(CFLAGS) $(LDFLAGS)
rm -f $@.o
clean:
rm -f *.o $(PROGS)
但是当我执行“make”时,它运行的实际gcc命令会使库和源文件的顺序错误。我的问题是:我需要在makefile中做什么来强制“-L ../ libs”选项出现在源文件之后,以便库能够正确链接?
我也试过包含“-Wl, - no-as-needed”选项,因为我认为--as-needed标志可能是该命令首先起作用的原因,但是这个似乎没有改变任何东西(即它仍然无法链接库,除非“-L ../ libs”出现在源文件之后)。
答案 0 :(得分:1)
问题是你以为你在使用那个规则,但你不是。您从未定义过名为all
的变量,因此第二条规则的目标实际上已扩展为 nothing 。当您命令Make构建myProgram
时,Make在此makefile中找不到合适的规则。 Make有一个implicit rules的工具箱,在这种情况下它可以依赖;它想要构建myProgram
,它看到了一个名为myProgram.c
的文件,其中一个规则看起来像这样:
%: %.c
$(CC) $(LDFLAGS) $^ -o $@
你有源代码之前的链接器标志。
您可以编写自己的模式规则,而Make将使用:
%: %.o
$(CC) -o $@ $^ $(LIBS) $(CFLAGS) $(LDFLAGS)
(请注意,这会从myProgram
构建myProgram.o
,并让我们弄清楚如何构建myProgram.o
。)
如果要从多个目标文件构建可执行文件,请添加如下规则:
myProgram: other.o yetAnother.o
如果你愿意,你可以再制定一条规则(第一条)告诉Make你想要建造什么:
all: myProgram myOtherProgram friendsProgram
(最后一点:我们都有紧张的工作截止日期。一次寻求帮助比学习工具更快,但学习工具比寻求帮助N次要快。确定N的价值是由你决定。)