ESP-IDF添加外部库报错‘project command is not scriptable’问题排查
ESP-IDF添加外部库构建失败问题
项目结构
. ├── app │ ├── CMakeLists.txt │ ├── components │ │ ├── DummyLib │ │ │ ├── CMakeLists.txt │ │ │ ├── test.cpp │ │ │ └── test.h │ │ └── DummyLibComponent │ │ └── CMakeLists.txt │ └── main │ ├── CMakeLists.txt │ └── mm01.c └── esp-idf
构建报错信息
idf.py build Executing action: all (aliases: build) Running ninja in directory <PATH_TO_PROJECT>/app/build Executing "ninja all"... [0/1] Re-running CMake...-- Building ESP-IDF components for target esp32s3 CMake Error at <PATH_TO_PROJECT>/esp-idf/tools/cmake/component.cmake:224 (message): CMake Warning (dev) at build_properties.temp.cmake:8: Syntax Warning in cmake code at column 51 Argument not separated from preceding token by whitespace. Call Stack (most recent call first): <PATH_TO_PROJECT>/esp-idf/tools/cmake/scripts/component_get_requirements.cmake:3 (include) This warning is for project developers. Use -Wno-dev to suppress it. CMake Error at <PATH_TO_PROJECT>/app/components/DummyLib/CMakeLists.txt:2 (project): project command is not scriptable Call Stack (most recent call first): <PATH_TO_PROJECT>/esp-idf/tools/cmake/scripts/component_get_requirements.cmake:106 (include) <PATH_TO_PROJECT>/esp-idf/tools/cmake/scripts/component_get_requirements.cmake:124 (__component_get_requirements)
用户疑问
- 当前配置存在什么问题?
- ‘project command is not scriptable’是什么含义?
- 不修改外部库的前提下,正确添加外部库的方式是什么?
问题解答
1. 当前配置的问题
你将外部库DummyLib直接放在了ESP-IDF的components目录下,ESP-IDF会自动把该目录下的所有子目录识别为ESP-IDF组件处理。但DummyLib的CMakeLists.txt中使用了project()命令,这违反了ESP-IDF组件的CMake规则:ESP-IDF组件的CMake脚本不能包含project(),因为整个项目的project()已经由ESP-IDF顶层构建系统定义,组件仅作为子模块被导入,不能重新定义项目属性。
2. ‘project command is not scriptable’的含义
这个错误是CMake的提示:当一个CMake文件被作为脚本(通过include()命令)导入到现有构建系统中时,不能使用project()命令。ESP-IDF处理组件时,会把组件的CMakeLists.txt作为脚本导入主构建系统,而非作为独立项目构建,此时project()会试图重新定义项目的基础属性,与主构建系统冲突,因此被禁止。
3. 不修改外部库的正确添加方式
无需修改DummyLib的代码和CMake配置,以下两种方案均可:
方案一:将外部库移出components目录
- 将
DummyLib从components目录迁移到其他位置,比如app/external/DummyLib - 在
app/main/CMakeLists.txt或app/CMakeLists.txt中用原生CMake命令引入该库:# 添加外部库目录,指定构建输出路径避免冲突 add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../external/DummyLib ${CMAKE_BINARY_DIR}/DummyLib) # 将外部库链接到main组件 target_link_libraries(${COMPONENT_LIB} PRIVATE DummyLib)
方案二:用中间组件封装外部库
保留DummyLib在当前位置,通过DummyLibComponent作为中间层封装:
- 修改
DummyLibComponent/CMakeLists.txt:# 注册空组件作为占位 idf_component_register(SRCS "") # 导入外部库的构建脚本 add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../DummyLib ${CMAKE_BINARY_DIR}/DummyLib) # 将外部库链接到中间组件 target_link_libraries(${COMPONENT_LIB} PRIVATE DummyLib) - 在
main/CMakeLists.txt中添加对中间组件的依赖:idf_component_register(SRCS "mm01.c" REQUIRES DummyLibComponent)
内容的提问来源于stack exchange,提问作者killdaclick
相关产品推荐
相关产品推荐

