CMake-CPack组件化生成DEB包为空问题求助
我需要为IMX6/IMX8平台生成组件化DEB包,工具链会自动设置对应平台变量。使用IMX6时CPack输出如下:
Run CPack packaging tool... CPack: Create package using DEB CPack: Install projects CPack: - Run preinstall target for: main_project CPack: - Install project: main_project [] CPack: - Install component: PRIMARY_DISPLAY CPack: - Install component: SECONDARY_DISPLAY CPack: Create package -- CPACK_DEBIAN_PACKAGE_DEPENDS not set, the package will have no dependencies. -- CPACK_DEBIAN_PACKAGE_DEPENDS not set, the package will have no dependencies. CPack: - package: /home/anzipex/Downloads/add_target_package_secondary_47154/debs_47154/unca_23/cmake-build-release-imx6/unca-1.0.1-Linux-PRIMARY_DISPLAY.deb generated. CPack: - package: /home/anzipex/Downloads/add_target_package_secondary_47154/debs_47154/unca_23/cmake-build-release-imx6/unca-1.0.1-Linux-SECONDARY_DISPLAY.deb generated.
现在的问题是生成的DEB包为空,_CPack_Packages目录下的DEB包中,data.tar.gz仅包含空的usr目录。但设置set(CPACK_MONOLITHIC_INSTALL 1)后,主DEB包能包含所有数据,这是什么原因?
主项目CMakeLists.txt内容:
cmake_minimum_required(VERSION 3.0.0) set(CPACK_GENERATOR "DEB") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Company") set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_DEB_COMPONENT_INSTALL ON) if(NOT CMAKE_CROSSCOMPILING) set(CPACK_COMPONENTS_ALL DESKTOP) set(CPACK_DEBIAN_DESKTOP_PACKAGE_ARCHITECTURE "amd64") add_subdirectory(desktop) elseif(IMX6) set(CPACK_COMPONENTS_ALL PRIMARY_DISPLAY SECONDARY_DISPLAY) set(CPACK_DEBIAN_PRIMARY_DISPLAY_PACKAGE_ARCHITECTURE "armhf") set(CPACK_DEBIAN_SECONDARY_DISPLAY_PACKAGE_ARCHITECTURE "armhf") add_subdirectory(primary_display) add_subdirectory(secondary_display) elseif(IMX8) set(CPACK_COMPONENTS_ALL PRIMARY_DISPLAY SECONDARY_DISPLAY) set(CPACK_DEBIAN_PRIMARY_DISPLAY_PACKAGE_ARCHITECTURE "arm64") set(CPACK_DEBIAN_SECONDARY_DISPLAY_PACKAGE_ARCHITECTURE "arm64") add_subdirectory(primary_display) add_subdirectory(secondary_display) endif() include(CPack)
secondary_display/CMakeLists.txt示例:
cmake_minimum_required(VERSION 3.0.0) install(DIRECTORY ${PROJECT_SOURCE_DIR}/apps/secondary_display/resources DESTINATION /opt/unca COMPONENT secondary_display) install(TARGETS secondary_display DESTINATION /opt/unca COMPONENT secondary_display) install(TARGETS ahrs DESTINATION /opt/unca COMPONENT secondary_display) install(TARGETS sns DESTINATION /opt/unca COMPONENT secondary_display) install(DIRECTORY DESTINATION /var/opt/unca COMPONENT secondary_display DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_WRITE GROUP_READ GROUP_EXECUTE WORLD_WRITE WORLD_READ WORLD_EXECUTE ) install(FILES ${PROJECT_SOURCE_DIR}/resources/configs/net.xml DESTINATION /var/opt/unca COMPONENT secondary_display) install(FILES services/unca-secondary-display.service DESTINATION /etc/systemd/system/ COMPONENT secondary_display) install(FILES services/unca-ahrs.service DESTINATION /etc/systemd/system/ COMPONENT secondary_display) install(FILES services/unca-sns.service DESTINATION /etc/systemd/system/ COMPONENT secondary_display) set(CPACK_DEBIAN_SECONDARY_DISPLAY_PACKAGE_NAME "unca-secondary-display") set(CPACK_DEBIAN_SECONDARY_DISPLAY_FILE_NAME "unca-secondary-display-${CPACK_PACKAGE_VERSION}-${CPACK_DEBIAN_DESKTOP_PACKAGE_ARCHITECTURE}.deb") set(CPACK_DEBIAN_SECONDARY_DISPLAY_DESCRIPTION "UNCA SECONDARY DISPLAY") string(CONCAT CPACK_DEBIAN_SECONDARY_DISPLAY_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/debian/prerm;" "${CMAKE_CURRENT_SOURCE_DIR}/debian/preinst;" "${CMAKE_CURRENT_SOURCE_DIR}/debian/postinst" )
问题核心是组件名称大小写不匹配:
主CMakeLists.txt中定义的组件是PRIMARY_DISPLAY和SECONDARY_DISPLAY(全大写),但子目录secondary_display/CMakeLists.txt的install指令里指定的组件是secondary_display(全小写)。CPack对组件名称大小写敏感,导致安装内容无法关联到对应的组件包,最终生成空DEB。而设置CPACK_MONOLITHIC_INSTALL 1时,CPack会忽略组件划分,将所有内容打包到主包,因此能正常包含数据。
修复步骤:
统一组件名称大小写
选择以下两种方式之一:- 将主CMakeLists.txt中的组件名改为小写:
# IMX6分支修改 set(CPACK_COMPONENTS_ALL primary_display secondary_display) # IMX8分支同理修改 set(CPACK_COMPONENTS_ALL primary_display secondary_display) - 或将子目录中所有
install指令的COMPONENT参数改为大写:install(DIRECTORY ... COMPONENT SECONDARY_DISPLAY) install(TARGETS ... COMPONENT SECONDARY_DISPLAY) # 所有install指令的COMPONENT都改为大写
- 将主CMakeLists.txt中的组件名改为小写:
修正包名架构变量
secondary_display/CMakeLists.txt中的CPACK_DEBIAN_SECONDARY_DISPLAY_FILE_NAME引用了桌面平台的${CPACK_DEBIAN_DESKTOP_PACKAGE_ARCHITECTURE},在IMX6/IMX8环境下需替换为对应平台的变量:set(CPACK_DEBIAN_SECONDARY_DISPLAY_FILE_NAME "unca-secondary-display-${CPACK_PACKAGE_VERSION}-${CPACK_DEBIAN_SECONDARY_DISPLAY_PACKAGE_ARCHITECTURE}.deb")
内容的提问来源于stack exchange,提问作者a.wise

