包括标头文件,但仍未定义的参考



我将代码简化为最小

#include "frozen.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
int main()
{
    char *json = "{ "a": 123, "b": "hi", c: true }";
    int value = 0;
    json_scanf(json, strlen(json), "{c: %B}", &value);
    printf("Hello Worldn");
    // assert( json != NULL );
    printf( "json: %sn", json );
    printf( "json.c: %sn", value );
    // free( json );
    return 0;
}

目录结构:

  • /home/projects/json-test/main.c
  • /home/projects/json-test/冻结/{https://github.com/cesanta/frozen repo的内容}

我做什么:

  1. gcc main.c -Ifrozen -o main

输出中显示的内容:

main /tmp/ccsYWNAP.o: In function `main': main.c:(.text+0x43):
undefined reference to `json_scanf' collect2: error: ld returned 1
exit status

我在C中的知识非常有限,因此我可能会缺少一些步骤,因此,考虑到我实际上没有做过上面写的其他任何事情,也许我应该拥有。我习惯于松散地键入PHP/JS/Python的语言,但是我读到的只是包括文件不告诉GCC"您应该在frozen.h中搜索JSON_SCANF"。我是否缺少某种"胶"或"链接"步骤?

更新:根据响应,我创建了此Makefile

CC = gcc
FLAGS = -std=c99
DEST_DIR = ./bin
DEST_PATH = "$(DEST_DIR)/main"
BUILD_DIR = ./build

all: clean directories json main.o
    $(CC) $(BUILD_DIR)/*.o -o $(DEST_PATH) $(FLAGS)
main.o: src/main.c $(BUILD_DIR)/frozen.o
    $(CC) src/main.c -c -o $(BUILD_DIR)/main.o $(FLAGS)
json: json.o

json.o: src/frozen/frozen.c src/frozen/frozen.h
    $(CC) src/frozen/frozen.c -c -o $(BUILD_DIR)/frozen.o $(FLAGS)
clean:
    rm -rf $(BUILD_DIR)
directories:
    mkdir -p $(DEST_DIR)/
    mkdir -p $(BUILD_DIR)/

#include "frozen.h"更改为#include "frozen/frozen.h",并且运行make创建可以使用./bin/main命令成功运行的build/main文件。谢谢!

ugh。你没有错误。图书馆开发人员有一些非常糟糕的编码实践。基本上,无论出于何种原因,他的标题都不足以编译。如果您在冷冻存储库中查看unit_test.c,您会发现他实际上包括frozen.c而不是frozen.h。如果将#include "frozen.h"更改为#include "frozen.c",则可以正常工作。另一个选项是明确提供.c文件:

gcc frozen/frozen.c main.c -Ifrozen

通常,您将所有内容都放在标题中,或者要求库作为.a文件,然后在您使用时链接,但他没有提供这样做的makefile。

编辑:您也可以事先编译frozen.o,但是图书馆的作者应该确实提供了一个制造商来做到这一点...

gcc -c frozen.c -o ../frozen.o
cd ..
gcc main.c frozen.o -Ifrozen