Home > Enterprise >  How does make use variables when expanding and compiling before linking?
How does make use variables when expanding and compiling before linking?

Time:12-22

Info:

Linux watvde0453 3.10.0-1062.1.1.el7.x86_64 #1 SMP Fri Sep 13 22:55:44 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

GNU Make 4.2.1
Built for x86_64-pc-linux-gnu

Hi

I have been playing around with a make file to allow builds of shared, static libraries and an exe (and also to get some sort of understanding about how it works) and came across some behavior I do not understand.

I was trying to separate out the flags used for lib / exe into separate variables, but when using a line to compile and link all in one it looks like only the CFLAGS variable is being included for the compile step.

When using the following makefile:

LIBCFLAGS := -fPIC
CFLAGS := -O3 -g -Wall -Werror
CC := gcc 
SRCS=hashfunction.c hashtable.c hashtablelinkedlist.c
OBJS=hashfunction.o hashtable.o hashtablelinkedlist.o
LIBSO  = lib$(NAME).so

libso: $(OBJS)
    $(CC) $(LIBCFLAGS) $(CFLAGS) -shared -o $(LIBSO) $(OBJS)

I get the following output when running the make command for libso:

$ make libso
gcc -O3 -g -Wall -Werror   -c -o hashfunction.o hashfunction.c
gcc -O3 -g -Wall -Werror   -c -o hashtable.o hashtable.c
gcc -O3 -g -Wall -Werror   -c -o hashtablelinkedlist.o hashtablelinkedlist.c
gcc -fPIC -O3 -g -Wall -Werror -shared -o lib.so hashfunction.o hashtable.o hashtablelinkedlist.o
/tools/oss/packages/x86_64-centos7/binutils/default/bin/ld: hashtable.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
hashtable.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [Makefile:12: libso] Error 1

I can get it all working by sticking all the flags in CFLAGS, but I was wondering if anyone could explain what make is doing underneath ?

It looks like the $(LIBCFLAGS) is being ignored for the implicit compile lines, but $(CFLAGS) is not. Is CFALGS used implicitly by make for all compilations ?

CodePudding user response:

You can see all the built-in rules make knows about by running make -p -f/dev/null. There you'll see:

%.o: %.c
#  recipe to execute (built-in):
        $(COMPILE.c) $(OUTPUT_OPTION) $<

which is the built-in rule make uses to create a .o file from a .c file. Looking elsewhere in the output you'll see:

COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

so these are the variables make uses to compile .c files into .o files.

  • Related