Home > Back-end >  How to create a Makefile that compiles auto-generated C files?
How to create a Makefile that compiles auto-generated C files?

Time:01-30

Automate the compilation of auto-generated C files with regular C files

We have developed a program "cperformer" that is able to generate a C file from a text file (to keep it simple). It is a kind of "meta-compiler" that generates C file as output. Thus, we would like to improve the usage of this "C generator" by automating the generation of each C file as a first step of a makefile, and then compile and link together all of these generated C files with other C files already present with GCC in the same makefile.

Makefile 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*

Error 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

It fails because the "cperformer" program is asked to generate the same C file each time "file3.c" so GCC don't find "file2.c" as expected and it aborts the compilation.


Makefile 2

Replace the C generative rule of the above makefile with the use of "%" :

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

Error 2

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

Nothing compiles here.


Makefile 3

The dirty fix

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

This is kind of working but remains very dirty because it re-generates all C files at each build and some duplication errors appear when it is not properly cleared between each make.


How can I fix the makefile ?

CodePudding user response:

You were close -- simply fix your pattern rule to look like this:

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

As @tripleee mentioned, the reason your makefile1 rule failed was that it expands to something like:

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

In this case $< expands to the first dependency which will always be file2.text...

In your makefile2 example, you used %.c instead of %_alg.c (and hence there's no rule to build file2_alg.c, and therefore no rule to build file2_alg.o)

  • Related