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
)