包含头文件,但仍未定义参考

时间:2019-05-13 10:36:01

标签: c

我已将代码简化到最少

#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 World\n");
    // assert( json != NULL );
    printf( "json: %s\n", json );
    printf( "json.c: %s\n", value );
    // free( json );

    return 0;
}

目录结构:

我做什么:

  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,创建build/main文件,可以使用./bin/main命令成功运行该文件。谢谢!

1 个答案:

答案 0 :(得分:2)

U。你没有错。库开发人员有一些非常糟糕的编码习惯。基本上,无论出于何种原因,他的标头都不足以进行编译。如果查看冻结的存储库中的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,但是库的作者确实应该提供了一个makefile来实现此目的...

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