Я получаю следующую ошибку и не могу ни за что в жизни выяснить то, что я делаю неправильно.
$ gcc main.c -o main
Undefined symbols:
"_wtf", referenced from:
_main in ccu2Qr2V.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
main.c:
#include <stdio.h>
#include "wtf.h"
main(){
wtf();
}
wtf.h:
void wtf();
wtf.c:
void wtf(){
printf("I never see the light of day.");
}
Теперь, если я включаю целую функцию в заголовочный файл вместо просто подписи, это соответствует прекрасное, таким образом, я знаю, что wtf.h включается. Почему компилятор не видит wtf.c? Или я пропускаю что-то?
С уважением.
Вам необходимо связать wtf
с вашим main
. Самый простой способ скомпилировать их вместе - gcc
свяжет их за вас, например:
gcc main.c wtf.c -o main
Более длинный путь (отдельная компиляция wtf
):
gcc -c wtf.c
gcc main.c wtf.o -o main
Еще дольше (отдельная компиляция и связывание)
gcc -c wtf.c
gcc -c main.c
gcc main.o wtf.o -o main
Вместо последнего вызова gcc
вы можете запустить ld
напрямую с тем же эффектом.
Вы упускаете тот факт, что простое включение заголовка ничего не говорит компилятору о том, где находится фактическая реализация (определения) вещей, объявленных в заголовке.
Они могут быть в C-файле рядом с тем, который выполняет включение, они могут прийти из предварительно скомпилированной библиотеки статических ссылок, или динамической библиотеки, загруженной системным компоновщиком при чтении вашего исполняемого файла, или они могут прийти во время выполнения, контролируемой программистом явной динамической загрузки (семейство функций dlopen()
в Linux, например).
C не похож на Java, здесь нет неявного правила, что только потому, что файл C включает определенный заголовок, компилятор также должен сделать что-то, чтобы "волшебным образом" найти реализацию вещей, объявленных в заголовке. Вам нужно сказать ему.