qt添加鸿蒙设备,使⽤CMake将Qt项⽬部署到嵌⼊式设备
运⾏ Qt 项⽬时,Qt Creator ⾸先通过 ssh 将项⽬部署到远程嵌⼊式 Linux 设备上,然后在远程设备上运⾏可执⾏⽂件。这个特性⼏乎可以即时反馈 Qt 应⽤程序如何在嵌⼊式设备上⼯作。
部署⼯作可以很好地使⽤ qmake 的 INSTALLS 变量 来实现。不过 CMake 不具备类似 qmake 的 INSTALLS 变量的功能。幸运的
是,Qt 提供了⼀个解决⽅案。下⾯将通过⼀个⽰例 ⽂件来演⽰这个解决⽅案。
我们希望在嵌⼊式设备的 /opt/mycompany/bin 中安装 Qt 项⽬的可执⾏⽂件,在 /opt/mycompany/lib 中存放需要的三⽅库,⽽
/opt/mycompany/cad 是包含 3D CAD ⽂件的⽬录。 的安装部分(位于 ${CMAKE_SOURCE_DIR}/src 中)与此类似。
set(CMAKE_INSTALL_PREFIX "/opt/mycompany")
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
)
install(FILES ./lib/other/libMagic.so
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
)
install(DIRECTORY ./cad/
DESTINATION ${CMAKE_INSTALL_PREFIX}/cad
)
上述设置本地部署到 Linux PC 与 make install 都⼯作良好。但是,嵌⼊式 Linux 设备的远程部署不能正常⼯作。
Qt Creator 在 项⽬>运⾏设置>部署>Files to deploy 设置中显⽰了从本地⽂件路径到远程⽂件路径的映射。对于上⾯的安装功能,Qt Creator 将只显⽰⼀个条⽬。可执⾏应⽤程序从其构建位置 ${CMAKE_BINARY_DIR}/src/app 映射到 src。这显然是不对的。
解决这个问题的思想 是让 CMake 将从本地⽂件路径到远程⽂件路径的映射写⼊⼀个被命名为 的⽂件中。正确定义的 将包含以下映射。
/opt/mycompany
src/../../build-app-Remote_Qt_5_12_1-Release/src/app:bin
src/lib/other/libMagic.so:libcmake如何使用
src/cad/machine1/part1.step:cad/machine1
src/cad/machine1/part3.step:cad/machine1
src/cad/machine2/part6.step:cad/machine2
...
第⼀⾏给出的是复制⽂件到远程计算机上的(绝对)路径前缀。第⼆⾏和后⾯所有⾏的格式是。
relative/local/file:relative/remote/dir
本地⽬录相对于 ${CMAKE_SOURCE_DIR} ⽬录,⽽远程⽬录相对于第⼀⾏中给出的安装前缀 /opt/mycompany ⽬录。因此,上⾯这⼀⾏在概念上等同于下⾯的远程复制命令:
scp ${CMAKE_SOURCE_DIR}/relative/local/file \
developer@192.168.100.100:/opt/mycompany/relative/remote/dir/file
与往常⼀样,Qt 让我们的远程部署⼯作变得轻松了⼀些,它提供了两个 CMake 宏来向 添加⽂件和⽬录树。第⼀个宏 add_deployment_file 如下所⽰:
macro(add_deployment_file SRC DEST)
file(RELATIVE_PATH path ${CMAKE_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
file(APPEND "${CMAKE_SOURCE_DIR}/"
"${path}/${SRC}:${DEST}\n")
endmacro()
第⼀个⽂件命令计算从源⽂件的根⽬录 ${CMAKE_SOURCE_DIR} 到当前处理的源⽬录 ${CMAKE_CURRENT_SOURCE_DIR} 的相对路径。第⼆个⽂件命令将⾏“${path}/${SRC}:${DEST}\n”追加到⽂件 。
⽰例,调⽤:
add_deployment_file("lib/other/libMagic.so" "lib")
被解析的结果类似于:
SRC = "lib/other/libMagic.so", "DEST = lib"
path = "src"
Append: "src/lib/other/libMagic.so:lib\n"
宏将映射⽂件 写到⽬录 ${CMAKE_SOURCE_DIR},该⽬录是源树的根⽬录。但是,在构建过程中⽣成的所有⽂件都应该写⼊到构建树中。幸运的是,Qt Creator 不仅在 ${CMAKE_SOURCE_DIR} ⽬录(源码根⽬录,例
如:/home/toby/test/TestEmptyCMakeProject)中查映射⽂件,⽽且在构建树的根⽬录(构建⽬录,例如:/home/toby/test/build-TestEmptyCMakeProject-target_qt5_12_5_syberos_5_0-Debug) {CMAKE_BINARY_DIR} 中查映射⽂件。因此,我们也可以将第⼀个宏中的第⼆条 file 命令更改为:
file(APPEND "${CMAKE_BINARY_DIR}/"
"${path}/${SRC}:${DEST}\n")
第⼆个宏 add_deployment_directory 如下所⽰:
macro(add_deployment_directory SRC DEST)
file(GLOB_RECURSE files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"${SRC}/*")
foreach(filename ${files})
get_filename_component(path ${filename} PATH)
add_deployment_file("${filename}" "${DEST}/${path}")
endforeach(filename)
endmacro()
file 命令⾏遍历⽬录 ${CMAKE_CURRENT_SOURCE_DIR} 处的树,并在 files 变量中存储与通配符表达式 ${SRC}/* 匹配的所有⽂件。
foreach 循环遍历 file 命令到的所有⽂件。对于每个⽂件,它使⽤相对本地⽂件路径和远程⽬录路径 ${DEST}/${path} 调⽤
add_deployment_file 宏,其中 ${path} 是本地⽂件的相对⽬录路径。
⽰例,调⽤:
add_deployment_directory("cad" ".")
的解析结果⽰例如下:
SRC = "cad", DEST = "."
files = all file paths relative to "${CMAKE_CURRENT_SOURCE_DIR}" and matching the pattern "cad/*
"
files = "cad/machine1/part1.step" "cad/machine1/part3.step"
"cad/machine2/part6.step"
foreach loop:
add_deployment_file("cad/machine1/part1.step" "./cad/machine1")
Append: "src/cad/machine1/part1.step:cad/machine1\n"
add_deployment_file("cad/machine1/part3.step" "./cad/machine1")
Append: "src/cad/machine1/part3.step:cad/machine1\n"
add_deployment_file("cad/machine2/part6.step" "./cad/machine2")
Append: "src/cad/machine2/part6.step:cad/machine2\n"
现在,我们可以将所有部分放在⼀起并重写 ⽂件的安装部分,如下所⽰:macro(add_deployment_file SRC DEST)
file(RELATIVE_PATH path ${CMAKE_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
file(APPEND "${CMAKE_BINARY_DIR}/"
"${path}/${SRC}:${DEST}\n")
endmacro()
macro(add_deployment_directory SRC DEST)
file(GLOB_RECURSE files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${SRC}/*")
foreach(filename ${files})
get_filename_component(path ${filename} PATH)
add_deployment_file("${filename}" "${DEST}/${path}")
endforeach(filename)
endmacro()
set(CMAKE_INSTALL_PREFIX "/opt/mycompany")
if(DEPLOYED_REMOTELY)
# Write base installation path as first line.
file(WRITE "${CMAKE_BINARY_DIR}/"
"${CMAKE_INSTALL_PREFIX}\n")
# Append mapping for executable.
file(RELATIVE_PATH relative_exe_path
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}")
add_deployment_file(relative_exe_path bin)
# Append mapping for single library file.
add_deployment_file("lib/other/libMagic.so" "lib")
# Append all 3D CAD files from local directory "cad".
add_deployment_directory("cad" ".")
else()
# The original install commands go here for local deployment.
...
endif()
上述代码中 DEPLOYED_REMOTELY 是⼀个 CMake 选项,其定义为:
option(DEPLOYED_REMOTELY "Turn on for remote deployment" OFF)
Qt Creator 在 项⽬>构建设置> CMake 设置页⾯中将此选项显⽰为复选框。如果希望远程部署应⽤程序,只需勾选复选框并按下 Apply Configuration Changes 按钮。
当我们使⽤ Ctrl+R 运⾏应⽤程序时,Qt Creator 将根据 中的映射将⽂件复制到嵌⼊式设备,并在嵌⼊式设备上运⾏应⽤程序。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论