Makefile を共通化

Makefile 共通化

RX マイコンの各プロジェクトで、Makefile で共有出来る部分を抜き出して、共通化を行った。

今まで、同じような「手順」を各プロジェクト毎にコピーしていたが、二度手間だし、プロジェクト数が多く、作業が大変だった。
※Makefile を複数に別けたく無かったとゆーこだわりがあったのだが、現在のように手順がそこそこ複雑だと、そうする「こだわり」はあまり意味が無い。

共通部分

# -*- tab-width : 4 -*-
#=======================================================================
#   @file
#   @brief  RX microcontroller share Makefile
#   @author 平松邦仁 (hira@rvf-rc45.net)
#   @copyright  Copyright (C) 2021 Kunihito Hiramatsu @n
#               Released under the MIT license @n
#               https://github.com/hirakuni45/RX/blob/master/LICENSE
#=======================================================================

# System include path for each environment
ifeq ($(OS),Windows_NT)
SYSTEM := WIN
# C++.boost root
LOCAL_PATH  =   /mingw64
else
  UNAME := $(shell uname -s)
  ifeq ($(UNAME),Linux)
    SYSTEM := LINUX
    LOCAL_PATH = /usr/local
  endif
  ifeq ($(UNAME),Darwin)
    SYSTEM := OSX
    OSX_VER := $(shell sw_vers -productVersion | sed 's/^\([0-9]*.[0-9]*\).[0-9]*/\1/')
    LOCAL_PATH = /opt/local
  endif
endif

まず、これは、Windows、Linux、OS-X の環境を判断して、微妙な違いを吸収する。
※一番重要な事は、boost のパスを各環境で同じように扱う事。


LIB_ROOT    =   ../../rxlib/lib

INC_SYS     =   ../../rxlib/include $(LOCAL_PATH)/include

PROG_VERIFY = --verify
  • LIB_ROOT は、RX マイコン専用ライブラリのパスを設定している。
  • INC_SYS は、RX マイコン専用ライブラリのインクルードパスと、ローカルのインクルードパス(boost)などを設定している。
  • PROG_VERIFY は、rx_prog でフラッシュ書き込みする際に、「VERIFY」を行う場合のキーワードとなっている。
  • RX24T は、通常の手順で、VERIFY が行われない為、無効にする必要がある。

ifeq ($(RX_DEF),SIG_RX24T)
  RX_CPU = RX24T
  RX_OPT = v2
  LDSCRIPT  =   ../../RX24T/$(DEVICE).ld
  PROG_VERIFY =
endif

ifeq ($(RX_DEF),SIG_RX64M)
  RX_CPU = RX64M
  RX_OPT = v2
  LDSCRIPT  =   ../../RX64M/$(DEVICE).ld
endif

ifeq ($(RX_DEF),SIG_RX71M)
  AS_OPT    +=  --defsym MEMWAIT=1
  RX_CPU = RX71M
  RX_OPT = v2
  LDSCRIPT  =   ../../RX71M/$(DEVICE).ld
endif

ifeq ($(RX_DEF),SIG_RX65N)
  LIB_ROOT += ../../RX600/drw2d
  INC_APP +=  ../../RX600/drw2d/inc/tes
  USER_LIBS += drw2d
  RX_CPU = RX65N
  RX_OPT = v2
  LDSCRIPT  =   ../../RX65x/$(DEVICE).ld
endif

ifeq ($(RX_DEF),SIG_RX66T)
  RX_CPU = RX66T
  RX_OPT = v3
  LDSCRIPT  =   ../../RX66T/$(DEVICE).ld
endif

ifeq ($(RX_DEF),SIG_RX72T)
  RX_CPU = RX72T
  RX_OPT = v3
  LDSCRIPT  =   ../../RX72T/$(DEVICE).ld
endif

ifeq ($(RX_DEF),SIG_RX72N)
  LIB_ROOT += ../../RX600/drw2d
  INC_APP +=  ../../RX600/drw2d/inc/tes 
  USER_LIBS += drw2d
  RX_CPU = RX72N
  RX_OPT = v3
  LDSCRIPT  =   ../../RX72N/$(DEVICE).ld
endif

ifeq ($(RX_DEF),SIG_RX72M)
  LIB_ROOT += ../../RX600/drw2d
  INC_APP +=  ../../RX600/drw2d/inc/tes
  USER_LIBS += drw2d
  RX_CPU = RX72M
  RX_OPT = v3
  LDSCRIPT  =   ../../RX72M/$(DEVICE).ld
endif

