Chinaunix

标题: 关于Makefile的语句执行顺序一问 [打印本页]

作者: 飞雪横天    时间: 2007-10-31 20:02
标题: 关于Makefile的语句执行顺序一问
我对Makefile的机制不熟悉, 今天碰到一个奇怪的现象:
我写了个简单的Makefile文件描述如下:

.PHONE: all

all:
    @echo "Creating so files"
    -@rm -rf demo
    -@mkdir demo
    -@cp -rf /usr/lib/libX*.so demo
    -@for i in $(shell find ./demo -name libX*.so); do echo $$i; done

假设我的/usr/lib目录下有以下文件: libX11.a,  libX11.so,  libX11.so.6,  libX11.so.6.2

按道理说, 应该打印出类似于下面的结果:
Create so files
libX11.so

但是实际上打印出来的是:
find: ./demo: No such file or directory
Creating so files
从表面上看来, 应该是-@for循环与-@mkdir同时执行才造成这种情况, 难道Makefile
不是单步执行的么? 如果是同时fork的话, 该如何禁止这种情况发生呢?

谢谢大家了.

[ 本帖最后由 飞雪横天 于 2007-11-1 18:46 编辑 ]
作者: 飞雪横天    时间: 2007-11-01 18:46
没人知道么? 我顶一下,谢谢
作者: web_surf    时间: 2007-11-02 09:33
原帖由 飞雪横天 于 2007-10-31 20:02 发表
我对Makefile的机制不熟悉, 今天碰到一个奇怪的现象:
我写了个简单的Makefile文件描述如下:

.PHONE: all

all:
    @echo "Creating so files"
    -@rm -rf demo
    -@mkdir demo
    -@cp -rf /us ...

1, Makefile肯定是顺序执行的.
2, 你的问题多半是demo下没有任何文件造成的。
作者: 飞雪横天    时间: 2007-11-02 12:40
但是实际上打印出来的是:
find: ./demo: No such file or directory
Creating so files

提示的是没有demo文件,  而且即使是demo下没有文件, 也应该是先打印"Creating so files"
再打印"find: ./demo: No such file or directory"?

谢谢
作者: web_surf    时间: 2007-11-02 13:10
原帖由 飞雪横天 于 2007-11-2 12:40 发表
但是实际上打印出来的是:
find: ./demo: No such file or directory
Creating so files

提示的是没有demo文件,  而且即使是demo下没有文件, 也应该是先打印"Creating so files"
再打印"find: ./demo: No  ...



试了一下,确实shell命令会首先执行。
你可以用下面的方式解决这个问题:
1
define display
    -@for i in $(shell find $1 -name libX*.so); do echo $$i; done
endef
.PHONE: all

all:
    @echo "Creating so files"
    -@rm -rf demo
    -@mkdir demo
    -@cp -rf /usr/lib/libX*.so demo
    -@$(call display, ./demo)

2
all:depend
    -@for i in $(shell find $1 -name libX*.so); do echo $$i; done

depend:
    @echo "Creating so files"
    -@rm -rf demo
    -@mkdir demo
    -@cp -rf /usr/lib/libX*.so demo
作者: 飞雪横天    时间: 2007-11-02 13:26
谢谢

我测试了一下第一种方法还是会出现同样的问题.
find: ./demo: No such file or directory
Creating so files

第二种方法是可以的.

但是我想知道什么原因导致shell命令提前执行呢? 另外我即使讲shell去掉改成:
-@for i in $(find $1 -name libX*.so); do echo $$i; done
还是有错误.

Makefile被执行的机制是如何的呢?
作者: web_surf    时间: 2007-11-02 14:12
原帖由 飞雪横天 于 2007-11-2 13:26 发表
谢谢

我测试了一下第一种方法还是会出现同样的问题.
find: ./demo: No such file or directory
Creating so files

第二种方法是可以的.

但是我想知道什么原因导致shell命令提前执行呢? 另外我即使讲 ...

sorry, 第一种确实不行。
另外,下面这种也可以
.PHONE: all

all:
    @echo "Creating so files"
    -@rm -rf demo
    -@mkdir demo
    -@cp -rf /usr/lib/libX*.so demo
    -@for i in `find ./demo -name libX*.so`; do echo $$i; done
作者: web_surf    时间: 2007-11-02 14:19
原帖由 飞雪横天 于 2007-11-2 13:26 发表
谢谢

我测试了一下第一种方法还是会出现同样的问题.
find: ./demo: No such file or directory
Creating so files

第二种方法是可以的.

但是我想知道什么原因导致shell命令提前执行呢? 另外我即使讲 ...


$(shell)首先执行,估记是 Makefile的语法{$(shell ...)} 跟shell的语法{for} 混用造成的。
作者: 飞雪横天    时间: 2007-11-02 14:47
谢谢精灵王了, 虽然现在还是对Makefile的执行机制不甚了解, 也不知道那里有这方面的书籍
作者: Bayweb    时间: 2007-11-04 21:04
原帖由 飞雪横天 于 2007-11-2 14:47 发表
谢谢精灵王了, 虽然现在还是对Makefile的执行机制不甚了解, 也不知道那里有这方面的书籍

>>
>>
>>GNU Makefile
>>
>>
作者: mymtom    时间: 2007-11-09 23:22
引用shell变量要用两个美元符号$$。
#
# Makefile
#

.PHONE: all

all:
        @echo "Creating so files"
        -@rm -rf demo
        -@mkdir demo
        -@cp -rf /usr/lib/libXt*.so demo
        -@for i in $$(find ./demo -name libX*.so); do echo $$i; done

运行结果是:
mymtom@fc6:src/csdn/misc$ make
Creating so files
./demo/libXtst.so
./demo/libXt.so

至于楼主遇到的问题,GNU MAKE有个-j参数也许有用,可以试试make --jobs=1或make -j1
       -j [jobs], --jobs[=jobs]
            Specifies the number of jobs (commands) to run simultaneously.  If
            there  is  more than one -j option, the last one is effective.  If
            the -j option is given without an argument, make  will  not  limit
            the number of jobs that can run simultaneously.




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2