是否需向库的Makefile传递--sysroot选项?该在何阶段配置?
问题
我开发了一款应用程序及若干库,所有代码需交叉编译至嵌入式平台,且已为该平台运行的Linux内核生成自定义根文件系统。目前我在应用程序的Makefile中导出了部分变量供库的Makefile使用,请问是否也需导出--sysroot选项?若需要,应在哪个阶段(编译、归档等)传入该选项?
应用程序Makefile
# ...application specific configuration ... SYSTEM_ROOT_PATH := /path/to/custom-rootfs # Variables exported for user-defined libraries export DEFINES export CPP_FLAGS export SANITIZERS # ... trigger library Makefiles ... all: $(CPP_OBJECTS) @$(CC) --sysroot="$(SYSTEM_ROOT_PATH)" -o app.elf $(CPP_OBJECTS) $(SANITIZERS) $(LIBS) $(PRJ_OBJECTS_DIR)/%.o : $(PRJ_SOURCE_CODE)/%.cpp @$(CC) $(CPP_FLAGS) $(SANITIZERS) $(INCLUDES) $(DEFINES) -c $< -o $@ -MD -MP
库Makefile
# ... library specific configuration ... all: $(CPP_OBJECTS) $(AR) rcs library.a $(CPP_OBJECTS) $(LIB_OBJECTS_DIR)/%.o : $(LIB_SOURCES)/%.cpp @$(CC) $(CPP_FLAGS) $(SANITIZERS) $(INCLUDES) $(DEFINES) -c $< -o $@ -MD -MP
回答
结论:必须导出--sysroot相关配置,且要在库的目标文件编译阶段传入
为什么需要?
交叉编译场景下,--sysroot是编译器定位目标平台头文件、系统库的核心参数。如果你的库代码依赖自定义根文件系统里的任何内容(比如平台专属的系统头文件、预编译的第三方库),不传递--sysroot的话,编译器会默认使用开发机的头文件和库,最终编译出的库要么无法在目标嵌入式平台运行,要么在编译阶段就出现头文件缺失、符号不匹配的错误。
哪个阶段传入?
- 编译
.cpp生成.o文件的阶段:这是唯一需要--sysroot的环节,编译器需要根据目标根文件系统的环境,编译出适配平台的目标文件。 - 归档(
ar打包静态库)阶段:完全不需要,ar只是把已编译好的.o文件打包成静态库,不涉及任何编译或平台相关逻辑。
具体实现方案
有两种简洁的实现方式:
单独导出根路径变量
在应用程序Makefile中新增导出:SYSTEM_ROOT_PATH := /path/to/custom-rootfs export SYSTEM_ROOT_PATH # 导出给库Makefile使用 export DEFINES export CPP_FLAGS export SANITIZERS然后修改库Makefile的编译规则:
$(LIB_OBJECTS_DIR)/%.o : $(LIB_SOURCES)/%.cpp @$(CC) --sysroot="$(SYSTEM_ROOT_PATH)" $(CPP_FLAGS) $(SANITIZERS) $(INCLUDES) $(DEFINES) -c $< -o $@ -MD -MP将
--sysroot整合到已导出的CPP_FLAGS中
修改应用程序Makefile的CPP_FLAGS定义:SYSTEM_ROOT_PATH := /path/to/custom-rootfs CPP_FLAGS += --sysroot="$(SYSTEM_ROOT_PATH)" # 把sysroot参数加入CPP_FLAGS export CPP_FLAGS export DEFINES export SANITIZERS这种方式下,库Makefile的编译规则无需修改,直接沿用原来的即可,因为
CPP_FLAGS已经包含了--sysroot参数。
内容的提问来源于stack exchange,提问作者Caglayan Dokme
相关产品推荐
相关产品推荐

