【问题标题】:GNU Makefile - Generic Makefile for several targetsGNU Makefile - 多个目标的通用 Makefile
【发布时间】:2014-12-12 10:50:12
【问题描述】:

我目前正在开发一个带有小代码示例的小 C++ 包,用于教学目的。我设法编写了一个像下面这样的 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

到目前为止一切顺利,效果很好。它将使用 example1.cpp、example2.cpp 和 example3.cpp 并将其编译/链接到 3 个可执行文件“example1 example2 example3”。

但是由于每个可执行文件都与对象具有相同的名称(例如“example1.o”将链接到可执行文件“example1”),我想知道是否还有一种方法可以使用通用规则。

我尝试了几种方法,例如:

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

据我了解,这条规则应该采用所有目标文件并创建一个与目标文件同名的可执行文件,但我无法让它工作!有没有人提示如何实现这一目标?

【问题讨论】:

  • 那么当你这样做时出了什么问题?

标签: c++ makefile rules targets


【解决方案1】:

问题在于有一个内置规则可以直接从源文件构建程序。 Make 会选择它,而不是链接你的两条规则。

您可以 cancel the rule 用空规则覆盖它:

%: %.cpp

或者您可以完全删除您的规则并让该规则做正确的事情。 implicit rule 的配方类似于

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

因此您可以使用这些变量来选择编译器,为预处理器、编译器和链接器指定标志。例如,您可以更改CXX 以使用错误语言的编译器,并通过添加LDFLAGS=-lstdc++ 来消除损坏,就像您的makefile 所做的那样,如果您真的想要的话。

【讨论】:

    【解决方案2】:

    解决办法如下:

    在上面的示例中,我没有使用内置默认规则使用的 $(LDLIBS) 变量。如果我将 Makefile 更改为使用 $(LDLIBS) 而不是 $(LDFLAGS),一切都很好!

    解决方案 #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
    

    解决方案 #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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 2011-05-08
      • 2017-11-08
      • 2016-12-19
      • 2018-09-13
      • 1970-01-01
      • 2019-01-14
      相关资源
      最近更新 更多