2

I'm very new to the makefiles. I'm compiling the c code file which contains cJson library from terminal using command

gcc -test1.c -o test -lcjson

with -lcjson at last and its running perfectly. But how to compile the same code using makefile as I have to add -lcjson at last. if I'm using without -lcjson I'm getting error

/tmp/cc4ESrx1.o: In function `parse_json':
test1.c:(.text+0x2d): undefined reference to `cJSON_Parse'
test1.c:(.text+0x42): undefined reference to `cJSON_GetObjectItem'
test1.c:(.text+0x59): undefined reference to `cJSON_GetObjectItem'
collect2: error: ld returned 1 exit status

I'm using a RTOS code

thanks in advance

Aditya
  • 23
  • 4
  • 1
    I believe your question is why you are getting undefined, you might want to review sequence of specifying the lib, also -test1.c should be -c test1.c – Pras Jun 08 '17 at 04:39
  • @Pras: No, `-c` is needed to get an object file. When compiling a single source file into an executable it should *not* be used. – Basile Starynkevitch Jun 08 '17 at 04:43
  • @Aditya: your are *not* compiling the C code of the `-lcjson` library. You are just *linking* and using that library. – Basile Starynkevitch Jun 08 '17 at 04:44

1 Answers1

-1

First, avoid naming your executable test since it is a standard program name (at least on POSIX).

Then, read documentation of GNU make. It contains a tutorial section.

At last, GNU make has several built-in rules, which you can get with make -p

See this answer for an example.

I strongly recommend compiling with all warnings and debug info (that is, with gcc -Wall -Wextra -g if using GCC). So put CFLAGS+= -Wall -Wextra -g and CC=gcc in your Makefile.

To link with your -lcjson add LIBES+= -lcjson in your Makefile. Remember that tab characters are important in a Makefile (so use some editor, e.g. emacs, able to edit them).

So try:

# your Makefile, replace four spaces with tab
CC= gcc
CFLAGS+= -Wall -Wextra -g
RM= rm -f
MY_SOURCES=$(wildcard *.c)
## above could be an MY_SOURCES= file1.c file2.c otherfile.c
MY_OBJECTS=$(patsubst %.c,%.o,$(MY_SOURCES))
# 
LIBES= -lcjson
#
.PHONY: all clean
##
all: myprog
## 
clean:
     $(RM) myprog *.o *~
myprog: $(MY_OBJECTS)

Use make --trace or remake -x to debug your Makefile

If you haver several *.c source files (that is translation units) linked together into the same program, you should have a common header file myheader.h (to share common declarations of all your public functions and variables) which should be #include-ed in every source file. Then you need to depend on it:

 MY_HEADER= myheader.h
 %.o: %.c $(MY_HEADER)

Notice that (with or without any Makefile) the order of program arguments to gcc is very significant. See this.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547