Cortex-A5 CMSISのリンカスクリプトをベースにコンパイル環境を構築していると こんなエラーが発生しました。
原因はARMCA5.ldのこの記述です。
#include "mem_ARMCA5.h" ← これ! MEMORY { ROM (rx) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE L_TTB (rw) : ORIGIN = __TTB_BASE, LENGTH = __TTB_SIZE RAM (rwx) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE } ...snip...
Cプリプロセッサの書式で書いてありますが、リンカはCプリプロセッサ機能を持っていないためエラーになります。
解決方法
どうやら、このリンカスクリプトは一旦Cプリプロセッサに通すことを前提に書かれているようです。
というとで、gccを使ってプリプロセスを実行してやります。
arm-none-eabi-gcc -I <mem_ARMCA5.hのあるディレクトリ> -nostdinc -P -E -x c ARMCA5.ld -o ARMCA5.generated.ld
このコマンドで生成したARMCA5.generated.ldを使ってリンカを起動すれば正常にリンクできます。
応用編
ARMCA5.ldやmem_ARMCA5.hを変更した際に自動的にARMCA5.generated.ldが生成できると便利ですね。そこで、こんなMakefileを作ってみました。これ単体で使ってもあまり意味はないと思いますので、ビルド用のMakefileに組み込んで使ってください。
CC = arm-none-eabi-gcc LDSCRIPT_CFLAGS = -I ./Device/include -nostdinc -MMD -MP -P -E -x c LDSCRIPT_SRC = ./Device/Source/ARMCA5.ld LDSCRIPT = ./Device/Source/ARMCA5.generated.ld LDSCRIPT_DEPEND = $(LDSCRIPT:.ld=.d) DEPENDS = $(LDSCRIPT_DEPEND) all: $(LDSCRIPT) $(LDSCRIPT): $(LDSCRIPT_SRC) $(CC) $(LDSCRIPT_CFLAGS) $< -o $@ sed -i "s|$(notdir $(basename $<)).o|$@|" $(LDSCRIPT_DEPEND) ifneq ($(MAKECMDGOALS),clean) -include $(DEPENDS) endif
なお、LDSCRIPT_CFLAGSの“./Device/include”はmem_ARMCA5.hがあるディレクトリです。環境によって書き換えてください。
Makefileサンプルの解説
-MMD -MPでARMCA5.generated.ldの依存関係ファイルを生成し、それをincludeすることで、ARMCA5.generated.ldの自動生成を実現しています。
ただし、これだけでは依存関係ファイルは以下のように生成されてしまい、正常にmakeされません。
ARMCA5.o: Device/Source/ARMCA5.ld Device/include/mem_ARMCA5.h Device/include/mem_ARMCA5.h:
そこで、sedを用いて以下の様に書き換えています。
Device/Source/ARMCA5.generated.ld: Device/Source/ARMCA5.ld Device/include/mem_ARMCA5.h Device/include/mem_ARMCA5.h:
これで正しく依存関係ファイルが生成できました。
もっと簡単な方法
いっそのこと、#includeを削除してリンカスクリプトの構文に書き換えてしまうのもありですね。