2015-12-09 104 views
1

我正在使用Makefile編譯帶有LLVM(clang)的C代碼,以便爲ARM Cortex-M3生成LLVM IR和程序集。編譯流程是:Makefile想自行編譯

  1. ​​C代碼 - > LLVM IR
  2. %.bc: $(SRC_LL) LLVM IR - > LLVM二進制
  3. %.s: $(SRC_BC) LLVM二進制 - > ARM組件
  4. %.s.o: $(SRC_S) ARM總成 - >目標文件
  5. all與main.o和stm32.ld目標文件的鏈接 - > ELF文件

的LLVM IR文件和ARM彙編文件不應該被刪除,因爲這個我加了這一行:.SECONDARY: $(SRC_LL) $(SRC_S)

這裏是Makefile中:

CFLAGS = -I./ -c -O0 -gdwarf-3 -mcpu=cortex-m3 --target=armv7m-none-eabi 
LFLAGS = -Tstm32.ld -nostartfiles 
LLCFLAGS = -O0 -mtriple=arm-none-eabi -march=thumb -mattr=thumb2 -mcpu=cortex-m3 -float-abi=soft -thread-model=single -filetype=asm 
CC = clang 
LD = arm-none-eabi-ld 

TARGET = example_code.elf 

SRC_C = example_code.c crc_function.c 
SRC_S = $(SRC_C:.c=.s) 
SRC_LL = $(SRC_C:.c=.ll) 
SRC_BC = $(SRC_C:.c=.bc) 
SRC_S = $(SRC_C:.c=.s) 
SRC_SO = $(SRC_C:.c=.s.o) 

.SECONDARY: $(SRC_LL) $(SRC_S) 

all: $(SRC_SO) main.o 
    $(LD) $(LFLAGS) -o $(TARGET) main.o $(SRC_SO) 

%.ll: $(SRC_C) 
    clang -O0 -emit-llvm -S -c $*.c -o $*.ll 

%.bc: $(SRC_LL) 
    llvm-as $*.ll -o $*.bc 

%.s: $(SRC_BC) 
    llc $(LLCFLAGS) $*.bc -o $*.s 

%.s.o: $(SRC_S) 
    $(CC) $(CFLAGS) -o $*.s.o -c $*.s 

main.o: main.c 
    $(CC) $(CFLAGS) -o main.o main.c 

clean: 
    -rm $(SRC_S) 
    -rm $(SRC_LL) 
    -rm $(SRC_BC) 
    -rm $(SRC_S) 
    -rm $(SRC_SO) 
    -rm main.o 
    -rm $(TARGET) 

這裏是我的文件:

crc_function.c 
crc_function.h 
example_code.c 
main.c 
stm32.ld 

能順利完成編譯:

clang -O0 -emit-llvm -S -c example_code.c -o example_code.ll 
clang -O0 -emit-llvm -S -c crc_function.c -o crc_function.ll 
llvm-as example_code.ll -o example_code.bc 
llvm-as crc_function.ll -o crc_function.bc 
llc -O0 -mtriple=arm-none-eabi -march=thumb -mattr=thumb2 -mcpu=cortex-m3 -float-abi=soft -thread-model=single -filetype=asm example_code.bc -o example_code.s 
llc -O0 -mtriple=arm-none-eabi -march=thumb -mattr=thumb2 -mcpu=cortex-m3 -float-abi=soft -thread-model=single -filetype=asm crc_function.bc -o crc_function.s 
clang -I./ -c -O0 -gdwarf-3 -mcpu=cortex-m3 --target=armv7m-none-eabi -o example_code.s.o -c example_code.s 
clang -I./ -c -O0 -gdwarf-3 -mcpu=cortex-m3 --target=armv7m-none-eabi -o crc_function.s.o -c crc_function.s 
clang -I./ -c -O0 -gdwarf-3 -mcpu=cortex-m3 --target=armv7m-none-eabi -o main.o main.c 
arm-none-eabi-ld -Tstm32.ld -nostartfiles -o example_code.elf main.o example_code.s.o crc_function.s.o 
rm example_code.bc crc_function.bc 

