I have the following Makefile:
CC=g++
top_srcdir=$(SRC_DIR)/cpp/src/
INCLUDES:= -I $(top_srcdir) -I $(top_srcdir)command_classes -I $(top_srcdir)platform -I $(top_srcdir)value_classes
LIBS:= -lopenzwave -lpthread -ludev
LDFLAGS += -L$(SRC_DIR) -Wl,-R$(SRC_DIR) '-Wl,-R$$ORIGIN'
all: ozw
ozw: Main.cpp
$(CC) $(INCLUDES) -c Main.cpp -o ozw-power-on-off.o
$(CC) $(LIBS) $(LDFLAGS) ozw-power-on-off.o -o ozw-power-on-off.out
clean:
rm -rf *.o *.out
I execute it with the following command:
make ARCH=$TARGET_ARCH \
CROSS_COMPILE=$TARGET_PREFIX \
SRC_DIR=$ROOT/$PKG_BUILD
But it ignores ARCH
and CROSS_COMPILE
values. I tried to replace $(CC)
with $(MAKE)
and added -$(MAKEFLAGS)
, but it was saying Nothing to be done for 'Main.cpp'
.
How can I fix it and add cross compilation support?
The things you are passing to make
(e.g. ARCH=$TARGET_ARCH
) are really just Makefile variables
.
make
doesn't know at all that they are related to cross-compilation (this is just something that you associate in your brain). E.g.
$ cat Makefile
ARCH=pdp-11
foo:
@echo arch: $ARCH
$ make
arch: pdp-11
$ make ARCH=le-corbusier
arch: le-corbusier
The standard way to do cross-compilation is to just override the compiler/linker. E.g. the following would cross-compile for i686-w64-mingw32
:
$ cat Makefile
.PHONY: ozw
owz: ozw-power-on-off.out
ozw-power-on-off.o: Main.cpp
$(CXX) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS) -c $^ -o $@
ozw-power-on-off.out: ozw-power-on-off.o
$(CXX) -o $@ $(LDFLAGS) $^ $(LIBS)
$ make CXX=i686-w64-mingw32-g++
Your makefile has a number of issues...
CC
is the standard variable for the C-Compiler; for a C++-compiler use CXX
Modern linkers will discard unused symbols, leading to possible linker errors if you don't get the order right. Therefore you should puts the $(LIBS)
variable at the very end of your linker-invocation
The power of make
really is in the ability to resolve dependencies (finding out which parts of the build tree need to be recompiled when a few files have changed). For this to work you need to write rules that encode these dependencies - rather than conjure arbitrary target names and force to rebuild everything.
A possible example of something I would try is below assuming $ARCH get's mapped to "arm" in this trivial example. I haven't tested it, but have done something similar before.
CC=g++
CC-arm=arm-g++
ozw: Main.cpp
$(CC-$(ARCH)) $(INCLUDES) -c Main.cpp -o ozw-power-on-off.o
$(CC-$(ARCH)) $(LIBS) $(LDFLAGS) ozw-power-on-off.o -o ozw-power-on-off.out
edit: This assumes that the tool chain exists in your path. edit: Might also modify it such that CC=$(PREFIX)-g++ it all depends on what you how what you pass into it maps against your tool chains naming convention.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With