常见的GNU makefile目录path
我正在尝试通过使用通用的makefile来合并一些构build信息。 我的问题是,我想从不同的子目录级别使用该生成文件,这使得工作目录值( pwd
)不可预知。 例如:
# Makefile.common TOP := $(shell pwd) COMPONENT_DIR := $(TOP)/component COMPONENT_INC := $(COMPONENT_DIR)/include COMPONENT_LIB := $(COMPONENT_DIR)/libcomponent.a
如果我从一个子目录中包含Makefile.common
,就像这样, $(TOP)
目录是不正确的,其他的都是这样:
# other_component/Makefile include ../Makefile.common # $(COMPONENT_LIB) is incorrectly other_component/component
Makefile.common
使用自己的目录path,而不是更多变幻的pwd
,最好的办法是什么?
您应该可以使用MAKEFILE_LISTvariables ,如下所示:
# This must be the first this in Makefile.common TOP := $(dir $(lastword $(MAKEFILE_LIST)))
从文档:
由于make读取各种makefile,包括从MAKEFILESvariables,命令行,默认文件或include指令获取的任何makefile,它们的名称将自动附加到MAKEFILE_LISTvariables。 在make开始parsing之前,它们被添加。 这意味着如果makefile所做的第一件事是检查这个variables中的最后一个单词,它将是当前makefile的名字。 一旦当前的makefile使用include,最后的单词将是刚刚包含的makefile。
这是不好的样式,因为它增加了另一个依赖项(即实时path二进制)。 根据您的使用情况,这可能是可以接受的。
ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
如果你没有安装realpath:
$ sudo apt-get install realpath # on debian and derivatives
编辑 :一定要使用:=
而不是=
因为后者导致使用后期绑定和MAKEFILE_LIST
可能已经改变,由于后来包括。
你有没有尝试过:
# Makefile.common TOP ?= $(shell pwd) COMPONENT_DIR := $(TOP)/component COMPONENT_INC := $(COMPONENT_DIR)/include COMPONENT_LIB := $(COMPONENT_DIR)/libcomponent.a # other_component/Makefile TOP ?= .. include ../Makefile.common
如果已经设置,使用?=构造将保持TOP不被重新定义。 在调用make时,可以根据树中的位置将其设置为适当的值。 我承认自从使用了GNU make之后已经有一段时间了,所以这可能不起作用,或者可能需要一些调整。
我的解决scheme
cwd := $(shell readlink -en $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))))
当你在/opt/other/path/subdir
这也适用于make -f /opt/some/dir/Makefile
调用。
只需在common.mk
写下常用的东西。 然后把common.mk是Make在遇到包含common.mk语句时查找的默认文件夹。
查看常见文件夹的帮助查找。 您也可以将common.mk放在您的home文件夹中,然后从任何文件夹中键入make -I$HOME
。
在每个子文件夹的Makefile里面,你只需要做
include common.mk
就这些。 无需担心path和移动的东西。