この条件文で、RX マイコン毎に異なる設定を行っている。
現状では、「SIG_xxx」のキーワード毎に行っているが、将来的には、DEVICE で IC の型番を設定しているので、それに従って行うのが妥当だと思う。

※型番で行えば、ピン数の違いによる変更をソースコードへ伝達する事が出来る。

RX71M だけは、ちょっと特殊で、スーパーバイザーモードでしかアクセス出来ないレジスタがある。
そこで、そのレジスタを、start.s アセンブラブログラム内で行っている。「--defsym MEMWAIT=1」

FreeRTOS の場合、ユーザーモードに移行しない事が重要だが、それは、各プロジェクト毎に設定する。

# for FreeRTOS option
AS_OPT      =   --defsym NOT_USER=1

# Renesas GNU-RX gcc compiler version check
TARGET_ISA_TEXT := $(shell rx-elf-gcc --target-help | grep ISA)

# Renesas GNU-RX (8.3.0) compiler 
ifeq ($(TARGET_ISA_TEXT),)
  # for gcc-7.5.0 current gcc source build
  AS_DEFS       =   -mcpu=rx600
  CC_DEFS       =   -mcpu=rx600 -Wa,-mcpu=rxv2
  CP_DEFS       =   -mcpu=rx600
else # Renesas GNU-RX gcc 8.3.0
  AS_DEFS       =   -misa=$(RX_OPT)
  CC_DEFS       =   -misa=$(RX_OPT)
  CP_DEFS       =   -misa=$(RX_OPT)
endif

これは、Renesas GNU-RX gcc コンパイラと、プレーンな gcc コンパイラで、オプションが異なるので、それを自動判別する。


# You should not have to change anything below here.
AS          =   rx-elf-as
CC          =   rx-elf-gcc
CP          =   rx-elf-g++
AR          =   rx-elf-ar
LD          =   rx-elf-ld
OBJCOPY     =   rx-elf-objcopy
OBJDUMP     =   rx-elf-objdump
SIZE        =   rx-elf-size

AFLAGS      =   $(AS_OPT) $(AS_DEFS)
CFLAGS      =   -std=gnu99 $(CC_OPT) $(OPTIMIZE) $(CC_DEFS) $(DEFS)
PFLAGS      =   -std=c++17 $(CP_OPT) $(OPTIMIZE) $(CP_DEFS) $(DEFS)
FLAGS       = $(AS_OPT) $(AS_DEFS) $(CC_OPT) $(CP_OPT) $(OPTIMIZE) $(CC_DEFS) $(CP_DEFS) $(DEFS)

# FLAGS_CMP := $(shell cat $(TARGET).opt)

override LDFLAGS = $(MCU_TARGET) -nostartfiles -Wl,-Map,$(TARGET).map -T $(LDSCRIPT)

OBJCOPY_OPT =   --srec-forceS3 --srec-len 32

OBJECTS =   $(addprefix $(BUILD)/,$(patsubst %.s,%.o,$(ASOURCES))) \
            $(addprefix $(BUILD)/,$(patsubst %.c,%.o,$(CSOURCES))) \
            $(addprefix $(BUILD)/,$(patsubst %.cpp,%.o,$(PSOURCES)))

DOBJECTS =  $(addprefix $(BUILD)/,$(patsubst %.c,%.o,$(CSOURCES))) \
            $(addprefix $(BUILD)/,$(patsubst %.cpp,%.o,$(PSOURCES)))

DEPENDS =   $(patsubst %.o,%.d, $(DOBJECTS))

# all, clean: optional make command
.PHONY: all clean clean_depend run text
.SUFFIXES :
.SUFFIXES : .hpp .s .h .c .cpp .d .o

all: $(BUILD) $(TARGET).elf text

$(TARGET).elf: $(OBJECTS) $(LDSCRIPT) Makefile
    $(CC) $(LDFLAGS) $(LIBINCS) -o $@ $(OBJECTS) $(LIBS)
    $(SIZE) $@

$(BUILD)/%.o: %.s
    mkdir -p $(dir $@); \
    $(AS) -c $(AOPT) $(AFLAGS) $(AINCS) -o $@ $<

$(BUILD)/%.o : %.c
    mkdir -p $(dir $@); \
    $(CC) -c $(COPT) $(CFLAGS) $(CINCS) $(CCWARN) -o $@ $<

$(BUILD)/%.o : %.cpp
    mkdir -p $(dir $@); \
    $(CP) -c $(POPT) $(PFLAGS) $(PINCS) $(CPWARN) -o $@ $<

