Проблема с линковкой / Makefile между файлами 3 .c / .h и основным - PullRequest
0 голосов
/ 13 октября 2018

У меня есть 2 .h файла, которые содержат определения для функций, и 2 .c файла, связанные с .h файлами.Существует третий файл .c (не основной), который имеет заголовочный файл и хочет использовать функции из других 2 файлов .c.Использование make-файла:

CC=gcc
CFLAGS=-Wall -std=c99 -I headers

main: main.o carFunctions.o
        $(CC) $(CFLAGS) build/main.o build/carFunctions.o -o main
carFunctions.o: source/carFunctions.c
        $(CC) $(CFLAGS) -c  source/carFunctions.c -o build/carFunctions.o
linkedList.o: source/linkedList.c
        $(CC) $(CFLAGS) -c source/linkedList.c -o build/linkedList.o
fileManage.o: source/fileManage.c
        $(CC) $(CFLAGS) -c source/fileManage.c -o build/fileManage.o
main.o: source/main.c
        $(CC) $(CFLAGS) -c source/main.c -o build/main.o
clean:
        rm -i build/*.o

приводит к ошибке:

gcc -Wall -std=c99 -I headers -c source/main.c -o build/main.o
gcc -Wall -std=c99 -I headers -c  source/carFunctions.c -o build/carFunctions.o
source/carFunctions.c: In function ‘test’:
source/carFunctions.c:9:9: warning: ‘tes3t’ is used uninitialized in this function [-Wuninitialized]
   tes3t = push(tes3t,"TEST");
         ^
gcc -Wall -std=c99 -I headers build/main.o build/carFunctions.o -o main
build/carFunctions.o: In function `test':
carFunctions.c:(.text+0x15): undefined reference to `push'
collect2: error: ld returned 1 exit status
makefile:5: recipe for target 'main' failed
make: *** [main] Error 1

Три файла .c для функций следующие:

carFunctions.c:

#include <stdio.h>
#include "carFunctions.h"
#include "linkedList.h"
#include "fileManage.h"

void test()
{
  LL* tes3t;
  tes3t = push(tes3t,"TEST");
  printf("it works?");
}

fileManage.c:

#include <stdio.h>
#include "fileManage.h"

void test2()
{
  printf("fileman");
}

и connectedList.c:

#include <stdio.h>
#include <stdlib.h>
#include "linkedList.h"

struct LLStruct
{
  char* plateNum;
  struct LLStruct* next;
};

LL* push(LL* myList, char* data)
{
  LL* newNode = malloc(sizeof(LL));
  if(newNode != NULL)
  {
    newNode->plateNum = data;
    newNode->next = myList;
    return newNode;
  }
  else
  {
    return myList;
  }
}

Заголовочные файлы: carFunctions.h:

#ifndef CARFUN
#define CARFUN

void test();

#endif

fileManage.h:

#ifndef FILEMAN
#define FILEMAN

void test2();

#endif

connectedList.h:

#ifndef LINKLIST
#define LINKLIST

typedef struct LLStruct LL; // Defines a structure for linked lists as "LL"
LL* push(LL* myList, char* data); // Adds an item to the linked list
#endif

И, наконец, main.c:

#include <stdio.h>
#include "carFunctions.h"

int main()
{
  test();
  return 0;
}

Я не совсем уверен, гдеошибка исходит из-за того, что я не думаю, что есть пропущенные скобки.Это может быть ссылка на файл / makefile, но я недостаточно хорош, чтобы проверить ссылку на файл.

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Сначала вы должны исправить предупреждение о неинициализированной переменной tes3t.

Если у вас есть (например) / home / me / src:

Поместите все .c и .h файлов в / home / me / src / source

Создать / home / me / src / build

Поместить Makefile в / home / me / src

Учитывая это, вот фиксированный Makefile:

CC=gcc
CFLAGS=-Wall -std=c99 -I headers

OBJS += build/main.o
OBJS += build/carFunctions.o
OBJS += build/linkedList.o
OBJS += build/fileManage.o

build/main: $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) -o main

build/carFunctions.o: source/carFunctions.c
    $(CC) $(CFLAGS) -c  source/carFunctions.c -o build/carFunctions.o

build/linkedList.o: source/linkedList.c
    $(CC) $(CFLAGS) -c source/linkedList.c -o build/linkedList.o

build/fileManage.o: source/fileManage.c
    $(CC) $(CFLAGS) -c source/fileManage.c -o build/fileManage.o

build/main.o: source/main.c
    $(CC) $(CFLAGS) -c source/main.c -o build/main.o

clean:
    rm -f build/*.o build/main

Еще лучше, вот более простая версия, которая использует подстановочные знаки:

CC=gcc
CFLAGS=-Wall -std=c99 -I headers

OBJS += build/main.o
OBJS += build/carFunctions.o
OBJS += build/linkedList.o
OBJS += build/fileManage.o

build/main: $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) -o main

build/%.o: source/%.c
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -f build/*.o build/main
0 голосов
/ 13 октября 2018

Здесь на самом деле происходит две вещи:

  • Первый:

    source/carFunctions.c: In function ‘test’:
    source/carFunctions.c:9:9: warning: ‘tes3t’ is used uninitialized in this function [-Wuninitialized]
       tes3t = push(tes3t,"TEST");
    

    Это показывает, что вы передали неинициализированный указатель в качестве первого аргумента дляфункция push.Поскольку указатель неинициализирован, он может содержать что угодно, указывая на любое произвольное место в памяти, и поведение вашей программы при запуске может сильно различаться в зависимости от того, что происходит по этому адресу памяти.

    Тем не менее, это предупреждение, которое означает, что в конечном итоге он не несет ответственности за сбой процесса сборки.(Часто предупреждения могут показать основные причины более запутанных ошибок, которые появляются позже, поэтому стоит обратить на них внимание.)

  • Второе:

    build/carFunctions.o: In function `test':
    carFunctions.c:(.text+0x15): undefined reference to `push'
    collect2: error: ld returned 1 exit status
    

    Это показывает, что компоновщик не смог найти скомпилированный машинный код для функции push.В данном случае это потому, что вы просто не включили объектный файл, содержащий этот машинный код (linkedList.o), в командную строку компоновщика.При других обстоятельствах такого рода ошибка может иногда означать, что вы допустили ошибку в определении функции и забыли включить соответствующий заголовочный файл, чтобы компилятор мог уловить эту ошибку.

...