Заголовочный файл включен, но ссылка до сих пор не определена - PullRequest
0 голосов
/ 13 мая 2019

Я упростил код до минимума

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

структура каталогов:

  • / Главная / Проекты / JSON-тест / main.c
  • / home / projects / json-test / замороженный / {содержимое https://github.com/cesanta/frozen репо}

Что я делаю:

  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, что «вы должны искать json_scanf внутри frozen.h». Должен ли я пропустить какой-то шаг «склеивания» или «связывания»?

ОБНОВЛЕНИЕ: на основе ответов я создал это 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 Ответ

2 голосов
/ 13 мая 2019

Тьфу.У вас нет ошибки.У разработчика библиотеки есть некоторые действительно плохие методы кодирования.По какой-то причине его заголовок не достаточен для компиляции.Если вы посмотрите на unit_test.c в хранилище замороженных, вы увидите, что он на самом деле включает frozen.c вместо frozen.h.Если вы измените свой #include "frozen.h" на #include "frozen.c", он будет работать нормально.Другой вариант - явно указать файл .c:

gcc frozen/frozen.c main.c -Ifrozen

Обычно вы помещаете все в заголовок или требует, чтобы библиотека компилировалась как a.файл, а затем связать его при использовании, но он не предоставил make-файл, который делает это.

РЕДАКТИРОВАТЬ: Вы также можете скомпилировать frozen.o заранее, но автор библиотеки должен был действительно предоставить make-файлчтобы сделать это ...

gcc -c frozen.c -o ../frozen.o
cd ..
gcc main.c frozen.o -Ifrozen 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...