常见的GNU makefile目录路径

时间:2008-11-27 04:35:45

标签: makefile

我正在尝试使用通用的makefile来整合一些构建信息。我的问题是我想从不同的子目录级别使用该makefile,这使得工作目录值(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使用自己的目录路径而不是更加善变pwd的最佳方式是什么?

5 个答案:

答案 0 :(得分:68)

您应该可以使用MAKEFILE_LIST variable,如下所示:

# This must be the first line in Makefile.common
TOP := $(dir $(lastword $(MAKEFILE_LIST)))

来自文档:

  

当make读取各种makefile时,包括从MAKEFILES变量,命令行,默认文件或include伪指令获得的任何makefile,它们的名称将自动附加到MAKEFILE_LIST变量中。它们在make开始解析之前添加。这意味着如果makefile执行的第一件事是检查此变量中的最后一个单词,它将是当前makefile的名称。但是,一旦当前的makefile使用了include,最后一个单词将是刚刚包含的makefile。

答案 1 :(得分:9)

这不是好的样式,因为它添加了另一个依赖项(即realpath二进制文件)。根据您的使用情况,这可能是可以接受的。

ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

如果您没有安装realpath:

$ sudo apt-get install realpath # on debian and derivatives

编辑:请务必使用:=代替=,因为后者导致make使用后期绑定,而MAKEFILE_LIST可能会由于后来的包括而改变了。

答案 2 :(得分:2)

你有没有尝试过:

# 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,则使用?=构造将使TOP不被重新定义。您可以根据调用make时树中的位置将其设置为适当的值。我承认自从我使用GNU make以来已经有一段时间了,所以这可能不起作用或者可能需要一些调整。

答案 3 :(得分:2)

我的解决方案:

cwd  :=  $(shell readlink -en $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))) 

当您进入make -f /opt/some/dir/Makefile

时,这也适用于/opt/other/path/subdir等来电

答案 4 :(得分:1)

只需在common.mk中编写常见内容即可。然后把common.mk放在Make遇到include common.mk语句时查找的默认文件夹中。

查看常用文件夹的帮助查找。您也可以将common.mk放在主文件夹中,然后从任何文件夹中键入make -I$HOME

在每个子文件夹的Makefile中,您只需执行

include common.mk

就是这样。无需担心路径和移动物体。