背景
在工作工程中,需要提供一个ARM32的Linux的USB驱动给到客户。为了实现这个问题,我这里预计使用以下流程实现:
- 使用Linux主机开发相关的代码;
- 使用buildroot使用外部编译链的配置实现交叉编译;
但是,在我的代码仓库的结构中,
CMakeLists.txt
并没有放在文件的根目录,在移植代码的时候出现了以下错误: 这篇文章主要是记录如何解决这个问题的。
解决方案
这里直接把解决方案列出来,后续在解决方案的分析过程进行说明。
解决方案
在
libavocado.mk
中添加以下代码:LIBAVOCADO_SUBDIR = avocado/usb
然后再进行编译即可。
分析过程
这个问题是有CMakeLists.txt
缺失导致。那么,解决这个问题的思路就是,在执行cmake
配置的时候把CMakeListst.txt
目录传递给cmake
。因此,解决这个问题,首先要对pkg-cmake.mk
进行分析,确认传递给cmake的参数有哪些,哪些是可以在包的Makefile中进行配置并修改的。下面是pkg-cmake.mk
中执行cmake的代码:
define $(2)_CONFIGURE_CMDS
(mkdir -p $$($$(PKG)_BUILDDIR) && \
cd $$($$(PKG)_BUILDDIR) && \
rm -f CMakeCache.txt && \
PATH=$$(BR_PATH) \
$$($$(PKG)_CONF_ENV) $$(BR2_CMAKE) $$($$(PKG)_SRCDIR) \
-G"Unix Makefiles" \
-DCMAKE_TOOLCHAIN_FILE="$$(HOST_DIR)/share/buildroot/toolchainfile.cmake" \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_INSTALL_RUNSTATEDIR="/run" \
-DCMAKE_COLOR_MAKEFILE=OFF \
-DBUILD_DOC=OFF \
-DBUILD_DOCS=OFF \
-DBUILD_EXAMPLE=OFF \
-DBUILD_EXAMPLES=OFF \
-DBUILD_TEST=OFF \
-DBUILD_TESTS=OFF \
-DBUILD_TESTING=OFF \
-DBUILD_SHARED_LIBS=$$(if $$(BR2_STATIC_LIBS),OFF,ON) \
$$(CMAKE_QUIET) \
$$($$(PKG)_CONF_OPTS) \
)
endef
从上面的代码中可以看到:$$($$(PKG)_SRCDIR)
是配置CMakeLists.txt
的关键变量。
于是,本人先做了以下尝试:设置LIBAVACADO_SRCDIR = $(@D)/avacado/usb
。但是,问题出现了,这个改动并没有丝毫作用,根据编译的输出来看,其SRCDIR
变量依然还是原来的值。
为了确定这个问题,我执行了以下命令确认:
结果显示,该变量的确没有任何的变更。
进一步对这个进行分析,个人觉得,该变量应该在其他地方被重新修改了。于是继续分析pkg-cmake.mk
的代码,发现以下内容:
# Call the generic package infrastructure to generate the necessary
# make targets
$(call inner-generic-package,$(1),$(2),$(3),$(4))
这里对inner-generic-package
进行了调用,而这个变量则位于pkg-generic.mk
中。于是打开这个文件进行分析,发现以下代码:
$(2)_SRCDIR = $$($(2)_DIR)/$$($(2)_SUBDIR)
这里的$(2)
代表的就是大写的包名称。
根据这个发现,于是做出上面的改动LIBAVOCADO_SUBDIR = avacado/usb
,重新编译,通过。
后记
其实真实的解决问题过程并没有这么轻松,中间有大量的变量查找、尝试和buildroot源码修改的过程。但整体的思路是这样的。
评论区