我的编译行和我的 makefile 之间有啥区别可能导致错误?

Posted

技术标签:

【中文标题】我的编译行和我的 makefile 之间有啥区别可能导致错误?【英文标题】:What difference between my compilation line and my makefile could cause the error?我的编译行和我的 makefile 之间有什么区别可能导致错误? 【发布时间】:2017-02-02 21:56:55 【问题描述】:

我之前写过一个正在运行的编译行。 但是,我的 Makefile 生成或多或少相同的东西,没有成功编译。

命令行(工作):

sh3eb-elf-gcc -m3 -mb -ffreestanding -nostdlib -T addin.ld src/crt0.s src/BTKOM.cpp src/bluetooth.cpp src/syscall.s -o addin.elf -Iinclude -L libs/ -lgcc -lmonochrome -lfx -O2 -fno-exceptions

生成文件:

CC = sh3eb-elf-gcc
SRCDIR = src
INCLDIR = include
LIBDIR = libs
EXTENSIONS = c cpp s
LIBS = -lgcc -lmonochrome -lfx
WFLAGS = -Wall
CFLAGS = -I $(INCLDIR) $(WFLAGS)
LFLAGS = -m3 -mb -ffreestanding -nostdlib -T addin.ld -L $(LIBDIR) $(LIBS) -O2 -fno-exceptions
SRCS := $(SRCS) $(foreach EXT,$(EXTENSIONS),$(wildcard $(SRCDIR)/*.$(EXT)))
OBJS := $(OBJS) $(foreach EXT,$(EXTENSIONS),$(patsubst $(SRCDIR)/%.$(EXT),%.o,$(wildcard $(SRCDIR)/*.$(EXT))))
OUT = addin

all : $(OUT).elf

$(OUT).elf : $(OBJS)
    $(CC) $(LFLAGS) -o $@ $^

$(OBJS) : $(SRCDIR)/$(SRCS)
    $(CC) $(CFLAGS) -c $(SRCS)

clean:
    rm -f *.o

cleaner:
    rm -f *.o $(OUT).elf $(OUT).g1a $(OUT).bin

从 makefile 生成的行:

sh3eb-elf-gcc -I include -Wall -c  src/MonochromeLib.c src/BTKOM.cpp src/bluetooth.cpp src/syscall.s src/crt0.s
sh3eb-elf-gcc -m3 -mb -ffreestanding -nostdlib -T addin.ld -L libs -lgcc -lmonochrome -lfx -O2 -fno-exceptions -o addin.elf MonochromeLib.o BTKOM.o bluetooth.o syscall.o crt0.o

输出:

BTKOM.o: In function `_main':
BTKOM.cpp:(.text+0xc4): undefined reference to `_memset'
BTKOM.cpp:(.text+0xec): undefined reference to `_GetKey'
bluetooth.o: In function `Bluetooth::Bluetooth()':
bluetooth.cpp:(.text+0xa0): undefined reference to `_srand'
bluetooth.cpp:(.text+0xa4): undefined reference to `_rand'
bluetooth.cpp:(.text+0xac): undefined reference to `_memcpy'
...

【问题讨论】:

Read up on what the -nostdlib option does. @user4581301 我知道-nostdlib 并且我故意使用它。它正在与我的编译行一起使用。这些指令在 libgcc (-lgcc) 中定义 知道了,只是$(CC) -o $@ $^ $(LFLAGS) 而不是$(CC) $(LFLAGS) -o $@ $^ ... 好的。我看起来像个傻瓜。订购可能。 BTKOM.o 列在库之后,因此链接器不知道它必须在库中查找 BTKOM.o 所需的内容 哈!时间安排如何? 【参考方案1】:

有一个reason的内置链接规则定义为

$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

LINK.o

$(CC) $(LDFLAGS) $(TARGET_ARCH)

你应该发现它可以通过将你的makefile重写为

LDLIBS  := -lgcc -lmonochrome -lfx
LDFLAGS := -nostdlib -T addin.ld -L libs

$(OUT).elf: $(OBJS)
    $(LINK.o) $^ $(LDLIBS) -o $@

请注意,-O2ffreestanding-fno-exceptions 是编译选项,而不是链接选项(我认为 -m3-mb 也是如此)。

【讨论】:

以上是关于我的编译行和我的 makefile 之间有啥区别可能导致错误?的主要内容,如果未能解决你的问题,请参考以下文章

android.mk makefile 有啥区别

Makefile 中的 := 和 = 有啥区别?

makefile 和 sh 文件有啥区别

为啥我的程序在使用 makefile 编译时会变慢?

可执行格式有啥区别?

tomcat 每次启动编译文件classes 为啥还用ANT进行重新编译? 和maven有啥区别