豪版本我不能叫make cleanmake all編譯成功後,它給了我下面的輸出:

llvm-as example_code.ll -o example_code.bc 
llvm-as crc_function.ll -o crc_function.bc 
llc -O0 -mtriple=arm-none-eabi -march=thumb -mattr=thumb2 -mcpu=cortex-m3 -float-abi=soft -thread-model=single -filetype=asm Makefile.bc -o Makefile.s 
llc: Makefile.bc: error: Could not open input file: No such file or directory 
make: *** [Makefile.s] Error 1 
rm example_code.bc crc_function.bc 

Makefile文件試圖編譯本身,我想不通爲什麼?

解決方案

感謝您的快速反應。這裏是我的問題的解決方案:

CFLAGS = -I./ -c -O0 -gdwarf-3 -mcpu=cortex-m3 --target=armv7m-none-eabi 
LFLAGS = -Tstm32.ld -nostartfiles 
LLCFLAGS = -O0 -mtriple=arm-none-eabi -march=thumb -mattr=thumb2 -mcpu=cortex-m3 -float-abi=soft -thread-model=single -filetype=asm 
CC = clang 
LD = arm-none-eabi-ld 

TARGET = example_code.elf 

SRC_C = example_code.c crc_function.c 
SRC_S = $(SRC_C:.c=.s) 
SRC_LL = $(SRC_C:.c=.ll) 
SRC_BC = $(SRC_C:.c=.bc) 
SRC_S = $(SRC_C:.c=.s) 
SRC_SO = $(SRC_C:.c=.s.o) 

.SECONDARY: $(SRC_LL) $(SRC_S) 

all: $(TARGET) 

$(TARGET): $(SRC_SO) main.o 
    $(LD) $(LFLAGS) -o $(TARGET) main.o $(SRC_SO) 

$(SRC_LL): %.ll: %.c 
    clang -O0 -emit-llvm -S -c $< -o [email protected] 

$(SRC_BC): %.bc: %.ll 
    llvm-as $*.ll -o $*.bc 

$(SRC_S): %.s: %.bc 
    llc $(LLCFLAGS) $< -o [email protected] 

$(SRC_SO): %.s.o: %.s 
    $(CC) $(CFLAGS) -o [email protected] -c $< 

main.o: main.c 
    $(CC) $(CFLAGS) -o main.o main.c 

.PHONY: clean 
clean: 
    -rm $(SRC_S) 
    -rm $(SRC_LL) 
    -rm $(SRC_BC) 
    -rm $(SRC_S) 
    -rm $(SRC_SO) 
    -rm main.o 
    -rm $(TARGET) 

回答

2

您需要查看.PHONY指令。 乾淨是不是特別的,並會檢查文件乾淨是否存在。

此外,您的規則需要更改,因爲Makefile.s有一些隱含的規則,它與'Makefile.bc - > Makefile.s'匹配。您可以查看Disable make builtin rules and variables from inside the make file以禁用所有內置規則。或者你可以使用static pattern rules。例如,如果您有另一種方法來生成'.s'文件作爲源文件,則此規則集可能會變得令人困惑。對於」 .S'的規則,這將是,

$(SRC_BC): %.s: %.bc 
    llc $(LLCFLAGS) $< -o [email protected] 

現在,只適用於$(SRC_BC)文件都會有這樣的規則,並沒有隱含的‘Makefile.s’會嘗試使用它。你也可以有其他的規則來生成彙編程序,只有輸入變量會指定這個集合(不是全局匹配;有些則會使隱式規則具有全局匹配)。

+0

'Makefile.s'可能是來自另一個規則的文件,用於創建最終的'Makefile'。您可以使用'make -p'和/或'make -d'來查看信息(在這種情況下只是'make --debug = i')。由於輸出很大,管道到一個文件,並使用grep等找到你的字符串; 'makefile.s'在這種情況下。 –