代码之家  ›  专栏  ›  技术社区  ›  Jamison Dance

在makefile中,如何对变量中的每个文件名执行命令?

  •  1
  • Jamison Dance  · 技术社区  · 15 年前

    我知道我做错了,但我不知道如何组织这个makefile。我定义了我的util源文件,并使用一些函数在这里定义.o文件:

    UTIL_SRC = utils/src/foo.cpp utils/src/bar.cpp utils/src/baz.cpp
    
    UTIL_OBJS = $(patsubst utils/src/%.cpp,utils/obj/%.o,$(UTIL_SRC))
    

    这是我使用这些文件的目标:

    lib : lib/libutils.a
    
    lib/libutils.a : $(UTIL_OBJS)
        rm -f lib/libutils.a
        ar -c -q lib/libutils.a $(UTIL_OBJS)
    

    然后,当我了解到编译这些婴儿的规则时,我希望只有一个命令,该命令将遍历每个Util_objs文件和每个Util_SRC文件。相反,我求助于这种可怕的东西,它破坏了将它们存储在变量中的目的。

    $(UTIL_OBJS) : $(UTIL_SRC)
        g++ $(UTIL_FLAGS) utils/src/foo.cpp -o utils/obj/foo.o
        g++ $(UTIL_FLAGS) utils/src/bar.cpp -o utils/obj/bar.o
        g++ $(UTIL_FLAGS) utils/src/baz.cpp -o utils/obj/baz.o
    

    我能把这个浓缩成一行吗?怎样?谢谢,好极了!

    2 回复  |  直到 15 年前
        1
  •  9
  •   falstro    15 年前

    使用隐式规则通常更容易。有很多预定义的变量,您只需要在其中指定变量。

    CXX=g++
    CXXFLAGS=$(UTIL_FLAGS)
    

    然后您需要定义一个可执行文件,如下所示

    myutil: $(UTIL_OBJS)
    

    因为您没有将对象存储在同一个目录中,所以您还需要指定一个新的隐式规则(否则,我们现在就完成了)。

    utils/obj/%.o: utils/obj/%.cpp
    

    %是模式匹配,它将在左侧和右侧匹配相同的文本,因此此规则将使foo.o从foo.cpp中退出。 如果没有命令(它可能是从另一个规则中获取的,我不确定),尝试一下,否则让它说:

    utils/obj/%.o: utils/obj/%.cpp
        $(CXX) $(CXXFLAGS) -o $@ $^
    

    $@是规则的目标(例如foo.o),而$^是右侧的所有文件。 我把这个写在头上,没法测试,所以请告诉我结果如何。:)

    为了使它更加优雅,您可以包括一个依赖文件

    include .depend
    

    如果您运行的是gnu make,它会尝试生成.depend文件,如果找不到它(对于旧的学校make,您需要先自己创建它,但是如果您想通过make file管理它,它可能只是一个虚拟文件)

    .depend: $(UTIL_SRC)
        $(CXX) -MM -o $@ $^
    

    依赖项文件将包含每个.cpp文件的行,告诉make它需要什么头文件,这将允许make在更改某些内容时重新编译必要的文件。不过,这对你最初的问题没有帮助,只是觉得它可能会有用。

    编辑:
    作为对编辑的回应。您也可以删除用于创建.a文件的命令,这也是一个隐式规则。但不确定它是如何工作的,并没有用太多。我知道有很多奇怪的事情需要处理。-文件。

        2
  •  0
  •   aviraldg Ortiga    15 年前

    我想你可以用这个:

    $(UTIL_OBJS) : $(UTIL_SRC)
        g++ $(UTIL_FLAGS) $(@ : .o = .cpp)  -o $@ 
    

    再说一次,我不太确定…特别是关于$(@:.cpp=.o)部分