LINUX.ORG.RU
ФорумTalks

Можно ли как-то покрасивше Makefile сделать?

 , ,


2

1

В связи с тем, что использовать cmake для разработки под STM32 — занятие крайне геморройное, пишу Makefile вручную.

Нагуглив кучу мануалов и перелистав все info make, упростил задачу конфигурирования Makefile'а под новые проекты. Однако, осталась там некрасивая штука:

$(OBJDIR):
	mkdir $(OBJDIR)

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

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

$(OBJDIR)/startup.o: ./cmsis/startup_stm32f10x_md.s
	$(AS) $(ASFLAGS) ./cmsis/startup_stm32f10x_md.s -o $(OBJDIR)/startup.o

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

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

— куча целей с по сути одинаковыми действиями.

А нельзя ли сделать просто: имеем два списка $(OBJ) и $(SRC), и каким-то чудным образом пишем

$(OBJ): $(SRC)
	$(CC) $(CFLAGS) $< -o $@
вместо этой портянки?

А еще такой вопросец: зависимость от заголовочных файлов я тоже через жопу сделал:

$(ALL_SRC) : %.c : %.h $(INDEPENDENT_HEADERS)
	@touch $@
а как по-человечески?



-------------------------------------------------------------
Товарищи модераторы, тема в Talks, ибо реально руки у меня из жопы, а воли — 0. Ну не осилил я cmake для микроконтроллера!


P.S. Обнаружил баг в своем скрипте для засаленной обезьяны: нет панельки при редактировании тем. Исправляю.

☆☆☆☆☆

Последнее исправление: Eddy_Em (всего исправлений: 3)

ибо реально руки у меня из жопы

Это у тебя-то руки из жопы?

У меня тогда их вообще нет.

И увы, по девелопменту ничего не скажу.

ekzotech ★★★★
()

А еще такой вопросец: зависимость от заголовочных файлов я тоже через жопу сделал:

Чтобы сгенерировать зависимости от заголовочных файлов, нужно вызвать gcc -MM и выхлоп сохранить в файл *.dep (с помощью цели в Makefile, не руками), а все эти файлы заинклудить в Makefile c помощью -include (именно -include, а не include, потому что сначала файлов зависимостей нет, а Makefile должен работать, чтобы их сгенерировать, после чего они заинклудятся автоматически). Но файлы *.dep лучше не получать напрямую от gcc -MM, а пропустить через sed, который преобразует это:

src1.c: header1.h header2.h header3.h \
        header4.h
в это:
src1.o src1.c: header1.h header2.h header3.h \
        header4.h

И ещё неплохо прописать такую цель:

%.h: ;
на случай удаления заголовочных файлов, чтобы не пришлось делать clean.

gentoo_root ★★★★★
()
Ответ на: комментарий от beastie

Ты через subdir делал, а мне захотелось весь мусор запихать в отдельную директорию.

Вот весь makefile:

BIN=testproject

# Here are STDPeriphLib objects used in project
# comment all unneeded (same as sources)
SPL=
SPL+=misc
SPL+=stm32f10x_adc
#~ SPL+=stm32f10x_bkp
#~ SPL+=stm32f10x_can
#~ SPL+=stm32f10x_cec
#~ SPL+=stm32f10x_crc
#~ SPL+=stm32f10x_dac
#~ SPL+=stm32f10x_dbgmcu
SPL+=stm32f10x_dma
SPL+=stm32f10x_exti
#~ SPL+=stm32f10x_flash
#~ SPL+=stm32f10x_fsmc
SPL+=stm32f10x_gpio
#~ SPL+=stm32f10x_i2c
#~ SPL+=stm32f10x_it
#~ SPL+=stm32f10x_iwdg
#~ SPL+=stm32f10x_pwr
SPL+=stm32f10x_rcc
#~ SPL+=stm32f10x_rtc
#~ SPL+=stm32f10x_sdio
#~ SPL+=stm32f10x_spi
#~ SPL+=stm32f10x_tim
SPL+=stm32f10x_usart
#~ SPL+=stm32f10x_wwdg

# Headers that don't have c-files with same name
#  but project depends on them
INDEPENDENT_HEADERS=stm32f10x_conf.h usb_conf.h user_protocol.h includes.h

STLIBDIR=stm32_lib
OBJDIR=mk
USB_LIBDIR=usb_lib

TOOLS_PATH=/usr/arm-none-eabi
TOOLS_PREFIX=arm-none-eabi-

CPFLAGS=-Obinary
ODFLAGS=-S

