Elle
Elle

Reputation: 15

Makefile: how to specify library name at the end of command using patsubst

I am new to Makefile, C and Linux. I am using gcc & ubuntu. I encountered a problem while trying to compile the code with a link to a library.

Here is my problem. I have:

a_tests.c & b_tests.c files in "tests" folder
lib.a file in "build" folder

Here is the codes in Makefile related to the problem:

CFLAGS=-g -O2 -Wall -Wextra -Isrc -DNDEBUG $(OPTFLAGS)
TARGET=build/lib.a

TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))

tests: CFLAGS += $(TARGET)
tests: $(TESTS)

When the tests files are compiled, "undefined reference to 'XXXfunction'"errors will be prompted. Because what executed behind is

gcc -g -O2 -Wall -Wextra -Isrc -DNDEBUG build/lib.a tests/a_tests.c -o test/a_tests
gcc -g -O2 -Wall -Wextra -Isrc -DNDEBUG build/lib.a tests/b_tests.c -o test/b_tests

But "build/lib.a" should be placed after the output file name to solve it (If I manually type in the below commands, the codes would be successfully compiled), ie:

gcc -g -O2 -Wall -Wextra -Isrc -DNDEBUG tests/a_tests.c -o test/a_tests build/lib.a 
gcc -g -O2 -Wall -Wextra -Isrc -DNDEBUG tests/b_tests.c -o test/b_tests build/lib.a 

But I don't know how to change in the Makefile, I tried -l -L options, they didn't work. It would warn that "cannot find the .a file". Any help would be appreciated. Thank you so much in advance!

Upvotes: 0

Views: 384

Answers (1)

the busybee
the busybee

Reputation: 12610

Define the library as a dependency, because it is one. It will be appended at the end of the other dependencies, here: the source.

CFLAGS=-g -O2 -Wall -Wextra -Isrc -DNDEBUG $(OPTFLAGS)
TARGET=build/lib.a

TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(TEST_SRC:%.c=%)

tests: $(TESTS)

$(TESTS): $(TARGET)

The library does not need to be after the output file, but after the depending input file.

The makefile is further simplified:

  • Replaced the patsubst with a simpler expression.
  • Moved the target tests up, so it is found as the first and therefore default target.

Good luck!

Upvotes: 1

Related Questions