如何修改Makefile以支持交叉编译?
How to modify Makefile to support cross compilation?
我有以下 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
我用下面的命令执行它:
make ARCH=$TARGET_ARCH \
CROSS_COMPILE=$TARGET_PREFIX \
SRC_DIR=$ROOT/$PKG_BUILD
但它会忽略 ARCH
和 CROSS_COMPILE
值。我试图用 $(MAKE)
替换 $(CC)
并添加 -$(MAKEFLAGS)
,但它说的是 Nothing to be done for 'Main.cpp'
.
如何修复它并添加交叉编译支持?
下面是我尝试的一个可能示例,假设在这个简单的示例中 $ARCH 被映射到 "arm"。我没有测试过,但之前做过类似的事情。
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
编辑:这假定工具链存在于您的路径中。
编辑:也可以修改它,使 CC=$(PREFIX)-g++ 这一切都取决于你传递给它的内容如何映射到你的工具链命名约定。
您传递给 make
(例如 ARCH=$TARGET_ARCH
)的 事物 实际上只是 Makefile variables
。
make
根本不知道他们和交叉编译有关(这只是你脑子里联想的东西)。例如
$ cat Makefile
ARCH=pdp-11
foo:
@echo arch: $ARCH
$ make
arch: pdp-11
$ make ARCH=le-corbusier
arch: le-corbusier
进行交叉编译的标准方法是覆盖compiler/linker。例如。以下将为 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++
一些注意事项
您的 makefile 有很多问题...
变量名
CC
是 C-Compiler 的标准变量;对于 C++ 编译器 使用 CXX
链接顺序很重要
现代链接器会 discard unused symbols,如果您没有得到正确的顺序,可能会导致链接器错误。因此,您应该将 $(LIBS)
变量放在链接器调用的最后
声明依赖关系
make
的强大之处在于解决依赖关系的能力(当一些文件发生更改时,找出构建树的哪些部分需要重新编译)。为此,您需要编写对这些依赖项进行编码的规则 - 而不是召唤任意目标名称并强制重建所有内容。
我有以下 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
我用下面的命令执行它:
make ARCH=$TARGET_ARCH \
CROSS_COMPILE=$TARGET_PREFIX \
SRC_DIR=$ROOT/$PKG_BUILD
但它会忽略 ARCH
和 CROSS_COMPILE
值。我试图用 $(MAKE)
替换 $(CC)
并添加 -$(MAKEFLAGS)
,但它说的是 Nothing to be done for 'Main.cpp'
.
如何修复它并添加交叉编译支持?
下面是我尝试的一个可能示例,假设在这个简单的示例中 $ARCH 被映射到 "arm"。我没有测试过,但之前做过类似的事情。
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
编辑:这假定工具链存在于您的路径中。 编辑:也可以修改它,使 CC=$(PREFIX)-g++ 这一切都取决于你传递给它的内容如何映射到你的工具链命名约定。
您传递给 make
(例如 ARCH=$TARGET_ARCH
)的 事物 实际上只是 Makefile variables
。
make
根本不知道他们和交叉编译有关(这只是你脑子里联想的东西)。例如
$ cat Makefile
ARCH=pdp-11
foo:
@echo arch: $ARCH
$ make
arch: pdp-11
$ make ARCH=le-corbusier
arch: le-corbusier
进行交叉编译的标准方法是覆盖compiler/linker。例如。以下将为 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++
一些注意事项
您的 makefile 有很多问题...
变量名
CC
是 C-Compiler 的标准变量;对于 C++ 编译器 使用 CXX
链接顺序很重要
现代链接器会 discard unused symbols,如果您没有得到正确的顺序,可能会导致链接器错误。因此,您应该将 $(LIBS)
变量放在链接器调用的最后
声明依赖关系
make
的强大之处在于解决依赖关系的能力(当一些文件发生更改时,找出构建树的哪些部分需要重新编译)。为此,您需要编写对这些依赖项进行编码的规则 - 而不是召唤任意目标名称并强制重建所有内容。