Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.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++ 为不同的输出目录生成GCC依赖项_C++_Gcc_Makefile_Dependencies - Fatal编程技术网

C++ 为不同的输出目录生成GCC依赖项

C++ 为不同的输出目录生成GCC依赖项,c++,gcc,makefile,dependencies,C++,Gcc,Makefile,Dependencies,我使用GCC生成依赖项文件,但我的构建规则将输出放在一个子目录中。有没有办法告诉GCC将我的子目录前缀放在它为我生成的依赖项文件中 gcc $(INCLUDES) -E -MM $(CFLAGS) $(SRC) >>$(DEP) 如果GCC有理由这么做,我不知道是什么。我们最终通过管道将依赖项输出重写为${OBJDIR}/.o好的,只是为了确保我的问题是正确的:我假设您有test.c,其中包括test.h,并且您想要生成subdir/test.d(不生成subdir/test.o)

我使用GCC生成依赖项文件,但我的构建规则将输出放在一个子目录中。有没有办法告诉GCC将我的子目录前缀放在它为我生成的依赖项文件中

gcc $(INCLUDES) -E -MM $(CFLAGS) $(SRC) >>$(DEP)

如果GCC有理由这么做,我不知道是什么。我们最终通过管道将依赖项输出重写为
${OBJDIR}/.o

好的,只是为了确保我的问题是正确的:我假设您有
test.c
,其中包括
test.h
,并且您想要生成
subdir/test.d
(不生成
subdir/test.o
)其中
subdir/test.d
包含

subdir/test.o: test.c test.h
而不是

test.o: test.c test.h
这就是你现在得到的,对吗

我想不出一个简单的方法来完全满足您的要求。但是,如果您想在生成.o文件时创建
.d
文件,您可以使用:

gcc $(INCLUDES) -MMD $(CFLAGS) $(SRC) -o $(SUBDIR)/$(OBJ)
(给定
SRC=test.c
SUBDIR=SUBDIR
OBJ=test.o
)这将创建SUBDIR/test.o和SUBDIR/test.d,其中
SUBDIR/test.d
包含上述所需的输出

  • [GNU]如果不将输出放在当前目录中,make会生气。您应该真正从构建目录运行make,并使用VPATH make变量来定位源代码。如果您对编译器撒谎,它迟早会报复的

  • 如果坚持在其他目录中生成对象和依赖项,则需要使用
    -o
    参数,如下所示

  • 答案是:使用
    -MT
    标志

    -MT目标

    更改依赖项生成发出的规则的目标。默认情况下,CPP采用主输入文件的名称,删除任何目录组件和任何文件后缀,如
    .c
    ,并附加平台的常用对象后缀。结果为目标

    -MT
    选项将目标设置为您指定的字符串。如果需要多个目标,可以将它们指定为
    -MT
    的单个参数,或使用多个
    -MT
    选项

    例如,
    -MT'$(objpfx)foo.o'
    可能会给出

    $(objpfx)foo.o: foo.c
    

    我假设您正在使用GNU Make和GCC。首先添加一个变量来保存依赖项文件列表。假设您已经有一个变量列出了所有源文件:

    SRCS = \
            main.c \
            foo.c \
            stuff/bar.c
    
    DEPS = $(SRCS:.c=.d)
    
    然后在makefile中包含生成的依赖项:

    include $(DEPS)
    
    然后添加此模式规则:

    # automatically generate dependency rules
    
    %.d : %.c
            $(CC) $(CCFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -MT"$(<:.c=.o)" "$<"
    
    # -MF  write the generated dependency rule to a file
    # -MG  assume missing headers will be generated and don't stop with an error
    # -MM  generate dependency rule for prerequisite, skipping system headers
    # -MP  add phony target for each header to prevent errors when header is missing
    # -MT  add a target to the generated dependency
    
    #自动生成依赖项规则
    %d.d:%
    
    $(CC)$(CCFLAGS)-MF“$@”-MG-MM-MP-MT“$@”-MT“$”(您可能会喜欢以下更简洁的版本:

    DEPS=$(SRCS:.c=.d)

    添加
    -include$(DEPS)
    请注意
    -
    前缀,如果
    .d
    文件尚不存在,它将使错误静音

    不需要单独的模式规则来生成依赖项文件。只需将
    -MD
    -MMD
    添加到正常的编译行,即可在编译源文件的同时生成
    .d
    文件。例如:

    %.o: %.c
         gcc $(INCLUDE) -MMD -c $< -o $@
    
    # -MD can be used to generate a dependency output file as a side-effect of the compilation process.
    
    %.o:%.c
    gcc$(包括)-MMD-c$<-o$@
    #-MD可用于生成依赖项输出文件,作为编译过程的副作用。
    
    详细说明,这对我来说非常有效:

    .depend: $(SOURCES)
        $(CC) $(CFLAGS) -MM $(SOURCES) | sed 's|[a-zA-Z0-9_-]*\.o|$(OBJDIR)/&|' > ./.depend
    

    这也适用于只有一个依赖项文件包含所有源文件的依赖项规则的情况。

    对于我来说,在gcc 4.1.2、gmake 3.8.1中,如果头文件不存在,则使用recipe“$(CC)$(CCFLAGS)-MF“$@”-MG-MM-MP-MT“$@”-MT$(顺便说一句,请确保避免放置“include”在您的第一个目标之上。将其放在Makefile的底部是合乎逻辑的,因为这一直是放置依赖项的传统位置,当它们必须手工制作时!
    -MT
    不适用于我的gcc 2.9.5,guest应该适用于3.x.xabove@checksum:…是不是14年前就被释放了?是的,我发现ut在使用过时的构建平台维护旧代码时:|它仍然使用2.9.1.57(被称为egcs而不是gcc),好的是它只有4个文件的最小依赖性,小于700k。:)坏的是它没有
    -MT
    支持(
    .depend: $(SOURCES)
        $(CC) $(CFLAGS) -MM $(SOURCES) | sed 's|[a-zA-Z0-9_-]*\.o|$(OBJDIR)/&|' > ./.depend