CFLAGS=-c -mcpu=cortex-m3 -mthumb -Wall -Werror -mapcs-frame -D__thumb2__=1 -Os
CFLAGS+=-msoft-float -gdwarf-2 -mno-sched-prolog -fno-hosted -mtune=cortex-m3
CFLAGS+=-march=armv7-m -mfix-cortex-m3-ldrd -ffunction-sections -fdata-sections
CFLAGS+=-I./cmsis -I./stm32_lib -I./usb_lib -I.
CFLAGS+=-DSTM32F10X_MD

LDFLAGS=-static -mcpu=cortex-m3 -mthumb -mthumb-interwork -Wl,--start-group
LDFLAGS+=-L$(TOOLS_PATH)/lib/thumb2 -lc -lg -lstdc++ -lsupc++ -lgcc -lm
LDFLAGS+=-Wl,--end-group -Xlinker -Map -Xlinker $(BIN).map -Xlinker
LDFLAGS+=-T ./cmsis/stm32f100rb_flash.ld -o $(BIN)

ASFLAGS=-mcpu=cortex-m3 -I./cmsis -I./stm32_lib -gdwarf-2 -gdwarf-2

CC=$(TOOLS_PREFIX)gcc
AS=$(TOOLS_PREFIX)as
SIZE=$(TOOLS_PREFIX)size
CP=$(TOOLS_PREFIX)objcopy
OD=$(TOOLS_PREFIX)objdump

# These are main project sources
SRC=$(wildcard *.c)
MAIN_OBJ=$(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))

STM32_LIBSRC=$(addprefix $(STLIBDIR)/, $(addsuffix .c, $(SPL)))
OBJ=$(addprefix $(OBJDIR)/, $(addsuffix .o, $(SPL)))

OBJ+=$(OBJDIR)/system_stm32f10x.o $(OBJDIR)/startup.o
STM32_LIBSRC+=cmsis/system_stm32f10x.c

