英文:
How to properly fetch Qt using CMake?
问题
我遇到了以下问题:我正在尝试使用 `CMake` 函数 `FetchContent_Declare` 获取 `Qt` C++ 库,特别是版本 6.4.2。我正在按照[此][1]网站上的指南进行操作,该指南解释了如何从源代码构建 Qt,如果手动执行且不使用 `CMake`,则可以正常工作;但是如果我想将它与 `FetchContent_Declare` 结合使用,事情就会变得更加困难,因为在编译之前,如链接中所示,我需要运行初始化命令:
perl init-repository
以及配置命令(在构建之前):
mkdir qt6-build
cd qt6-build
../qt6/configure
我该如何将这两个步骤整合到 CMake 的 fetch content 部分呢?
我的当前 `CMake` 脚本是:
include( FetchContent )
FetchContent_Declare(
Qt6
GIT_REPOSITORY "https://github.com/qt/qt5"
GIT_TAG v6.4.2
CONFIGURE_COMMAND "perl init-repository && ./configure"
)
FetchContent_MakeAvailable( Qt6 )
但是似乎不起作用:
CMake Error at /usr/share/cmake-3.22/Modules/FetchContent.cmake:1087 (message):
Build step for qt6 failed: 2
Call Stack (most recent call first):
/usr/share/cmake-3.22/Modules/FetchContent.cmake:1216:EVAL:2 (__FetchContent_directPopulate)
/usr/share/cmake-3.22/Modules/FetchContent.cmake:1216 (cmake_language)
/usr/share/cmake-3.22/Modules/FetchContent.cmake:1259 (FetchContent_Populate)
deps/qt6/CMakeLists.txt:19 (FetchContent_MakeAvailable)
如果可能的话,我还需要一种在通过 `FetchContent_Declare` 配置和安装库时不要求 GitHub 用户名和密码的方法。
[1]: https://wiki.qt.io/Building_Qt_6_from_Git#:~:text=perl%20init%2Drepository-,Configuring%20and%20Building,Where%20dot%20after%20%22%2D%2Dbuild%22%20means%20current%20folder.,-On%20Windows%3A
英文:
I am facing the following problem: I am trying to use the CMake
function FetchContent_Declare
to fetch Qt
C++ library and in particular the version 6.4.2. I am following the guide from this site in which is explained how to build Qt from source and it works well if performed "by hand" without CMake
; but if I want to incorporate it with FetchContent_Declare
things became harder since before compiling, as you can see from the link, I need to run the initialization command:
perl init-repository
and the configuration one (before building):
mkdir qt6-build
cd qt6-build
../qt6/configure
How can I incorporate these two steps into the fetch content part of CMake?
My current CMake
script is:
include( FetchContent )
FetchContent_Declare(
Qt6
GIT_REPOSITORY "https://github.com/qt/qt5"
GIT_TAG v6.4.2
CONFIGURE_COMMAND "perl init-repository && ./configure"
)
FetchContent_MakeAvailable( Qt6 )
but it seems not correctly working:
CMake Error at /usr/share/cmake-3.22/Modules/FetchContent.cmake:1087 (message):
Build step for qt6 failed: 2
Call Stack (most recent call first):
/usr/share/cmake-3.22/Modules/FetchContent.cmake:1216:EVAL:2 (__FetchContent_directPopulate)
/usr/share/cmake-3.22/Modules/FetchContent.cmake:1216 (cmake_language)
/usr/share/cmake-3.22/Modules/FetchContent.cmake:1259 (FetchContent_Populate)
deps/qt6/CMakeLists.txt:19 (FetchContent_MakeAvailable)
I need also a way, if possible, to not ask GitHube username and password when configuring and installing the library through FetchContent_Declare
.
答案1
得分: 1
我终于找到了一个解决方案!这个 `CMakeLists.txt` 完美地满足了这个目的:
项目设置
cmake_minimum_required(VERSION 3.15)
project(key-manager-dependencies-qt6
VERSION 1.0
DESCRIPTION "key-manager Qt6 依赖项的构建系统。"
LANGUAGES CXX
)
如果在源目录(或任何包含 CMakeLists.txt 文件的目录)中构建,则出现错误
file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH)
if(EXISTS "${LOC_PATH}")
message(FATAL_ERROR "您不能在源目录中构建(或任何包含 CMakeLists.txt 文件的目录)。请创建一个构建子目录。可以删除 CMakeCache.txt 和 CMakeFiles。")
endif()
获取包
find_package(Qt6 6.4.2 QUIET)
if(NOT Qt6_FOUND)
# 设置 Ninja 用于编译
set(CMAKE_GENERATOR "Ninja" CACHE STRING "CMake generator" FORCE)
# 初始消息
message(STATUS "未找到 Qt 6.4.2。正在下载和配置 Qt...")
# 下载和提取 Qt 6.4.2 的存档
set(QT_VERSION "6.4.2")
set(QT_ARCHIVE_URL "https://download.qt.io/official_releases/qt/6.4/${QT_VERSION}/submodules/qtbase-everywhere-src-${QT_VERSION}.tar.xz")
set(QT_ARCHIVE_FILE "${CMAKE_CURRENT_BINARY_DIR}/qtbase-everywhere-src-${QT_VERSION}.tar.xz")
set(QT_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/qtbase-everywhere-src-${QT_VERSION}")
message(STATUS "从官方存储库下载包...")
file(DOWNLOAD ${QT_ARCHIVE_URL} ${QT_ARCHIVE_FILE}
SHOW_PROGRESS
EXPECTED_HASH SHA256=a88bc6cedbb34878a49a622baa79cace78cfbad4f95fdbd3656ddb21c705525d)
message(STATUS "解压发行版...")
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ${QT_ARCHIVE_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
OUTPUT_QUIET
)
# 配置 Qt(跳过构建无用模块)
set(QT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/qt-build")
file(MAKE_DIRECTORY ${QT_BUILD_DIR})
message(STATUS "配置中...")
execute_process(COMMAND ${QT_SOURCE_DIR}/configure -prefix ${QT_BUILD_DIR}
WORKING_DIRECTORY ${QT_BUILD_DIR})
# 检查系统是否支持并行处理
if(DEFINED ENV{NUMBER_OF_PROCESSORS})
set(JOBS_OPTION "-j$ENV{NUMBER_OF_PROCESSORS}")
elseif(DEFINED ENV{PROCESSOR_COUNT})
set(JOBS_OPTION "-j$ENV{PROCESSOR_COUNT}")
else()
set(JOBS_OPTION "")
endif()
# 如果可能,使用 -j 选项进行编译(Qt 非常庞大)
if(JOBS_OPTION)
message(STATUS "使用并行处理进行编译...")
execute_process(COMMAND ninja ${JOBS_OPTION}
WORKING_DIRECTORY ${QT_BUILD_DIR})
else()
message(STATUS "不使用并行处理进行编译...")
execute_process(COMMAND ninja
WORKING_DIRECTORY ${QT_BUILD_DIR})
endif()
# 设置必要的环境变量以使用 Qt
set(ENV{QTDIR} ${QT_BUILD_DIR})
set(ENV{PATH} ${QT_BUILD_DIR}/bin:$ENV{PATH})
else()
message(STATUS "在系统中找到 Qt 6.4.2。")
endif()
<details>
<summary>英文:</summary>
I finally found a solution! This `CMakeLists.txt` works perfectly for this purpose:
Project settings
cmake_minimum_required( VERSION 3.15 )
project( key-manager-dependencies-qt6
VERSION 1.0
DESCRIPTION "Build system for key-manager Qt6 dependency."
LANGUAGES CXX
)
Error if building out of a build directory
file( TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH )
if( EXISTS "${LOC_PATH}" )
message( FATAL_ERROR "You cannot build in a source directory (or any directory with "
"CMakeLists.txt file). Please make a build subdirectory. Feel free to "
"remove CMakeCache.txt and CMakeFiles." )
endif()
Fetch the package
find_package( Qt6 6.4.2 QUIET )
if( NOT Qt6_FOUND )
# Set Ninja for compilation
set( CMAKE_GENERATOR "Ninja" CACHE STRING "CMake generator" FORCE )
# Initial message
message( STATUS "Qt 6.4.2 not found. Downloading and configuring Qt..." )
# Download and extract archive of Qt 6.4.2
set( QT_VERSION "6.4.2" )
set( QT_ARCHIVE_URL "https://download.qt.io/official_releases/qt/6.4/${QT_VERSION}/submodules/qtbase-everywhere-src-${QT_VERSION}.tar.xz" )
set( QT_ARCHIVE_FILE "${CMAKE_CURRENT_BINARY_DIR}/qtbase-everywhere-src-${QT_VERSION}.tar.xz" )
set( QT_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/qtbase-everywhere-src-${QT_VERSION}" )
message( STATUS "Downloading the package from the official repository..." )
file( DOWNLOAD ${QT_ARCHIVE_URL} ${QT_ARCHIVE_FILE}
SHOW_PROGRESS
EXPECTED_HASH SHA256=a88bc6cedbb34878a49a622baa79cace78cfbad4f95fdbd3656ddb21c705525d )
message( STATUS "Unpacking the release..." )
execute_process( COMMAND ${CMAKE_COMMAND} -E tar xvf ${QT_ARCHIVE_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
OUTPUT_QUIET
)
# Configure Qt (skip building of useless modules)
set( QT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/qt-build" )
file( MAKE_DIRECTORY ${QT_BUILD_DIR} )
message( STATUS "Configuring..." )
execute_process( COMMAND ${QT_SOURCE_DIR}/configure -prefix ${QT_BUILD_DIR}
WORKING_DIRECTORY ${QT_BUILD_DIR} )
# Check if system supports parallelization
if( DEFINED ENV{NUMBER_OF_PROCESSORS} )
set( JOBS_OPTION "-j$ENV{NUMBER_OF_PROCESSORS}" )
elseif( DEFINED ENV{PROCESSOR_COUNT} )
set( JOBS_OPTION "-j$ENV{PROCESSOR_COUNT}" )
else()
set( JOBS_OPTION "" )
endif()
# Use -j option to compile if possible (qt is very big)
if( JOBS_OPTION )
message( STATUS "Compiling with parallelization..." )
execute_process( COMMAND ninja ${JOBS_OPTION}
WORKING_DIRECTORY ${QT_BUILD_DIR} )
else()
message( STATUS "Compiling without parallelization..." )
execute_process( COMMAND ninja
WORKING_DIRECTORY ${QT_BUILD_DIR} )
endif()
# Set necessary environment variables to use Qt
set( ENV{QTDIR} ${QT_BUILD_DIR} )
set( ENV{PATH} ${QT_BUILD_DIR}/bin:$ENV{PATH})
else()
message( STATUS "Qt 6.4.2 found in the system." )
endif()
it is all well commented so hope this can be useful for other people.
**NOTE**: this script fetch Qt 6.4.2, but you can modify it with any required version.
**NOTE 2**: if you want to speed up the process you can ask to skip compilation of tests, examples and optional Qt modules by modifying this line:
execute_process( COMMAND ${QT_SOURCE_DIR}/configure -prefix ${QT_BUILD_DIR} WORKING_DIRECTORY ${QT_BUILD_DIR} )
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论