CMake: Don't use libraries in /usr/local by default on macOS
qmake builds of Qt don't use libraries in /usr/local because the path is not considered a system path. Only the SDK path should be used as a source of system libraries. We should do the same for the CMake builds, which involves a couple of things. Tell CMake not to consider /usr/local (and a bunch of other paths) as system prefix paths. Disable pkg-config usage which by default is not used in qmake Windows and macOS builds. If a user wishes to use libraries located in /usr/local on macOS, they can explicitly enable the behavior via -DFEATURE_pkg_config=ON. In addition to enabling pkg-config, that will also disable the system prefix modification described above. Implementation notes To disable pkg-config usage, we set an empty path for PKG_CONFIG_EXECUTABLE, because there is no other good way. The downside to this is that a lot of warning messages will be printed that the pkg-config package can not be found. The pkg-config feature needs to be computed in QtBuildInternals before qtbase/src/configure.cmake, because it's too late to do it in that file where a few qt_find_package calls already exist. The feature value is also saved to QtBuildInternalsExtra, to make sure that pkg-config is disabled whenever building another repo. System prefix adjustment is done by removing paths from CMAKE_SYSTEM_PREFIX_PATH. Ideally we would remove also /usr as a path, to match what qmake does, but that breaks find_program() calls for perl, python, etc. We have to make sure that qt_find_package does not look in PATH when looking for packages, which is the default behavior, because PATH on macOS most likely contains /usr/local. One last curiosity for future generations is that CMake 3.18+ has merged a change to prioritise SDK locations over regular /usr/lib. Fixes: QTBUG-85261 Change-Id: I28fe5bae7997507a83b37b4eb1e0188e64062c57 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
45c0f45e04
commit
f3c7d22dd0
@ -5246,6 +5246,12 @@ macro(qt_find_package)
|
||||
list(APPEND arg_UNPARSED_ARGUMENTS "COMPONENTS;${arg_COMPONENTS}")
|
||||
endif()
|
||||
|
||||
# Don't look for packages in PATH if requested to.
|
||||
if(QT_NO_USE_FIND_PACKAGE_SYSTEM_ENVIRONMENT_PATH)
|
||||
set(_qt_find_package_use_system_env_backup "${CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH}")
|
||||
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH "OFF")
|
||||
endif()
|
||||
|
||||
if(NOT (arg_CONFIG OR arg_NO_MODULE OR arg_MODULE) AND NOT _qt_find_package_skip_find_package)
|
||||
# Try to find a config package first in quiet mode
|
||||
set(config_package_arg ${arg_UNPARSED_ARGUMENTS})
|
||||
@ -5291,6 +5297,14 @@ macro(qt_find_package)
|
||||
find_package(${arg_UNPARSED_ARGUMENTS})
|
||||
endif()
|
||||
|
||||
if(QT_NO_USE_FIND_PACKAGE_SYSTEM_ENVIRONMENT_PATH)
|
||||
if("${_qt_find_package_use_system_env_backup}" STREQUAL "")
|
||||
unset(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH)
|
||||
else()
|
||||
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH "${_qt_find_package_use_system_env_backup}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${ARGV0}_FOUND AND arg_PROVIDED_TARGETS AND NOT _qt_find_package_skip_find_package)
|
||||
# If package was found, associate each target with its package name. This will be used
|
||||
# later when creating Config files for Qt libraries, to generate correct find_dependency()
|
||||
|
@ -51,6 +51,98 @@ endif()
|
||||
# build.
|
||||
include(QtPlatformSupport)
|
||||
|
||||
function(qt_build_internals_disable_pkg_config_if_needed)
|
||||
# pkg-config should not be used by default on Darwin and Windows platforms, as defined in
|
||||
# the qtbase/configure.json. Unfortunately by the time the feature is evaluated there are
|
||||
# already a few find_package() calls.
|
||||
# So we have to duplicate the condition logic here and disable pkg-config for those platforms by
|
||||
# default.
|
||||
#
|
||||
# Note that on macOS, if the pkg-config feature is enabled by the user explicitly, we will also
|
||||
# tell CMake to consider paths like /usr/local (Homebrew) as system paths when looking for
|
||||
# packages.
|
||||
# We have to do that because disabling these paths but keeping pkg-config
|
||||
# enabled won't enable finding all system libraries via pkg-config alone, many libraries can
|
||||
# only be found via FooConfig.cmake files which means /usr/local should be in the system prefix
|
||||
# path.
|
||||
set(pkg_config_enabled ON)
|
||||
if(APPLE OR WIN32)
|
||||
set(pkg_config_enabled OFF)
|
||||
endif()
|
||||
if(DEFINED FEATURE_pkg_config)
|
||||
if(FEATURE_pkg_config)
|
||||
set(pkg_config_enabled ON)
|
||||
else()
|
||||
set(pkg_config_enabled OFF)
|
||||
endif()
|
||||
endif()
|
||||
set(FEATURE_pkg_config "${pkg_config_enabled}" CACHE STRING "Using pkg-config")
|
||||
if(NOT pkg_config_enabled)
|
||||
qt_build_internals_disable_pkg_config()
|
||||
else()
|
||||
unset(PKG_CONFIG_EXECUTABLE CACHE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(qt_build_internals_disable_pkg_config)
|
||||
# Disable pkg-config by setting an empty executable path. There's no documented way to
|
||||
# mark the package as found, but force all pkg_check_modules calls to do nothing.
|
||||
set(PKG_CONFIG_EXECUTABLE "" CACHE STRING "Disabled pkg-config usage." FORCE)
|
||||
endfunction()
|
||||
|
||||
if(NOT QT_BUILD_INTERNALS_SKIP_PKG_CONFIG_ADJUSTMENT)
|
||||
qt_build_internals_disable_pkg_config_if_needed()
|
||||
endif()
|
||||
|
||||
macro(qt_build_internals_find_pkg_config)
|
||||
# Find package config once before any system prefix modifications.
|
||||
find_package(PkgConfig QUIET)
|
||||
endmacro()
|
||||
|
||||
if(NOT QT_BUILD_INTERNALS_SKIP_FIND_PKG_CONFIG)
|
||||
qt_build_internals_find_pkg_config()
|
||||
endif()
|
||||
|
||||
function(qt_build_internals_set_up_system_prefixes)
|
||||
if(APPLE AND NOT FEATURE_pkg_config)
|
||||
# Remove /usr/local and other paths like that which CMake considers as system prefixes on
|
||||
# darwin platforms. CMake considers them as system prefixes, but in qmake / Qt land we only
|
||||
# consider the SDK path as a system prefix.
|
||||
# 3rd party libraries in these locations should not be picked up when building Qt,
|
||||
# unless opted-in via the pkg-config feature, which in turn will disable this behavior.
|
||||
#
|
||||
# Note that we can't remove /usr as a system prefix path, because many programs won't be
|
||||
# found then (e.g. perl).
|
||||
set(QT_CMAKE_SYSTEM_PREFIX_PATH_BACKUP "${CMAKE_SYSTEM_PREFIX_PATH}" PARENT_SCOPE)
|
||||
set(QT_CMAKE_SYSTEM_FRAMEWORK_PATH_BACKUP "${CMAKE_SYSTEM_FRAMEWORK_PATH}" PARENT_SCOPE)
|
||||
|
||||
list(REMOVE_ITEM CMAKE_SYSTEM_PREFIX_PATH
|
||||
"/usr/local" # Homebrew
|
||||
"/usr/X11R6"
|
||||
"/usr/pkg"
|
||||
"/opt"
|
||||
"/sw" # Fink
|
||||
"/opt/local" # MacPorts
|
||||
)
|
||||
if(_CMAKE_INSTALL_DIR)
|
||||
list(REMOVE_ITEM CMAKE_SYSTEM_PREFIX_PATH "${_CMAKE_INSTALL_DIR}")
|
||||
endif()
|
||||
list(REMOVE_ITEM CMAKE_SYSTEM_FRAMEWORK_PATH "~/Library/Frameworks")
|
||||
set(CMAKE_SYSTEM_PREFIX_PATH "${CMAKE_SYSTEM_PREFIX_PATH}" PARENT_SCOPE)
|
||||
set(CMAKE_SYSTEM_FRAMEWORK_PATH "${CMAKE_SYSTEM_FRAMEWORK_PATH}" PARENT_SCOPE)
|
||||
|
||||
# Also tell qt_find_package() not to use PATH when looking for packages.
|
||||
# We can't simply set CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH to OFF because that will break
|
||||
# find_program(), and for instance ccache won't be found.
|
||||
# That's why we set a different variable which is used by qt_find_package.
|
||||
set(QT_NO_USE_FIND_PACKAGE_SYSTEM_ENVIRONMENT_PATH "ON" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if(NOT QT_BUILD_INTERNALS_SKIP_SYSTEM_PREFIX_ADJUSTMENT)
|
||||
qt_build_internals_set_up_system_prefixes()
|
||||
endif()
|
||||
|
||||
macro(qt_build_internals_set_up_private_api)
|
||||
# Qt specific setup common for all modules:
|
||||
include(QtSetup)
|
||||
|
@ -444,6 +444,14 @@ endif()\n")
|
||||
"set(QT_EXTRA_RPATHS \"${QT_EXTRA_RPATHS}\" CACHE STRING \"\")\n")
|
||||
endif()
|
||||
|
||||
# Save pkg-config feature value to be able to query it internally as soon as BuildInternals
|
||||
# package is loaded. This is to avoid any pkg-config package from being found when
|
||||
# find_package(Qt6Core) is called in case if the feature was disabled.
|
||||
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS "
|
||||
if(NOT QT_SKIP_BUILD_INTERNALS_PKG_CONFIG_FEATURE)
|
||||
set(FEATURE_pkg_config \"${FEATURE_pkg_config}\" CACHE STRING \"Using pkg-config\" FORCE)
|
||||
endif()\n")
|
||||
|
||||
# The OpenSSL root dir needs to be saved so that repos other than qtbase (like qtopcua) can
|
||||
# still successfully find_package(WrapOpenSSL) in the CI.
|
||||
# qmake saves any additional include paths passed via the configure like '-I/foo'
|
||||
|
Loading…
x
Reference in New Issue
Block a user