如何在第一步后查看扩展结果

时间:2014-07-01 13:33:45

标签: makefile preprocessor gnu

使用gnu make我可以在第一步(预处理器的类型)中拥有afaik,扩展的命令和变量,并且在第二步中实际上执行步骤

所以当我写:

$(OBJECTSFULL) :
    @echo ' '
    @echo '*** Compiling:   $(basename $(notdir $@)).cpp'

    $(CXX) $(CPPFLAGS) $(LIBCCFLAGS) -I$(MAIN_INCLUDES) $(CXXFLAGS) \
    -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" \
    -o"$@" -c $(filter %/$(basename $(notdir $@)).cpp, $(SOURCES))  2>&1           
    @echo '*** Compiler finished'

,我的变量$(OBJECTSFULL)包含:src/foo.o src/bar.o src/baz.o

我希望“预处理器”在实际构建目标之前会创建类似的东西:

src/foo.o :
    @echo ' '
    @echo '*** Compiling:   foo.cpp'

    g++ -c     ......


src/bar.o :
    @echo ' '
    @echo '*** Compiling:   bar.cpp'

    g++ -c     ......


src/baz.o :
    @echo ' '
    @echo '*** Compiling:   baz.cpp'

    g++ -c     ......

问题:

有没有什么方法可以在第一步之后打印出这些结果?这会帮助我调试一个非常棘手的makefile功能,有几个$() - 调用......

------ ------编辑

使其更精确:我动态生成makefile代码。想象一下,我有一些“设备”,我在列表中定义它们:

devices := Car Bike Plane Ship

然后我定义了一个模板:

define make-device-lib
  LIBBASENAME$(1)   := device$(1)
  LIBNAME$(1)       := lib$$(LIBBASENAME$(1))
  LIBSONAME$(1)     := $$(LIBNAME$(1)).so
  LIBSOX$(1)        := $$(LIBSONAME$(1)).1
  LIBSOXX$(1)       := $$(LIBSONAME$(1)).1.1
  LIBSOXXFULL$(1)   := $$(SHAREDLIBDIR)/$$(LIBSOXX$(1))
  DEVICELIBS        += $$(LIBSOXXFULL$(1))

  OBJECTS$(1)       := $$(call objects_from_dirs, $$(SOURCEDIRS_$(1)))
  OBJECTSCOMMON     := $$(filter-out $$(OBJECTS$(1)), $$(OBJECTSCOMMON))

  $$(LIBSOXXFULL$(1)) : $$(OBJECTS$(1))
    @echo ' '
    @echo '*** Linking:   $$(LIBSONAME$(1))'
    $(CXX) $(CXXFLAGS) $(LIBLNFLAGS) -Wl,-soname,$$(LIBSONAME$(1)) -L$(SHAREDLIBDIR) $$^ -o $$@
    -@ln -f -s $$(LIBSOXX$(1)) $$(SHAREDLIBDIR)/$$(LIBSOX$(1))
    -@ln -f -s $$(LIBSOX$(1))  $$(SHAREDLIBDIR)/$$(LIBSONAME$(1))
endef

现在代码实际上是为每个“设备”生成的,调用“make-device-lib”:

$(foreach device,$(devices),$(eval $(call make-device-lib,$(device))))

模板中的每个$(1)都被每个设备名称替换。 例如:$$(LIBSOXXFULL$(1))最终将在第一个区块中展开为/usr/lib/libdeviceCar.so.1.1,而在第二个区域中展开/usr/lib/libdeviceBike.so.1.1等。$OBJECTSCar包含目标所依赖的自动收集的对象(“ objects_from_dirs“是另一个宏,它会这样做。”

所以当行

$$(LIBSOXXFULL$(1)) : $$(OBJECTS$(1))

展开,表现得像我手写的那样:

/usr/lib/libdeviceCar.so.1.1 : Logging.o Printer.o Engine.o Seats.o

我希望看到的是这个“虚拟”makefile,就好像我手写了一切。

1 个答案:

答案 0 :(得分:0)

Make总是在扩展它之后并在将命令发送到shell之前打印命令,除非您在行前加@。您看到的输出完全发送到shell的内容,听起来就像您正在寻找的那样。

你能解释一下你缺少哪些信息吗?

如果问题是您希望查看@隐藏的内容,则需要使用--trace标记(请注意这是GNU make 4.0中引入的),或者删除{ {1}}(通常人们使用包含@的变量可以重置)或使用@运行,但这也可以改变make的行为。

ETA:

除了-n之外,没有任何内容可以打印整个makefile,并且不会按照原来的顺序显示makefile;它只是按照存储的顺序转储make的内部数据库。

特别针对make -p个函数,如果您使用eval调用替换eval调用,则可以准确查看解析的内容。例如:

info

将被替换为:

$(foreach device,$(devices),$(eval $(call make-device-lib,$(device))))

当然你可以做到这两点,你可以将$(foreach device,$(devices),$(info $(call make-device-lib,$(device)))) 版本放到某种条件中,这样只有在指定变量或其他东西时它才会运行:

info

但是,要使用它,你显然必须修改你的makefile来支持它;它没有内置于make。