Перейти к содержанию
    

Makefile мечты

Добрый день.

 

Хочется странного. На данный момент есть вполне рабочий makefile со следующим кодом.

 

# C source files
CFILES = $(filter %.c, $(SRC))
# Assembly source files
ASMFILES = $(filter %.S, $(SRC))

# Object files
COBJ = $(CFILES:.c=.o)
SOBJ = $(ASMFILES:.S=.o)
OBJ = $(SOBJ) $(COBJ) 

##### OBJ = $(patsubst src/%.cpp, obj/%.o, $(SRC))

#all: $(SRC) $(PROJECT).elf $(PROJECT).bin $(PROJECT).lst

$(PROJECT).lst: $(PROJECT).elf
$(OD) -h -S $(PROJECT).elf > $(PROJECT).lst
$(SZ) --format=berkeley $(PROJECT).elf

$(PROJECT).bin: $(PROJECT).elf
$(CP) -O binary $(PROJECT).elf $@

$(PROJECT).elf: $(OBJ)
$(CC) $(LDFLAGS) $(OBJ) -o $@

$(COBJ): %.o: %.c
$(CC) -c $(FEATURES) $(INC) $(CFLAGS) $< -o $@

$(SOBJ): %.o: %.S
$(CC) -c $(ASFLAGS) $< -o $@

$(SRC) - полное имя файла, включая путь. Данная конструкция нормально собирает проект.

Хочется, чтобы объектные файлы лежали в отдельном каталоге: например /obj/.

Написал следующую конструкцию:

# Object files
COBJ := $(addprefix $(OBJDIR)/,$(notdir $(CSRC:.c=.o)))
AOBJ := $(addprefix $(OBJDIR)/,$(notdir $(ASRC:.S=.o)))

$(PROJECT).lst: $(PROJECT).elf
$(OD) -h -S $(PROJECT).elf > $(PROJECT).lst
$(SZ) --format=berkeley $(PROJECT).elf

$(PROJECT).bin: $(PROJECT).elf
$(CP) -O binary $(PROJECT).elf $@

$(PROJECT).elf: OBJDIR $(AOBJ) $(COBJ)
$(CC) $(LDFLAGS) $(AOBJ) $(COBJ) -o $@

OBJDIR:
$(MKDIR) $(OBJDIR)

$(AOBJ): $(OBJDIR)/%.o : %.S
$(CC) -c $(ASFLAGS) $< -o $@

$(COBJ): $(OBJDIR)/%.o : %.c
$(CC) -c $(FEATURES) $(INC) $(CFLAGS) $< -o $@

При этом получаю ругань на то, что отсутствует цель для ассемблерного файла (.S). Для "сишных", как я понимаю, тоже нет цели. Как мне уговорить make "увидеть" цель для компиляции ассемблерных и сишных исходников?

Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...

Возьмите makefile из примеров для scmrtos. Да и я когда-то выкладывал свой.

Вам имеет смысл изучить язык makefile, чтобы самому править его при необходимости. Документация на русском язуке есть в сети.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

Хочется, чтобы объектные файлы лежали в отдельном каталоге: например /obj/.

 

Выложу пока здесь. Представляемая система сборки размещает объектные файлы не просто в каталоге ./obj/, но рассовывает их по подкаталогам в соответствии с подкаталогами исходных текстов. Из крайне приятных плюшек: возможность указать ключи компиляции для каждого файла индивидуально.

 

 

Готовые модули программ, оформленные как библиотеки, для микроконтроллеров (МК)

разрабатываются и поставляются, чаще всего, в виде исходных текстов

(т.к. вариантов компиляции для МК очень много и учесть их все для поставки

библиотеки в объектных файлах практически невозможно). При добавлении

в программу такой библиотеки хотелось бы абстрагироваться от её состава

и необходимых ей специфичных правил компиляции. Традиционно это решается

оформлением отдельного файла Makefile для библиотеки. Но, как показано

в статье "Recursive Make Considered Harmful"

