我有以下makefile
target: debug
debug: $(BIN_DEBUG)/$(TARGET_NAME).lib
#BIN_DEBUG is the path of debug folder
#TARGET_NAME is the library name.
#Rule for .libs
$(BIN_DEBUG)/$(TARGET_NAME).lib: $(DEBUG_OBJECT_LIST)
$(LIB) /OUT:$@ $^
#DEBUG_OBJECT_LIST is the list of .obj files in BIN_DEBUG folder.
#Rule for obj files
$(DEBUG_OBJECT_LIST):$(BIN_DEBUG)/%.obj:%.cpp
@cl /c /Z7 /W3 /Od /D "_UNICODE" /D "UNICODE" /Gm /EHsc /Fo$@ /Gd /analyze- /errorReport:queue $(CFLAGS) $^
#In the rule for each obj file, I want to pick the corresponding file for the obj file. I have file list in SOURCE_LIST.
#It shows how DEBUG_OBJECT_LIST is derived.
DEBUG_OBJECT_LIST1 = $(patsubst %.cpp, %.obj,$(SOURCE_LIST))
DEBUG_OBJECT_LIST2 = $(notdir $(DEBUG_OBJECT_LIST1))
DEBUG_OBJECT_LIST = $(patsubst %, $(BIN_DEBUG)/%, $(DEBUG_OBJECT_LIST2))
我需要有关obj文件的规则的帮助。如何获取给定obj文件的确切文件?
答案 0 :(得分:0)
好的,一般点make
是棘手的野兽,对空白非常敏感。
您的patsubst
命令不应在逗号后面包含空格。现在,在这个的情况下,它应该没有什么区别,因为你要做的只是在项目之间增加一个额外的空间,但我可以保证,如果你没有剔除这个习惯当你做一个更大,更复杂的构建时,它会回来咬你...
obj文件的规则不必要地复杂。
$(DEBUG_OBJECT_LIST):$(BIN_DEBUG)/%.obj:%.cpp
@cl ... $^
更简单的模式规则将完成这项工作:
$(BIN_DEBUG)/%.obj: %.cpp
@cl ... $<
这意味着:“每当我需要.obj
下的$(BIN_DEBUG)
文件时,请查找相对于当前目录”的相应.cpp
文件。另请注意,我使用$<
而不是$^
作为编译行。这将确保只将.cpp
文件传递给编译器,如果您想要将隐式规则添加Makefile或标头,这将非常有用。
最后,DEBUG_OBJECT_LIST
应该可能:
DEBUG_OBJECT_LIST = $(patsubst %.cpp,$(BIN_DEBUG)/%.obj,$(SOURCE_LIST))
只是不首先将它们添加到列表中,因此过滤目录更容易。如果您不使用通配符(wildcard
或*.*
构造),这很容易。通配符似乎是个好主意;一个方便,但他们实际上创造了比他们解决的更多的问题(包括目录,非源文件,你现在想要编译的文件) - 只需咬紧牙关并添加源文件到您的来源列表。
编辑:更正错误。静态模式规则。正确的错字。
答案 1 :(得分:0)
通过设置VPATH
变量解决问题。请详细了解VPATH。
SRC_DIR_LIST = $(dir $(SOURCE_LIST))
VPATH = $(sort $(SRC_DIR_LIST))