make:使用不同的编译器强制重新编译相同的对象

发布于 2024-12-29 12:46:21 字数 1797 浏览 0 评论 0原文

我希望我的 makefile 构建相同的二进制文件两次,首先使用 gcc 编译,然后使用 mingw 编译。所以,我写了这个,但它不起作用:

OBJ_DIR = obj
SRC_DIR = src
BIN_DIR = bin

INCLUDE = -I./$(SRC_DIR)
LIBS = 

_SRCS = print_current_dir.c test_main.c
_OBJS = print_current_dir.o test_main.o

SRCS = $(addprefix $(SRC_DIR)/,$(_SRCS))
OBJS = $(addprefix $(OBJ_DIR)/,$(_OBJS))

all: $(BIN_DIR)/pps-linux $(BIN_DIR)/pps-win32

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
    $(CC) -c -o $@ $< $(CFLAGS)

$(BIN_DIR)/pps-linux: CC = cc
$(BIN_DIR)/pps-linux: CFLAGS = -g -Wall $(INCLUDE) $(LIBS)
$(BIN_DIR)/pps-linux: $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) -o $@

$(BIN_DIR)/pps-win32: CC = i586-mingw32msvc-cc
$(BIN_DIR)/pps-win32: CFLAGS = -g -Wall $(INCLUDE) $(LIBS)
$(BIN_DIR)/pps-win32: $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) -o $@

一旦它使用 gcc 为目标 pps-linux 编译了 $(OBJS) 中的对象文件,它就会尝试使用相同的对象文件构建 pps-win32,显然失败了,尽管我为目标 pps-win32 重新定义了 CC 和 CFLAGS。 这是输出:

$ make
cc -c -o obj/print_current_dir.o src/print_current_dir.c -g -Wall -I./src 
cc -c -o obj/test_main.o src/test_main.c -g -Wall -I./src 
cc -g -Wall -I./src  obj/print_current_dir.o obj/test_main.o -o bin/pps-linux
i586-mingw32msvc-cc -g -Wall -I./src  obj/print_current_dir.o obj/test_main.o -o bin/pps-win32
obj/print_current_dir.o: In function `print_dir':
/home/matteo/Desktop/pps/src/print_dir.c:23: undefined reference to `get_current_dir_name'
/home/matteo/Desktop/pps/src/print_dir.c:25: undefined reference to `puts'
/home/matteo/Desktop/pps/src/print_dir.c:27: undefined reference to `free'
/usr/lib/gcc/i586-mingw32msvc/4.4.4/../../../../i586-mingw32msvc/lib/libmingw32.a(main.o):(.text+0x85): undefined reference to `_WinMain@16'
collect2: ld returned 1 exit status
make: *** [bin/pps-win32] Error 1

如何强制重新编译刚刚使用不同编译器编译的对象文件?

谢谢。

I want my makefile to build the same binary 2 times, first compiling with gcc and then with mingw. So, I've written this, but it does not work:

OBJ_DIR = obj
SRC_DIR = src
BIN_DIR = bin

INCLUDE = -I./$(SRC_DIR)
LIBS = 

_SRCS = print_current_dir.c test_main.c
_OBJS = print_current_dir.o test_main.o

SRCS = $(addprefix $(SRC_DIR)/,$(_SRCS))
OBJS = $(addprefix $(OBJ_DIR)/,$(_OBJS))

all: $(BIN_DIR)/pps-linux $(BIN_DIR)/pps-win32

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
    $(CC) -c -o $@ 
lt; $(CFLAGS)

$(BIN_DIR)/pps-linux: CC = cc
$(BIN_DIR)/pps-linux: CFLAGS = -g -Wall $(INCLUDE) $(LIBS)
$(BIN_DIR)/pps-linux: $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) -o $@

$(BIN_DIR)/pps-win32: CC = i586-mingw32msvc-cc
$(BIN_DIR)/pps-win32: CFLAGS = -g -Wall $(INCLUDE) $(LIBS)
$(BIN_DIR)/pps-win32: $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) -o $@

Once it compiles the objects file in $(OBJS) with gcc for the target pps-linux, it tries to build pps-win32 with the very same objects file, obviously failing, and despite the fact that I redefined CC and CFLAGS for the target pps-win32.
Here is the output:

$ make
cc -c -o obj/print_current_dir.o src/print_current_dir.c -g -Wall -I./src 
cc -c -o obj/test_main.o src/test_main.c -g -Wall -I./src 
cc -g -Wall -I./src  obj/print_current_dir.o obj/test_main.o -o bin/pps-linux
i586-mingw32msvc-cc -g -Wall -I./src  obj/print_current_dir.o obj/test_main.o -o bin/pps-win32
obj/print_current_dir.o: In function `print_dir':
/home/matteo/Desktop/pps/src/print_dir.c:23: undefined reference to `get_current_dir_name'
/home/matteo/Desktop/pps/src/print_dir.c:25: undefined reference to `puts'
/home/matteo/Desktop/pps/src/print_dir.c:27: undefined reference to `free'
/usr/lib/gcc/i586-mingw32msvc/4.4.4/../../../../i586-mingw32msvc/lib/libmingw32.a(main.o):(.text+0x85): undefined reference to `_WinMain@16'
collect2: ld returned 1 exit status
make: *** [bin/pps-win32] Error 1

How do I force the recompilation of the objects file just compiled with a different compiler?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

哆兒滾 2025-01-05 12:46:21

通过使目标文件也依赖于编译器,而不是尝试用不同的内容覆盖相同的 .o 文件,例如。

LINUX_OBJS = $(addprefix $(LINUX_OBJ_DIR)/,$(_OBJS))
...
$(BIN_DIR)/pps-linux: $(LINUX_OBJS)

注意。您可以通过使用 OBJ_DIR 的目标相关定义来更整洁地完成此操作,

$(BIN_DIR)/pps-linux: OBJ_DIR = linux-obj

但我必须尝试一下才能确定。

By making the object files compiler-dependent too, rather than trying to overwrite the same .o file in place with different contents, eg.

LINUX_OBJS = $(addprefix $(LINUX_OBJ_DIR)/,$(_OBJS))
...
$(BIN_DIR)/pps-linux: $(LINUX_OBJS)

NB. you may be able to do it more tidily by just using a target-dependent definition of OBJ_DIR, ie,

$(BIN_DIR)/pps-linux: OBJ_DIR = linux-obj

but I'd have to try it to be sure.

最近可好 2025-01-05 12:46:21

我建议使用单独的 OBJ_DIR 和 BIN_DIR 目录来实现此目的,其中名称部分由编译器供应商构建:

OBJ_DIR = obj-$(CC)
BIN_DIR = bin-$(CC)

我使用具有完全独立的构建目录的类似方法和安装目录,其名称构造自:

  • 编译器供应商
  • 编译器版本
  • 体系结构
  • libc 版本(如果是 linux)

生成的目录名为(例如):

  • gcc_3.4.6-x86-libc_2.3.4
  • forte_5.10-x64
  • gcc_4.2.3-x86

I would suggest using separate OBJ_DIR and BIN_DIR directories to accomplish this, with the names being constructed in part from the compiler vendor:

OBJ_DIR = obj-$(CC)
BIN_DIR = bin-$(CC)

I use a similar approach that has completely separate build directories, and installation directories, with the names constructed from:

  • compiler vendor
  • compiler version
  • architecture
  • libc version (if linux)

which results in directories named (for example):

  • gcc_3.4.6-x86-libc_2.3.4
  • forte_5.10-x64
  • gcc_4.2.3-x86
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文