我有一个生成的makefile,然后调用另一个makefile.由于这个makefile调用更多makefile来完成工作,因此它并没有真正改变.因此,它一直认为项目是建立和最新的.
dnetdev11 ~ # make
make: `release' is up to date.
Run Code Online (Sandbox Code Playgroud)
如何强制makefile重建目标?
clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean
build = svn up ~/xxx \
$(clean) \
~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace \
$(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1) \
release:
$(build )
debug:
$(build DEBUG=1)
clean:
$(clean)
install:
cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib
Run Code Online (Sandbox Code Playgroud)
注意:删除名称以保护无辜者
编辑:最终修正版:
clean = $(MAKE) -f xxx_compile.workspace.mak clean;
build = svn up; \
$(clean) \
./cbp2mak/cbp2mak -C . xxx_compile.workspace; \
$(MAKE) -f xxx_compile.workspace.mak $(1); \
.PHONY: release debug clean install
release:
$(call build,)
debug:
$(call build,DEBUG=1)
clean:
$(clean)
install:
cp ./source/xxx_utillity/release/xxx_util /usr/bin
cp ./dlls/Release/xxxcore.so /usr/lib
Run Code Online (Sandbox Code Playgroud)
syk*_*ora 672
该-B
开关之作,它的长形式--always-make
,讲述make
忽略时间戳,使指定的目标.这可能会破坏使用make的目的,但它可能就是您所需要的.
Dav*_*ave 24
您可以声明一个或多个目标是虚假的.
伪目标是一个实际上不是文件名的目标; 相反,它只是在您发出明确请求时要执行的配方的名称.使用虚假目标有两个原因:避免与同名文件冲突,并提高性能.
...
伪目标不应该是真实目标文件的先决条件; 如果是,每次make更新该文件时都会运行其配方.只要虚假目标永远不是真实目标的先决条件,只有当虚假目标是指定目标时才会执行虚假目标配方.
Jon*_*ler 16
过去在Sun手册中记录的一个技巧make
是使用(不存在的)目标'.FORCE'.您可以通过创建一个包含以下内容的文件force.mk来执行此操作:
.FORCE:
$(FORCE_DEPS): .FORCE
Run Code Online (Sandbox Code Playgroud)
然后,假设您调用现有的makefile makefile
,您可以运行:
make FORCE_DEPS=release -f force.mk -f makefile release
Run Code Online (Sandbox Code Playgroud)
由于.FORCE
不存在,任何依赖它的东西都会过时并重建.
所有这些都适用于任何版本的make
; 在Linux上,你有GNU Make,因此可以使用.PHONY目标.
值得考虑的是为什么make
认为发布是最新的.这可能是因为你touch release
在执行的命令中有一个命令; 可能是因为存在一个名为'release'的文件或目录,并且没有依赖关系,因此是最新的.那是真正的原因......
eas*_*sel 13
有人建议.PHONY绝对是正确的..PHONY应该用于输入和输出之间的日期比较无效的任何规则.由于你没有任何形式的目标,output: input
你应该使用.PHONY所有这些!
总而言之,您可能应该在makefile的顶部为各种文件名定义一些变量,并定义包含输入和输出部分的真实make规则,这样您就可以使用make的好处,即您只能实际编译copmile需要的东西!
编辑:添加示例.未经测试,但这就是你做的.PHONY
.PHONY: clean
clean:
$(clean)
Run Code Online (Sandbox Code Playgroud)
如果我没记错的话,'make'使用时间戳(文件修改时间)来确定目标是否是最新的.强制重新构建的常用方法是使用"touch"命令更新该时间戳.您可以尝试在makefile中调用"touch"来更新其中一个目标(可能是其中一个子makefile)的时间戳,这可能会强制Make执行该命令.
这种简单的技术将允许 makefile 在不需要强制时正常运行。在makefile的末尾创建一个名为force的新目标。该部队的目标将涉及一个程序文件的默认目标取决于。在下面的示例中,我添加了touch myprogram.cpp。我还添加了一个递归调用make。这将导致每次键入make force时都会生成默认目标。
yourProgram: yourProgram.cpp
g++ -o yourProgram yourProgram.cpp
force:
touch yourProgram.cpp
make
Run Code Online (Sandbox Code Playgroud)
小智 6
正如 abernier 指出的,GNU make 手册中有一个推荐的解决方案,它使用“假”目标来强制重建目标:
clean: FORCE
rm $(objects)
FORCE: ;
Run Code Online (Sandbox Code Playgroud)
无论任何其他依赖项如何,这都将运行干净。
我在手册中的解决方案中添加了分号,否则需要空行。
我试过了,它对我有用
将这些行添加到 Makefile
clean:
rm *.o output
new: clean
$(MAKE) #use variable $(MAKE) instead of make to get recursive make calls
Run Code Online (Sandbox Code Playgroud)
保存并立即调用
make new
Run Code Online (Sandbox Code Playgroud)
它将再次重新编译所有内容
发生了什么?
1) 'new' 调用干净。'clean' do 'rm' 删除所有扩展名为 '.o' 的目标文件。
2) 'new' 调用 'make'。'make' 看到没有 '.o' 文件,所以它再次创建所有的 '.o' 文件。然后链接器将所有 .o 文件链接到一个可执行输出
祝你好运