C — множественное определение с помощью makefile

#c #makefile

#c #makefile

Вопрос:

Я пытаюсь скомпилировать свою программу на C с помощью make, и я столкнулся с этой проблемой, которую я не совсем понимаю. У меня есть 3 файла в папке ‘calc’ моего проекта: add.c sub.c и main.c. Мой Makefile находится в корневой папке моего проекта, в которой есть папка calc, которую я упомянул в ней. Вот как выглядит мой Makefile:

 CC=gcc
OBJECTS=obj/main.o obj/add.o obj/sub.o 

elf/new: ${OBJECTS}
        ${CC} -o elf/new ${OBJECTS}
obj/main.o: calc/main.c
    ${CC} -c -g calc/main.c -o obj/main.o
obj/add.o: calc/add.c
    ${CC} -c -g calc/add.c -o obj/add.o
obj/sub.o: calc/sub.c
    ${CC} -c -g calc/sub.c -o obj/sub.o

clean:
    rm obj/${OBJECTS} elf/new
  

Когда я ввожу «make» в терминал для компиляции, я получаю сообщение об ошибке, подобное этому:

 gcc -c -g calc/add.c -o obj/add.o
gcc -c -g calc/sub.c -o obj/sub.o
gcc -o elf/new obj/main.o obj/add.o obj/sub.o 
obj/add.o: In function `add':
/home/bigger/workspace/test/calc/add.c:1: multiple definition of `add'
obj/main.o:/home/bigger/workspace/test/calc/add.c:1: first defined here
obj/sub.o: In function `sub':
/home/bigger/workspace/test/calc/sub.c:1: multiple definition of `sub'
obj/main.o:/home/bigger/workspace/test/calc/sub.c:1: first defined here
collect2: error: ld returned 1 exit status
makefile:5: recipe for target 'elf/new' failed
make: *** [elf/new] Error 1
  

И мой код там:

 bigger@linux:~/workspace/test> cat calc/add.c 
int add(int a, int b){
    return a b;
}


bigger@linux:~/workspace/test> cat calc/sub.c 
int sub(int a, int b) {
    return a-b;
}


bigger@linux:~/workspace/test> cat calc/main.c 
#include <stdio.h>
#include "add.c"
#include "sub.c"

int main(int argc, char* argv[])
{
    int a = 10;
    int b = 5;
    printf("add: %dnsub:%dn", a b, a-b);
    return 0;
}
  

Комментарии:

1. Включить заголовочные файлы, а не c-файлы.

2. Я переименовал файлы add/ sub.c в add / sub.h. И получил еще одну ошибку: obj / add.o: файл не распознан: формат файла не распознан

3. Не переименовывайте c-файлы в h-файлы, записывайте дополнительные h-файлы только с объявлениями, а не с определениями .

4. Сохраните их как три c-файла. Удалите #includes из main.c, вместо этого объявите «extern int sub(int,int); extern int add(int,int);»

5. Большое спасибо @Secto Kia. Теперь ошибка исчезает

Ответ №1:

Когда вы включаете, это делает функции add и sub частью вашего main.c, затем, когда вы создаете, вы связываете main (который уже имеет функции по include) с объектами add и sub, которые имеют одинаковые функциональные символы. Вам нужно включать заголовочные файлы с объявлениями функций, а не включать определения функций. См. http://www.cprogramming.com/declare_vs_define.html для более длительного обсуждения.