首页 文章

如何获取Makefile的当前相对目录?

提问于
浏览
147

我在app特定目录中有几个Makefile,如下所示:

/project1/apps/app_typeA/Makefile
/project1/apps/app_typeB/Makefile
/project1/apps/app_typeC/Makefile

每个Makefile在此路径中包含一个.inc文件:

/project1/apps/app_rules.inc

在app_rules.inc里面我正在设置我希望在构建时放置二进制文件的目的地 . 我希望所有二进制文件都在各自的 app_type 路径中:

/project1/bin/app_typeA/

I tried using $(CURDIR) ,像这样:

OUTPUT_PATH = /project1/bin/$(CURDIR)

但相反,我把二进制文件埋在整个路径名中,如下所示: (notice the redundancy)

/project1/bin/projects/users/bob/project1/apps/app_typeA

我该怎么做才能获得执行"current directory"以便我只知道 app_typeX 以便将二进制文件放在各自的类型文件夹中?

10 回答

  • 102

    shell函数 .

    您可以使用shell函数: current_dir = $(shell pwd) . 或者 shellnotdir结合使用,如果不需要绝对路径: current_dir = $(notdir $(shell pwd)) .

    更新 .

    给定解决方案仅在从Makefile的当前目录运行 make 时才有效 .
    正如@Flimm所说:

    请注意,这将返回当前工作目录,而不是Makefile的父目录 . 例如,如果你运行cd /; make -f / home / username / project / Makefile,current_dir变量将是/,而不是/ home / username / project / .

    以下代码适用于从任何目录调用的Makefile:

    mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
    current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path))))
    
  • 0

    取自here;

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

    显示为;

    $ cd /home/user/
    
    $ make -f test/Makefile 
    /home/user/test
    
    $ cd test; make Makefile 
    /home/user/test
    

    希望这可以帮助

  • 2

    如果您使用的是GNU make,$(CURDIR)实际上是一个内置变量 . 它是Makefile驻留当前工作目录的位置,可能是Makefile所在的位置,但并非总是如此 .

    OUTPUT_PATH = /project1/bin/$(notdir $(CURDIR))
    

    请参阅http://www.gnu.org/software/make/manual/make.html中的附录A快速参考

  • 3
    THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
    
  • 0

    我尝试了很多这些答案,但在我的AIX系统上使用gnu make 3.80我需要做一些旧学校的事情 .

    事实证明,直到3.81才添加 lastwordabspathrealpath . :(

    mkfile_path := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
    mkfile_dir:=$(shell cd $(shell dirname $(mkfile_path)); pwd)
    current_dir:=$(notdir $(mkfile_dir))
    

    正如其他人所说的那样,并不是最优雅的,因为它会两次调用shell,而且它仍然存在空间问题 .

    但由于我的路径中没有任何空格,无论我如何开始,它都适用于我: make

    • make -f ../wherever/makefile

    • make -C ../ wherever

    • make -C~ / wherever

    • cd ../wherever;使

    对于 current_dir ,所有给我 wherever ,为 mkfile_dir 给出 wherever 的绝对路径 .

  • 193

    我喜欢所选择的答案,但我认为实际展示它的工作比解释它更有帮助 .

    /tmp/makefile_path_test.sh

    #!/bin/bash -eu
    
    # Create a testing dir
    temp_dir=/tmp/makefile_path_test
    proj_dir=$temp_dir/dir1/dir2/dir3
    mkdir -p $proj_dir
    
    # Create the Makefile in $proj_dir
    # (Because of this, $proj_dir is what $(path) should evaluate to.)
    cat > $proj_dir/Makefile <<'EOF'
    path := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
    cwd  := $(shell pwd)
    
    all:
        @echo "MAKEFILE_LIST: $(MAKEFILE_LIST)"
        @echo "         path: $(path)"
        @echo "          cwd: $(cwd)"
        @echo ""
    EOF
    
    # See/debug each command
    set -x
    
    # Test using the Makefile in the current directory
    cd $proj_dir
    make
    
    # Test passing a Makefile
    cd $temp_dir
    make -f $proj_dir/Makefile
    
    # Cleanup
    rm -rf $temp_dir
    

    输出:

    + cd /tmp/makefile_path_test/dir1/dir2/dir3
    + make
    MAKEFILE_LIST:  Makefile
             path: /private/tmp/makefile_path_test/dir1/dir2/dir3
              cwd: /tmp/makefile_path_test/dir1/dir2/dir3
    
    + cd /tmp/makefile_path_test
    + make -f /tmp/makefile_path_test/dir1/dir2/dir3/Makefile
    MAKEFILE_LIST:  /tmp/makefile_path_test/dir1/dir2/dir3/Makefile
             path: /tmp/makefile_path_test/dir1/dir2/dir3
              cwd: /tmp/makefile_path_test
    
    + rm -rf /tmp/makefile_path_test
    

    NOTE: 函数 $(patsubst %/,%,[path/goes/here/]) 用于去除尾部斜杠 .

  • 34

    示例供您参考,如下:

    文件夹结构可能如下:

    enter image description here

    有两个Makefile,每个Makefiles如下;

    sample/Makefile
    test/Makefile
    

    现在,让我们看看Makefile的内容 .

    sample / Makefile

    export ROOT_DIR=${PWD}
    
    all:
        echo ${ROOT_DIR}
        $(MAKE) -C test
    

    test / Makefile

    all:
        echo ${ROOT_DIR}
        echo "make test ends here !"
    

    现在,执行sample / Makefile,as;

    cd sample
    make
    

    输出:

    echo /home/symphony/sample
    /home/symphony/sample
    make -C test
    make[1]: Entering directory `/home/symphony/sample/test'
    echo /home/symphony/sample
    /home/symphony/sample
    echo "make test ends here !"
    make test ends here !
    make[1]: Leaving directory `/home/symphony/sample/test'
    

    解释是,parent / home目录可以存储在environment-flag中,并且可以导出,以便它可以在所有子目录makefile中使用 .

  • -1

    这是使用shell语法获取 Makefile 文件的绝对路径的单行程序:

    SHELL := /bin/bash
    CWD := $(shell cd -P -- '$(shell dirname -- "$0")' && pwd -P)
    

    这里是基于@0xff answer的没有shell的版本:

    CWD=$(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
    

    通过打印测试它,如:

    cwd:
            @echo $(CWD)
    
  • 0

    如果make变量包含Relative路径是 ROOT_DIR

    ROOT_DIR := ../../../
    

    他们获取绝对路径只是使用下面的方法 .

    ROOT_DIR := $(abspath $(ROOT_DIR))
    

    它在GNUMake中工作得很好......

  • 21

    更新2018/03/05 finnaly我用这个:


    shellPath=`echo $PWD/``echo ${0%/*}`
    
    # process absolute path
    shellPath1=`echo $PWD/`
    shellPath2=`echo ${0%/*}`
    if [ ${shellPath2:0:1} == '/' ] ; then
        shellPath=${shellPath2}
    fi
    

    它可以在相对路径或绝对路径中正确执行 . 执行正确的crontab调用 . 在其他shell中执行正确 .

    显示示例,a.sh打印自我路径 .

    [root@izbp1a7wyzv7b5hitowq2yz /]# more /root/test/a.sh
    shellPath=`echo $PWD/``echo ${0%/*}`
    
    # process absolute path
    shellPath1=`echo $PWD/`
    shellPath2=`echo ${0%/*}`
    if [ ${shellPath2:0:1} == '/' ] ; then
        shellPath=${shellPath2}
    fi
    
    echo $shellPath
    [root@izbp1a7wyzv7b5hitowq2yz /]# more /root/b.sh
    shellPath=`echo $PWD/``echo ${0%/*}`
    
    # process absolute path
    shellPath1=`echo $PWD/`
    shellPath2=`echo ${0%/*}`
    if [ ${shellPath2:0:1} == '/' ] ; then
        shellPath=${shellPath2}
    fi
    
    $shellPath/test/a.sh
    [root@izbp1a7wyzv7b5hitowq2yz /]# ~/b.sh
    /root/test
    [root@izbp1a7wyzv7b5hitowq2yz /]# /root/b.sh
    /root/test
    [root@izbp1a7wyzv7b5hitowq2yz /]# cd ~
    [root@izbp1a7wyzv7b5hitowq2yz ~]# ./b.sh
    /root/./test
    [root@izbp1a7wyzv7b5hitowq2yz ~]# test/a.sh
    /root/test
    [root@izbp1a7wyzv7b5hitowq2yz ~]# cd test
    [root@izbp1a7wyzv7b5hitowq2yz test]# ./a.sh
    /root/test/.
    [root@izbp1a7wyzv7b5hitowq2yz test]# cd /
    [root@izbp1a7wyzv7b5hitowq2yz /]# /root/test/a.sh
    /root/test
    [root@izbp1a7wyzv7b5hitowq2yz /]#
    

    老:我用这个:

    MAKEFILE_PATH := $(PWD)/$({0%/*})
    

    如果在其他shell和其他目录中执行,它可以显示正确 .

相关问题