How Do I get Compiler to Recognize Reference to Library?

0

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!

c
makefile
compiler-errors
asked on Stack Overflow Mar 18, 2018 by Zach466920

1 Answer

1

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
answered on Stack Overflow Mar 18, 2018 by John Bollinger

User contributions licensed under CC BY-SA 3.0