(http://aegis.sourceforge.net/auug97.pdf), это может вызывать ошибки.

 

Описываемая система позволяет включать библиотеку функций в виде исходных

текстов и не отслеживать изменения в её составе: в основной программе

достаточно ограничится включением обработки файла files.mk библиотеки.

Возможные дальнейшие изменения в составе библиотеки и правилах её компиляции

должны отражаться в соответствующем файле files.mk и не будут вызывать

никаких изменений в правилах компиляции основной программы. Именно

для достижения этой цели была создана данная система компиляции программ.

 

Илья

makefiles.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какие требования к make.exe?

 

Начал прикручивать - в files.mk перечислил пару .c файлов, запускаю (с ключём -d) и вижу:

GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for Windows32
Reading makefiles...
Reading makefile `Makefile.arm'...
Reading makefile `makef.mk' (search path) (no ~ expansion)...
makef.mk:309: *** missing separator.  Stop.

 

Другие сборки make.exe (но той же версии) ведут себя точно так же.

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какие требования к make.exe?makef.mk:309: *** missing separator. Stop.

 

Другие сборки make.exe (но той же версии) ведут себя точно так же.

 

missing separator говорит о том, что там, скорее всего, этот самый сепаратор не табуляция. В GNU make должна быть табуляция.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какие требования к make.exe?

 

У меня 4.1. Директива undefine появилась только в 3.82 (http://stackoverflow.com/questions/20384656/can-we-undefine-unset-a-variable-in-makefile). Кроме того, функция $(file ...) в 3.81 или отсутствует или работает как-то не так.

 

Подредактировал, теперь работает в 3.81.

 

Илья

 

Подредактировал, теперь работает в 3.81.

 

Проверил, работает один раз ;-)

 

В 4.1 по-другому выполняется обработка строк, передаваемых в вызываемую программу.

 

Вот этот фрагмент:

@$(SED) -e "1s/^.*:/\n$(subst /,\/,$@) $(subst /,\/,$@).d : /" \

-e "\$s/$/ \\\\\n $(subst /,\/,$($(strip $(1))_MK_FILES_{:content:}lt;))\n/" \

в 3.81 добавляет строки "\n" вместо символов перевода строки. В 4.1 добавляет переводы строк, как и задумано.

 

Илья

 

в 3.81 добавляет строки "\n" вместо символов перевода строки. В 4.1 добавляет переводы строк, как и задумано.

 

Вот вариант, который в 3.81 работает правильно.

 

@$(SED) -e "1s/^.*:/\n$(subst /,\/,$@) $(subst /,\/,$@).d : /" \

-e "\$s/$/ \\\\\\\\\n $(subst /,\/,$($(strip $(1))_MK_FILES_{:content:}lt;))\n/" \

 

arm_test.rar

Изменено пользователем 501-q

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно, я не совсем корректно (или совсем некорректно) сформулировал вопрос. Есть следующая структура каталогов проекта.

Core/

STM32F10x_StdPeriph_Driver/

Project/

Makefile

 

Я написал для нее следующий makefile.

 

PROJECT=RadioModem

RM= rm -f
MKDIR = mkdir -p

OBJDIR = $(CURDIR)/obj

TOOLCHAIN = /opt/gcc-arm-none-eabi-4_9
TOOLCHAIN_BIN = $(TOOLCHAIN)/bin/
TOOLCHAIN_LIB = $(TOOLCHAIN)/arm-none-eabi/lib/
TOOLCHAIN_INC = $(TOOLCHAIN)/arm-none-eabi/include/

CXX = $(TOOLCHAIN_BIN)arm-none-eabi-g++
CC = $(TOOLCHAIN_BIN)arm-none-eabi-gcc
AS = $(TOOLCHAIN_BIN)arm-none-eabi-as
LD = $(TOOLCHAIN_BIN)arm-none-eabi-ld
CP = $(TOOLCHAIN_BIN)arm-none-eabi-objcopy
OD = $(TOOLCHAIN_BIN)arm-none-eabi-objdump
SZ = $(TOOLCHAIN_BIN)arm-none-eabi-size

# Interrupts vector table
VECTOR = $(CURDIR)/Core/src/startup_stm32f10x_hd.S
# Linker script 
LDSCRIPT = $(CURDIR)/Core/stm32_flash.ld
LDFLAGS = -T$(LDSCRIPT) -L$(TOOLCHAIN_LIB) -nostartfiles -Xlinker --gc-sections -Wl,-Map,$(PROJECT).map -mcpu=cortex-m3 -mthumb

#assembler flags
ASFLAGS = -x assembler-with-cpp -Wall -c -fmessage-length=0 -mcpu=cortex-m3 -mthumb
# compiler flags
CFLAGS = -mthumb -mcpu=cortex-m3 -Os -fno-builtin -Wall -std=gnu99


INC := -I$(CURDIR)/STM32F10x_StdPeriph_Driver/inc/
INC += -I$(CURDIR)/Core/inc/
INC += -I$(CURDIR)/Project/inc/
INC += -I$(TOOLCHAIN_INC)

DEFINITIONS := -DSTM32F10X_HD
DEFINITIONS +=-DUSE_STDPERIPH_DRIVER
DEFINITIONS +=-DMAGOR_VER=0
DEFINITIONS +=-DMINOR_VER=1

CFLAGS+= $(DEFINITIONS)
CFLAGS+= $(INC)


# System sources
ASRC := $(VECTOR)
CSRC := $(wildcard $(CURDIR)/STM32F10x_StdPeriph_Driver/src/*.c)
CSRC += $(wildcard $(CURDIR)/Core/src/*.c)

# Project sources
CSRC += $(CURDIR)/Project/src/main.c 
CSRC += $(CURDIR)/Project/src/stm32_it.c

COBJ := $(CSRC:.c=.o)
AOBJ := $(ASRC:.S=.o)

#COBJ := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o))) 
#AOBJ := $(addprefix $(OBJDIR)/, $(notdir $(ASRC:.S=.o))) 

all: $(PROJECT).elf $(PROJECT).bin $(PROJECT).lst

$(PROJECT).lst: $(PROJECT).elf
$(OD) -h -S $(PROJECT).elf > $(PROJECT).lst
$(SZ) --format=berkeley $(PROJECT).elf

$(PROJECT).bin: $(PROJECT).elf
$(CP) -O binary $(PROJECT).elf $@

$(PROJECT).elf: $(OBJDIR) $(AOBJ) $(COBJ)
$(CC) $(LDFLAGS)  $(AOBJ) $(COBJ) -o $@

$(OBJDIR):
$(MKDIR) $(OBJDIR)	

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

%.o: %.S
$(CC) -c $(ASFLAGS) $< -o $@

clean:
rm -f $(PROJECT) $(COBJ) $(AOBJ)
rm $(PROJECT).elf $(PROJECT).lst $(PROJECT).map $(PROJECT).bin
rm -rf obj
.PHONY: clean

 

Данный makefile абсолютно рабочий. И он меня почти всем устраивает. Но, у меня возникло желание не загромождать каталоги Core, STM32F10x_StdPeriph_Driver и Project объектными файлами при компиляции.

Как только я заменяю кострукцию

COBJ := $(CSRC:.c=.o)

AOBJ := $(ASRC:.S=.o)

на

COBJ := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o)))

AOBJ := $(addprefix $(OBJDIR)/, $(notdir $(ASRC:.S=.o)))

сразу пропадают из видимости make-а правила построения объектников из исходников. Меня это немного смущает. Как можно написать кострукцию зависимости *с и *S файлов, разбросанным по разным каталогам, чтобы правило

 

%.o: %.c

$(CC) -c $(CFLAGS) $< -o $@

 

%.o: %.S

$(CC) -c $(ASFLAGS) $< -o $@

 

работало корректно? Спасибо.

 

 

Cpu_M.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как только я заменяю кострукцию

COBJ := $(CSRC:.c=.o)

AOBJ := $(ASRC:.S=.o)

на

COBJ := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o)))

AOBJ := $(addprefix $(OBJDIR)/, $(notdir $(ASRC:.S=.o)))

сразу пропадают из видимости make-а правила построения объектников из исходников. Меня это немного смущает. Как можно написать кострукцию зависимости *с и *S файлов, разбросанным по разным каталогам, чтобы правило

Потому что $(OBJDIR)/ надо добавлять не к списку объектов, а к правилу:

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

Плюс добавить в VPATH все каталоги с исходниками.

 

ЗЫ. Вам в первом же ответе дали ссылку на makefile из scmRTOS. Там сделано как раз то, что вы хотите. Хотя с VPATH может и ваш вариант сработает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как только я заменяю кострукцию

COBJ := $(CSRC:.c=.o)

AOBJ := $(ASRC:.S=.o)

на

COBJ := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o)))

AOBJ := $(addprefix $(OBJDIR)/, $(notdir $(ASRC:.S=.o)))

сразу пропадают из видимости make-а правила построения объектников из исходников. Меня это немного смущает. Как можно написать кострукцию зависимости *с и *S файлов, разбросанным по разным каталогам, чтобы правило

 

%.o: %.c

$(CC) -c $(CFLAGS) $< -o $@

 

%.o: %.S

$(CC) -c $(ASFLAGS) $< -o $@

 

работало корректно? Спасибо.

Правило "%.o: %.c" не будет работать, так как stem (часть, которая соответствует %) в правой и левой частях правила не совпадают.

Попробуй написать "тройное" правило, что-то типа "$(COBJ) : $(OBJDIR)/%.o : %.c" (т.е. явно указав, что для файлов из списка $(COBJ) нужно применять данное правило). Возможно, что с VPATH это сработает.

Я же повторил в каталоге объектных файлов структуру каталогов исходных текстов и обошелся без VPATH (кроме всего прочего, это позволяет иметь файлы с одинаковым именем в разных каталогах).

 

Илья

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ЗЫ. Вам в первом же ответе дали ссылку на makefile из scmRTOS. Там сделано как раз то, что вы хотите. Хотя с VPATH может и ваш вариант сработает.

 

Спасибо. С VPATH заработало. Большое спасибо всем откликнувшимся.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...