使用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,就好像我手写了一切。
答案 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。