# USB library sources
USB_SRC=$(wildcard $(USB_LIBDIR)/*.c)
USB_OBJ=$(addprefix $(OBJDIR)/, $(USB_SRC:$(USB_LIBDIR)/%.c=%.o))

ALL_OBJ=$(OBJ) $(MAIN_OBJ) $(USB_OBJ)
ALL_SRC=$(SRC) $(STM32_LIBSRC) $(USB_SRC)

all: $(BIN)

$(OBJDIR):
	mkdir $(OBJDIR)

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

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

$(OBJDIR)/startup.o: ./cmsis/startup_stm32f10x_md.s
	$(AS) $(ASFLAGS) ./cmsis/startup_stm32f10x_md.s -o $(OBJDIR)/startup.o

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

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

$(ALL_SRC) : %.c : %.h $(INDEPENDENT_HEADERS)
	@touch $@

$(BIN): $(OBJDIR) $(ALL_OBJ)
	$(CC) $(ALL_OBJ) $(LDFLAGS)
	$(CP) $(CPFLAGS) $(BIN) ../$(BIN).bin
	$(OD) $(ODFLAGS) $(BIN) > $(BIN).list
	$(SIZE) -B $(BIN)

clean:
	rm -f $(ALL_OBJ) $(BIN).map $(BIN) $(BIN).list
	rmdir $(OBJDIR)

load: $(BIN)
	st-flash write $(BIN).bin 0x08000000


.PHONY: clean load

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от gentoo_root

Попробовал вручную для одного файла:

gcc -DSTM32F10X_MD -MM main.c -I./cmsis -I./stm32_lib -I. -I./usb_lib
main.o: main.c includes.h hw_config.h cmsis/stm32f10x.h cmsis/core_cm3.h \
 cmsis/core_cmInstr.h cmsis/core_cmFunc.h cmsis/system_stm32f10x.h \
 stm32f10x_conf.h stm32_lib/stm32f10x_adc.h stm32_lib/stm32f10x_dma.h \
 stm32_lib/stm32f10x_exti.h stm32_lib/stm32f10x_flash.h \
 stm32_lib/stm32f10x_gpio.h stm32_lib/stm32f10x_rcc.h \
 stm32_lib/stm32f10x_usart.h stm32_lib/misc.h interrupts.h leds.h \
 onewire.h usb_conf.h usb_desc.h usb_istr.h usb_lib/usb_lib.h \
 usb_lib/usb_type.h usb_lib/usb_regs.h usb_lib/usb_def.h \
 usb_lib/usb_core.h usb_lib/usb_init.h usb_lib/usb_sil.h \
 usb_lib/usb_mem.h usb_lib/usb_int.h usb_prop.h user_protocol.h usb_pwr.h \
 main.h
Ничего ж себе! Честно говоря, как это автоматизировать таки не представляю, может, натолкнешь на нужную статью?

gentoo_root

И ещё неплохо прописать такую цель:


%.h: ;

Спасибо, добавил.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от AiFiLTr0

И это, зависимости по хедерам тебе должен генерить gcc (см. опции -M, -D).
А самый простой вариант подсосать все сишные файлы перифлибов: свалить их в каталог и сделать
stm32_src = $(shell ls periphlib/*.c)

AiFiLTr0 ★★★★★
()
Последнее исправление: AiFiLTr0 (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

И да, если будешь юзать antares не забудь сказать gcc чтобы сносил неиспользуемый код. Иначе при юзаньи перифлибов прошивка растет как на дрожжах. В antares это make menuconfig > Toolchain Settings ->

  • Remove dead code
AiFiLTr0 ★★★★★
()
Ответ на: комментарий от Eddy_Em

Там уже в комплекте все для stm32 и не только, а билдсистема во многом похожа на kbuild. (По сути это открученный от линуксового ядра kconfig прикрученный для программирования совсем мелких мк)

AiFiLTr0 ★★★★★
()
Ответ на: комментарий от AiFiLTr0

Мне все не нужны — только используемые.

Кстати, а нельзя ли при помощи gcc из подключаемых заголовочных файлов выудить информацию о нужных файлах библиотек? Тогда вообще элементарно было бы — тупо скопировал Makefile в другой проект, и все бы работало…

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Так если добавишь gc-sections, то то, что ты не будешь юзать из бинаря будет вырезаться, один хрен. В случае антарес у меня там тупо выбор библиотек из списка, какие собирать.

AiFiLTr0 ★★★★★
()
Ответ на: комментарий от Eddy_Em

Когда я решал подобную задачу это в итоге закончилось тем, что сейчас на гитхабе.

AiFiLTr0 ★★★★★
()
Ответ на: комментарий от Eddy_Em

Только учти, оно типа преальфа, библиотечного кода местами не хватает, документации тоже. Под STM32 есть все их либы + дрова на SPI флешку (референсные, от ST).
Стек lwip пока там в экспериментальном состоянии, нет бэкэндов. Патчез велком.

AiFiLTr0 ★★★★★
()
Ответ на: комментарий от Eddy_Em
%.d:
        gcc ${INC} -MM -MT "$@ ${@:.d=.o}" {@:.d=.c} -o $@
%.o:
        gcc ${CFLAGS} ${INC} ${@:.o=.c} -c -o $@
staseg ★★★★★
()

Не знаю, как в make, но вот в mk наверняка возможно.

quantum-troll ★★★★★
()
Ответ на: комментарий от AiFiLTr0

Не понял, как запускать-то?

В своей директории пишет:

make menuconfig
Makefile:38: /home/eddy/Docs/SAO/ELECTRONICS/STM32/WORK/ant/tmp/arch.mk: Нет такого файла или каталога

Please, do not run make in the antares directory
Use an out-of-tree project directory instead.
Have a look at the documentation on how to do that

Makefile:53: *** Cowardly refusing to go further.  Останов.

Запихал свое туда же, сменил директорию — все равно косяк:

make menuconfig -C..
make: Вход в каталог `/home/eddy/Docs/SAO/ELECTRONICS/STM32/WORK/ant'
Makefile:38: /home/eddy/Docs/SAO/ELECTRONICS/STM32/WORK/ant/tmp/arch.mk: Нет такого файла или каталога

Please, do not run make in the antares directory
Use an out-of-tree project directory instead.
Have a look at the documentation on how to do that

Makefile:53: *** Cowardly refusing to go further.  Останов.
make: Выход из каталога `/home/eddy/Docs/SAO/ELECTRONICS/STM32/WORK/ant'
Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от AiFiLTr0

библиотечного кода местами не хватает

И у тебя устаревшая STDPeriphLib + нет USB

Лучше бы ты стандартные библиотеки туда не помещал (чтобы в актуальном состоянии не поддерживать).

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от AiFiLTr0

Охрененную работу ты выполнил!

Правда, чтобы въехать во все это, надо немало почитать...

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Adds -Wall -Werror flags. (trollface.jpg) A true paranoid behaviour.

Не передергивай! Я вообще никуда без -Wall -Werror не хожу. И считаю, что в серьезных проектах только так и можно жить.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от AiFiLTr0

Глянул, как ты подчищаешь ненужное:

-Wl,--gc-sections -Wl,-s
Добавил, и — о чудо! с 15к объем кода сократился до 11к!!!

// а вообще, у тебя довольно-таки мудро все придумано, буду копаться дальше, чтобы врубиться, как это использовать с «автоподцеплением» нужных библиотек (USB, ETH, LCD…)

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от olibjerd

Ты заставил меня снова подписаться на этот тэг.

[рукожопие]?

Кстати, где звезда?

Пропил ☺

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от schizoid

Плохо понятно, что именно ты имеешь в виду.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Повесил баг в треккер, на выходных обновлю. К сожалению, там немного подрехтоввывать пришлось периф либы, чтобы настраивалось через менюконфиг и работали ANTARES_INIT_LOW/INIT_HIGH макросы.

AiFiLTr0 ★★★★★
()
Последнее исправление: AiFiLTr0 (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

Так и не надо там запускать. антарес лежит отдельно, а проект твой с твоим кастомным кодом отдельно. И make запуаскается там. см. aproj, он тебе копирует семплы проектов туда.

AiFiLTr0 ★★★★★
()
Ответ на: комментарий от Eddy_Em

Библиотеки ты можешь подцепить просто сложив куда-нибудь в src/lib Сшные файлы, и добавив их в Makefile в виде objects-y+=...
Хедеры правда придется закинуть в include/

А вообще, может просто добавить либы в дерево антарес и прислать патчи, я вмержу.

AiFiLTr0 ★★★★★
()

как-то так:

SRCDIR := src
#subdir
SDIRS := $(addprefix $(SRCDIR)/, subdir1 shared math phys gfx engine)
SDIRS += $(SRCDIR)

BPREF := bin/release
BDIRS := $(patsubst $(SRCDIR)%, $(BPREF)%, $(SDIRS))

SRCHWILDCARDS := $(addsuffix /*.c, $(SDIRS))

SFILES := $(wildcard $(SRCHWILDCARDS))
OFILES := $(patsubst $(SRCDIR)%.c, $(BPREF)%.o, $(SFILES))

VPATH := $(SDIRS)

INC :=
CF := -std=c99 -Wall -ggdb #$(CFLAGS)

override CF += -pipe $(INC)

LF := -L`gcc -print-file-name=` -lgcc -lc -lm -lGL -lGLU -lGLEW `sdl-config --cflags --libs` -lpthread

all: mkdirs main
	@echo ":-)"


main: $(OFILES)
	@echo "[LD] $^ => $@"
	clang -Qunused-arguments $(LF) $^ -o $(BPREF)/$@
#ld /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o $^ -o $(BPREF)/$@ $(LF)
#gcc $(LF) $^ -o $(BPREF)/$@

$(BPREF)/%.o: $(SRCDIR)/%.c
	@echo "[CC] $< -> $@"
	clang -Qunused-arguments $(CF) -c $< -o $@


.PHONY: showvars mkdirs clean rebuild

showvars:
	@echo $(SRCDIR)
	@echo $(SDIRS)
	@echo $(BPREF)
	@echo $(BDIRS)
	@echo $(SFILES)
	@echo $(OFILES)
	@echo $(VPATH)

mkdirs:
	@echo [MKDIR] -p $(BDIRS)
	@mkdir -p $(BDIRS)

clean:
	@echo cleaning...
	@echo [RM] $(OFILES)
	@rm $(OFILES)
	@echo [RM] $(BPREF)/main
	@rm $(BPREF)/main


rebuild: clean all

Bad_ptr ★★★★★
()
Ответ на: комментарий от Eddy_Em

Ничего ж себе! Честно говоря, как это автоматизировать таки не представляю, может, натолкнешь на нужную статью?

Вот мой файл с правилами, который я инклудил из основного Makefile: http://pastebin.ca/2293481. Для использования нужно установить переменные в Makefile (SOURCES, TARGET, LDSCRIPT и т.п.) и прописать «include rules.mk», где rules.mk — это имя того файла.

Здесь, кстати, даже лучше сделано, потому что вместо sed используется параметр gcc -MT, я о нём только сейчас узнал, поэтому у меня всё через sed, но там легко переделать без sed.

gentoo_root ★★★★★
()

Вот, если интересно, мейкфайл для проектика на арме, который я делал лет 5-6 назад: http://pastebin.com/RJ26Ki9d

Довольно простой и универсальный.

Puzan ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.