如何让编译器识别对库的引用?

时间:2018-03-18 18:28:01

标签: c makefile compiler-errors

我下载了json-c库并尝试在我的环境中进行一些基本测试(使用Atom和gcc的Ubuntu)。但是,我似乎在makefile中遗漏了一些东西,因为每次我尝试编译时都会得到未定义的引用错误。以下是我试图运行的内容,

#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;
}

根据网站的说法,我应该使用这两个标志链接到图书馆。

CFLAGS += $(shell pkg-config --cflags json-c)
LDFLAGS += $(shell pkg-config --libs json-c)

我在下面的makefile中这样做,但它仍然无法正常工作。

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 *

当我跑步时,让json&#39;我收到以下错误,

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

我非常擅长编写makefile,所以希望它有点傻。任何建议都会有所帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

链接器命令行上的目标文件和库的顺序非常重要。按照遇到的顺序搜索库,以便找到满足前面对象中的依赖项的函数。您将所有库放在需要它们的对象之前,因此它们实际上不会用于解析任何未定义的引用。

此外,您正在非常规地使用一些众所周知的make变量,并且根本不使用make的内置默认值:

  • 变量CC,如果您选择重新定义它,则应包含运行C编译器的基本命令。通常这不包括任何标志:

    CC = gcc
    # or
    CC = /usr/bin/gcc
    
  • 然后将所有所需的C编译标记放入CFLAGS变量:

    CFLAGS = -O3 $(shell pkg-config --cflags json-c) -Wall -Wextra -pedantic -std=c99 -g -fsanitize=address
    
  • 我必须假设当json-c建议将json-c库选项放在LDFLAGS中时,json-c意味着给你一个说明性的例子而不是食谱。使用GNU make,pkg-config --libs的输出最好放在变量LDLIBS中:

    LDLIBS = $(shell pkg-config --libs json-c)
    
  • 话虽如此,如果您还依赖make的内置规则,则以常规方式使用内置变量最为重要。这些对你的情况来说已经足够了,所以你实际上不必在你的makefile中表达一个构建命令,只需要适当的依赖:

    json: json_type.o
    

因此,假设正确安装了json-c和pkg-config,并且您正在使用GNU make,那么这个Makefile就足够了:

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