2014-12-11 8 views
0

Я пытаюсь создать Makefile для моей программы на Raspbian (Raspberry Pi). Моя программа состоит из кучи файлов .c и .h. Я посмотрел на бесчисленные Make-файлы, но я просто не понимаю, как это работает с несколькими файлами. В Makefile всегда есть файлы .o, но, как я понимаю, объектные файлы являются результатом компиляции, поэтому у меня нет o. Файлы, когда я пытаюсь скомпилировать мои файлы .c.Создание Makefile в Raspbian

Пожалуйста, объясните мне, как это работает.

Редактировать:

Спасибо. Поэтому я попробовал это, и он начинает компиляцию, но есть «множественное определение» ошибок. Пример:

Это мои файлы:

main.c main.h 
calibration.c calibration.h 
file.c file.h 
frame.c frame.h 
gamepad.c gamepad.h 
gpio.c gpio.h 
uart.c uart.h 
types.h 

это мой Makefile:

all: main 

main: main.o calibration.o file.o frame.o gamepad.o gpio.o uart.o 

%.o: %.c 
    gcc -c -std=c99 -Wall $< -o [email protected] -lncurses 

Где я могу поставить 'types.h'? С каждым файлом я

+1

Вы скомпилируете файлы источника ('.c') * в * object (' .o'). Для 'gcc' добавьте опцию' -c'. Затем, когда у вас есть ваши объектные файлы, вы связываете их вместе. Если вы правильно настроили свои зависимости, только исходные файлы, которые вы измените, будут перекомпилированы в объектные файлы при вызове 'make'. –

+0

Итак, я компилирую файлы .c по одному, а затем создаю файл makefile, где я связываю все файлы объектов вместе? – user3030653

+0

@ user3030653: Файл make не может сделать этого.Если ваша реальная проблема заключается в компиляции и связывании нескольких источников, а не с конкретной потребностью в make-файлах, тогда IDE, такая как Code :: Blocks, сделает это для вас и будет доступна на RPi через aptget и имеет другие преимущества, такие как GUI интерфейс для GDB и подсветки синтаксиса кода и навигации. – Clifford

ответ

1

Основной синтаксисом ошибкой нескольких определений "из make правил является:

target … : prerequisites … 
    recipe 
    … 
    … 

Слева от точки с запятой являются мишенями. Целями являются ваши объектные файлы (.o). Справа от точки с запятой находятся файлы, которые вам понадобятся для создания этого файла. Эти файлы являются исходными файлами (.c).

Давайте дадим основной пример того, как могло выглядеть такое правило.

%.o: %.c 
    gcc -c $< -o [email protected] 

Знак % - это шаблон. %.o означает все, что заканчивается .o. Итак, если вы хотите создать объектный файл, вы можете сказать make file.o, а make попытается найти правило, с помощью которого оно может сделать эту цель. Это правило, которое я только что показал в качестве примера, потому что file.o соответствует %.o.

Затем recipe. Это то, что будет выполнено. Обычно речь идет о вызове компилятора (gcc) и подачи его исходного файла для создания объектного файла. Это то, что мы делаем с gcc -c $< -o [email protected]. $< и [email protected] - target и prerequisites соответственно.

Итак, что происходит, когда вы просто хотите создать свою программу? Обычно вы набираете make, и он будет строить. Правило по умолчанию, которое используется при вводе make, составляет all. Итак, если вы сделаете правило о all, то вы можете указать, какие файлы вы хотите создать для создания своей программы. Пример такого правила:

all: main 

Затем, когда make вызывается, он обнаружит, что правила и выясняет, что нужно main.Для создания main вам нужно еще одно правило:

main: file.o 

Это правило говорит, что строить main, вам нужно file.o. Так что, когда вы положили все вместе, например правила вы получите это:

all: main 

main: file.o 

%.o: %.c 
    gcc -c $< -o [email protected] 

Обратите внимание, что вы можете указать более одного файла, так что вместо file.o, вы можете сказать, file.o main.o other_file.o и т.д. все предпосылки, что вы определяете, будет если они могут найти правило, чтобы сделать это.

+0

Я понимаю. Но как это работает с несколькими исходными файлами? Могу ли я создать одну цель с именем моей программы и поместить все исходные файлы в предварительные условия? – user3030653

+0

См. Мое редактирование. Если у вас возникнут вопросы, я буду рад ответить на них. – bzeaman

+0

Спасибо. Поэтому я попробовал это, и он начинает компиляцию, но есть «множественное определение» ошибок. Пример: Это мои файлы: main.c main.h calibration.c calibration.h file.c file.h frame.c frame.h gamepad.c gamepad.h gpio.c GPIO. ч uart.c uart.h types.h это мой Makefile: все: главный главная: main.o calibration.o file.o frame.o gamepad.o gpio.o uart.o % .o:% .c \t gcc -c -std = c99 -Wall $ <-o $ @ -lncurses Где я могу поставить «types.h»? С каждым файлом я получаю несколько «определений ошибок» – user3030653

1

очень простой, но типичный Makefile может выглядеть так

SOURCES = source1.c source2.c source3.c 
OBJECTS = $(SOURCES:%.c=%.o) 

TARGET = myExecutable 

$(TARGET): $(OBJECTS) 
    gcc $^ -o [email protected] 

%.o: %.c 
    gcc -c $< -o [email protected] 

осложненных частей:

  • SOURCES = source1.c source2.c source3.c Это определение переменной, он присваивает строку "source1.c source2.c source3.c переменной SOURCES.

  • $(SOURCES:%.c=%.o) Это сокращенная версия patsubsttext function. Он принимает весь текст из переменной $(SOUCES) и заменяет шаблон %.c на %.o, то есть он принимает, например, строку source1.c и замените ее на source1.o.

  • $(TARGET): $(OBJECTS) Это означает, что myExecutable зависит от всех объектных файлов, что означает, что если будет изменен один файл объекта, тогда будет выполнена команда в правиле.

  • gcc $^ -o [email protected] Это вызывает команду gcc, передавая все зависимости ($^) в качестве аргументов (то есть, все объектные файлы), и говорит gcc для вывода файла с именем цели ([email protected]).

  • %.o: %.c Это правило, которое заставляет объектные файлы зависеть от исходного файла. Поэтому, если у вас есть source1.c, тогда source1.o будет зависеть от этого исходного файла.

  • gcc -c $< -o [email protected] Это команда, которая компилирует исходный файл (первая зависимость, $<) в объектный файл (с опцией -c) и назовите его как цель правила ([email protected]).

отметить также, что если вы вызываете make без определенной цели, то первое правило будет выбран. В случае с вышеуказанным make-файлом это будет правило $(TARGET): $(OBJECTS), которое будет гарантировать, что все объектные файлы будут созданы из исходных файлов, а затем свяжутся с объектными файлами в результирующий исполняемый файл.