Makefile想要编译自己

时间:2015-12-09 07:37:22

标签: gcc makefile llvm

我正在使用Makefile来编译带有LLVM(clang)的C代码,以便为ARM Cortex-M3生成LLVM IR和程序集。编译流程为:

  1. %.ll: $(SRC_C) 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文件
  6. 不应删除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 $@
    
    $(SRC_BC): %.bc: %.ll
        llvm-as $*.ll -o $*.bc
    
    $(SRC_S): %.s: %.bc
        llc $(LLCFLAGS)  $< -o $@
    
    $(SRC_SO): %.s.o: %.s
        $(CC) $(CFLAGS) -o $@ -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)
    

1 个答案:

答案 0 :(得分:2)

您需要查看.PHONY指令。 clean 并不特别,make将检查文件 clean 是否存在。

此外,您的规则需要更改,因为Makefile的一些隐式规则匹配'Makefile.bc - &gt; 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 $@

现在,只有$(SRC_BC)中的文件才会应用此规则,并且没有隐式的'Makefile.s'会尝试使用它。您还可以使用其他规则来生成汇编程序,并且只有输入变量将指定集合(不是全局匹配;某些使隐式规则具有全局匹配)。