我下载了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,所以希望它有点傻。任何建议都会有所帮助,谢谢!
答案 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