Reputation: 165
I downloaded the json-c library and was trying to do some basic tests in my environment (Ubuntu with Atom and gcc). However, I seem to be missing something in my makefile because every time I try to compile I get undefined reference errors. Below is what I'm trying to run,
#include "json.h"
#include <stdio.h>
int main() {
struct json_object *jobj;
char *str = "{ \"msg-type\": [ \"0xdeadbeef\", \"irc log\" ], \
\"msg-from\": { \"class\": \"soldier\", \"name\": \"Wixilav\" }, \
\"msg-to\": { \"class\": \"supreme-commander\", \"name\": \"[Redacted]\" }, \
\"msg-log\": [ \
\"soldier: Boss there is a slight problem with the piece offering to humans\", \
\"supreme-commander: Explain yourself soldier!\", \
\"soldier: Well they don't seem to move anymore...\", \
\"supreme-commander: Oh snap, I came here to see them twerk!\" \
] \
}";
printf("str:\n---\n%s\n---\n\n", str);
jobj = json_tokener_parse(str);
printf("jobj from str:\n---\n%s\n---\n", json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY));
return 0;
}
According to website, I'm supposed to use the two flags to link to the library.
CFLAGS += $(shell pkg-config --cflags json-c)
LDFLAGS += $(shell pkg-config --libs json-c)
I do that in the makefile below but it still doesn't work.
CFLAGS += $(shell pkg-config --cflags json-c)
LDFLAGS += $(shell pkg-config --libs json-c)
CCBIN=/usr/bin/gcc
CC=$(CCBIN) $(CFLAGS) $(LDFLAGS) -Wall -Wextra -pedantic -std=c99 -g -fsanitize=address
default: json
json: json_type.c
$(CC) -O3 -o json json_type.c -lm
.PHONY: clean
clean:
rm -Rf *.o lib/*.o json *.dSYM
.PHONY: package
package:
tar -cvzf json.tar *
When I run 'make json' I get the following errors,
make json
/usr/bin/gcc -I/usr/local/include/json-c -L/usr/local/lib -ljson-c -Wall -Wextra -pedantic -std=c99 -g -fsanitize=address -O3 -o json json_type.c -lm
/tmp/ccXo2zav.o: In function `main':
/home/zachary/Atom_Projects/Projects/SandBox/JSON/json_type.c:25: undefined reference to `json_tokener_parse'
/home/zachary/Atom_Projects/Projects/SandBox/JSON/json_type.c:26: undefined reference to `json_object_to_json_string_ext'
collect2: error: ld returned 1 exit status
makefile:10: recipe for target 'json' failed
make: *** [json] Error 1
I'm really new to writing makefiles so hopefully it's something silly. Any advice would be helpful, thanks!
Upvotes: 0
Views: 829
Reputation: 181244
The order of object files and libraries on the linker command line is significant. Libraries are searched in the order they are encountered in order to find function to satisfy dependencies in the preceding objects. You are putting all the libraries before the objects that need them, so they won't actually be used to resolve any of those undefined references.
Additionally, you are using some well-known make
variables unconventionally, and making no use at all of make
's built-in defaults:
variable CC
, if you choose to redefine it, should contain the essential command for running the C compiler. Usually this does not include any flags:
CC = gcc
# or
CC = /usr/bin/gcc
you would then put all the C compilation flags you need into the CFLAGS
variable:
CFLAGS = -O3 $(shell pkg-config --cflags json-c) -Wall -Wextra -pedantic -std=c99 -g -fsanitize=address
I have to assume that json-c means to give you an illustrative example, not a recipe, when it suggests putting the json-c library options in LDFLAGS
. With GNU make, the output of pkg-config --libs
would be better put in variable LDLIBS
:
LDLIBS = $(shell pkg-config --libs json-c)
With that said, using built-in variables in the conventional way matters most if you also rely on make
's built-in rules. These will be entirely sufficient for your case, so you don't actually have to express a build command in your makefile, just the appropriate depedencies:
json: json_type.o
So, supposing that json-c and pkg-config are properly installed, and you're using GNU make, this Makefile should be sufficient:
CC = /usr/bin/gcc
CFLAGS = -std=c99 -O3 -g
CFLAGS += $(shell pkg-config --cflags json-c)
CFLAGS += -fsanitize=address -Wall -Wextra -pedantic
LDLIBS = $(shell pkg-config --libs json-c)
all: json
json: json_type.o
clean:
rm -rf *.o json
.PHONY: clean
Upvotes: 1