#gcc #linker #makefile #compilation
#gcc #компоновщик #makefile #Сборник
Вопрос:
Я довольно новичок в Makefiles и пытаюсь собрать исполняемый файл из 3 файлов: file1.c, file2.c и file1.h в исполняемый файл с именем exFile. Вот что я получил:
all: exFile
exFile: file1.o file2.o
gcc -Wall -g -m32 repeat.o show.o -o repeat
file1.o: file1.c file1.h
gcc -Wall -g -m32 -S file1.c -o file1.o
file2.o: file2.c
gcc -Wall -g -m32 -S file2.c -o file2.o
Я искал в Интернете make-файлы в этом формате, но пришел с пустыми руками, поэтому мне было интересно, может ли кто-нибудь помочь. Когда он пытается скомпилироваться, я получаю:
usr/bin/ld:file1.o:1: file format not recognized; treating as linker script
Я компилировал программы, используя файлы ассемблера, но я не уверен, что делать с файлами c или файлом file1.h. file1.c включает file1.h, поэтому я должен связать их (я думаю?). Любые предложения или ссылки на ссылку были бы оценены
Ответ №1:
У вас две проблемы с вашей gcc
командной строкой. Во-первых, вы указываете -S
флаг, который заставляет gcc выдавать ассемблерный код, а не объектный код. Во-вторых, у вас отсутствует -c
флаг, который сообщает gcc скомпилировать файл в объектный файл, но не связать его. Если вы просто удалите -S
и больше ничего не измените, в итоге вы получите исполняемую программу с именем file1.o
и другую с именем file2.o
, а не два объектных файла.
Помимо этих ошибок, вы могли бы упростить свой makefile, используя шаблонные правила. Я предлагаю вам вместо этого попробовать следующее:
all: exFile
exFile: file1.o file2.o
gcc -Wall -g -m32 $^ -o $@
%.o: %.c
gcc -Wall -g -m32 -c $< -o $@
file1.o: file1.h
Или, как указывает EmployedRussian, вы можете выбрать что-то еще более минимальное, что использует больше встроенных функций GNU make:
CC=gcc
CFLAGS=-Wall -g -m32
all: exFile
exFile: file1.o file2.o
$(LINK.c) $^ -o $@
file1.o: file1.h
Комментарии:
1. Этот makefile все еще довольно плох. Вам не нужно шаблонное правило — в make оно уже встроено. Кроме того, exFile всегда будет устаревшим, потому что вместо этого вы создаете «repeat». Если вы предоставляете пример того, как исправить makefile, пожалуйста, сделайте это лучше!
2. @Employed Russian: упс, спасибо, что заметили эту опечатку (скопировано из OP). Что касается упрощения makefile, да, это могло бы быть проще, но я не уверен, что это помогло бы пониманию OP, учитывая, что проблемы вызывала не структура makefile.
Ответ №2:
-S
Переключение на gcc сообщает ему выводить ассемблер, так что это:
gcc -Wall -g -m32 -S file1.c -o file1.o
Вводит ассемблер в, file1.o
но вы хотите, предположительно, скомпилировать file1.c
в объектный код:
gcc -Wall -g -m32 file1.c -o file1.o
Когда компоновщик получает ваш, file1.o
он сбит с толку, потому что file1.o
работает на ассемблере, когда компоновщик ожидает объектный код, отсюда и ваша ошибка.
Поэтому избавьтесь от -S
переключателей для file1.o
и file2.o
.
Комментарии:
1. Спасибо за ответ, но по-прежнему безуспешно … получаю ту же ошибку. Я полностью в тупике по этому поводу. Я изучу это подробнее, я знаю, что я не так уж далек от истины, возможно, просто какую-то деталь я упустил.
2. @user695978: Что произойдет, если вы
file file1.o
получите тип файла?