生成文件中的错误

发布于 2024-10-06 18:31:02 字数 710 浏览 4 评论 0原文

我正在使用 gnu Make 3.82,但有一个恼人的问题。

我有一个规则设置目录之间的依赖关系。

OBJDIR=../obj

$(objdir)/%.o: %.C
    $(COMPILE) -MM -MT$(objdir)/$(notdir $@) $< -o $(DEPDIR)/$(notdir $(basename $<).d )
$(COMPILE) -o $(objdir)/$(notdir $@ ) -c $<

为此,obj 目录必须存在。 我想 mkdir 该目录作为先决条件

$(objdir)/%.o: %.C $(objdir)
    $(COMPILE) -MM -MT$(objdir)/$(notdir $@) $< -o $(DEPDIR)/$(notdir $(basename $<).d )
$(COMPILE) -o $(objdir)/$(notdir $@ ) -c $<

$(objdir):
    mkdir $(objdir)

这不起作用,因为当目录存在时它会失败然后 make 停止 我尝试了 shell

if [ ! -d $(objdir) ] ; then  \
  mkdir $(objdir)             \
fi

,但显然我出了问题。这样做的最佳方法是什么?

I am using gnu Make 3.82 and have an annoying problem.

I have a rule setting dependencies between directories.

OBJDIR=../obj

$(objdir)/%.o: %.C
    $(COMPILE) -MM -MT$(objdir)/$(notdir $@) 
lt; -o $(DEPDIR)/$(notdir $(basename 
lt;).d )
$(COMPILE) -o $(objdir)/$(notdir $@ ) -c 
lt;

In order to do this, the obj directory must exist.
I want to mkdir the directory as a prerequisite

$(objdir)/%.o: %.C $(objdir)
    $(COMPILE) -MM -MT$(objdir)/$(notdir $@) 
lt; -o $(DEPDIR)/$(notdir $(basename 
lt;).d )
$(COMPILE) -o $(objdir)/$(notdir $@ ) -c 
lt;

$(objdir):
    mkdir $(objdir)

This doesn't work, because it fails when the directory is there and then the make stops
I tried shell

if [ ! -d $(objdir) ] ; then  \
  mkdir $(objdir)             \
fi

but obviously I've got something wrong. What's the best way of doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不回头走下去 2024-10-13 18:31:02

一种简单的方法是使用:

mkdir -p ../obj

当目录存在时它不会失败。

我通常为此创建一个宏 MKPATH:

MKPATH = mkdir -p

然后在规则中引用该宏:

$(objdir):
    $(MKPATH) $(objdir)

这样,如果有必要,我可以在不更改 makefile 的情况下更改行为。


您的 shell 片段:

if [ ! -d $(objdir) ] ; then
  mkdir $(objdir)
fi

无法按编写的方式工作,因为 make 单独执行每一行。

您可以写(注意添加的分号):

if [ ! -d $(objdir) ] ; then \
  $(MKPATH) $(objdir) ; \
fi

或:

if [ ! -d $(objdir) ] ; then $(MKPATH) $(objdir); fi

或:

[ -d $(objdir) ] || $(MKPATH) $(objdir)

请注意,命令行总体上必须成功,因此不要尝试:

[ ! -d $(objdir) ] && $(MKPATH) $(objdir)

如果目录存在,第一个替代方案失败,但 shell 以非零值退出状态,从而失败......并导致构建失败。

One simple way is to use:

mkdir -p ../obj

It doesn't fail when the directory exists.

I usually create a macro, MKPATH, for this:

MKPATH = mkdir -p

and then reference the macro in the rule:

$(objdir):
    $(MKPATH) $(objdir)

That way, I can change the behaviour without changing the makefile if it becomes necessary.


Your shell fragment:

if [ ! -d $(objdir) ] ; then
  mkdir $(objdir)
fi

does not work as written because make executes each line separately.

You could write (note the added semi-colon):

if [ ! -d $(objdir) ] ; then \
  $(MKPATH) $(objdir) ; \
fi

Or:

if [ ! -d $(objdir) ] ; then $(MKPATH) $(objdir); fi

Or:

[ -d $(objdir) ] || $(MKPATH) $(objdir)

Note that the command line must be successful overall, so do not try:

[ ! -d $(objdir) ] && $(MKPATH) $(objdir)

If the directory exists, the first alternative fails, but the shell exits with a non-zero status, thus failing...and causing the build to fail.

淡淡绿茶香 2024-10-13 18:31:02

mkdir

"mkdir -p"

更改:

$(objdir): mkdir $(objdir) 

为 =>

$(objdir): 
   mkdir -p $(objdir)

如果特定的mkdir没有-p,那么:

$(objdir): 
   test -d $(objdir) || mkdir $(objdir)

Makefiles

目标:和命令(mkdir等)放在单独的行上。

另外,在 make 中,要忽略失败的命令,请在命令前加上 减号

$(objdir):
    -mkdir $(objdir)

多行命令(if-then-else;for 循环等)需要添加“\;”表示 shell 的换行符:

$(objdir):
    if [ ! -d $(objdir) ] ; then \
      mkdir $(objdir) ; \
    fi

if-then-else 的这种特殊用法也可以写为:

$(objdir):
    if [ ! -d $(objdir) ] ; then mkdir $(objdir) ; fi

上面的每一点:

all: setup dirs report

# Create an intefering dir1
# Remove dir2.  It is work to be done later.
setup: 
    @mkdir -p dir1
    @if test -d dir2 ; then rmdir dir2 ; fi

# Continue (with dir2), even though dir1 re-creation fails
dirs:
    -mkdir dir1
    mkdir -v dir2

# Show we're still running
report:
    @echo DIRS:
    @for d in dir?;  do \
        test -d $d || break ; \
        echo -n "$d " ; \
    done
    @echo

下面的 Makefile 演示了运行 make 的输出

mkdir dir1
mkdir: cannot create directory `dir1': File exists
make: [dirs] Error 1 (ignored)
mkdir -v dir2
mkdir: created directory `dir2'
DIRS:
dir1 dir2 

mkdir

"mkdir -p"

Change:

$(objdir): mkdir $(objdir) 

to =>

$(objdir): 
   mkdir -p $(objdir)

If that particular mkdir does not have -p then:

$(objdir): 
   test -d $(objdir) || mkdir $(objdir)

Makefiles

Keep the target: and the comands (mkdir, etc) on seperate lines.

Also, in make, to ignore failed commands, prefix command with minus:

$(objdir):
    -mkdir $(objdir)

Commands (if-then-else; for loops, etc) with multiple lines require adding `\;' to represent newlines to the shell:

$(objdir):
    if [ ! -d $(objdir) ] ; then \
      mkdir $(objdir) ; \
    fi

This particular usage of if-then-else can also written as:

$(objdir):
    if [ ! -d $(objdir) ] ; then mkdir $(objdir) ; fi

The following Makefile that demonstrates each point above

all: setup dirs report

# Create an intefering dir1
# Remove dir2.  It is work to be done later.
setup: 
    @mkdir -p dir1
    @if test -d dir2 ; then rmdir dir2 ; fi

# Continue (with dir2), even though dir1 re-creation fails
dirs:
    -mkdir dir1
    mkdir -v dir2

# Show we're still running
report:
    @echo DIRS:
    @for d in dir?;  do \
        test -d $d || break ; \
        echo -n "$d " ; \
    done
    @echo

Output from running running make:

mkdir dir1
mkdir: cannot create directory `dir1': File exists
make: [dirs] Error 1 (ignored)
mkdir -v dir2
mkdir: created directory `dir2'
DIRS:
dir1 dir2 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文