Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.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_Batch File_Makefile_C Preprocessor - Fatal编程技术网

C 如何使用Makefile将多个文件提供给后台进程

C 如何使用Makefile将多个文件提供给后台进程,c,batch-file,makefile,c-preprocessor,C,Batch File,Makefile,C Preprocessor,我有一个Makefile,其中一个目标依赖于多个文件——每个文件都必须单独处理(不提供中间输出文件)。我的具体情况更为复杂: 我有一个C源代码,我想从中提取枚举定义。有一些皱纹我无法改变: 编译器不是GCC——它是由宇宙软件制作的定制编译器 除了编译器之外,我还可以单独运行解析器(我们称之为parser.exe),它还可以选择(-e)在STDOUT上输出预处理的源代码 make实际上是PTC Integrity软件包附带的专有版本。它不支持循环——如果我想使用循环,我必须执行Windows批处理

我有一个Makefile,其中一个目标依赖于多个文件——每个文件都必须单独处理(不提供中间输出文件)。我的具体情况更为复杂:

我有一个C源代码,我想从中提取枚举定义。有一些皱纹我无法改变:

  • 编译器不是GCC——它是由宇宙软件制作的定制编译器
  • 除了编译器之外,我还可以单独运行解析器(我们称之为parser.exe),它还可以选择(
    -e
    )在STDOUT上输出预处理的源代码
  • make实际上是PTC Integrity软件包附带的专有版本。它不支持循环——如果我想使用循环,我必须执行Windows批处理脚本
  • 这些都是在Windows上运行的
  • 我已经编写了一个实用程序(使用C#和ANTLR),我们称之为ExtractEnums.exe,它从C源中提取枚举(并计算表达式),只要该源已经过预处理。整个预处理源的重量略高于30MB。我选择通过管道将预处理的源代码写入ExtractEnums.exe,而不是使用宇宙解析器将其写入磁盘。因为我需要为每个源文件调用解析器,所以我需要使用命名管道,而不仅仅是管道(
    |
    )操作符。在Windows上,命名管道不会获得真实的文件名,这就是为什么您将看到
    ExtractEnums.exe-client
    写入管道和后台进程
    ExtractEnums.exe-server
    ,后者在下面的示例中从管道读取

    ############################################################################
    # Dummy files - these will never exist
    #
    D_FILES = $(SRCS:.c=.dummy)                       # All dummy files
    
    server :
        cmd /c start /B ExtractEnums.exe -server > temp.pipe
    
    %.dummy : %.c server
        cmd /c parser.exe $(DEFINES_AND_OPTS) -e $^ | cmd /c ExtractEnums.exe -client
    
    # Extract enums from all the preprocessed source:
    %.enums : $(D_FILES)
        cmd /c echo ;;exit;; | cmd /c ExtractEnums.exe -client
        cmd /c move temp.pipe $@
    
    如果我调用
    make product\u name.enums
    ,所有这些都会运行
    SRCS
    是所有源文件的列表<代码>;;退出是一个特殊的字符串,我发送到
    ExtractEnums.exe-server
    ,告诉它退出。问题是:

    为了循环所有源代码并将它们输入预处理器,我列出了一个永远不存在的
    .dummy
    文件列表。由于这些目标从未存在过,因此它们总是过时的。这意味着调用
    make product_name.enum
    将始终通过预处理器运行所有源,即使源没有更改


    我意识到我想出了一个复杂的解决办法。如果你有一个更简单的方法来解决这个问题,我愿意接受建议——在这种情况下,我将编辑这个问题的名称以使其合适。

    我在解决类似问题时遇到了这个老问题。只需将“虚拟”文件转换为真实(空)文件,即可跟踪上次处理源文件的时间。在下面的示例中,我将它们分组到一个子目录(
    dummies
    )中,这样它们就不会对源代码树造成太多干扰:

    D_DIR = dummies
    D_FILES = $(patsubst %.c,$(D_DIR)/%.dummy,$(SRCS))   # All dummy files
    
    $(D_DIR)/%.dummy : %.c
        [ -f server ] || { cmd /c start /B ExtractEnums.exe -server > temp.pipe && touch server; }
        cmd /c parser.exe $(DEFINES_AND_OPTS) -e $^ | cmd /c ExtractEnums.exe -client
        mkdir -p $(dir $@) # create dummy's directory if it does not exist
        touch $@           # create dummy
    
    # Extract enums from all the preprocessed source:
    %.enums : $(D_FILES)
        cmd /c echo ;;exit;; | cmd /c ExtractEnums.exe -client
        rm -f server
        cmd /c move temp.pipe $@
    

    注意:我还使用一个空的虚拟文件(
    server
    )将服务器标记为正在运行,并仅在虚拟配方中需要时启动它。这样可以避免将其作为每个虚拟机的先决条件,并在其相应的源文件未更改但服务器未运行时重新构建虚拟机。

    您对问题2的描述不清楚。接收器(由
    服务器
    规则启动)将输出定向到
    产品名称.pipe
    ,而
    %.enums
    规则将该文件重命名为其他文件。问题是什么?您可以使用问题中所述的批处理循环,将所有对象减少到单个目标
    %.enums
    。有什么理由不这么做吗?@Beta--我想你是对的。product_name.pipe只是一个临时文件。我将编辑我的问题,以明确它是一个临时文件,并删除第#1项。@perencia——不知何故,使用批处理循环对我来说似乎有点脏。但是,我非常喜欢Windows(即
    cmd/cstart/B
    )。是否要添加一个使用批处理循环作为答案的版本?