0

My problem with re

I have a problem with the re recipe in my Makefile when I have --jobs greater than 1.

When I run make re --jobs=N it successfully deletes the object files and the archive via fclean. It then sucessfully recompiles the library via all if N=1:

$ make re --jobs=1

rm -rf obj/
rm -f library.a
mkdir -p obj/
cc -c -Wall -Werror -Wextra func01.c -o obj/func01.o
...
cc -c -Wall -Werror -Wextra func37.c -o obj/func37.o
ar -crs library.a obj/func01.o ... obj/func37.o

However, if N>1, it always makes fclean but only makes all every 2nd in 2 consecutive runs:

$ make re --jobs=2

rm -rf obj/
rm -f libft.a

$ make re --jobs=2

rm -rf obj/
rm -f library.a
mkdir -p obj/
cc -c -Wall -Werror -Wextra func01.c -o obj/func01.o
...
cc -c -Wall -Werror -Wextra func37.c -o obj/func37.o
ar -crs library.a obj/func01.o ... obj/func37.o

I think it tries to make fclean and all simultaneously and doesn't finish the recipe correctly every 1st in 2 runs. Is this even possible? Do I forget it and just use --jobs=1 or do I fix it and make it work for any number of --jobs? How?

My Makefile

It's a Makefile that compiles a certain library archive (library.a) for a certain school project. I have 1 C header file (library.h) and 37 explicitly listed C source files (func01.c ... func37.c). The compiled object files have a dedicated obj/ directory. The Makefile does not relink and looks like this:

NAME    :=  library.a
CFLAGS  :=  -Wall -Werror -Wextra

H_FILES :=  library.h
C_FILES :=  func01.c ... func37.c

O_DIR   :=  obj/
O_FILES :=  $(C_FILES:%.c=$(O_DIR)%.o)

all: $(NAME)

$(NAME): $(O_FILES)
    ar -crs $@ $^

$(O_DIR):
    mkdir -p $@

$(O_FILES): $(O_DIR)%.o: %.c $(H_FILES) | $(O_DIR)
    $(CC) -c $(CFLAGS) $< -o $@

clean:
    rm -rf $(O_DIR)

fclean: clean
    rm -f $(NAME)

re: fclean all

My environment

I use GNU Make 4.1 built for x86_64-pc-linux-gnu on Debian GNU/Linux under WSL (Linux 4.4.0-19041-Microsoft #1237-Microsoft Sat Sep 11 14:32:00 PST 2021 x86_64 GNU/Linux).

Arthur Khazbs
  • 705
  • 8
  • 19
  • 1
    The first answer on that question shows how create a rebuild target which does clean in parallel, then does the build in parallel, with the clean finishing before the build is started. – Nick ODell Nov 14 '21 at 18:04
  • Thank you! This answer helped: https://stackoverflow.com/a/8496739/7212563 I did rely on the order of prerequisites, but now I explicitly specified a sequence of two submakes: first for `fclean`, then for `all`. – Arthur Khazbs Nov 14 '21 at 18:19

0 Answers0