如何从GNU make文件运行Linux shell命令以设置构建目标的前提条件

时间:2014-05-19 05:55:35

标签: linux makefile gnu-make

我的问题是,在我的make文件中,我想在构建它之前为所有目标代码创建目录,但是我无法找到一种方法来执行此操作,而不会影响make的输出。此外,我想在一个地方,而不是每个目标文件。

我试过这个:

build: setup exe.i686

setup:
    mkdir -p obj

exe.i686: $(OBJS)
    @echo 'Building target: $@'
    @echo 'Invoking: GCC C++ Linker'
    ${GCC_LOCATION}/Linux/i686/bin/i686-pc-linux-gnu-g++ $(OBJS) -o "exe.i686" -L...
    @echo 'Finished building target: $@'
    @echo ' '

其中OBJS是我的所有目标代码。如果我没有先运行安装程序并且没有./obj目录,则构建将因尝试构建目标代码时缺少目录而失败。

为了清楚起见,这里是一个如何构建一个目标文件的例子:

./obj/Cell.o: ${CELL_ROOT}/main/cell/Cell/src/Cell.cc
    @echo 'Building file: $<'
    @echo 'Invoking: GCC C++ Compiler'
    $(GCC_C++_BUILD) -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
    @echo 'Finished building: $<'
    @echo ' '

我不想在我的make文件所在的目录中构建目标代码。

现在到了实际问题。当我建立tarket&#34; build&#34;这样的第一次一切正常:

make build

但如果我再次构建它并且我的源代码中没有更新(目标代码是最新的),它的行为如下:

[7:37] [user1] [/local/repo/user1/project_x/test/bin] $ make build
mkdir -p obj
[7:37] [user1] [/local/repo/user1/project_x/test/bin] $ 

在这种情况下,我希望make能够像这样返回没有任何待完成的字符串:

[7:37] [user1] [/local/repo/user1/project_x/test/bin] $ make build
make: Nothing to be done for `build'.
[7:41] [user1] [/local/repo/user1/project_x/test/bin] $ 

如果我不必依赖设置目标(添加到.PHONY),就会出现这种情况。是每个目标代码文件的唯一替代方法吗?我想这是可能的,但我想避免这种情况,因为它会使make文件变得非常混乱。至少在我看来。

由于

2 个答案:

答案 0 :(得分:2)

您的目标setup始终执行,因为它没有依赖关系。

您有两种选择:

(1)创建stamp或使用其他机制,以便存在实际的依赖关系。目录本身可以是目标,但可能会产生一些问题:请参阅http://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html以获取示例。

来自链接文章的修改后的相关摘录:

$(OBJS): | obj

obj:
    mkdir $(OBJDIR)

(2)通过测试存在来抑制输出:

setup:
    test -d obj || mkdir -p obj

答案 1 :(得分:1)

这与之前的答案类似,只是为了便于阅读:

build: exe.i686
$(OBJS): | obj
obj:
    @if [ ! -d obj ]; then mkdir -p obj; fi

exe.i686: $(OBJS)
    @echo 'Building target: $@'
    ...