GNU makes an implicit archive rule with a stem

I am trying to configure the Makefile to create both static (.a) and dynamic (.so) libraries depending on the extension of the target file.

I previously used the following Makefile for static libraries only:

NAME    :=  config

LIB     :=  lib$(NAME).a

SRC     :=  $(wildcard *.c)

OBJ     :=  $(SRC:.c=.o)

CFLAGS  +=  -W -Wall

.PHONY:     all clean fclean re

all:        $(LIB)

clean:
    @$(RM) $(OBJ)

fclean:     clean
    @$(RM) $(LIB)

re:         fclean all

$(LIB): $(LIB)($(OBJ))
    ranlib $@

My main goal is to collect several libraries, only changing the variables LIBand NAME.

Everything worked fine, so I added the following for dynamic libraries:

LDFLAGS +=  -shared

%.so:   CFLAGS += -fPIC
%.so:   $(OBJ)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^

And changed the rule $(LIB):to the following general rule:

%.a:    %.a($(OBJ))
    ranlib $@

If I change LIBto lib$(NAME).so, everything will work as expected, but with the extension .amake the fingerprints of me with this error:

make: *** No rule to make target 'libconfig.a', needed by 'all'. Stop.

The only solution I found was to add another explicit rule :

%.a($(OBJ)):    $(OBJ)
    $(AR) rv $@ $^

And now everything works.

GNU make ar, .

- - ?

P.S.: make -v :

GNU Make 3.82
Built for x86_64-unknown-linux-gnu

64- OpenSUSE 12.3 (Dartmouth).

+4
3

, , .

- conditional :

ifeq "$(suffix $(LIB))" ".a"
$(LIB): $(LIB)($(OBJ))
else ifeq "$(suffix $(LIB))" ".so"
$(LIB): override CFLAGS += -fPIC
$(LIB): $(OBJ)
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
endif

Makefile, , :

NAME := config

LIB := lib$(NAME).so

SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(OBJ:.o=.d)

CPPFLAGS := -MMD -MP
CFLAGS   := -W -Wall
LDFLAGS  := -shared
ARFLAGS  := rs

.PRECIOUS: $(OBJ)
.PHONY: all clean fclean re

all: $(LIB)

clean:
    $(RM) $(OBJ) $(DEP)

fclean: clean
    $(RM) $(LIB)

re: fclean all

ifeq "$(suffix $(LIB))" ".a"
$(LIB): $(LIB)($(OBJ))
else ifeq "$(suffix $(LIB))" ".so"
$(LIB): override CFLAGS += -fPIC
$(LIB): $(OBJ)
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
endif

ifeq "$(MAKECMDGOALS)" ""
-include $(DEP)
endif

, ARFLAGS , ar. r , , s (ranlib ).

0

, , , . , - . make , .

, . , :

$(foreach a,$(filter %.a,$(MAKECMDGOALS) $(.DEFAULT_GOAL)),$(eval $a: $a($$(OBJ)); ranlib $$@))

all, / . , , .

+3

You need to specify which .o files a particular .a file depends on. You can do this with a simple dpendency without any action:

libconfig.a: libconfig.a($(OBJ))

make will then invoke the default rule to place .o files in the .a file to actually create libconfig.a

0
source

Source: https://habr.com/ru/post/1533537/


All Articles