aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weickelt <richard@weickelt.de>2020-04-15 22:37:21 +0200
committerRichard Weickelt <richard@weickelt.de>2020-04-15 22:37:51 +0200
commit99d009c0ae5558d86159206e7a27d4ed7e8ade28 (patch)
tree31a6917ba50c52c5987f4cec29be24dce2152565
parent7d9c004b9692ee681f4778a1062e40ee1211f7e5 (diff)
parent846fc574f38395af24a9e60726372cb56075cff4 (diff)
Merge branch '1.16' into master
-rw-r--r--.travis.yml9
-rw-r--r--changelogs/changes-1.16.0.md126
-rw-r--r--doc/howtos.qdoc32
-rw-r--r--doc/qbs.qdoc43
-rw-r--r--doc/reference/items/convenience/application.qdoc33
-rw-r--r--doc/reference/items/convenience/cppapplication.qdoc4
-rw-r--r--doc/reference/items/convenience/dynamiclibrary.qdoc52
-rw-r--r--doc/reference/items/convenience/javajarfile.qdoc2
-rw-r--r--doc/reference/items/convenience/library.qdoc130
-rw-r--r--doc/reference/items/convenience/loadablemodule.qdoc4
-rw-r--r--doc/reference/items/convenience/staticlibrary.qdoc26
-rw-r--r--doc/reference/items/probe/conanfile-probe.qdoc2
-rw-r--r--doc/reference/items/probe/library-probe.qdoc62
-rw-r--r--doc/reference/modules/cpp-module.qdoc9
-rw-r--r--doc/reference/modules/qbs-module.qdoc96
-rw-r--r--doc/reference/modules/qt-qml-module.qdoc5
-rw-r--r--docker-compose.yml11
-rw-r--r--docker/docker.qbs38
-rw-r--r--docker/stretch/Dockerfile73
-rwxr-xr-xdocker/stretch/entrypoint.sh69
-rw-r--r--examples/baremetal/cc2540usbdongle/greenblink/system.h3
-rw-r--r--examples/cocoa-touch-application/CocoaTouchApplication.qbs5
-rw-r--r--examples/helloworld-complex/hello.qbs2
-rw-r--r--examples/helloworld-complex/src/main.cpp4
-rw-r--r--qbs-resources/modules/docker/docker.qbs50
-rw-r--r--qbs.qbs9
-rwxr-xr-xscripts/build-qbs-with-qbs.sh2
-rw-r--r--share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs1
-rw-r--r--share/qbs/imports/qbs/Probes/LibraryProbe.qbs33
-rw-r--r--share/qbs/imports/qbs/base/Application.qbs8
-rw-r--r--share/qbs/imports/qbs/base/DynamicLibrary.qbs20
-rw-r--r--share/qbs/imports/qbs/base/Library.qbs53
-rw-r--r--share/qbs/imports/qbs/base/NativeBinary.qbs3
-rw-r--r--share/qbs/imports/qbs/base/StaticLibrary.qbs9
-rw-r--r--share/qbs/module-providers/Qt/templates/qml.qbs2
-rw-r--r--share/qbs/modules/bundle/BundleModule.qbs3
-rw-r--r--share/qbs/modules/cpp/sdcc.js22
-rw-r--r--share/qbs/modules/protobuf/cpp/protobufcpp.qbs2
-rw-r--r--share/qbs/modules/xcode/xcode.js16
-rw-r--r--share/qbs/modules/xcode/xcode.qbs16
-rw-r--r--src/app/qbs-setup-toolchains/gccprobe.cpp2
-rw-r--r--src/app/qbs-setup-toolchains/sdccprobe.cpp27
-rw-r--r--src/app/qbs/stdinreader.cpp30
-rw-r--r--src/lib/corelib/language/artifactproperties.cpp1
-rw-r--r--src/lib/corelib/language/language.cpp1
-rw-r--r--src/lib/corelib/language/modulemerger.cpp4
-rw-r--r--src/lib/corelib/tools/hostosinfo.h7
-rw-r--r--src/lib/corelib/tools/id.cpp6
-rw-r--r--src/lib/corelib/tools/jsonhelper.h6
-rw-r--r--tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs7
-rw-r--r--tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs22
-rw-r--r--tests/auto/blackbox/testdata/install-locations/install-locations.qbs12
-rw-r--r--tests/auto/blackbox/testdata/install-locations/theplugin.cpp3
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp127
-rw-r--r--tests/auto/blackbox/tst_blackboxapple.cpp22
-rw-r--r--tests/auto/blackbox/tst_blackboxqt.cpp4
56 files changed, 877 insertions, 493 deletions
diff --git a/.travis.yml b/.travis.yml
index 4add585f1..1818ff595 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -96,6 +96,8 @@ jobs:
- ./scripts/install-qt.sh -d ${QT_INSTALL_DIR} --version ${QT_VERSION} qtbase qtdeclarative qttools qtscript qtscxml
- ./scripts/install-qt.sh -d ${QT_INSTALL_DIR} --version ${QTCREATOR_VERSION} qtcreator
- pip3 install --user beautifulsoup4 lxml
+ before_script:
+ - ulimit -c unlimited -S # enable core dumps
script:
- ccache -s
- qbs setup-toolchains --detect
@@ -105,6 +107,13 @@ jobs:
- qbs config --list profiles
- scripts/build-qbs-with-qbs.sh
- ccache -s
+ # Find core dump and print traceback on failure
+ after_failure:
+ - |
+ for f in $(find /cores -maxdepth 1 -name 'core.*' -print); do
+ lldb --core $f --batch --one-line "bt"
+ done;
+
- <<: *build-on-macos
name: With Qbs on macOS (xcode 10.3)
diff --git a/changelogs/changes-1.16.0.md b/changelogs/changes-1.16.0.md
new file mode 100644
index 000000000..23628b904
--- /dev/null
+++ b/changelogs/changes-1.16.0.md
@@ -0,0 +1,126 @@
+# General
+
+* A new freedesktop module helps UNIX application developers to follow the
+ freedesktop.org guidelines.
+* The Android module now allows resourcesDir, sourcesDir and assetsDir to be
+ specified as relative paths.
+* A new ConanfileProbe allows better and more flexible integration of Qbs and
+ the Conan package manager.
+* A new hostArchitecture property has been added to the qbs module.
+
+
+# Language
+
+* List properties in modules are now merged according to inter-module
+ dependencies. This is important when flags like cpp.staticLibraries are
+ contributed by multiple modules with dependencies between each other.
+ (QBS-1517).
+* Dependency matching of multiplexed products is now less strict and does not
+ require all multiplex properties to match. For instance, if product A is
+ multiplexed over qbs.architecture and qbs.buildVariant while product B is only
+ multiplexed over one of these axes, then Qbs no longer fails (QBS-1515).
+
+
+# C/C++ Support
+
+* The Renesas RL78 architecture is now supported in GCC and IAR and the
+ toolchains are auto-detected by qbs-setup-toolchains.
+* The Renesas RX as well as the RH850, V850, 78K are now supported in IAR and
+ the toolchains are auto-detected by qbs-setup-toolchains.
+* The MPLAB X32 GCC-based toolchain is now auto-detected on Windows.
+* Multiple occurrences of static libraries on the linker command line are now
+ pruned and the last instance always wins when using GCC or LLVM-based
+ toolchains. This avoids problems with excessively long linker command lines
+ (QBS-1273).
+* Clang-cl and MSVC toolchains use the compiler frontend instead of the linker
+ when linking. The old behavior can be restored by setting cpp.linkerMode to
+ "manual". This allows to use sanitizers with clang-cl by passing
+ "-fsanitise=xxx" via cpp.driverFlags (QBS-1522).
+* The clang-cl toolchain now uses "link.exe" as the default linker.
+ "lld-link.exe" can be explicitly selected by setting cpp.linkerVariant to
+ "lld" (QBS-1522).
+* The MSVC, clang-cl and MinGW toolchains are now automatically detected if the
+ profile does not set an explicit installation location, for instance because
+ no profile was given.
+* Installation of separate debug information can now be enabled and configured
+ by simply setting the installDebugInformation and debugInformationInstallDir
+ properties in the Application and Library convenience items. This works for
+ toolchains based upon GCC, MSVC or clang-cl.
+* Xcode version 11.4 is now supported on macOS.
+
+
+# Qt Support
+
+* Qbs now supports Qt 5.14 for Android which comes as a multi-architecture
+ package. The qbs-setup-android tool has been updated accordingly (QBS-1497).
+* JSON metatype files generated by moc (Qt >= 5.15) are supported by setting
+ Qt.core.generateMetaTypesFile and Qt.core.metaTypesInstallDir (QBS-1531).
+* Pure debug builds of Qt (>= 5.14) with MinGW are now properly supported. They
+ don't have the 'd' suffix (QTBUG-80792).
+* The QML type declaration mechanism introduced in Qt 5.15 is now supported by
+ the Qt.qml module (QBS-1531).
+* Generated qmltypes files are now named according to the product's targetName
+ property (QTBUG-82710).
+
+
+# Documentation
+
+* The how-to chapter has been extended with sections about debugging Qbs files
+ and about building separate debug information in C++ projects.
+* The item and module reference documentation has been improved for the
+ cpp.libraryPaths, cpp.dynamicLibraries (QBS-1516), qbs.toolchainType and
+ qbs.toolchain properties as well as the Export item and the Library
+ convenience item.
+* Documentation for various path probes has been added (QBS-1187).
+* The README was extended and a CONTRIBUTING file has been added which provides
+ useful information for potential contributors. This is important for people
+ looking at our github mirror.
+
+
+# Infrastructure
+
+* The Debian Docker image has been removed.
+* We are now using ccache and clcache in our CI pipelines to shrink the build
+ time.
+* Clang-tidy is now used to identify potential problems in the code base and a
+ lot of action was taken upon a lot of findings.
+* A Docker image for testing Qbs with Android and Qt has been added.
+
+
+# Important Bug Fixes
+
+* Fix nullpointer access and heap-use-after-free error (QBS-1485).
+* Select the right instance when Depends.profiles is used on a dependency with
+ an aggregator product (QBS-1513).
+* Fix crash when specifying a non-existing profile in Depends.profiles
+ (QBS-1514).
+* Try harder to detect GCC toolchains in qbs-setup-toolchains (QBS-1524).
+* Code signing for Core Foundation Bundles on macOS has been fixed.
+* Automatic artifact scanning now prefers artifacts from product dependencies if
+ multiple candidates are found. This improves dependency tracking in complex
+ projects (QBS-1532).
+* The grpcIncludePath property in the probufcpp module has been fixed
+ (QBS-1542).
+* Qbs does no longer crash when accessing a property of a non-existent module in
+ "IDE mode".
+
+
+# Contributors
+
+* Alberto Mardegan
+* Björn Schäpers
+* BogDan Vatra
+* Christian Kandeler
+* Christian Stenger
+* Denis Shienkov
+* Ivan Komissarov
+* Jochen Ulrich
+* Joerg Bornemann
+* Leon Buckel
+* Marius Sincovici
+* Maximilian Goldstein
+* Mitch Curtis
+* Oliver Wolff
+* Orgad Shaneh
+* Raphaël Cotty
+* Richard Weickelt
diff --git a/doc/howtos.qdoc b/doc/howtos.qdoc
index 61da7af53..696c444cb 100644
--- a/doc/howtos.qdoc
+++ b/doc/howtos.qdoc
@@ -151,15 +151,31 @@
}
\endcode
- If the \l{cpp::separateDebugInformation}{cpp.separateDebugInformation} property is set to
- \c true, \QBS will create debugging symbols with the corresponding file tags
+ Now, you can install your \l{Application}{application}, \l{DynamicLibrary}{dynamic library}
+ or \l{LoadableModule}{loadable module} among with its debugging symbols as follows:
+ \code
+ CppApplication {
+ // ...
+ install: true
+ installDir: "bin"
+ installDebugInformation: true
+ debugInformationInstallDir: "bin"
+ }
+ \endcode
+
+ If you are not using \l{List of Convenience Items}{convenience items},
+ you can install debug symbols manually using the \l{Group} item. If the
+ \l{cpp::separateDebugInformation}{cpp.separateDebugInformation} property is set to \c true,
+ \QBS will create debugging symbols with the corresponding file tags
\c "debuginfo_app" (for an application), \c "debuginfo_dll" (for a dynamic library),
or \c "debuginfo_loadablemodule" (for a macOS plugin).
- Now, you can install your application and its debugging symbols as follows:
\code
- CppApplication {
- // ...
+ Product {
+ type: "application"
+ Depends { name: "cpp" }
+ cpp.debugInformation: qbs.buildVariant !== "release"
+ cpp.separateDebugInformation: true
Group {
fileTagsFilter: cpp.separateDebugInformation ? ["debuginfo_app"] : []
qbs.install: true
@@ -171,7 +187,8 @@
If you're building a shared library, you need to use the \c "debuginfo_dll" tag instead:
\code
- DynamicLibrary {
+ Product {
+ type: "dynamic_library"
// ...
Group {
fileTagsFilter: cpp.separateDebugInformation ? ["debuginfo_dll"] : []
@@ -185,7 +202,8 @@
If you're building a macOS plugin, you need to use the \c "debuginfo_loadablemodule"
tag instead:
\code
- LoadableModule {
+ Product {
+ type: "loadablemodule"
// ...
Group {
fileTagsFilter: cpp.separateDebugInformation ? ["debuginfo_loadablemodule"] : []
diff --git a/doc/qbs.qdoc b/doc/qbs.qdoc
index 0b1592bfd..db9a64af4 100644
--- a/doc/qbs.qdoc
+++ b/doc/qbs.qdoc
@@ -694,7 +694,7 @@
A set of Docker images for developing \QBS (which are maintained by the \QBS team) is available
\l{https://hub.docker.com/u/qbsbuild/}{on Docker Hub}.
- Both Windows Server Core and Debian Linux container types are available.
+ Both Windows 10 and Debian Linux container types are available.
\note The source code for the \QBS development Docker images is located in the \c{docker/}
directory of the \QBS source tree, if you wish to build them yourself.
@@ -712,45 +712,46 @@
\li Latest stable release of \QBS for building \QBS with \QBS
\endlist
- Run the following command to download the \QBS development image based on Ubuntu 18.04 \e Bionic:
+ We are using docker-compose for building and running the Docker images because it simplifies
+ the Docker command line and ensures that the correct image tag is used. All available images
+ are listed in the \c docker-compose.yml file in the project root directory.
+
+ Run the following command to download the \QBS development image based on Ubuntu 18.04
+ \e Bionic:
\code
- docker pull qbsbuild/qbsdev:bionic
+ docker-compose pull bionic
\endcode
You can then create a new container with the \QBS source directory mounted from your host
machine's file system, by running:
\code
- docker run -it -v ${PWD}:/qbs -w /qbs qbsbuild/qbsdev:bionic
- \endcode
-
- You will now be in an interactive Linux shell where you can develop and build \QBS.
-
- For convenience, you can also run \c docker-compose from the project root directory:
-
- \code
docker-compose run --rm bionic
\endcode
- This will download and run the container in one go and mount the project root directory
- to \c /qbs in the container.
+ You will now be in an interactive Linux shell where you can develop and build \QBS.
\section2 Windows Containers
To build \QBS for Windows using Windows containers, your host OS must be running Windows 10 Pro
- and have Hyper-V enabled. \l{https://docs.docker.com/docker-for-windows/#switch-between-windows-and-linux-containers}{Switch your Docker environment to use Windows containers}, then run the
- following command to download the Windows 10 \QBS development image:
+ and have Hyper-V enabled. \l{https://docs.docker.com/docker-for-windows/#switch-between-windows-and-linux-containers}{Switch your Docker environment to use Windows containers}.
+
+ We are using docker-compose for building and running the Docker images because it simplifies
+ the Docker command line and ensures that the correct image tag is used. All available images
+ are listed in the \c docker-compose.yml file in the project root directory.
+
+ Run the following command to download the \QBS development image based on Windows 10:
\code
- docker pull qbsbuild/qbsdev:windowsservercore
+ docker-compose pull windows
\endcode
You can then create a new container with the \QBS source directory mounted from your host
machine's file system, by running:
\code
- docker run -it -v %CD%:C:\qbs -w C:\qbs qbsbuild/qbsdev:windowsservercore
+ docker-compose run --rm windows
\endcode
If you want to use Windows containers on a macOS or Linux host, you will have to create a
@@ -764,7 +765,7 @@
\code
eval $(docker-machine env windows)
- docker run -it -v C:$PWD:C:\\qbs -w C:\\qbs qbsbuild/qbsdev:windowsservercore
+ docker-compose run --rm windows
\endcode
\section2 Building Release Packages
@@ -772,14 +773,14 @@
Release packages for \QBS for Windows can be built using the following command on Windows:
\code
- docker run --rm -v %CD%:C:\qbs -w C:\qbs qbsbuild/qbsdev:windowsservercore cmd /c scripts\make-release-archives
+ docker-compose run --rm windows cmd /c scripts\make-release-archives
\endcode
For building release packages for Windows on macOS or Linux:
\code
eval $(docker-machine env windows)
- docker run --rm -v C:$PWD:C:\\qbs -w C:\\qbs qbsbuild/qbsdev:windowsservercore cmd /c scripts\\make-release-archives
+ docker-compose run --rm windows cmd /c scripts\\make-release-archives
\endcode
*/
@@ -1614,6 +1615,8 @@
To introduce a custom item \c MyItem, create the file \c{search-path/imports/MyItem.qbs}.
+ \note Item file names must start with a capital letter due to the fact that type names can
+ only start with a capital letter. Otherwise, the file will be silently ignored.
\section1 Making \QBS Aware of Custom Modules and Items
diff --git a/doc/reference/items/convenience/application.qdoc b/doc/reference/items/convenience/application.qdoc
index c09d15918..e92247f5f 100644
--- a/doc/reference/items/convenience/application.qdoc
+++ b/doc/reference/items/convenience/application.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
\contentspage list-of-convenience-items.html
- \previouspage AppleApplicationDiskImage
+ \previouspage AppleDiskImage
\nextpage ApplicationExtension
\qmltype Application
\inherits Product
@@ -49,7 +49,7 @@
\qmlproperty bool Application::install
If \c{true}, the executable that is produced when building the application will be installed
- to \l installDir.
+ to \l{Application::installDir}{installDir}.
\defaultvalue \c false
\since Qbs 1.13
@@ -58,8 +58,8 @@
/*!
\qmlproperty string Application::installDir
- Where to install the executable that is produced when building the application, if \l install
- is enabled.
+ Where to install the executable that is produced when building the application, if
+ \l{Application::install}{install} is enabled.
The value is appended to \l{qbs::installPrefix}{qbs.installPrefix}
when constructing the actual installation directory.
@@ -67,3 +67,28 @@
\defaultvalue \c Applications if the app is a \l{bundle::isBundle}{bundle}, \c bin otherwise.
\since Qbs 1.13
*/
+
+/*!
+ \qmlproperty string Application::installDebugInformation
+
+ If \c{true}, the debug information will be installed to
+ \l{Application::debugInformationInstallDir}{debugInformationInstallDir}.
+
+ \defaultvalue \c false
+ \since Qbs 1.16
+ \sa{How do I separate and install debugging symbols?}
+*/
+
+/*!
+ \qmlproperty string Application::debugInformationInstallDir
+
+ Where to install the debug information if \l installDebugInformation is enabled.
+
+ The value is appended to \l{qbs::installPrefix}{qbs.installPrefix}
+ when constructing the actual installation directory.
+
+ \defaultvalue \l installDir.
+ \since Qbs 1.16
+
+ \sa{How do I separate and install debugging symbols?}
+*/
diff --git a/doc/reference/items/convenience/cppapplication.qdoc b/doc/reference/items/convenience/cppapplication.qdoc
index 13bd523b7..7e71eec41 100644
--- a/doc/reference/items/convenience/cppapplication.qdoc
+++ b/doc/reference/items/convenience/cppapplication.qdoc
@@ -29,14 +29,14 @@
\previouspage AutotestRunner
\nextpage DynamicLibrary
\qmltype CppApplication
- \inherits Product
+ \inherits Application
\inqmlmodule QbsConvenienceItems
\ingroup list-of-items
\keyword QML.CppApplication
\brief C++ application.
- A CppApplication is a \l{Product}{product} that has a dependency on the
+ A CppApplication is an \l{Application}{application} that has a dependency on the
\l{cpp} module. It is entirely equivalent to the following:
\code
diff --git a/doc/reference/items/convenience/dynamiclibrary.qdoc b/doc/reference/items/convenience/dynamiclibrary.qdoc
index 488aef3eb..18a11bf11 100644
--- a/doc/reference/items/convenience/dynamiclibrary.qdoc
+++ b/doc/reference/items/convenience/dynamiclibrary.qdoc
@@ -29,7 +29,7 @@
\previouspage CppApplication
\nextpage InnoSetup
\qmltype DynamicLibrary
- \inherits Product
+ \inherits Library
\inqmlmodule QbsConvenienceItems
\ingroup list-of-items
\keyword QML.DynamicLibrary
@@ -37,7 +37,7 @@
\brief Dynamic library.
- A DynamicLibrary item is a \l{Product} of the \l{Product::}{type}
+ A DynamicLibrary item is a \l{Library}{library} of the \l{Product::}{type}
\c "dynamiclibrary".
For Android targets, the following applies:
@@ -47,51 +47,3 @@
\li There is a dependency on the \l{cpp} and \l{Android.ndk} modules.
\endlist
*/
-
-/*!
- \qmlproperty bool DynamicLibrary::install
-
- If \c{true}, the library will be installed to \l installDir.
-
- \defaultvalue \c false
- \since Qbs 1.13
-*/
-
-/*!
- \qmlproperty string DynamicLibrary::installDir
-
- Where to install the library, if \l install is enabled. On Unix, the symbolic links
- are also installed to this location.
-
- The value is appended to \l{qbs::installPrefix}{qbs.installPrefix}
- when constructing the actual installation directory.
-
- \defaultvalue \c Library/Frameworks if the library is a \l{bundle::isBundle}{bundle},
- otherwise \c bin for Windows and \c lib for Unix-like targets.
- \since Qbs 1.13
-*/
-
-/*!
- \qmlproperty bool DynamicLibrary::installImportLib
-
- If \c{true}, the import library will be installed to \l importLibInstallDir.
- This property is only relevant for Windows targets.
- Enable it if you want to create a development package.
-
- \defaultvalue \c false
- \since Qbs 1.13
-*/
-
-/*!
- \qmlproperty string DynamicLibrary::importLibInstallDir
-
- Where to install the import library, if \l installImportLib is enabled.
-
- The value is appended to \l{qbs::installPrefix}{qbs.installPrefix}
- when constructing the actual installation directory.
-
- This property is only relevant for Windows targets.
-
- \defaultvalue \c lib
- \since Qbs 1.13
-*/
diff --git a/doc/reference/items/convenience/javajarfile.qdoc b/doc/reference/items/convenience/javajarfile.qdoc
index 48643d80e..cda3e4ba0 100644
--- a/doc/reference/items/convenience/javajarfile.qdoc
+++ b/doc/reference/items/convenience/javajarfile.qdoc
@@ -27,7 +27,7 @@
/*!
\contentspage list-of-convenience-items.html
\previouspage JavaClassCollection
- \nextpage LoadableModule
+ \nextpage Library
\qmltype JavaJarFile
\inherits Product
\inqmlmodule QbsConvenienceItems
diff --git a/doc/reference/items/convenience/library.qdoc b/doc/reference/items/convenience/library.qdoc
new file mode 100644
index 000000000..fc3a75640
--- /dev/null
+++ b/doc/reference/items/convenience/library.qdoc
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \contentspage list-of-convenience-items.html
+ \previouspage JavaJarFile
+ \nextpage LoadableModule
+ \qmltype Library
+ \since Qbs 1.4
+ \inherits Product
+ \inqmlmodule QbsConvenienceItems
+ \ingroup list-of-items
+ \keyword QML.NativeBinary
+
+ \brief Generic library.
+
+ A Library item is a base item for native libraries and can have \l{Product::}{type} set to
+ one of the following values: \c "dynamiclibrary", \c "staticlibrary", \c "loadablemodule".
+
+ The default \l{Product::}{type} value is \c "dynamiclibrary" except for iOS prior to
+ version 8, in which case the default value is \c "staticlibrary".
+
+ This item can automatically install the library target (and library symlinks on Unix) and
+ separated debug information.
+
+ For Android targets, the following applies:
+ \list
+ \li The \l{Product::type}{Product.type} property value contains
+ \c "android.nativelibrary" in addition to \c "dynamiclibrary".
+ \li There is a dependency on the \l{cpp} and \l{Android.ndk} modules.
+ \endlist
+*/
+
+/*!
+ \qmlproperty bool Library::install
+
+ If \c{true}, the library will be installed to \l{Library::installDir}{installDir}.
+
+ \defaultvalue \c false
+ \since Qbs 1.13
+*/
+
+/*!
+ \qmlproperty string Library::installDir
+
+ Where to install the library, if \l{Library::install}{install} is enabled. On Unix,
+ the symbolic links are also installed to this location.
+
+ The value is appended to \l{qbs::installPrefix}{qbs.installPrefix}
+ when constructing the actual installation directory.
+
+ \defaultvalue \c Library/Frameworks if the library is a \l{bundle::isBundle}{bundle},
+ otherwise \c bin for Windows and \c lib for Unix-like targets.
+ \since Qbs 1.13
+*/
+
+/*!
+ \qmlproperty string Library::installDebugInformation
+
+ If \c{true}, the debug information will be installed to
+ \l{Library::debugInformationInstallDir}{debugInformationInstallDir}.
+
+ \defaultvalue \c false
+ \since Qbs 1.16
+ \sa{How do I separate and install debugging symbols?}
+*/
+
+/*!
+ \qmlproperty string Library::debugInformationInstallDir
+
+ Where to install the debug information if \l installDebugInformation is enabled.
+
+ The value is appended to \l{qbs::installPrefix}{qbs.installPrefix}
+ when constructing the actual installation directory.
+
+ \defaultvalue \l installDir.
+ \since Qbs 1.16
+
+ \sa{How do I separate and install debugging symbols?}
+*/
+
+/*!
+ \qmlproperty bool Library::installImportLib
+
+ If \c{true}, the import library will be installed to \l importLibInstallDir.
+ This property is only relevant for Windows targets.
+ Enable it if you want to create a development package.
+
+ \defaultvalue \c false
+ \since Qbs 1.13
+*/
+
+/*!
+ \qmlproperty string Library::importLibInstallDir
+
+ Where to install the import library, if \l installImportLib is enabled.
+
+ The value is appended to \l{qbs::installPrefix}{qbs.installPrefix}
+ when constructing the actual installation directory.
+
+ This property is only relevant for Windows targets.
+
+ \defaultvalue \c lib
+ \since Qbs 1.13
+*/
+
diff --git a/doc/reference/items/convenience/loadablemodule.qdoc b/doc/reference/items/convenience/loadablemodule.qdoc
index d02dbae1c..76022350d 100644
--- a/doc/reference/items/convenience/loadablemodule.qdoc
+++ b/doc/reference/items/convenience/loadablemodule.qdoc
@@ -27,10 +27,10 @@
****************************************************************************/
/*!
\contentspage list-of-convenience-items.html
- \previouspage JavaJarFile
+ \previouspage Library
\nextpage QtApplication
\qmltype LoadableModule
- \inherits Product
+ \inherits Library
\inqmlmodule QbsConvenienceItems
\ingroup list-of-items
\keyword QML.LoadableModule
diff --git a/doc/reference/items/convenience/staticlibrary.qdoc b/doc/reference/items/convenience/staticlibrary.qdoc
index cd459cf6e..eeaba0639 100644
--- a/doc/reference/items/convenience/staticlibrary.qdoc
+++ b/doc/reference/items/convenience/staticlibrary.qdoc
@@ -29,35 +29,13 @@
\previouspage QtGuiApplication
\nextpage XPCService
\qmltype StaticLibrary
- \inherits Product
+ \inherits Library
\inqmlmodule QbsConvenienceItems
\ingroup list-of-items
\keyword QML.StaticLibrary
\brief Static library.
- A StaticLibrary item is a \l{Product}{product} of the \l{Product::}{type}
+ A StaticLibrary item is a \l{Library}{library} of the \l{Product::}{type}
\c "staticlibrary".
*/
-
-/*!
- \qmlproperty bool StaticLibrary::install
-
- If \c{true}, the library will be installed to \l installDir.
-
- \defaultvalue \c false
- \since Qbs 1.13
-*/
-
-/*!
- \qmlproperty string StaticLibrary::installDir
-
- Where to install the library, if \l install is enabled.
-
- The value is appended to \l{qbs::installPrefix}{qbs.installPrefix}
- when constructing the actual installation directory.
-
- \defaultvalue \c Library/Frameworks if the library is a \l{bundle::isBundle}{bundle},
- \c lib otherwise.
- \since Qbs 1.13
-*/
diff --git a/doc/reference/items/probe/conanfile-probe.qdoc b/doc/reference/items/probe/conanfile-probe.qdoc
index cef1195c8..191d7c894 100644
--- a/doc/reference/items/probe/conanfile-probe.qdoc
+++ b/doc/reference/items/probe/conanfile-probe.qdoc
@@ -70,7 +70,7 @@
generators: "qbs"
}
- references: conan.generatorOutputPath + "/conanbuildinfo.qbs"
+ references: conan.generatedFilesPath + "/conanbuildinfo.qbs"
CppApplication {
type: "application"
diff --git a/doc/reference/items/probe/library-probe.qdoc b/doc/reference/items/probe/library-probe.qdoc
new file mode 100644
index 000000000..2d1e35a51
--- /dev/null
+++ b/doc/reference/items/probe/library-probe.qdoc
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \contentspage list-of-probes.html
+ \qmltype LibraryProbe
+ \ingroup list-of-probes
+ \ingroup list-of-items
+ \keyword QML.IncludeProbe
+ \inherits PathProbe
+
+ \brief Locates library files outside the project.
+
+ On Windows, searches for library files within directories specified by the \c PATH environment
+ variable.
+
+ On Unix, searches for library files within directories specified by the \c LIBRARY_PATH
+ environment variable, as well as in \c "/usr/lib" and \c "/usr/local/lib".
+
+ On Linux, also searches in platform-specific directories, such as \c "/usr/lib64" and
+ \c "/usr/lib/x86_64-linux-gnu".
+
+ For example, LibraryProbe can be used to search for a \c zlib library as follows:
+
+ \code
+ import qbs.Probes
+
+ CppApplication {
+ Probes.LibraryProbe {
+ id: zlibProbe
+ names: "z"
+ }
+ cpp.libraryPaths: zlibProbe.found ? [zlibProbe.path] : []
+ cpp.dynamicLibraries: zlibProbe.found ? [zlibProbe.names] : []
+ files: 'main.cpp'
+ }
+ \endcode
+*/
diff --git a/doc/reference/modules/cpp-module.qdoc b/doc/reference/modules/cpp-module.qdoc
index 2fc592d4e..ff8c0172e 100644
--- a/doc/reference/modules/cpp-module.qdoc
+++ b/doc/reference/modules/cpp-module.qdoc
@@ -615,6 +615,15 @@
*/
/*!
+ \qmlproperty string cpp::compilerVersion
+
+ Compiler version string consisting of major, minor and patch numbers,
+ separated by a dot.
+
+ \nodefaultvalue
+*/
+
+/*!
\qmlproperty int cpp::compilerVersionMajor
\since Qbs 1.4
diff --git a/doc/reference/modules/qbs-module.qdoc b/doc/reference/modules/qbs-module.qdoc
index 683caa0ce..ac4633d00 100644
--- a/doc/reference/modules/qbs-module.qdoc
+++ b/doc/reference/modules/qbs-module.qdoc
@@ -295,6 +295,102 @@
Commonly used values are: \c{"x86"}, \c{"x86_64"}, and \c{"arm"}.
+ \section2 Supported Processor Architectures
+
+ This table describes the possible values of the \l{qbs::}{architecture} property:
+ \table
+ \header
+ \li Architecture
+ \li Description
+ \row
+ \li \c{"78k"}
+ \li 16- and 8-bit accumulator-based register-bank CISC architecture
+ microcontroller family manufactured by Renesas Electronics
+ \row
+ \li \c{"arm"}
+ \li 32-bit RISC architecture for computer processors
+ developed by Acorn RISC Machine
+ \note There are a lot of sub-variants of the ARM architecture.
+ Some specialized \QBS modules differentiate between them,
+ making use of values such as \c "armv7a". Please consult the
+ respective module-specific documentation for information
+ on what kind of value to use.
+ \row
+ \li \c{"arm64"}
+ \li 64-bit RISC architecture for computer processors
+ developed by Acorn RISC Machine
+ \row
+ \li \c{"avr"}
+ \li 8-bit modified Harvard RISC architecture microcontroller
+ family manufactured by Microchip Technology
+ \row
+ \li \c{"avr32"}
+ \li 32-bit RISC architecture microcontroller family developed by Atmel
+ \row
+ \li \c{"ia64"}
+ \li 64-bit ISA architecture of the Itanium family processors
+ developed by Intel
+ \row
+ \li "mcs51"}
+ \li 8-bit Harvard architecture microcontroller family developed by Intel
+ \row
+ \li \c{"mips"}
+ \li 32-bit RISC microprocessor without interlocked pipelined stages
+ architecture developed by MIPS Computer Systems
+ \row
+ \li \c{"mips64"}
+ \li 64-bit RISC microprocessor without interlocked pipelined stages
+ architecture developed by MIPS Computer Systems
+ \row
+ \li \c{"msp430"}
+ \li 16-bit mixed-signal microcontroller family manufactured
+ by Texas Instruments
+ \row
+ \li \c{"ppc"}
+ \li 32-bit RISC architecture processor family developed by
+ Apple–IBM–Motorola alliance
+ \row
+ \li \c{"ppc64"}
+ \li 64-bit RISC architecture processor family developed by
+ Apple–IBM–Motorola alliance
+ \row
+ \li \c{"rh850"}
+ \li 32-bit automotive microcontroller family manufactured
+ by Renesas Electronics
+ \row
+ \li \c{"rl78"}
+ \li 16- and 8-bit accumulator-based register-bank CISC architecture
+ with 3-stage instruction pipelining microcontroller family manufactured
+ by Renesas Electronics
+ \row
+ \li \c{"rx"}
+ \li High performance 32-bit CISC microcontroller family manufactured
+ by Renesas Electronics
+ \row
+ \li \c{"s390x"}
+ \li 64- and 32-bit System/390 processor architecture developed by IBM
+ \row
+ \li \c{"sparc"}
+ \li 32-bit RISC architecture processor family developed by
+ Sun Microsystems and Fujitsu
+ \row
+ \li \c{"sparc64"}
+ \li 64-bit RISC architecture processor family developed by
+ Sun Microsystems and Fujitsu
+ \row
+ \li \c{"stm8"}
+ \li 8-bit microcontroller family manufactured by STMicroelectronics
+ \row
+ \li \c{"v850"}
+ \li 32-bit RISC microcontroller family manufactured by Renesas Electronics
+ \row
+ \li \c{"x86"}
+ \li 32-bit ISA architecture processor family developed by Intel
+ \row
+ \li \c{"x86_64"}
+ \li 64-bit ISA architecture processor family developed by AMD
+ \endtable
+
\nodefaultvalue
*/
diff --git a/doc/reference/modules/qt-qml-module.qdoc b/doc/reference/modules/qt-qml-module.qdoc
index 3d5758fc3..ba8dddf2f 100644
--- a/doc/reference/modules/qt-qml-module.qdoc
+++ b/doc/reference/modules/qt-qml-module.qdoc
@@ -98,8 +98,9 @@
\qmlproperty string Qt.qml::typesFileName
Specifies the name of the file that declares the types registered for this product.
- Per default, it is called "app.qmltypes" for applications and "plugins.qmltypes"
- otherwise.
+ For applications, the default value is \c{<name>.qmltypes},
+ where \c{<name>} is the product's \l{Product::targetName}{target name}.
+ Otherwise, the default value is "plugins.qmltypes".
\note The naming conventions are still in flux.
When in doubt, consult the Qt documentation.
diff --git a/docker-compose.yml b/docker-compose.yml
index e26beed00..2b777c6f3 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -43,17 +43,6 @@ services:
args:
QT_VERSION: 5.14.0
- stretch:
- << : *linux
- hostname: stretch
- image: ${DOCKER_USER:-qbsbuild}/qbsdev:stretch
- build:
- dockerfile: docker/stretch/Dockerfile
- context: .
- args:
- QT_VERSION: 5.12.4
- QTCREATOR_VERSION: 4.9.2
-
windows:
image: ${DOCKER_USER:-qbsbuild}/qbsdev:windowsservercore-5.12.7_1.15.0-0
build:
diff --git a/docker/docker.qbs b/docker/docker.qbs
index 752c61d3b..513a5fd8b 100644
--- a/docker/docker.qbs
+++ b/docker/docker.qbs
@@ -1,34 +1,8 @@
-import qbs
-Project {
- Product {
- Depends { name: "docker"; required: false }
-
- name: "qbs-docker-stretch"
- type: ["docker.docker-image"]
- builtByDefault: false
- condition: docker.present
-
- docker.imageTag: "qbsbuild/qbsdev:stretch"
-
- files: [
- "stretch/Dockerfile",
- "stretch/entrypoint.sh",
- ]
- }
-
- Product {
- Depends { name: "docker"; required: false }
-
- name: "qbs-docker-windowsservercore"
- type: ["docker.docker-image"]
- builtByDefault: false
- condition: docker.present
-
- docker.imageTag: "qbsbuild/qbsdev:windowsservercore"
-
- files: [
- "windowsservercore/Dockerfile",
- ]
- }
+// This is a convenience product to be able to use Qt Creator for editing the docker files.
+// For building and managing the images, use docker-compose as explained in
+// https://doc.qt.io/qbs/building-qbs.html#using-docker.
+Product {
+ name: "docker"
+ files: "**"
}
diff --git a/docker/stretch/Dockerfile b/docker/stretch/Dockerfile
deleted file mode 100644
index 736bd1ef7..000000000
--- a/docker/stretch/Dockerfile
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# Downloads and builds Qt from source. This is simpler than using the Qt online
-# installer. We do it in a separate stage to keep the number of dependencies low
-# in the final Docker image.
-#
-FROM debian:9
-LABEL Description="Debian development environment for Qbs with Qt and various dependencies for testing Qbs modules and functionality"
-ARG QT_VERSION
-ARG QTCREATOR_VERSION
-
-# Allow colored output on command line.
-ENV TERM=xterm-color
-
-#
-# Make it possible to change UID/GID in the entrypoint script. The docker
-# container usually runs as root user on Linux hosts. When the Docker container
-# mounts a folder on the host and creates files there, those files would be
-# owned by root instead of the current user. Thus we create a user here who's
-# UID will be changed in the entrypoint script to match the UID of the current
-# host user.
-#
-ARG USER_UID=1000
-ARG USER_NAME=devel
-RUN apt-get update -qq && \
- apt-get install -qq -y --no-install-recommends \
- ca-certificates \
- gosu \
- sudo && \
- groupadd -g ${USER_UID} ${USER_NAME} && \
- useradd -s /bin/bash -u ${USER_UID} -g ${USER_NAME} -o -c "" -m ${USER_NAME} && \
- usermod -a -G sudo ${USER_NAME} && \
- echo "%devel ALL = (ALL) NOPASSWD: ALL" >> /etc/sudoers
-
-COPY docker/stretch/entrypoint.sh entrypoint.sh
-ENTRYPOINT ["/entrypoint.sh"]
-
-
-# Build and run dependencies for Qbs
-RUN apt-get install -qq -y --no-install-recommends \
- build-essential \
- curl \
- git \
- help2man \
- libclang-3.9 \
- libdbus-1-3 \
- libgl1-mesa-glx \
- libfreetype6 \
- libfontconfig1 \
- libgl1-mesa-dev \
- make \
- pkg-config \
- python-pip \
- p7zip-full && \
- pip install beautifulsoup4 lxml # for building the documentation
-
-ENV LLVM_INSTALL_DIR=/usr/lib/llvm-3.9
-
-COPY scripts/install-qt.sh install-qt.sh
-
-RUN ./install-qt.sh --version ${QT_VERSION} qtbase qtdeclarative qtscript qttools qtx11extras icu && \
- ./install-qt.sh --version ${QTCREATOR_VERSION} qtcreator && \
- echo "export PATH=/opt/Qt/${QT_VERSION}/gcc_64/bin:/opt/Qt/Tools/QtCreator/bin:\${PATH}" > /etc/profile.d/qt.sh
-
-ENV PATH=/opt/Qt/${QT_VERSION}/gcc_64/bin:/opt/Qt/Tools/QtCreator/bin:${PATH}
-
-# Configure Qbs
-USER $USER_NAME
-RUN qbs-setup-toolchains --detect && \
- qbs-setup-qt /opt/Qt/${QT_VERSION}/gcc_64/bin/qmake qt && \
- qbs config defaultProfile qt
-
-# Switch back to root user for the entrypoint script.
-USER root
diff --git a/docker/stretch/entrypoint.sh b/docker/stretch/entrypoint.sh
deleted file mode 100755
index 04504ffcc..000000000
--- a/docker/stretch/entrypoint.sh
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-#############################################################################
-##
-## Copyright (C) 2019 Richard Weickelt <richard@weickelt.de>
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qbs.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-#
-# Try to determine the uid of the working directory and adjust the current
-# user's uid/gid accordingly.
-#
-WORKDIR_GID=$(stat -c "%g" .)
-WORKDIR_UID=$(stat -c "%u" .)
-USER_NAME=${USER_NAME:-devel}
-EXEC=""
-
-if [ "$(id -u ${USER_NAME})" != "0" ] && [ "${WORKDIR_UID}" != "0" ] ; then
-
- export HOME=/home/${USER_NAME}
-
- if [ "$(id -u ${USER_NAME})" != "${WORKDIR_UID}" ]; then
- usermod -u ${WORKDIR_UID} ${USER_NAME}
- groupmod -g ${WORKDIR_GID} ${USER_NAME}
- chown -R -h ${WORKDIR_UID} /home;
- chgrp -R -h ${WORKDIR_GID} /home;
- fi
- EXEC="exec gosu ${USER_NAME}:${USER_NAME}"
-fi
-
-if [ -z "$1" ]; then
- ${EXEC} bash --login
-else
- ${EXEC} bash --login -c "$*"
-fi
diff --git a/examples/baremetal/cc2540usbdongle/greenblink/system.h b/examples/baremetal/cc2540usbdongle/greenblink/system.h
index cdc6302d4..4f105dbd0 100644
--- a/examples/baremetal/cc2540usbdongle/greenblink/system.h
+++ b/examples/baremetal/cc2540usbdongle/greenblink/system.h
@@ -66,6 +66,9 @@ extern "C" {
#elif defined (__SDCC_mcs51)
#include <mcs51/compiler.h>
# define DEFINE_SFR(name, addr) __sfr __at(addr) name;
+# ifndef NOP
+# define NOP() __asm NOP __endasm
+# endif
# define system_nop() NOP()
#else
#error "Unsupported toolchain"
diff --git a/examples/cocoa-touch-application/CocoaTouchApplication.qbs b/examples/cocoa-touch-application/CocoaTouchApplication.qbs
index cf0a273d5..ec1772f1f 100644
--- a/examples/cocoa-touch-application/CocoaTouchApplication.qbs
+++ b/examples/cocoa-touch-application/CocoaTouchApplication.qbs
@@ -54,12 +54,9 @@ import qbs 1.0
CppApplication {
Depends { name: "xcode"; required: false }
Depends { condition: product.condition; name: "ib" }
- condition: qbs.hostOS.contains("macos") && xcode.present
+ condition: qbs.hostOS.contains("macos") && xcode.present && qbs.targetPlatform.contains("ios")
name: "Cocoa Touch Application"
- qbs.targetPlatform: "ios"
- qbs.architecture: "arm64"
-
cpp.useObjcPrecompiledHeader: true
cpp.minimumIosVersion: "8.0"
cpp.frameworks: [ "UIKit", "Foundation", "CoreGraphics" ]
diff --git a/examples/helloworld-complex/hello.qbs b/examples/helloworld-complex/hello.qbs
index 725424e49..16e7eace0 100644
--- a/examples/helloworld-complex/hello.qbs
+++ b/examples/helloworld-complex/hello.qbs
@@ -74,7 +74,7 @@ Project {
cpp.defines: {
var defines = outer.concat([
'HAVE_MAIN_CPP',
- cpp.debugInformation ? '_DEBUG' : '_RELEASE'
+ cpp.debugInformation ? 'HAS_DEBUG' : 'HAS_RELEASE'
]);
if (project.hasSpecialFeature)
defines.push("HAS_SPECIAL_FEATURE");
diff --git a/examples/helloworld-complex/src/main.cpp b/examples/helloworld-complex/src/main.cpp
index 691c401e5..8827c1e5e 100644
--- a/examples/helloworld-complex/src/main.cpp
+++ b/examples/helloworld-complex/src/main.cpp
@@ -67,9 +67,9 @@
int main()
{
someUsefulFunction();
-#ifdef _DEBUG
+#if defined(HAS_DEBUG)
puts("Hello World! (debug version)");
-#else
+#elif defined(HAS_RELEASE)
puts("Hello World! (release version)");
#endif
#ifdef HAS_SPECIAL_FEATURE
diff --git a/qbs-resources/modules/docker/docker.qbs b/qbs-resources/modules/docker/docker.qbs
deleted file mode 100644
index 1460cff3c..000000000
--- a/qbs-resources/modules/docker/docker.qbs
+++ /dev/null
@@ -1,50 +0,0 @@
-import qbs
-import qbs.FileInfo
-import qbs.Probes
-import qbs.Utilities
-
-Module {
- Probes.BinaryProbe {
- id: dockercli
- names: ["docker"]
- }
-
- property string dockerFilePath: dockercli.filePath
- property string imageTag
- property stringList buildFlags
-
- FileTagger {
- patterns: ["Dockerfile"]
- fileTags: ["docker.dockerfile"]
- }
-
- Rule {
- inputs: ["docker.dockerfile"]
-
- Artifact {
- // Let Docker handle the dependency management
- filePath: FileInfo.joinPaths(product.buildDirectory,
- Utilities.getHash(input.filePath), ".docker-image-dummy")
- fileTags: ["docker.docker-image"]
- }
-
- prepare: {
- var args = ["build"];
- var tag = product.docker.imageTag;
- if (tag)
- args.push("-t", tag);
- Array.prototype.push.apply(args, product.docker.buildFlags);
- args.push(".");
- var cmd = new Command(product.docker.dockerFilePath, args);
- cmd.workingDirectory = FileInfo.path(input.filePath);
- cmd.description = "building docker image "
- + FileInfo.fileName(cmd.workingDirectory) + (tag ? " (" + tag + ")" : "");
- return [cmd];
- }
- }
-
- validate: {
- if (!dockerFilePath)
- throw ModUtils.ModuleError("Could not find Docker.");
- }
-}
diff --git a/qbs.qbs b/qbs.qbs
index f36bd0ee4..c409eefb6 100644
--- a/qbs.qbs
+++ b/qbs.qbs
@@ -4,7 +4,6 @@ Project {
minimumQbsVersion: "1.6"
qbsSearchPaths: ["qbs-resources"]
property bool withCode: true
- property bool withDocker: true
property bool withDocumentation: true
property bool withExamples: false
property bool withTests: withCode
@@ -12,18 +11,12 @@ Project {
property stringList autotestWrapper: []
references: [
+ "docker/docker.qbs",
"share/share.qbs",
"scripts/scripts.qbs",
]
SubProject {
- filePath: "docker/docker.qbs"
- Properties {
- condition: parent.withDocker
- }
- }
-
- SubProject {
filePath: "doc/doc.qbs"
Properties {
condition: parent.withDocumentation
diff --git a/scripts/build-qbs-with-qbs.sh b/scripts/build-qbs-with-qbs.sh
index a116bc7b9..856cf71b6 100755
--- a/scripts/build-qbs-with-qbs.sh
+++ b/scripts/build-qbs-with-qbs.sh
@@ -54,6 +54,8 @@ BUILD_OPTIONS="\
modules.qbsbuildconfig.enableProjectFileUpdates:true \
modules.qbsbuildconfig.enableUnitTests:true \
modules.cpp.treatWarningsAsErrors:true \
+ modules.cpp.separateDebugInformation:true \
+ modules.qbs.debugInformation:true \
project.withExamples:true \
${BUILD_OPTIONS} \
config:release \
diff --git a/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs b/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs
index 02caad501..9081f5efb 100644
--- a/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs
+++ b/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs
@@ -3,6 +3,7 @@ import qbs.FileInfo
import "path-probe.js" as PathProbeConfigure
BinaryProbe {
+ nameSuffixes: undefined // _compilerName already contains ".exe" suffix on Windows
// Inputs
property string _compilerName
property string _toolchainPrefix
diff --git a/share/qbs/imports/qbs/Probes/LibraryProbe.qbs b/share/qbs/imports/qbs/Probes/LibraryProbe.qbs
index 26787d1b4..dfa9890a9 100644
--- a/share/qbs/imports/qbs/Probes/LibraryProbe.qbs
+++ b/share/qbs/imports/qbs/Probes/LibraryProbe.qbs
@@ -29,6 +29,7 @@
****************************************************************************/
PathProbe {
+ property string endianness
nameSuffixes: {
if (qbs.targetOS.contains("windows"))
return [".lib"];
@@ -36,10 +37,34 @@ PathProbe {
return [".dylib", ".a"];
return [".so", ".a"];
}
- platformSearchPaths: qbs.targetOS.contains("unix") ? [
- "/usr/lib",
- "/usr/local/lib",
- ] : []
+ platformSearchPaths: {
+ var result = [];
+ if (qbs.targetOS.contains("unix")) {
+ if (qbs.targetOS.contains("linux") && qbs.architecture) {
+ if (qbs.architecture === "armv7")
+ result = ["/usr/lib/arm-linux-gnueabihf"]
+ else if (qbs.architecture === "arm64")
+ result = ["/usr/lib/aarch64-linux-gnu"]
+ else if (qbs.architecture === "mips" && endianness === "big")
+ result = ["/usr/lib/mips-linux-gnu"]
+ else if (qbs.architecture === "mips" && endianness === "little")
+ result = ["/usr/lib/mipsel-linux-gnu"]
+ else if (qbs.architecture === "mips64")
+ result = ["/usr/lib/mips64el-linux-gnuabi64"]
+ else if (qbs.architecture === "ppc")
+ result = ["/usr/lib/powerpc-linux-gnu"]
+ else if (qbs.architecture === "ppc64")
+ result = ["/usr/lib/powerpc64le-linux-gnu"]
+ else if (qbs.architecture === "x86_64")
+ result = ["/usr/lib64", "/usr/lib/x86_64-linux-gnu"]
+ else if (qbs.architecture === "x86")
+ result = ["/usr/lib32", "/usr/lib/i386-linux-gnu"]
+ }
+ result = result.concat(["/usr/lib", "/usr/local/lib"]);
+ }
+
+ return result;
+ }
nameFilter: {
if (qbs.targetOS.contains("unix")) {
return function(name) {
diff --git a/share/qbs/imports/qbs/base/Application.qbs b/share/qbs/imports/qbs/base/Application.qbs
index 694cfb83b..63ffc6283 100644
--- a/share/qbs/imports/qbs/base/Application.qbs
+++ b/share/qbs/imports/qbs/base/Application.qbs
@@ -66,4 +66,12 @@ NativeBinary {
qbs.installDir: installDir
qbs.installSourceBase: isBundle ? destinationDirectory : outer
}
+
+ Group {
+ condition: installDebugInformation
+ fileTagsFilter: ["debuginfo_app"]
+ qbs.install: true
+ qbs.installDir: debugInformationInstallDir
+ qbs.installSourceBase: destinationDirectory
+ }
}
diff --git a/share/qbs/imports/qbs/base/DynamicLibrary.qbs b/share/qbs/imports/qbs/base/DynamicLibrary.qbs
index 267519a42..818665e38 100644
--- a/share/qbs/imports/qbs/base/DynamicLibrary.qbs
+++ b/share/qbs/imports/qbs/base/DynamicLibrary.qbs
@@ -30,24 +30,4 @@
Library {
type: ["dynamiclibrary"].concat(isForAndroid ? ["android.nativelibrary"] : [])
-
- installDir: isBundle ? "Library/Frameworks" : qbs.targetOS.contains("windows")
- ? "bin" : "lib"
- property bool installImportLib: false
- property string importLibInstallDir: "lib"
-
- Group {
- condition: install
- fileTagsFilter: isBundle ? "bundle.content" : ["dynamiclibrary", "dynamiclibrary_symlink"]
- qbs.install: true
- qbs.installDir: installDir
- qbs.installSourceBase: isBundle ? destinationDirectory : outer
- }
-
- Group {
- condition: installImportLib
- fileTagsFilter: "dynamiclibrary_import"
- qbs.install: true
- qbs.installDir: importLibInstallDir
- }
}
diff --git a/share/qbs/imports/qbs/base/Library.qbs b/share/qbs/imports/qbs/base/Library.qbs
index 615c2319f..62e5f9d30 100644
--- a/share/qbs/imports/qbs/base/Library.qbs
+++ b/share/qbs/imports/qbs/base/Library.qbs
@@ -34,4 +34,57 @@ NativeBinary {
return ["staticlibrary"];
return ["dynamiclibrary"].concat(isForAndroid ? ["android.nativelibrary"] : []);
}
+
+ readonly property bool isDynamicLibrary: type.contains("dynamiclibrary")
+ readonly property bool isStaticLibrary: type.contains("staticlibrary")
+ readonly property bool isLoadableModule: type.contains("loadablemodule")
+
+ installDir: {
+ if (isBundle)
+ return "Library/Frameworks";
+ if (isDynamicLibrary)
+ return qbs.targetOS.contains("windows") ? "bin" : "lib";
+ if (isStaticLibrary)
+ return "lib";
+ }
+
+ property bool installImportLib: false
+ property string importLibInstallDir: "lib"
+
+ Group {
+ condition: install
+ fileTagsFilter: {
+ if (isBundle)
+ return ["bundle.content"];
+ if (isDynamicLibrary)
+ return ["dynamiclibrary", "dynamiclibrary_symlink"];
+ if (isStaticLibrary)
+ return ["staticlibrary"];
+ return [];
+ }
+ qbs.install: true
+ qbs.installDir: installDir
+ qbs.installSourceBase: isBundle ? destinationDirectory : outer
+ }
+
+ Group {
+ condition: installImportLib && type.contains("dynamiclibrary")
+ fileTagsFilter: "dynamiclibrary_import"
+ qbs.install: true
+ qbs.installDir: importLibInstallDir
+ }
+
+ Group {
+ condition: installDebugInformation
+ fileTagsFilter: {
+ if (isDynamicLibrary)
+ return ["debuginfo_dll"];
+ else if (isLoadableModule)
+ return ["debuginfo_loadablemodule"];
+ return [];
+ }
+ qbs.install: true
+ qbs.installDir: debugInformationInstallDir
+ qbs.installSourceBase: destinationDirectory
+ }
}
diff --git a/share/qbs/imports/qbs/base/NativeBinary.qbs b/share/qbs/imports/qbs/base/NativeBinary.qbs
index 3597f348f..0928e96bb 100644
--- a/share/qbs/imports/qbs/base/NativeBinary.qbs
+++ b/share/qbs/imports/qbs/base/NativeBinary.qbs
@@ -36,6 +36,9 @@ Product {
property bool install: false
property string installDir
+ property bool installDebugInformation: false
+ property string debugInformationInstallDir: installDir
+
Depends { name: "bundle"; condition: isForDarwin }
aggregate: {
diff --git a/share/qbs/imports/qbs/base/StaticLibrary.qbs b/share/qbs/imports/qbs/base/StaticLibrary.qbs
index 4eea3c991..5a78a83b0 100644
--- a/share/qbs/imports/qbs/base/StaticLibrary.qbs
+++ b/share/qbs/imports/qbs/base/StaticLibrary.qbs
@@ -30,13 +30,4 @@
Library {
type: ["staticlibrary"]
-
- installDir: isBundle ? "Library/Frameworks" : "lib"
- Group {
- condition: install
- fileTagsFilter: isBundle ? "bundle.content" : "staticlibrary";
- qbs.install: true
- qbs.installDir: installDir
- qbs.installSourceBase: isBundle ? destinationDirectory : outer
- }
}
diff --git a/share/qbs/module-providers/Qt/templates/qml.qbs b/share/qbs/module-providers/Qt/templates/qml.qbs
index f6d3fbb1f..c63937649 100644
--- a/share/qbs/module-providers/Qt/templates/qml.qbs
+++ b/share/qbs/module-providers/Qt/templates/qml.qbs
@@ -66,7 +66,7 @@ QtModule {
readonly property stringList _importVersionParts: (importVersion || "").split(".")
property string typesFileName: {
if (product.type && product.type.contains("application"))
- return "app.qmltypes";
+ return product.targetName + ".qmltypes";
return "plugins.qmltypes";
}
property string typesInstallDir
diff --git a/share/qbs/modules/bundle/BundleModule.qbs b/share/qbs/modules/bundle/BundleModule.qbs
index 0b3ceb4a6..f285c6e61 100644
--- a/share/qbs/modules/bundle/BundleModule.qbs
+++ b/share/qbs/modules/bundle/BundleModule.qbs
@@ -613,7 +613,8 @@ Module {
for (var i = 0; i < artifacts.length; ++i)
artifacts[i].bundle = { wrapperPath: wrapperPath };
- if (product.qbs.hostOS.contains("darwin") && product.xcode.signingIdentity) {
+ if (product.qbs.hostOS.contains("darwin") && product.xcode
+ && product.xcode.signingIdentity) {
artifacts.push({
filePath: FileInfo.joinPaths(product.bundle.contentsFolderPath, "_CodeSignature/CodeResources"),
fileTags: ["bundle.code-signature", "bundle.content"]
diff --git a/share/qbs/modules/cpp/sdcc.js b/share/qbs/modules/cpp/sdcc.js
index 70d0506b9..147fa160f 100644
--- a/share/qbs/modules/cpp/sdcc.js
+++ b/share/qbs/modules/cpp/sdcc.js
@@ -90,10 +90,24 @@ function guessEndianness(macros) {
}
function guessVersion(macros) {
- return { major: parseInt(macros["__SDCC_VERSION_MAJOR"], 10),
- minor: parseInt(macros["__SDCC_VERSION_MINOR"], 10),
- patch: parseInt(macros["__SDCC_VERSION_PATCH"], 10),
- found: macros["SDCC"] }
+ if ("__SDCC_VERSION_MAJOR" in macros
+ && "__SDCC_VERSION_MINOR" in macros
+ && "__SDCC_VERSION_PATCH" in macros) {
+ return { major: parseInt(macros["__SDCC_VERSION_MAJOR"], 10),
+ minor: parseInt(macros["__SDCC_VERSION_MINOR"], 10),
+ patch: parseInt(macros["__SDCC_VERSION_PATCH"], 10),
+ found: macros["SDCC"] }
+ } else if ("__SDCC" in macros) {
+ var versions = macros["__SDCC"].split("_");
+ if (versions.length === 3) {
+ return {
+ major: parseInt(versions[0], 10),
+ minor: parseInt(versions[1], 10),
+ patch: parseInt(versions[2], 10),
+ found: macros["SDCC"] };
+ }
+ }
+ return { found: false };
}
function dumpMacros(compilerFilePath, architecture) {
diff --git a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
index 0c511f2aa..4d5228813 100644
--- a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
+++ b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
@@ -42,7 +42,7 @@ ProtobufBase {
cpp.includePaths: {
var result = [outputDir, includePath];
if (useGrpc)
- result.push("grpcIncludePath");
+ result.push(grpcIncludePath);
return result;
}
diff --git a/share/qbs/modules/xcode/xcode.js b/share/qbs/modules/xcode/xcode.js
index bda41ade9..d20d9cf0c 100644
--- a/share/qbs/modules/xcode/xcode.js
+++ b/share/qbs/modules/xcode/xcode.js
@@ -114,7 +114,7 @@ function sdkInfoList(sdksPath) {
if (!plist || !plist["CanonicalName"] || !plist["Version"])
return false;
- var re = /^([0-9]+)\.([0-9]+)$/;
+ var re = /^[0-9]+\.[0-9]+(\.[0-9]+)?$/;
return plist["Version"].match(re);
}
@@ -132,19 +132,7 @@ function sdkInfoList(sdksPath) {
}
// Sort by SDK version number
- sdkInfo.sort(function (a, b) {
- var re = /^([0-9]+)\.([0-9]+)$/;
- a = a["Version"].match(re);
- if (a)
- a = {major: a[1], minor: a[2]};
- b = b["Version"].match(re);
- if (b)
- b = {major: b[1], minor: b[2]};
-
- if (a.major === b.major)
- return a.minor - b.minor;
- return a.major - b.major;
- });
+ sdkInfo.sort(function (a, b) { return Utilities.versionCompare(a["Version"], b["Version"]); });
return sdkInfo;
}
diff --git a/share/qbs/modules/xcode/xcode.qbs b/share/qbs/modules/xcode/xcode.qbs
index 648948192..7bbb29c6e 100644
--- a/share/qbs/modules/xcode/xcode.qbs
+++ b/share/qbs/modules/xcode/xcode.qbs
@@ -49,6 +49,12 @@ Module {
return _sdkSettings["Version"];
}
}
+ readonly property string shortSdkVersion: {
+ var v = sdkVersion;
+ if (v && v.split('.').length > 2)
+ v = v.slice(0, v.lastIndexOf('.'));
+ return v;
+ }
readonly property string latestSdkName: {
if (_latestSdk) {
@@ -117,8 +123,8 @@ Module {
+ ".platform")
readonly property path sdkPath: FileInfo.joinPaths(sdksPath,
DarwinTools.applePlatformDirectoryName(
- qbs.targetOS, platformType, sdkVersion)
- + ".sdk")
+ qbs.targetOS, platformType,
+ shortSdkVersion) + ".sdk")
// private properties
readonly property path toolchainsPath: FileInfo.joinPaths(developerPath, "Toolchains")
@@ -206,14 +212,14 @@ Module {
validator.setRequiredProperty("platformPath", platformPath);
validator.setRequiredProperty("sdksPath", sdkPath);
validator.setRequiredProperty("sdkPath", sdkPath);
- validator.addVersionValidator("sdkVersion", sdkVersion, 2, 2);
+ validator.addVersionValidator("sdkVersion", sdkVersion, 2, 3);
validator.addCustomValidator("sdkName", sdkName, function (value) {
return value === DarwinTools.applePlatformDirectoryName(
- qbs.targetOS, platformType, sdkVersion, false).toLowerCase();
+ qbs.targetOS, platformType, shortSdkVersion, false).toLowerCase();
}, "is '" + sdkName + "', but target OS is [" + qbs.targetOS.join(",")
+ "] and Xcode SDK version is '" + sdkVersion + "'");
validator.addCustomValidator("sdk", sdk, function (value) {
- return value === sdkName || (value + sdkVersion) === sdkName;
+ return value === sdkName || (value + shortSdkVersion) === sdkName;
}, "is '" + sdk + "', but canonical SDK name is '" + sdkName + "'");
validator.validate();
}
diff --git a/src/app/qbs-setup-toolchains/gccprobe.cpp b/src/app/qbs-setup-toolchains/gccprobe.cpp
index df3f92f62..6cbe246a5 100644
--- a/src/app/qbs-setup-toolchains/gccprobe.cpp
+++ b/src/app/qbs-setup-toolchains/gccprobe.cpp
@@ -111,7 +111,7 @@ class ToolchainDetails
public:
explicit ToolchainDetails(const QFileInfo &compiler)
{
- auto baseName = compiler.completeBaseName();
+ auto baseName = HostOsInfo::stripExecutableSuffix(compiler.fileName());
// Extract the version sub-string if it exists. We assume that a version
// sub-string located after the compiler prefix && suffix. E.g. this code
// parses a version from the compiler names, like this:
diff --git a/src/app/qbs-setup-toolchains/sdccprobe.cpp b/src/app/qbs-setup-toolchains/sdccprobe.cpp
index 3eb37cfd3..977d834c4 100644
--- a/src/app/qbs-setup-toolchains/sdccprobe.cpp
+++ b/src/app/qbs-setup-toolchains/sdccprobe.cpp
@@ -151,6 +151,21 @@ static std::vector<Profile> createSdccProfileHelper(
return profiles;
}
+static Version dumpOldSddcCompilerVersion(const QByteArray &macroDump)
+{
+ const auto keyToken = QByteArrayLiteral("__SDCC ");
+ const int startIndex = macroDump.indexOf(keyToken);
+ if (startIndex == -1)
+ return Version{};
+ const int endIndex = macroDump.indexOf('\n', startIndex);
+ if (endIndex == -1)
+ return Version{};
+ const auto keyLength = keyToken.length();
+ return Version::fromString(QString::fromLatin1(
+ macroDump.mid(startIndex + keyLength,
+ endIndex - startIndex - keyLength).replace('_', '.')));
+}
+
static Version dumpSdccCompilerVersion(const QFileInfo &compiler)
{
const QByteArray dump = dumpSdccMacros(compiler);
@@ -161,10 +176,14 @@ static Version dumpSdccCompilerVersion(const QFileInfo &compiler)
const int minor = extractVersion(dump, "__SDCC_VERSION_MINOR ");
const int patch = extractVersion(dump, "__SDCC_VERSION_PATCH ");
if (major < 0 || minor < 0 || patch < 0) {
- qbsWarning() << Tr::tr("No '__SDCC_VERSION_xxx' token was found "
- "in the compiler dump:\n%1")
- .arg(QString::fromUtf8(dump));
- return Version{};
+ const auto version = dumpOldSddcCompilerVersion(dump);
+ if (!version.isValid()) {
+ qbsWarning() << Tr::tr("No '__SDCC_VERSION_xxx' or '__SDCC' token was found "
+ "in the compiler dump:\n%1")
+ .arg(QString::fromUtf8(dump));
+ return Version{};
+ }
+ return version;
}
return Version{major, minor, patch};
diff --git a/src/app/qbs/stdinreader.cpp b/src/app/qbs/stdinreader.cpp
index b90abf9d1..5f00d7de4 100644
--- a/src/app/qbs/stdinreader.cpp
+++ b/src/app/qbs/stdinreader.cpp
@@ -43,13 +43,13 @@
#include <QtCore/qfile.h>
#include <QtCore/qsocketnotifier.h>
+#include <QtCore/qtimer.h>
#include <cerrno>
#include <cstring>
#ifdef Q_OS_WIN32
#include <qt_windows.h>
-#include <QtCore/qtimer.h>
#else
#include <fcntl.h>
#endif
@@ -87,6 +87,18 @@ private:
connect(&m_notifier, &QSocketNotifier::activated, this, [this] {
emit dataAvailable(m_stdIn.readAll());
});
+
+ // Neither the aboutToClose() nor the readChannelFinished() signals
+ // are triggering, so we need a timer to check whether the controlling
+ // process disappeared.
+ const auto stdinClosedChecker = new QTimer(this);
+ connect(stdinClosedChecker, &QTimer::timeout, this, [this, stdinClosedChecker] {
+ if (m_stdIn.atEnd()) {
+ stdinClosedChecker->stop();
+ emit errorOccurred(tr("Input channel closed unexpectedly."));
+ }
+ });
+ stdinClosedChecker->start(1000);
}
QFile m_stdIn;
@@ -112,14 +124,22 @@ private:
// (how would we abort that one?), but ideally we'd like
// to have a signal-based approach like in the Unix variant.
const auto timer = new QTimer(this);
- connect(timer, &QTimer::timeout, this, [this] {
+ connect(timer, &QTimer::timeout, this, [this, timer] {
char buf[1024];
DWORD bytesAvail;
- PeekNamedPipe(m_stdinHandle, nullptr, 0, nullptr, &bytesAvail, nullptr);
+ if (!PeekNamedPipe(m_stdinHandle, nullptr, 0, nullptr, &bytesAvail, nullptr)) {
+ timer->stop();
+ emit errorOccurred(tr("Failed to read from input channel."));
+ return;
+ }
while (bytesAvail > 0) {
DWORD bytesRead;
- ReadFile(m_stdinHandle, buf, std::min<DWORD>(bytesAvail, sizeof buf), &bytesRead,
- nullptr);
+ if (!ReadFile(m_stdinHandle, buf, std::min<DWORD>(bytesAvail, sizeof buf),
+ &bytesRead, nullptr)) {
+ timer->stop();
+ emit errorOccurred(tr("Failed to read from input channel."));
+ return;
+ }
emit dataAvailable(QByteArray(buf, bytesRead));
bytesAvail -= bytesRead;
}
diff --git a/src/lib/corelib/language/artifactproperties.cpp b/src/lib/corelib/language/artifactproperties.cpp
index e5b11f4d7..011e58d88 100644
--- a/src/lib/corelib/language/artifactproperties.cpp
+++ b/src/lib/corelib/language/artifactproperties.cpp
@@ -64,6 +64,7 @@ bool operator==(const ArtifactProperties &ap1, const ArtifactProperties &ap2)
{
return ap1.fileTagsFilter() == ap2.fileTagsFilter()
&& ap1.extraFileTags() == ap2.extraFileTags()
+ && !ap1.propertyMap() == !ap2.propertyMap()
&& *ap1.propertyMap() == *ap2.propertyMap();
}
diff --git a/src/lib/corelib/language/language.cpp b/src/lib/corelib/language/language.cpp
index 7eec99947..3b3e7401e 100644
--- a/src/lib/corelib/language/language.cpp
+++ b/src/lib/corelib/language/language.cpp
@@ -857,6 +857,7 @@ bool operator==(const SourceArtifactInternal &sa1, const SourceArtifactInternal
&& sa1.fileTags == sa2.fileTags
&& sa1.overrideFileTags == sa2.overrideFileTags
&& sa1.targetOfModule == sa2.targetOfModule
+ && !sa1.properties == !sa2.properties
&& *sa1.properties == *sa2.properties;
}
diff --git a/src/lib/corelib/language/modulemerger.cpp b/src/lib/corelib/language/modulemerger.cpp
index 5a5bd3ac0..c5deaae04 100644
--- a/src/lib/corelib/language/modulemerger.cpp
+++ b/src/lib/corelib/language/modulemerger.cpp
@@ -173,7 +173,9 @@ void ModuleMerger::mergeModule(Item::PropertyMap *dstProps, const Item::Module &
if (dstVal) {
if (srcDecl.isScalar()) {
// Scalar properties get replaced.
- if (dstVal->type() == Value::JSSourceValueType) {
+ if ((dstVal->type() == Value::JSSourceValueType)
+ && (srcVal->type() == Value::JSSourceValueType)) {
+ // Warn only about conflicting source code values
const JSSourceValuePtr dstJsVal =
std::static_pointer_cast<JSSourceValue>(dstVal);
const JSSourceValuePtr srcJsVal =
diff --git a/src/lib/corelib/tools/hostosinfo.h b/src/lib/corelib/tools/hostosinfo.h
index 42ce3f8cf..0876d39ec 100644
--- a/src/lib/corelib/tools/hostosinfo.h
+++ b/src/lib/corelib/tools/hostosinfo.h
@@ -112,6 +112,13 @@ public:
return finalName;
}
+ static QString stripExecutableSuffix(const QString &executable)
+ {
+ constexpr QLatin1String suffix(QBS_HOST_EXE_SUFFIX, sizeof(QBS_HOST_EXE_SUFFIX) - 1);
+ return !suffix.isEmpty() && executable.endsWith(suffix)
+ ? executable.chopped(suffix.size()) : executable;
+ }
+
static QString dynamicLibraryName(const QString &libraryBaseName)
{
return QLatin1String(QBS_HOST_DYNAMICLIB_PREFIX) + libraryBaseName
diff --git a/src/lib/corelib/tools/id.cpp b/src/lib/corelib/tools/id.cpp
index 6dd1147f2..33cfd60f7 100644
--- a/src/lib/corelib/tools/id.cpp
+++ b/src/lib/corelib/tools/id.cpp
@@ -269,9 +269,9 @@ Id Id::withPrefix(const char *prefix) const
bool Id::operator==(const char *name) const
{
- const char *string = getStringFromId(m_id);
- if (string && name)
- return strcmp(string, name) == 0;
+ const auto string = getStringFromId(m_id);
+ if (!string.isNull() && name)
+ return strcmp(string.data(), name) == 0;
else
return false;
}
diff --git a/src/lib/corelib/tools/jsonhelper.h b/src/lib/corelib/tools/jsonhelper.h
index d87802c0a..991d6bd6c 100644
--- a/src/lib/corelib/tools/jsonhelper.h
+++ b/src/lib/corelib/tools/jsonhelper.h
@@ -78,9 +78,9 @@ template<> inline QProcessEnvironment fromJson(const QJsonValue &v)
template<typename T> inline void setValueFromJson(T &targetValue, const QJsonObject &data,
const char *jsonProperty)
{
- const QJsonValue v = data.value(QLatin1String(jsonProperty));
- if (!v.isNull())
- targetValue = fromJson<T>(v);
+ const auto it = data.find(QLatin1String(jsonProperty));
+ if (it != data.end())
+ targetValue = fromJson<T>(*it);
}
} // namespace Internal
diff --git a/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs b/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs
index fbab6d0b1..fa4c67b96 100644
--- a/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs
+++ b/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs
@@ -43,8 +43,11 @@ Project {
}
for (var i = 0; i < a.length; ++i) {
- if (a[i] !== b[i]) {
- throw msg;
+ var version1 = a[i].split('.');
+ var version2 = b[i].split('.');
+ for (var j = 0; j < version1.length; ++j) {
+ if (version1[j] !== version2[j])
+ throw msg;
}
}
}
diff --git a/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs b/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs
index 991e4ddcb..208305c1f 100644
--- a/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs
+++ b/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs
@@ -33,18 +33,22 @@ Project {
prepare: {
var cmd = new Command(input.filePath);
cmd.description = "running " + input.filePath;
- var pathVar;
- var pathValue;
+
+ var envVars = {};
if (product.qbs.hostOS.contains("windows")) {
- pathVar = "PATH";
- pathValue = FileInfo.toWindowsSeparators(input["Qt.core"].binPath);
+ envVars["PATH"] = FileInfo.toWindowsSeparators(input["Qt.core"].binPath);
+ } else if (product.qbs.hostOS.contains("macos")) {
+ envVars["DYLD_LIBRARY_PATH"] = input["Qt.core"].libPath;
+ envVars["DYLD_FRAMEWORK_PATH"] = input["Qt.core"].libPath;
} else {
- pathVar = "LD_LIBRARY_PATH";
- pathValue = input["Qt.core"].libPath;
+ envVars["LD_LIBRARY_PATH"] = input["Qt.core"].libPath;
+ }
+ for (var varName in envVars) {
+ var oldValue = Environment.getEnv(varName) || "";
+ var newValue = envVars[varName] + product.qbs.pathListSeparator + oldValue;
+ cmd.environment.push(varName + '=' + newValue);
}
- var oldValue = Environment.getEnv(pathVar) || "";
- var newValue = pathValue + product.qbs.pathListSeparator + oldValue;
- cmd.environment = [pathVar + '=' + newValue];
+
return [cmd];
}
}
diff --git a/tests/auto/blackbox/testdata/install-locations/install-locations.qbs b/tests/auto/blackbox/testdata/install-locations/install-locations.qbs
index 8a97f74a1..4ad37c498 100644
--- a/tests/auto/blackbox/testdata/install-locations/install-locations.qbs
+++ b/tests/auto/blackbox/testdata/install-locations/install-locations.qbs
@@ -10,7 +10,9 @@ Project {
CppApplication {
name: "theapp"
install: true
+ installDebugInformation: true
files: "main.cpp"
+ cpp.separateDebugInformation: true
Group {
fileTagsFilter: "application"
fileTags: "some-tag"
@@ -20,7 +22,17 @@ Project {
name: "thelib"
install: true
installImportLib: true
+ installDebugInformation: true
Depends { name: "cpp" }
+ cpp.separateDebugInformation: true
files: "thelib.cpp"
}
+ LoadableModule {
+ name: "theplugin"
+ install: true
+ installDebugInformation: true
+ Depends { name: "cpp" }
+ cpp.separateDebugInformation: true
+ files: "theplugin.cpp"
+ }
}
diff --git a/tests/auto/blackbox/testdata/install-locations/theplugin.cpp b/tests/auto/blackbox/testdata/install-locations/theplugin.cpp
new file mode 100644
index 000000000..ac1ede090
--- /dev/null
+++ b/tests/auto/blackbox/testdata/install-locations/theplugin.cpp
@@ -0,0 +1,3 @@
+#include "../dllexport.h"
+
+DLL_EXPORT void pluginFunc() {}
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index ecb8bd1e9..2eaf3e3be 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -3546,26 +3546,30 @@ void TestBlackbox::emptyProfile()
const SettingsPtr s = settings();
const Profile buildProfile(profileName(), s.get());
bool isMsvc = false;
- const auto toolchainType = buildProfile.value(QStringLiteral("qbs.toolchainType")).toString();
+ auto toolchainType = buildProfile.value(QStringLiteral("qbs.toolchainType")).toString();
QbsRunParameters params;
params.profile = "none";
+
+ if (toolchainType.isEmpty()) {
+ const auto toolchain = buildProfile.value(QStringLiteral("qbs.toolchain")).toStringList();
+ if (!toolchain.isEmpty())
+ toolchainType = toolchain.first();
+ }
if (!toolchainType.isEmpty()) {
params.arguments = QStringList{QStringLiteral("qbs.toolchainType:") + toolchainType};
isMsvc = toolchainType == "msvc" || toolchainType == "clang-cl";
- } else {
- const auto toolchain = buildProfile.value(QStringLiteral("qbs.toolchain")).toStringList();
- if (!toolchain.isEmpty()) {
- params.arguments = QStringList{QStringLiteral("qbs.toolchain:")
- + toolchain.join(QLatin1Char(','))};
- isMsvc = toolchainType.contains("msvc");
- }
}
+
if (!isMsvc) {
- const auto tcPath
- = buildProfile.value(QStringLiteral("cpp.toolchainInstallPath")).toString();
- if (!tcPath.isEmpty() && !qEnvironmentVariable("PATH")
- .split(HostOsInfo::pathListSeparator(), QString::SkipEmptyParts).contains(tcPath)) {
- params.arguments << QStringLiteral("modules.cpp.toolchainInstallPath:") + tcPath;
+ const auto tcPath =
+ QDir::toNativeSeparators(
+ buildProfile.value(QStringLiteral("cpp.toolchainInstallPath")).toString());
+ auto paths = params.environment.value(QStringLiteral("PATH"))
+ .split(HostOsInfo::pathListSeparator(), QString::SkipEmptyParts);
+ if (!tcPath.isEmpty() && !paths.contains(tcPath)) {
+ paths.prepend(tcPath);
+ params.environment.insert(
+ QStringLiteral("PATH"), paths.join(HostOsInfo::pathListSeparator()));
}
}
QCOMPARE(runQbs(params), 0);
@@ -4001,8 +4005,16 @@ void TestBlackbox::installLocations_data()
QTest::addColumn<QString>("binDir");
QTest::addColumn<QString>("dllDir");
QTest::addColumn<QString>("libDir");
- QTest::newRow("explicit values") << QString("bindir") << QString("dlldir") << QString("libdir");
- QTest::newRow("default values") << QString() << QString() << QString();
+ QTest::addColumn<QString>("pluginDir");
+ QTest::addColumn<QString>("dsymDir");
+ QTest::newRow("explicit values")
+ << QString("bindir")
+ << QString("dlldir")
+ << QString("libdir")
+ << QString("pluginDir")
+ << QString("dsymDir");
+ QTest::newRow("default values")
+ << QString() << QString() << QString() << QString() << QString();
}
void TestBlackbox::installLocations()
@@ -4011,6 +4023,8 @@ void TestBlackbox::installLocations()
QFETCH(QString, binDir);
QFETCH(QString, dllDir);
QFETCH(QString, libDir);
+ QFETCH(QString, pluginDir);
+ QFETCH(QString, dsymDir);
QbsRunParameters params("resolve");
if (!binDir.isEmpty())
params.arguments.push_back("products.theapp.installDir:" + binDir);
@@ -4018,35 +4032,88 @@ void TestBlackbox::installLocations()
params.arguments.push_back("products.thelib.installDir:" + dllDir);
if (!libDir.isEmpty())
params.arguments.push_back("products.thelib.importLibInstallDir:" + libDir);
+ if (!pluginDir.isEmpty())
+ params.arguments.push_back("products.theplugin.installDir:" + pluginDir);
+ if (!dsymDir.isEmpty()) {
+ params.arguments.push_back("products.theapp.debugInformationInstallDir:" + dsymDir);
+ params.arguments.push_back("products.thelib.debugInformationInstallDir:" + dsymDir);
+ params.arguments.push_back("products.theplugin.debugInformationInstallDir:" + dsymDir);
+ }
QCOMPARE(runQbs(params), 0);
const bool isWindows = m_qbsStdout.contains("is windows");
const bool isMac = m_qbsStdout.contains("is mac");
const bool isUnix = m_qbsStdout.contains("is unix");
QVERIFY(isWindows || isMac || isUnix);
QCOMPARE(runQbs(QbsRunParameters(QStringList("--clean-install-root"))), 0);
- const QString dllFileName = isWindows ? "thelib.dll" : isMac ? "thelib" : "libthelib.so";
- const QString appFileName = isWindows ? "theapp.exe" : "theapp";
- if (binDir.isEmpty())
- binDir = isMac ? "/Applications" : "/bin";
- if (dllDir.isEmpty())
- dllDir = isMac ? "/Library/Frameworks" : isWindows ? "/bin" : "/lib";
- if (libDir.isEmpty())
- libDir = "/lib";
- if (isMac) {
- binDir += "/theapp.app/Contents/MacOS";
- dllDir += "/thelib.framework";
- }
+
+ struct BinaryInfo
+ {
+ QString fileName;
+ QString installDir;
+ QString subDir;
+
+ QString absolutePath(const QString &prefix) const
+ {
+ return QDir::cleanPath(prefix + '/' + installDir + '/' + subDir + '/' + fileName);
+ }
+ };
+
+ const BinaryInfo dll = {
+ isWindows ? "thelib.dll" : isMac ? "thelib" : "libthelib.so",
+ dllDir.isEmpty() ? (isMac ? "/Library/Frameworks" : isWindows ? "/bin" : "/lib") : dllDir,
+ isMac ? "thelib.framework" : ""
+ };
+ const BinaryInfo dllDsym = {
+ isWindows ? "thelib.pdb" : isMac ? "thelib.framework.dSYM" : "libthelib.so.debug",
+ dsymDir.isEmpty() ? dll.installDir : dsymDir,
+ {}
+ };
+ const BinaryInfo plugin = {
+ isWindows ? "theplugin.dll" : isMac ? "theplugin" : "libtheplugin.so",
+ pluginDir.isEmpty() ? dll.installDir : pluginDir,
+ isMac ? "theplugin.bundle/Contents/MacOS" : ""
+ };
+ const BinaryInfo pluginDsym = {
+ isWindows ? "theplugin.pdb" : isMac ? "theplugin.bundle.dSYM" : "libtheplugin.so.debug",
+ dsymDir.isEmpty() ? plugin.installDir : dsymDir,
+ {}
+ };
+ const BinaryInfo app = {
+ isWindows ? "theapp.exe" : "theapp",
+ binDir.isEmpty() ? (isMac ? "/Applications" : "/bin") : binDir,
+ isMac ? "theapp.app/Contents/MacOS" : ""
+ };
+ const BinaryInfo appDsym = {
+ isWindows ? "theapp.pdb" : isMac ? "theapp.app.dSYM" : "theapp.debug",
+ dsymDir.isEmpty() ? app.installDir : dsymDir,
+ {}
+ };
+
const QString installRoot = QDir::currentPath() + "/default/install-root";
const QString installPrefix = isWindows ? QString() : "/usr/local";
const QString fullInstallPrefix = installRoot + '/' + installPrefix + '/';
- const QString appFilePath = fullInstallPrefix + binDir + '/' + appFileName;
+ const QString appFilePath = app.absolutePath(fullInstallPrefix);
QVERIFY2(QFile::exists(appFilePath), qPrintable(appFilePath));
- const QString dllFilePath = fullInstallPrefix + dllDir + '/' + dllFileName;
+ const QString dllFilePath = dll.absolutePath(fullInstallPrefix);
QVERIFY2(QFile::exists(dllFilePath), qPrintable(dllFilePath));
if (isWindows) {
- const QString libFilePath = fullInstallPrefix + libDir + "/thelib.lib";
+ const BinaryInfo lib = {
+ "thelib.lib",
+ libDir.isEmpty() ? "/lib" : libDir,
+ ""
+ };
+ const QString libFilePath = lib.absolutePath(fullInstallPrefix);
QVERIFY2(QFile::exists(libFilePath), qPrintable(libFilePath));
}
+ const QString pluginFilePath = plugin.absolutePath(fullInstallPrefix);
+ QVERIFY2(QFile::exists(pluginFilePath), qPrintable(pluginFilePath));
+
+ const QString appDsymFilePath = appDsym.absolutePath(fullInstallPrefix);
+ QVERIFY2(QFileInfo(appDsymFilePath).exists(), qPrintable(appDsymFilePath));
+ const QString dllDsymFilePath = dllDsym.absolutePath(fullInstallPrefix);
+ QVERIFY2(QFileInfo(dllDsymFilePath).exists(), qPrintable(dllDsymFilePath));
+ const QString pluginDsymFilePath = pluginDsym.absolutePath(fullInstallPrefix);
+ QVERIFY2(QFile::exists(pluginDsymFilePath), qPrintable(pluginDsymFilePath));
}
void TestBlackbox::inputsFromDependencies()
diff --git a/tests/auto/blackbox/tst_blackboxapple.cpp b/tests/auto/blackbox/tst_blackboxapple.cpp
index ff7afd274..259517323 100644
--- a/tests/auto/blackbox/tst_blackboxapple.cpp
+++ b/tests/auto/blackbox/tst_blackboxapple.cpp
@@ -653,47 +653,47 @@ void TestBlackboxApple::deploymentTarget_data()
}
QTest::newRow("macos x86_64") << "macosx" << macos << "x86_64"
<< "-triple x86_64-apple-macosx10.6"
- << "-macosx_version_min 10.6";
+ << "10.6";
if (xcodeVersion >= qbs::Version(6))
QTest::newRow("macos x86_64h") << "macosx" << macos << "x86_64h"
<< "-triple x86_64h-apple-macosx10.12"
- << "-macosx_version_min 10.12";
+ << "10.12";
QTest::newRow("ios armv7a") << "iphoneos" << ios << "armv7a"
<< "-triple thumbv7-apple-ios6.0"
- << "-iphoneos_version_min 6.0";
+ << "6.0";
QTest::newRow("ios armv7s") << "iphoneos" <<ios << "armv7s"
<< "-triple thumbv7s-apple-ios7.0"
- << "-iphoneos_version_min 7.0";
+ << "7.0";
if (xcodeVersion >= qbs::Version(5))
QTest::newRow("ios arm64") << "iphoneos" <<ios << "arm64"
<< "-triple arm64-apple-ios7.0"
- << "-iphoneos_version_min 7.0";
+ << "7.0";
QTest::newRow("ios-simulator x86") << "iphonesimulator" << ios_sim << "x86"
<< "-triple i386-apple-ios6.0"
- << "-ios_simulator_version_min 6.0";
+ << "6.0";
if (xcodeVersion >= qbs::Version(5))
QTest::newRow("ios-simulator x86_64") << "iphonesimulator" << ios_sim << "x86_64"
<< "-triple x86_64-apple-ios7.0"
- << "-ios_simulator_version_min 7.0";
+ << "7.0";
if (xcodeVersion >= qbs::Version(7)) {
if (xcodeVersion >= qbs::Version(7, 1)) {
QTest::newRow("tvos arm64") << "appletvos" << tvos << "arm64"
<< "-triple arm64-apple-tvos9.0"
- << "-tvos_version_min 9.0";
+ << "9.0";
QTest::newRow("tvos-simulator x86_64") << "appletvsimulator" << tvos_sim << "x86_64"
<< "-triple x86_64-apple-tvos9.0"
- << "-tvos_simulator_version_min 9.0";
+ << "9.0";
}
QTest::newRow("watchos armv7k") << "watchos" << watchos << "armv7k"
<< "-triple thumbv7k-apple-watchos2.0"
- << "-watchos_version_min 2.0";
+ << "2.0";
QTest::newRow("watchos-simulator x86") << "watchsimulator" << watchos_sim << "x86"
<< "-triple i386-apple-watchos2.0"
- << "-watchos_simulator_version_min 2.0";
+ << "2.0";
}
}
diff --git a/tests/auto/blackbox/tst_blackboxqt.cpp b/tests/auto/blackbox/tst_blackboxqt.cpp
index 33d0ba1b8..68e344a9a 100644
--- a/tests/auto/blackbox/tst_blackboxqt.cpp
+++ b/tests/auto/blackbox/tst_blackboxqt.cpp
@@ -412,9 +412,9 @@ void TestBlackboxQt::qmlTypeRegistrar()
QCOMPARE(m_qbsStdout.contains("running qmltyperegistrar"), enabled);
QCOMPARE(m_qbsStdout.contains("compiling myapp_qmltyperegistrations.cpp"), enabled);
const QString buildDir = relativeProductBuildDir("myapp");
- QCOMPARE(regularFileExists(buildDir + "/app.qmltypes"), enabled);
+ QCOMPARE(regularFileExists(buildDir + "/myapp.qmltypes"), enabled);
QCOMPARE(regularFileExists(relativeBuildDir() + "/install-root/" + installDir
- + "/app.qmltypes"), enabled && !installDir.isEmpty());
+ + "/myapp.qmltypes"), enabled && !installDir.isEmpty());
}
void TestBlackboxQt::qtKeywords()