Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用$**&引用;在Makefile中直接输入文件_C_File Io_Makefile - Fatal编程技术网

C 使用$**&引用;在Makefile中直接输入文件

C 使用$**&引用;在Makefile中直接输入文件,c,file-io,makefile,C,File Io,Makefile,我正在处理一个有很多源文件的大型C项目。以下是其中一个makefiles中的一行: !$(TOOLSDIRECTORY)unifdef $(UNIFDEF_ARGUMENTS) $** > $(TARGET)\$** 此行引用的Unifdef工具是开源的,可在以下位置获得: 在本例中,Unifdef的最后一个参数是要处理的文件组。据我所知,这段代码使用“$**”符号表示“此文件夹中的每个文件”,然后将所有输出传输到目标目录 我的困惑是,我不明白Unifdef如何在一个命令中接收多个文件

我正在处理一个有很多源文件的大型C项目。以下是其中一个makefiles中的一行:

!$(TOOLSDIRECTORY)unifdef $(UNIFDEF_ARGUMENTS) $** > $(TARGET)\$**
此行引用的Unifdef工具是开源的,可在以下位置获得:

在本例中,Unifdef的最后一个参数是要处理的文件组。据我所知,这段代码使用“$**”符号表示“此文件夹中的每个文件”,然后将所有输出传输到目标目录

我的困惑是,我不明白Unifdef如何在一个命令中接收多个文件。makefile在看到“$**”时是否将所有文件打包成一个文件流?我理解Unifdef如何处理它接收到的输入,但是多个文件如何变成Unifdef接收到的单个参数呢


其他注意事项:此makefile正在MSVS 2010中的Windows上运行。

我怀疑这实际上并没有实现您想要的功能

$**
不是单个构造;它后面紧跟着shell glob通配符
*
。这一行将被重写两次:首先,通过Make,改写为

!../path/to/tools/unifdef --opt1 --opt2 foo* > ../path/to/target/foo\*
!../path/to/tools/unifdef --opt1 --opt2 foo.c foo1.c foo2.c fooquux.c \
    > ../path/to/target/foo*
然后,通过
/bin/sh
,将

!../path/to/tools/unifdef --opt1 --opt2 foo* > ../path/to/target/foo\*
!../path/to/tools/unifdef --opt1 --opt2 foo.c foo1.c foo2.c fooquux.c \
    > ../path/to/target/foo*
然后才被执行

你没有引用任何上下文,所以我不能再具体了。但我认为这不可能是正确的原因如下:

  • 除非您设置了
    ,这是我以前从未听说过的功能没有任何意义,应该会导致命令失败,因为没有可执行文件名为
    /路径/to/tools/unifdef

  • 第二次出现的
    $**
    上的反斜杠不会转义
    $*
    (您可以通过编写
    $*
    来实现);它被保留,并转义shell glob-star,因此输出被写入一个名为
    。/path/to/target/foo*
    的文件,这非常奇怪,我认为它不可能是预期的

  • 如果目标目录glob没有被转义,那么还会有两个问题:

    • Glob扩展在源目录和目标目录中独立进行,因此(至少可能)会匹配不相关的文件集

    • 输出重定向(
      )仅适用于命令行上的下一个事件;目标目录中与glob匹配的所有其他内容将作为输入提供给
      unifdef

  • 基于对你想做什么的疯狂猜测,我认为你可能更想要这样的东西:

    # Resist the temptation to use wildcards.  It will be less grief in the long run
    # to list each file explicitly.
    GENERIC_SOURCES   := foo.c foo1.c foo2.c fooquux.c barblurf.c barbaz.c
    
    UNIFDEFED_SOURCES := $(patsubst %.c,$(TARGET)/%-u.c,$(GENERIC_SOURCES))
    
    # The indented lines below must be indented using exactly one hard tab character.
    $(UNIFDEFED_SOURCES): %-u.c: %.c
            $(TOOLSDIRECTORY)unifdef $(UNIFDEF_ARGUMENTS) $< > $@T
            mv -f $@T $@
    
    #抵制使用通配符的诱惑。从长远来看,这将减少悲伤
    #明确列出每个文件。
    通用_源代码:=foo.cfoo1.cfoo2.cfooqux.cbarblurf.cbarbaz.c
    统一定义的_源:=$(patsubst%.c,$(目标)/%-u.c,$(通用_源))
    #下面的缩进行必须使用一个硬制表符缩进。
    $(统一来源):%-u.c:%
    $(TOOLSDIRECTORY)unifdef$(unifdef_参数)$<>$@T
    mv-f$@T$@
    
    这不会尝试批调用
    unifdef
    ;如果每个规则只创建一个输出文件,Make通常会更快乐


    这些都是特别的特征。我通常提倡可移植性,但在Make的情况下,GNU的化身比可移植功能集强大得多,因此值得作为一个依赖项来使用。

    Windows CMD提示符将$**扩展为多个对Unifdef的单独调用,每个调用以目录中的一个文件为参数,并将输出通过管道传输到目标目录中同名的文件。因此,每次调用Unifdef只接收一个文件名作为其输入。

    如果没有看到它所处的目标,我无法说我理解它试图做什么,但它在我看来肯定不是很正常
    $*
    是包含匹配的隐式规则的词干的
    $**
    应该扩展到
    *
    ,这在重定向的左侧作为通配符在大量文件上运行unifdef可能是合理的,但重定向的右侧对我来说似乎很奇怪。我感谢您的回答,如果可以的话,我会投赞成票,因为它似乎适合最初提出的问题。