gcc 如何创建一个编译自动生成的C文件的Makefile?

8gsdolmq  于 2023-01-30  发布在  其他
关注(0)|答案(1)|浏览(163)

使用常规C文件自动编译自动生成的C文件

我们开发了一个程序“cperformer”,它能够从文本文件生成C文件(为了简单起见)。它是一种“元编译器”,可以生成C文件作为输出。因此,我们希望通过自动生成每个C文件作为生成文件的第一步来改进这个“C生成器”的使用,然后编译所有这些生成的C文件并将其与其他已经与GCC一起存在于同一makefile中的C文件链接在一起。

* 生成文件1*

C_GEN   :=./cperformer -n
CC      :=gcc
CFLAGS  :=-I.

#List all .c files generated from .text files 
AUTO_SRCS   = $(wildcard *.text)
AUTO_OBJS_C := $(patsubst %.text,%_alg.c,$(AUTO_SRCS))

$(info *INFO* Text files = $(AUTO_SRCS))

#List all .c files to compile (auto-generated or not)
SRCS = $(AUTO_OBJS_C)
SRCS += $(wildcard *.c)
OBJS := $(patsubst %.c,%.o,$(SRCS))

$(info *INFO* C files = $(SRCS))

# Main target rule
target : $(OBJS)
    $(CC) -o $@ $(OBJS)  $(CFLAGS)

# Pre-compilation step (some C files generation)
prelim $(AUTO_OBJS_C): $(AUTO_SRCS)
    $(C_GEN) $<

# Pre-compilation step (object files generation)
%.o: %.c
    $(CC) -c -o $@ $< $(CFLAGS)

all: prelim target

clean :
    rm -f TARGET $(OBJS) *_alg*

* 错误1*

$ make all
*INFO* Text files = file3.text file2.text file1.text
*INFO* C files = file3_alg.c file2_alg.c file1_alg.c linked_list.c main.c

./cperformer -n file3.text
Compiling: file3.text ...
 No error.
 Done.

gcc -c -o file3_alg.o file3_alg.c -I.

./cperformer -n file3.text
Compiling: file3.text ...
 No error.
 Done.

gcc -c -o file2_alg.o file2_alg.c -I.
gcc: error: file2_alg.c: No such file or directory
gcc: fatal error: no input files
compilation terminated.
make: *** [Makefile:29: file2_alg.o] Error 1

它失败的原因是“cperformer”程序被要求在每次生成“file3.c”时生成相同的C文件,因此GCC没有按预期找到“file2.c”,并中止编译。

* 生成文件2*

使用“%”替换上述makefile的C生成规则:

# Pre-compilation step (some C files generation)
%.c: %.text
    $(C_GEN) $<

* 错误2*

make: *** No rule to make target 'file3_alg.o', needed by 'target'.  Stop.

这里什么都不编译。

* 生成文件3*

肮脏的修补

batch_c_generation :
    @$(foreach TXT_FILE, $(AUTO_SRCS), $(C_GEN) $(TXT_FILE);)

这是一种工作方式,但仍然非常脏,因为它在每次构建时重新生成所有C文件,并且在每次构建之间没有正确清除它时会出现一些重复错误。
如何修复makefile?

83qze16e

83qze16e1#

您已经很接近了--只需将您的模式规则修改为如下所示:

%_alg.c : %.text
    $(C_GEN) $<

正如@tripleee提到的,makefile 1规则失败的原因是它扩展为如下形式:

file2_alg.c file1_alg.c: file2.text file1.text
   $(CGEN) $<

在本例中,$<扩展到第一个依赖项,该依赖项始终为file2.text...
在makefile 2示例中,使用了%.c而不是%_alg.c(因此没有构建file2_alg.c的规则,也没有构建file2_alg.o的规则)

相关问题