Reputation: 675
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 $@ $< $(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.
Upvotes: 2
Views: 279
Reputation: 121961
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:
which results in directories named (for example):
Upvotes: 1
Reputation: 67723
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.
Upvotes: 3