简体   繁体   English

GNU Makefile-多个目标的通用Makefile

[英]GNU Makefile - Generic Makefile for several targets

I am currently developing a little C++ package with small code examples for teaching purposes. 我目前正在开发一个带有小代码示例的C ++软件包,用于教学目的。 I managed to write a Makefile like the following that will compile all *.cpp files to *.o files an link them to executables: 我设法编写了一个如下所示的Makefile,它将所有* .cpp文件编译为* .o文件,并将它们链接到可执行文件:

CC=gcc
CFLAGS=-g
LDFLAGS= -lstdc++
ECHO = echo
SILENT = @

MODULES = example1 example2 example3

all: $(MODULES)

#a generic rule to create .o files from .cpp files (e.g. example1.cpp -> example1.o)
%.o: %.cpp
    $(SILENT) $(ECHO) "--- Compiling $< ---"
    $(SILENT) $(CC) -c $(CFLAGS) $<

#define targets and their dependencies
example1: example1.o
    $(SILENT) $(ECHO) "--- Linking $@ ---"
    $(SILENT) $(CC) $^ -o $@ $(LDFLAGS)

example2: example2.o
    $(SILENT) $(ECHO) "--- Linking $@ ---"
    $(SILENT) $(CC) $^ -o $@ $(LDFLAGS)

example3: example3.o
    $(SILENT) $(ECHO) "--- Linking $@ ---"
    $(SILENT) $(CC) $^ -o $@ $(LDFLAGS)

clean:
    $(SILENT) $(ECHO) "--- Removing object files and binaries ---"
    $(SILENT) rm -f *.o 
    $(SILENT) rm -f $(MODULES)

.PHONY: clean

So far so good, this works well. 到目前为止,一切正常。 It will take example1.cpp, example2.cpp and example3.cpp and compile / link it to 3 executables "example1 example2 example3". 它将使用example1.cpp,example2.cpp和example3.cpp,并将其编译/链接到3个可执行文件“ example1 example2 example3”。

But since every executable has the same name as the object (eg "example1.o" will be linked to executable "example1"), I wonder if there is a way to use a generic rule as well. 但是,由于每个可执行文件都具有与对象相同的名称(例如,“ example1.o”将链接到可执行文件“ example1”),所以我想知道是否还有一种使用通用规则的方法。

I tried several things like: 我尝试了几种方法:

%: %.o
    $(SILENT) $(ECHO) "--- Linking $@ ---"
    $(SILENT) $(CC) $^ -o $@ $(LDFLAGS)

From my understanding, this rule should take all object files and create an executable with the same name as the object file, but I could not get it working! 据我了解,该规则应采用所有目标文件并创建一个与目标文件同名的可执行文件,但我无法使其正常运行! Does anyone have a hint how to achieve this? 有没有人暗示如何实现这一目标?

The problem is that there's a built-in rule for building a program directly from a source file. 问题在于,存在一个直接从源文件构建程序的内置规则。 Make will choose that, rather than chaining your two rules. Make将选择该选项,而不是链接两个规则。

You could cancel the rule by overriding it with an empty rule: 您可以通过用空规则覆盖该规则取消该规则:

%: %.cpp

Or you could remove your rules altogether and let that rule do the right thing. 或者,您可以完全删除规则,然后让该规则做正确的事情。 The implicit rule has a recipe along the lines of 隐式规则有一条沿

$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@

so you can use those variables to choose a compiler specify flags for the preprocessor, compiler and linker. 因此您可以使用这些变量来选择编译器为预处理器,编译器和链接器指定的标志。 For example, you could change CXX to use a compiler for the wrong language and undo the damage by adding LDFLAGS=-lstdc++ , as your makefile does, if you really want. 例如,您可以更改CXX以将编译器用于错误的语言,并根据需要通过添加LDFLAGS=-lstdc++消除损害,就像您的makefile一样。

Here is the solution: 解决方法如下:

In the examples above I do not make Use of the $(LDLIBS) variable, which is used by the built-in default rule. 在上面的示例中,我没有使用$(LDLIBS)变量,该变量由内置默认规则使用。 If I change my Makefile to use $(LDLIBS) instead of $(LDFLAGS), everything is fine! 如果我将Makefile更改为使用$(LDLIBS)而不是$(LDFLAGS),一切都很好!

Solution #1: (built-in rule) 解决方案1 ​​:(内置规则)

CC=gcc
CFLAGS=-g -fopenmp
LDFLAGS= 
LDLIBS = -lstdc++ -lgomp
ECHO = echo
SILENT = @

MODULES = example1 example2 example3

all: $(MODULES)

clean:
    $(SILENT) $(ECHO) "--- Removing object files and binaries ---"
    $(SILENT) rm -f *.o 
    $(SILENT) rm -f $(MODULES)

.PHONY: clean

Solution #2: (user defined rules) 解决方案2 :(用户定义的规则)

CC=gcc
CFLAGS=-g -fopenmp
LDFLAGS= 
LDLIBS = -lstdc++ -lgomp
ECHO = echo
SILENT = @

MODULES = example1 example2 example3

all: $(MODULES)

#disable built-in rule
%: %.cpp

#rule for *.cpp -> *.o
%.o: %.cpp
    $(SILENT) $(ECHO) "--- Compiling $< ---"
    $(SILENT) $(CC) -c $(CFLAGS) $(LDFLAGS) $<

#rule for object -> exectutable
%: %.o
    $(SILENT) $(ECHO) "--- Linking $@ ---"
    $(SILENT) $(CC) $^ $(LDLIBS) -o $@ 

clean:
    $(SILENT) $(ECHO) "--- Removing object files and binaries ---"
    $(SILENT) rm -f *.o 
    $(SILENT) rm -f $(MODULES)

.PHONY: clean

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM