Создание файла объектного файла, подстановка переменных и другие вопросы - PullRequest
0 голосов
/ 17 октября 2018

В настоящее время я пытаюсь создать Makefile для проекта AC University, но чтение учебников мне не очень помогло (также makefile не является частью процесса оценки, и нас не учат, как это делать.it)

Моя цель - сделать make-файл автоматическим, поэтому он автоматически создает объектные файлы из .c-файлов в src (src / *. c), помещает объектные файлы в папку bin и связывает их висполняемый файл в главном каталоге.

project/
    bin/
        (object files)
    src/
        (source files)
    executable
    Makefile

Пока что я примерно собрал этот make-файл и тестовый исходный код, но он не работает так, как я намереваюсь, и я объясню, каквпереди:

#compiler used
COMPILER = gcc

#flags for individual object file compilation
FLAGS = -Wall -ansi -g
#RELEASE
# -Wall -ansi -O3
#DEVELOPMENT
# -Wall -ansi -g

#source .c files
SOURCE = $(wildcard src/*.c)
#object files created
OBJECTS = $(SOURCE:.c=.o)
OBJECTS = $(SOURCE: src/=bin/)

#executable name
EXECUTABLE = app

############################################################

all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(COMPILER) $(FLAGS) -o $(EXECUTABLE) $(OBJECTS)

%.o: %.c
    $(COMPILER) $(FLAGS) -c %< -o %@

В результате получается следующая команда:

user@user-lenovo:~/Desktop/C Projects/AED/project$ make
gcc -Wall -ansi -g -o app src/main.c src/test.c

Как ни странно, это работает, но на самом деле не должно.Это также отрицает необходимость иметь make-файл, так как все компилируется снова, как только обнаруживается одно изменение.

Прежде всего, я заметил, что OBJECTS непосредственно скопировал SOURCE, и не заменил .c на .oили src / для бина /.Я попытался заменить '=' на ': =', но результат тот же, и я не совсем понимаю, в чем разница между ними.Моей идеей было бы, например, src / main.c стать bin / main.o.

%.o: %.c
    $(COMPILER) $(FLAGS) -c %< -o %@

Эта часть также является моей неудачной попыткой генерировать все объектные файлы индивидуально с одной целью.Я попытался прочитать об этом, но не мог понять, как это работает: «% <», «% @» или «% .o» и «% .c» </p>

Я верю, что это не такХотя он вообще не запускается, поскольку никаких объектных файлов не обнаружено.

Надеюсь, вы поможете мне исправить это, заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 17 октября 2018
OBJECTS = $(SOURCE:.c=.o)
OBJECTS = $(SOURCE: src/=bin/)

Вы дважды назначаете OBJECTS - первый результат перезаписывается вторым, который не работает.Вы хотите объединить их в одно утверждение, подобное этому

OBJECTS=$(SOURCE:src/%.c=bin/%.o)

Ваша следующая проблема заключается в том, что вам нужно сообщить make, что «bin / what.o» построен из «src / what.c».В настоящее время он будет искать «what.c» в «bin /»

. Таким образом, ваш рецепт для создания .o файлов требует добавления каталогов

bin/%.o: src/%.c
    $(COMPILER) $(FLAGS) -c $< -o $@

У вас также должен быть $@вместо %@ и $< вместо %<

0 голосов
/ 17 октября 2018
  1. Автоматические переменные расширяются с префиксом $, как и любая другая переменная, а не %.
  2. Поскольку ваши объектные и исходные файлы находятся в разных каталогах, вы не можете просто %.o: %.c.

Попробуйте:

CC = gcc
CFLAGS = -Wall -ansi -g

OBJECTS = $(patsubst src/%.c,bin/%.o,$(SOURCE))

bin/%.o: src/%.c
    $(CC) $(CFLAGS) -c $< -o $@

Примечание: стандартная переменная make для компилятора C - CC и CFLAGS для флагов.Лучше их использовать.

...