$(BUILD)/%.d: %.c
    mkdir -p $(dir $@); \
    $(CC) -MM -DDEPEND_ESCAPE $(COPT) $(CFLAGS) $(APPINCS) $< \
    | sed 's/$(notdir $*)\.o:/$(subst /,\/,$(patsubst %.d,%.o,$@) $@):/' > $@ ; \
    [ -s $@ ] || rm -f $@

$(BUILD)/%.d: %.cpp
    mkdir -p $(dir $@); \
    $(CP) -MM -DDEPEND_ESCAPE $(POPT) $(PFLAGS) $(APPINCS) $< \
    | sed 's/$(notdir $*)\.o:/$(subst /,\/,$(patsubst %.d,%.o,$@) $@):/' > $@ ; \
    [ -s $@ ] || rm -f $@

clean:
    rm -rf $(BUILD) $(TARGET).elf $(TARGET).mot $(TARGET).lst $(TARGET).map

clean_depend:
    rm -f $(DEPENDS)

これは、gcc の設定で、従属規則を自動生成する仕組みを内包する。


lst: $(TARGET).lst

%.lst: %.elf
    $(OBJDUMP) -h -S $< > $@

# Rules for building the .text rom images

text: mot lst

lst: $(TARGET).lst
mot: $(TARGET).mot
bin: $(TARGET).bin

%.lst: %.elf
    $(OBJDUMP) -h -S $< > $@

%.mot: %.elf
    $(OBJCOPY) $(OBJCOPY_OPT) -O srec $< $@

%.bin: %.elf
    $(OBJCOPY) -O binary $< $@

これは、リンカーで実行バイナリーを作成後、リストファイル、モトローラーファイル、バイナリーファイルを作成する手順だ。


# Serial Flash write 
run:
    $(MAKE)
    rx_prog -d $(RX_CPU) --progress --erase --write $(PROG_VERIFY) $(TARGET).mot

最後は、シリアル接続で、フラッシュ書き込みを行うツールの設定などになっている。

個別部分

上記のように、共通出来る部分を追い出したので、個別部分はシンプルとなった。

# -*- tab-width : 4 -*-
#=======================================================================
#   @file
#   @brief  RX72N Makefile
#   @author 平松邦仁 (hira@rvf-rc45.net)
#   @copyright  Copyright (C) 2020, 2021 Kunihito Hiramatsu @n
#               Released under the MIT license @n
#               https://github.com/hirakuni45/RX/blob/master/LICENSE
#=======================================================================
TARGET      =   raytracer_sample

DEVICE      =   R5F572NN

RX_DEF      =   SIG_RX72N

BUILD       =   release
# BUILD     =   debug

VPATH       =   ../../

ASOURCES    =   common/start.s

CSOURCES    =   common/init.c \
                common/vect.c \
                common/syscalls.c

PSOURCES    =   RAYTRACER_sample/main.cpp \
                graphics/font8x16.cpp \
                graphics/color.cpp \
                common/stdapi.cpp

USER_LIBS   =

USER_DEFS   =

INC_APP     =   . ../ ../../

AS_OPT      =

CP_OPT      =   -Wall -Werror \
                -Wno-unused-variable \
                -Wno-unused-function \
                -fno-exceptions

CC_OPT      =   -Wall -Werror \
                -Wno-unused-variable \
                -fno-exceptions

ifeq ($(BUILD),debug)
    CC_OPT += -g -DDEBUG
    CP_OPT += -g -DDEBUG
    OPTIMIZE = -O0
endif

ifeq ($(BUILD),release)
    CC_OPT += -DNDEBUG
    CP_OPT += -DNDEBUG
    OPTIMIZE = -O3
endif

-include ../../common/makefile

-include $(DEPENDS)

これは、RX72T の RAYTRACER_sample の Makefile で、基本、リンクするファイルの記述が殆どだ。

リリースビルドと、デバッグビルドの違いで切り替える部分は共通化しなかった。
最適化を変えたり、プロジェクト毎に微妙な違いを許容する事が出来るように配慮した。


まとめ

共通化する過程で、オプションなどを変更した場合に、フルコンパイルが自動で行えるように出来ないか検討したが、make を完全に理解していない為、思ったように作れなかった・・

これは今後の課題にしたいと思う。

「Makefile を共通化」への1件のフィードバック

  1. はじめまして。
    今回仕事(個人事業)で初めてRXマイコン(72N)を使うことになり環境から何から何まで手探りで理解に努めてますが、ちんぷんかんぷんで悩んでいます。仕様~回路~A/W~ソフト~量産への非常識な(笑)ロードマップで、初マイコンで行うにはリスクが高すぎてテンパってます。そういうところにこのサイトを見つけて只今奮闘中です。大変助かります。これからもアップされるのを楽しみにしてます。

海の無い県のぼっち へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください