Instead of trying to compute and validate the QT_HOST_PATH and
QT_HOST_PATH_CMAKE_DIR variables in the generated toolchain file,
do it in the Qt6 package.
This provides better error messages when a project is configured
without using the Qt generated toolchain file.
Because it's not done in the toolchain anymore, remove the various
host variables from __qt_toolchain_used_variables.
Pick-to: 6.4
Task-number: QTBUG-104998
Change-Id: I1ca239ff83b8f783897e171fee352fc43e8ad7a8
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
For cross-compiled conan packages we need conan to export QT_HOST_PATH
as an environment variable. The Qt build now picks up this environment
variable if no QT_HOST_PATH cache variable was specified.
Pick-to: 6.2 6.3
Change-Id: I0c3e15e82842061d5db81949ffcc1c240f6ed6a4
Reviewed-by: Iikka Eklund <iikka.eklund@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
All variables that are used in qt.toolchain.cmake should be recorded in
__qt_toolchain_used_variables. This is mostly done for consistency and
to avoid surprises in future configure checks.
Pick-to: 6.2 6.3
Change-Id: I1ae18c5dfe9677c5f46a102e434e32187cb0d703
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Except on Windows, the values in CMake environment variables that
contain path lists are separated by colons, not semicolons. See
documentation of CMAKE_PREFIX_PATH.
This is necessary for conan's virtualenv generator which sets these
environment variables with native list separators.
This amends commit e044c94a61.
Pick-to: 6.2 6.3
Task-number: QTBUG-94524
Change-Id: I7f3d140a8462347b181f1d9601fd11cc1ba449db
Reviewed-by: Iikka Eklund <iikka.eklund@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
When installing conan packages we have one installation prefix per
package. When cross-building a conan package, we need to make known
those multiple host prefixes to Qt, analogous to
QT_ADDITIONAL_PACKAGES_PREFIX_PATH.
Pick-to: 6.2 6.3
Fixes: QTBUG-94524
Change-Id: I68cbede350f95266a5fd3559e9b9c214c5858eed
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
One might want to build qtbase in Release, but qtsvg or some test in
Debug mode. Before if qtbase was configured as Release, there was no
way to override that.
Now we try to detect whether a custom build type was specified to
qt-cmake / qt-configure-module / qt-cmake-standalone-test /
qt-internal-configure-tests
Note mixing won't work on Windows due to different C/C++ runtimes.
Also, now we don't force set a single build type when a multi config
generator is used as well as one opts out via the
QT_NO_FORCE_SET_CMAKE_BUILD_TYPE variable.
Pick-to: 6.2 6.3
Change-Id: I6dc4325087ff7f905ad677d87b0267e2f3e4693f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
One can now pass -DQT_REQUIRE_HOST_PATH_CHECK=OFF or
-DQT_REQUIRE_HOST_PATH_CHECK=ON to force disable or enable
the QT_HOST_PATH and QT_HOST_CMAKE_DIR_PATH validity checks.
One potential use case is if a project wants to manually find
QtFooTools packages by manipulating CMAKE_FIND_ROOT_PATH and such,
in which case they might not want to pass a QT_HOST_PATH.
Another potential use case is cross-building Qt with
-DQT_BUILD_TOOLS_WHEN_CROSSCOMPILING=ON and allowing the same
generated toolchain file to be used on the device image.
By default the generated toolchain file would require a host path
because it expects that it's still being used for cross-compiling.
But once the toolchain file is deployed to the device there's no need
to use the host tools anymore.
Another use case is building a desktop Qt using the host tools of
another desktop Qt. The new desktop Qt can use its newly built tools
just fine and wouldn't need the original desktop Qt tools.
QT_REQUIRE_HOST_PATH_CHECK needs to be added the list of vars to pass
through to try_compile calls.
Change-Id: I4b922b5d854828e6b9210dd8c07b4b1b8630aad1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Craig Scott <craig.scott@qt.io>
The environment variable check to set extra env vars
was using invalid syntax. The condition always resolved to TRUE
which means the env vars were constantly re-assigned inside each
try_compile project.
To check for undefined-ness, one can use if(NOT DEFINED ENV{...})
To check for false-ness, one can use if(NOT "$ENV{...}")
To check for string emptiness, one can use
if(NOT "$ENV{...}" STREQUAL "")
In this particular case checking for false-ness is good enough.
The extra re-assigning had no visible effect, so this is just cleanup.
As a drive-by, clarify one comment.
Amends ca59c20939
Pick-to: 6.2
Change-Id: I8fd400101efa9e610a81268c33cac8c0cb33cba3
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Craig Scott <craig.scott@qt.io>
Previously when one wanted to use a cross-compiled Qt with a host Qt
installed in a non-default location, they'd have to provide both
QT_HOST_PATH and QT_HOST_PATH_CMAKE_DIR.
This change will now try to first check if ${QT_HOST_PATH}/lib/cmake
is a valid path on disk and use that. This is nicer to the user
because they don't need to specify 2 paths anymore.
Furthermore the path computation and sanity checks are now done after
any extra toolchain cmake files are loaded, to give an opportunity
to the files to set the paths first.
Finally, both variables need to be added to
__qt_toolchain_used_variables so they are passed along to try_compile
calls if the variables are specified manually.
Otherwise when the toolchain file is loaded by a try_compile project,
it will error out saying no host path found (as long as the initial
paths embedded in the toolchain are invalid).
Amends 93fc3afe71 and
ec90f9013b
Pick-to: 6.2
Change-Id: I433239b36b084f2d0a7a0dd043fdf87d77c138f3
Reviewed-by: Craig Scott <craig.scott@qt.io>
Certain platform-related variables, in this case UNIX, must be set in a
platform module, because they get cleared after the toolchain file is
loaded. Such platform modules live in upstream CMake, but there is none
yet for INTEGRITY. This manifests in an undefined UNIX variable and
"System is unknown to CMake" warnings for the project and every
configure test.
Add the CMake module "Platform/Integrity" in the cmake/platforms
directory. Add this directory to CMAKE_MODULE_PATH to let CMake load
Platform/Integrity when the toolchain file set CMAKE_SYSTEM_NAME to
"Integrity".
CMake's module directory takes precedence, when loading platform
modules. This is special for platform modules and different from the
documented behavior of CMAKE_MODULE_PATH and include().
In case the user wants to provide their own platform modules via
CMAKE_MODULE_PATH, they can instruct Qt to not add its path by setting
QT_AVOID_CUSTOM_PLATFORM_MODULES to ON.
Make sure that configure tests with project files also load the custom
platform module.
Pick-to: 6.2
Fixes: QTBUG-96998
Change-Id: I9855d620d24dc66353cec5e847a2675b464ace26
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Rather than fail with obscure can't find Qt packages errors when the
Webassembly CMake toolchain file can not be found, error out with a
clear error on how to ensure it is found.
Pick-to: 6.2
Task-number: QTBUG-96843
Change-Id: I0f34cdcde05efb25c93017f3fd365186335ed52c
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
The QT_ADDITIONAL_PACKAGES_PREFIX_PATH variable was introduced to
allow specifying extra locations to find Qt packages.
The reason it was introduced instead of just using CMAKE_PREFIX_PATH
is because the Qt6 component find_package call uses NO_DEFAULT_PATH
which means CMAKE_PREFIX_PATH is ignored.
We use NO_DEFAULT_PATH to ensure we don't accidentally pick up
system / distro Qt packages.
The paths from QT_ADDITIONAL_PACKAGES_PREFIX_PATH are added to the
find_package PATHS option in the Qt6 package, each
ModuleDependencies.cmake file and some other places.
Unfortunately that's not enough to make it work for cross-builds.
Imagine the following scenario.
host qtbase, qtdeclarative installed in /host_qt
target qtbase installed in /target_qtbase
target qtdeclarative installed in /target_qtdeclarative
We want to cross-build qtlottie.
We configure qtlottie as follows
/target_qtbase/bin/qt-configure-module /qtlottie_src -- -DQT_ADDITIONAL_PACKAGES_PREFIX_PATH=/target_qtdeclarative
We expect the target QtQuick package to be found, but it won't be.
The reason is that QT_ADDITIONAL_PACKAGES_PREFIX_PATH is added to the
PATHs option, but we don't adjust CMAKE_FIND_ROOT_PATH.
Without adding the new paths in CMAKE_FIND_ROOT_PATH, CMake will
re-root the passed PATHs under the existing CMAKE_FIND_ROOT_PATH,
which is QT_TOOLCHAIN_RELOCATABLE_INSTALL_PREFIX, which evaluates to
/target_qtbase. There is no QtQuick package there.
To fix this, prepend the values of QT_ADDITIONAL_PACKAGES_PREFIX_PATH
to CMAKE_FIND_ROOT_PATH.
The location where we currently do CMAKE_FIND_ROOT_PATH manipulations
is in the qt.toolchain.cmake file, so to be consistent, we prepend the
new prefixes there as well.
We need to adjust both CMAKE_FIND_ROOT_PATH and CMAKE_PREFIX_PATH,
due the path re-rooting bug in CMake.
See https://gitlab.kitware.com/cmake/cmake/-/issues/21937 as well as
the existing comment in qt.toolchain.cmake marked with
REROOT_PATH_ISSUE_MARKER.
We also need to do a few more things to make the setup work
Because Qt6Config uses NO_DEFAULT_PATH, the CMAKE_PREFIX_PATH
adjustments we do in the toolchain file are not enough, so we still need
to add the same prefixes to the Qt6Config find_package PATHS option.
One would ask why do we need to adjust CMAKE_PREFIX_PATH at all then.
It's for find_package(Qt6Foo) calls to work which don't go through
the Qt6Config umbrella package.
To make the CMake re-rooting behavior happy, we need to ensure the
provided paths are absolute.
So we iterate over the values of QT_ADDITIONAL_PACKAGES_PREFIX_PATH,
to make them absolute. We do the same for the environment variable.
We need to append lib/cmake to the prefixes which are added to
CMAKE_PREFIX_PATH, otherwise the CMake re-rooting bug is hit.
We need to specify the Qt6 package location (${_qt_cmake_dir}) to the
PATHS option in the various Dependencies.cmake.in files, to ensure
that dependency resolution can jump around between the Qt6 dir and
the additional prefixes. Previously the dependency lookup code assumed
that all dependencies would be within the same prefix.
The same is needed for qt and qml plugin dependency lookup.
Amends 7bb91398f2
Amends 60c87c6801
Amends 5bbd700124
Pick-to: 6.2
Fixes: QTBUG-95854
Change-Id: I35ae82330fec427d0d38fc9a0542ffafff52556a
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
list(PREPEND) command was added in CMake 3.15+, but so far we claim
support for CMake 3.14 in user projects.
Use set command instead.
This is not the only place where we use list PREPEND in public API,
but it's the first immediate issue that comes up when using CMake
3.14.
Amends 963017f588
Pick-to: 6.1
Change-Id: I7ba4507fc7da2dc550317848751502b8b46c298c
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
We have some cache variables that are used in our qt.toolchain.cmake
toolchain file, for example QT_CHAINLOAD_TOOLCHAIN_FILE. When CMake
runs a configure test with try_compile, our toolchain file is included
again, but only a restricted set of variables is available.
Add the variables that are used in our internal toolchain file to
CMAKE_TRY_COMPILE_PLATFORM_VARIABLES. This makes them visible for
try_compile calls operating on source files.
Also pass the variables via the environment to support try_compile
calls that operate on whole projects.
Fixes: QTBUG-87873
Change-Id: Iebca9e23686bec5072194b15482e1782b9367a0e
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Allow CMake for Android to use ANDROID_NDK_ROOT to deduce the path for
QT_CHAINLOAD_TOOLCHAIN_FILE instead of the user providing it manually.
Change-Id: Ida728011d5ca8d5a723d341ea77b173e8f105f8c
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Provide two customization points:
- optionally include a 'qt.toolchain.extra.cmake' file if it exists
and is placed next to the main generated toolchain file.
This use case is mostly for the Qt installer, so that it can create
an extra file with correct installer-provided paths, instead of
patching the toolchain file directly.
- optionally include a file passed via the command line CMake argument
'QT_TOOLCHAIN_INCLUDE_FILE'.
The use case is for application developers that might want to adjust
the toolchain file after the modifications done by the Qt installer.
These options do not replace the existing QT_CHAINLOAD_TOOLCHAIN_FILE
option, which is meant to chainload a platform specific existing
toolchain file (like Android or Emscripten).
Task-number: QTBUG-87068
Change-Id: I956949840f55742cfbd3bc8fc0bd8c6b3f774d3d
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This variable can be set when using qt-cmake[-private] to override the
CMake toolchain file that is chainloaded by Qt's toolchain file.
Task-number: QTBUG-87068
Change-Id: Id529408381e4174becda1ba07a489535c8cf1314
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
If a consumer wants to cross-compile a Qt app, they need to provide
the host Qt path location.
When building Qt in the CI we embed the Qt host path into the
generated CMake toolchain file for convenient building of other Qt
modules.
But once Qt is built, packaged and installed on a user's machine, most
likely the Qt host path will not be the same. In such a case, if the
user wants to use the convenience toolchain, they should explicitly
provide the Qt host path via the QT_HOST_PATH and
QT_HOST_PATH_CMAKE_DIR variables.
Show an error message if the values are not provided or don't exist
on the file system.
It's possible that in the future the Qt installer will patch the
toolchain file, or provide additional info, to point to the host
Qt installation so that the user doesn't have to do it manually.
But until that's done, a friendly error message is a good way to
inform the user what they should do.
Task-number: QTBUG-83999
Change-Id: I26291e3c47bb77375f8a5ce7b848c0382a660ca9
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Rather than force setting the apple sysroot and Qt host paths, first
check if they are not already defined on the command line and if they
aren't, check that the paths with which Qt was configured exist.
The goal of the patch is to not set invalid paths, like when using a
Qt built in the CI, which will have a different host path / sysroot
compared to what a user has locally.
Task-number: QTBUG-85240
Change-Id: Ic37566b4fa845d8d1b4e4b5ba7fa4be769e99ca8
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
While trying to implement the 'host artifact reuse' Coin instructions
change, a bug surfaced where the qemu configurations didn't find
the host tools and instead tried to use the cross-compiled tools
while building qtbase, which failed due to not finding the
runtime linker (another unsolved issue).
Before the host artifact reuse change, the host tools were found
successfully.
The difference that caused the issue is that the target install prefix
was a direct subfolder of the host prefix.
host - /home/qt/work/qt/install
target - /home/qt/work/qt/install/target
Before the host reuse change the install prefixes were as follows
host - /home/qt/work/qt/install/host
target - /home/qt/work/qt/install/target
While looking for the Qt6CoreTools package, we temporarily set
CMAKE_FIND_ROOT_PATH and CMAKE_PREFIX_PATH to contain first
'/home/qt/work/qt/install' and then '/home/qt/work/qt/install/target'.
CMake then reroots the CMAKE_PREFIX_PATH values onto values in
CMAKE_FIND_ROOT_PATH, making an MxN list of prefixes to search.
Rerooting essentially means concatenating 2 paths, unless the
considered prefix is a subfolder of the root path.
What happened was that the first considered value was
'/home/qt/work/qt/install/home/qt/work/qt/install', a non-existent
location that gets discarded.
The second considered value was '/home/qt/work/qt/install/target.
The second value is the result of seeing that
'/home/qt/work/qt/install/target' is a subfolder of
'/home/qt/work/qt/install' and thus the root path is stripped.
All of this is done in cmFindPackageCommand::FindConfig() ->
cmFindCommon::RerootPaths.
The behavior above caused the target tools be found instead of the
host ones.
Before the host reuse change, both of the initial constructed prefixes
were discared due to them not existing, e.g.
'/home/qt/work/qt/install/target/home/qt/work/qt/install/target'
and '/home/qt/work/qt/install/host/home/qt/work/qt/install/host'
One of the later prefixes combined CMAKE_FIND_ROOT_PATH ==
'/home/qt/work/qt/install/host' + CMAKE_PREFIX_PATH == '/' resulting
in '/home/qt/work/qt/install/host/' and this accidentally found the
host tools package.
We actually stumbled upon this issue a while ago when implementing Qt
5.14 Android CMake support in 52c799ed44
That commit message mentions the fix is to add a "lib/cmake"
suffix to the PATHS option of find_package().
This would cause the subfolder => strip root behavior mentioned
above.
So finally the fix.
First, make sure not to append QT_HOST_PATH in the toolchain file,
there shouldn't be any need to do that, give that we temporarily set
it when looking for Tools packages.
Second, recreate the subdir scenario in the Qt toolchain file by
setting CMAKE_FIND_ROOT_PATH to the current (relocated) install
prefix as usual, but also setting CMAKE_PREFIX_PATH to a new value
poining to the CMake directory.
Aka '/home/alex/qt' and '/home/alex/qt/lib/cmake'.
Third, when a QT_HOST_PATH is given, save 2 paths in the generated Qt
toolchain: QT_HOST_PATH and QT_HOST_PATH_CMAKE_DIR. There are the host
equivalents of the target ones above. Use these values when looking
for host tools in Qt6CoreModuleDependencies.cmake, again facilitaing
the subdir behavior.
Note these are currently absolute paths and are not relocatable.
We'll have to figure out if it's even possible to make the host path
relocatable.
Finally as a cleanup, look for the Qt6HostInfo package in QtSetup
strictly in the given QT_HOST_PATH, so CMake doesn't accidentally find
a system Qt package.
Change-Id: Iefbcfbbcedd35f1c33417ab7e9f44eaf35ff6337
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Three different people have encountered the issue that calling
calling qt-cmake on a project prints 1000 inclusion lines of the same
qt toolchain file, and then CMake bails out saying can't find the
CMAKE_MAKE_PROGRAM Ninja.
This happened because people accidentally called qt-cmake to configure
qtbase (instead of just cmake), which created a toolchain file that
chainloads itself recursively.
Error out when configuring qtbase, and when using the generated
toolchain file in the case when it would try to include itself.
The solution is to remove the qtbase CMakeCache.txt file, and
configure qtbase again, so it generates a proper qt.toolchain.cmake
file.
If somebody feels enthusiastic, they can move the check into the
qt-cmake and qt-cmake-private shell scripts, and error out before the
qtbase/CMakeCache.txt is polluted with the wrong toolchain file.
That is left for people that feel more comfortable with bash and batch
scripting.
Change-Id: If518c94791fe7c30731e6e462e347f26a5213c64
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Aka handle CMAKE_INSTALL_PREFIX in a more relocatable way.
The following story inspired this change.
If a user wants to build a Qt repo into a different install prefix
than the usual Qt one, this will fail configuration because we
look for various things like syncqt, qdoc, etc relative to
CMAKE_INSTALL_PREFIX, which will now point to a different location
where none of the above tools are located.
The intent for such a use case is to support building Qt packages with
Conan, which sets a random install prefix when configuring a repo.
The idea is to derive the qt prefix dynamically from the
QtBuildInternals package location. Essentially it's a reverse relative
path from the QtBuildInternalsConfig.cmake file to the install prefix
that was specified when initially configuring qtbase.
Once the dynamic prefix is computed (so we know where the possibly
relocated Qt is), we can find tools like syncqt and qdoc.
This is an initial attempt to support a use case like that.
More design work will probably needed in case if tools / libs need to
be found in a location different than the Qt install prefix (so
support for multiple install prefixes / search paths).
An example of such a case would be when building qtdeclarative and
qtquickcontrols2 as Conan packages in one go. Most likely the
qmltyperegistrar tool will be located in the random install prefix
set by Conan, so building qtquickcontrols2 might fail due to not
finding the tool in the original Qt install prefix.
As to the implementation details, the change does the following:
- Dynamically computes and sets the
QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX variable when
find_package()'ing QtBuildInternals. It's an absolute path
pointing to where the relocated Qt is.
- When building qtbase this variable is not yet available (due
to QtBuildInternalsExtra not existing), in that case we set
the variable to the absolute path of CMAKE_INSTALL_PREFIX
(but only for the initial qtbase configuration).
- Remove QT_BUILD_INTERNALS_ORIGINAL_INSTALL_PREFIX which was used
for standalone tests purposes. It's not needed now that we compute
the location of the Qt prefix dynamically.
- The Unixy qt-cmake and qt-cmake-private shell scripts now
use a relative path to find the toolchain file we created.
- The toolchain file also dynamically computes the location of the Qt
packages, and adds them to CMAKE_PREFIX_PATH.
- A lot of existing CMAKE_INSTALL_PREFIX uses are replaced with
QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX. This includes finding
tool locations, mkspecs dir, path environment setup for tools, etc.
- Some places still use CMAKE_PREFIX_PATH in the following cases
- When determining paths while configuring qtbase (valid cases)
- When I wasn't sure what the behavior should be, so I left them
as-is (an example is documentation generation, do we want to
install it into the random Conan prefix, or into the main prefix?
Currently it installs in the random prefix).
Note that relocating a Qt installation does not work for non-prefix /
non-installed builds, due to hardcoded paths to include directories
and libraries in generated FooTargets.cmake files.
Task-number: QTBUG-83999
Change-Id: I87d6558729db93121b1715771034b03ce3295923
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
The original toolchain file may set CMAKE_FIND_ROOT_PATH instead of
appending it, which overrides the Qt's path.
Change-Id: I69a4bf4be6a999854bb8a84cf5032c6a9b739b2e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
We need to save them in the toolchain file, otherwise we can't compile
anything :)
Change-Id: Ic5c53524fa4aa05d0b3229c2905dff92ca437ec1
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Qt CMake Build Bot
This gets us a step into the direction of convenience that qmake
offered:
* QtBase is configured with a long command line (especially when
cross-compiling)
* Afterwards application developers (or other module builds) can
just use qmake && make
By generating a toolchain file we can capture vcpkg and toolchain
chain-loading and a shell script can take care of providing the prefix
path.
Change-Id: Ided81f5432cab862306f2bea86cfe8e56adf71b0
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>