|
|
  |
Makefile мечты, распихивание результатов сборки по каталогам. |
|
|
|
Jun 8 2015, 15:08
|
Участник

Группа: Участник
Сообщений: 69
Регистрация: 10-06-08
Пользователь №: 38 190

|
Добрый день. Хочется странного. На данный момент есть вполне рабочий makefile со следующим кодом. CODE # 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/. Написал следующую конструкцию: CODE # 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 "увидеть" цель для компиляции ассемблерных и сишных исходников? Спасибо.
|
|
|
|
|
Jun 8 2015, 16:25
|

Начинающий профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648

|
Цитата(zemlemer @ Jun 8 2015, 19:08)  ... Возьмите makefile из примеров для scmrtos. Да и я когда-то выкладывал свой. Вам имеет смысл изучить язык makefile, чтобы самому править его при необходимости. Документация на русском язуке есть в сети.
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
Jun 9 2015, 02:53
|
Участник

Группа: Участник
Сообщений: 38
Регистрация: 24-02-09
Из: Екатеринбург
Пользователь №: 45 296

|
Приветствую! Цитата(zemlemer @ Jun 8 2015, 20:08)  Хочется, чтобы объектные файлы лежали в отдельном каталоге: например /obj/. Выложу пока здесь. Представляемая система сборки размещает объектные файлы не просто в каталоге ./obj/, но рассовывает их по подкаталогам в соответствии с подкаталогами исходных текстов. Из крайне приятных плюшек: возможность указать ключи компиляции для каждого файла индивидуально. Готовые модули программ, оформленные как библиотеки, для микроконтроллеров (МК) разрабатываются и поставляются, чаще всего, в виде исходных текстов (т.к. вариантов компиляции для МК очень много и учесть их все для поставки библиотеки в объектных файлах практически невозможно). При добавлении в программу такой библиотеки хотелось бы абстрагироваться от её состава и необходимых ей специфичных правил компиляции. Традиционно это решается оформлением отдельного файла Makefile для библиотеки. Но, как показано в статье "Recursive Make Considered Harmful" (http://aegis.sourceforge.net/auug97.pdf), это может вызывать ошибки. Описываемая система позволяет включать библиотеку функций в виде исходных текстов и не отслеживать изменения в её составе: в основной программе достаточно ограничится включением обработки файла files.mk библиотеки. Возможные дальнейшие изменения в составе библиотеки и правилах её компиляции должны отражаться в соответствующем файле files.mk и не будут вызывать никаких изменений в правилах компиляции основной программы. Именно для достижения этой цели была создана данная система компиляции программ. Илья
|
|
|
|
|
Jun 9 2015, 06:07
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Какие требования к 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 - Jun 9 2015, 06:10
|
|
|
|
|
Jun 9 2015, 07:31
|
Участник

Группа: Участник
Сообщений: 38
Регистрация: 24-02-09
Из: Екатеринбург
Пользователь №: 45 296

|
Цитата(Genadi Zawidowski @ Jun 9 2015, 11:07)  Какие требования к 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. Илья Цитата(501-q @ Jun 9 2015, 11:58)  Подредактировал, теперь работает в 3.81. Проверил, работает один раз ;-) В 4.1 по-другому выполняется обработка строк, передаваемых в вызываемую программу. Вот этот фрагмент: @$(SED) -e "1s/^.*:/\n$(subst /,\/,$@) $(subst /,\/,$@).d : /" \ -e "\$s/$/ \\\\\n $(subst /,\/,$($(strip $(1))_MK_FILES_{:content:}lt;))\n/" \ < $@.p.d >> $@.d
в 3.81 добавляет строки "\n" вместо символов перевода строки. В 4.1 добавляет переводы строк, как и задумано. Илья Цитата(501-q @ Jun 9 2015, 12:17)  в 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/" \ < $@.p.d >> $@.d
Сообщение отредактировал 501-q - Jun 10 2015, 00:25
|
|
|
|
|
Jun 9 2015, 09:26
|
Участник

Группа: Участник
Сообщений: 38
Регистрация: 24-02-09
Из: Екатеринбург
Пользователь №: 45 296

|
Вариант, который работает в версии make 3.81 или 4.1. Илья
|
|
|
|
|
Jun 9 2015, 16:08
|
Участник

Группа: Участник
Сообщений: 69
Регистрация: 10-06-08
Пользователь №: 38 190

|
Возможно, я не совсем корректно (или совсем некорректно) сформулировал вопрос. Есть следующая структура каталогов проекта. Core/ STM32F10x_StdPeriph_Driver/ Project/ Makefile Я написал для нее следующий makefile. CODE 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 ( 302 килобайт )
Кол-во скачиваний: 8
|
|
|
|
|
Jun 9 2015, 16:30
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(zemlemer @ Jun 9 2015, 21:08)  Как только я заменяю кострукцию 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 может и ваш вариант сработает.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jun 10 2015, 00:24
|
Участник

Группа: Участник
Сообщений: 38
Регистрация: 24-02-09
Из: Екатеринбург
Пользователь №: 45 296

|
Цитата(zemlemer @ Jun 9 2015, 21:08)  Как только я заменяю кострукцию 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 (кроме всего прочего, это позволяет иметь файлы с одинаковым именем в разных каталогах). Илья
|
|
|
|
|
Jun 10 2015, 16:32
|
Участник

Группа: Участник
Сообщений: 69
Регистрация: 10-06-08
Пользователь №: 38 190

|
Цитата ЗЫ. Вам в первом же ответе дали ссылку на makefile из scmRTOS. Там сделано как раз то, что вы хотите. Хотя с VPATH может и ваш вариант сработает. Спасибо. С VPATH заработало. Большое спасибо всем откликнувшимся.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|