diff options
307 files changed, 7765 insertions, 1963 deletions
diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 000000000..7af193cc6 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,208 @@ +--- +Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,bugprone-*,clang-analyzer-*,cppcoreguidelines-c-copy-assignment-signature,cppcoreguidelines-interfaces-global-init,cppcoreguidelines-no-malloc,cppcoreguidelines-pro-bounds-constant-array-index,cppcoreguidelines-pro-bounds-pointer-arithmetic,cppcoreguidelines-pro-type-const-cast,cppcoreguidelines-pro-type-cstyle-cast,cppcoreguidelines-pro-type-member-init,cppcoreguidelines-pro-type-union-access,cppcoreguidelines-slicing,cppcoreguidelines-special-member-functions,fuchsia-virtual-inheritance,google-build-explicit-make-pair,google-build-namespaces,google-global-names-in-headers,google-objc-*,google-readability-casting,google-readability-function-size,google-readability-namespace-comments,google-readability-todo,google-runtime-int,google-runtime-operator,misc-definitions-in-headers,misc-misplaced-const,misc-new-delete-overloads,misc-non-copyable-objects,misc-redundant-expression,misc-static-assert,misc-unconventional-assign-operator,misc-uniqueptr-reset-release,misc-unused-*,modernize-avoid-bind,modernize-deprecated-headers,modernize-loop-convert,modernize-make-*,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-*,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-emplace,modernize-use-equals-*,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-using,performance-*,readability-avoid-const-params-in-decls,readability-container-size-empty,readability-delete-null-pointer,readability-deleted-default,readability-function-size,readability-identifier-naming,readability-inconsistent-declaration-parameter-name,readability-misleading-indentation,readability-misplaced-array-index,readability-non-const-parameter,readability-redundant-*,readability-simplify-boolean-expr,readability-static-definition-in-anonymous-namespace,readability-uniqueptr-delete-release' +WarningsAsErrors: '' +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +CheckOptions: + - key: bugprone-argument-comment.StrictMode + value: '0' + - key: bugprone-assert-side-effect.AssertMacros + value: assert + - key: bugprone-assert-side-effect.CheckFunctionCalls + value: '0' + - key: bugprone-dangling-handle.HandleClasses + value: 'std::basic_string_view;std::experimental::basic_string_view' + - key: bugprone-exception-escape.FunctionsThatShouldNotThrow + value: '' + - key: bugprone-exception-escape.IgnoredExceptions + value: '' + - key: bugprone-misplaced-widening-cast.CheckImplicitCasts + value: '0' + - key: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant + value: '1' + - key: bugprone-sizeof-expression.WarnOnSizeOfConstant + value: '1' + - key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression + value: '0' + - key: bugprone-sizeof-expression.WarnOnSizeOfThis + value: '1' + - key: bugprone-string-constructor.LargeLengthThreshold + value: '8388608' + - key: bugprone-string-constructor.WarnOnLargeLength + value: '1' + - key: bugprone-suspicious-enum-usage.StrictMode + value: '0' + - key: bugprone-suspicious-missing-comma.MaxConcatenatedTokens + value: '5' + - key: bugprone-suspicious-missing-comma.RatioThreshold + value: '0.200000' + - key: bugprone-suspicious-missing-comma.SizeThreshold + value: '5' + - key: bugprone-suspicious-string-compare.StringCompareLikeFunctions + value: '' + - key: bugprone-suspicious-string-compare.WarnOnImplicitComparison + value: '1' + - key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison + value: '0' + - key: bugprone-unused-return-value.CheckedFunctions + value: '::std::async;::std::launder;::std::remove;::std::remove_if;::std::unique;::std::unique_ptr::release;::std::basic_string::empty;::std::vector::empty' + - key: cert-dcl16-c.NewSuffixes + value: 'L;LL;LU;LLU' + - key: cppcoreguidelines-no-malloc.Allocations + value: '::malloc;::calloc' + - key: cppcoreguidelines-no-malloc.Deallocations + value: '::free' + - key: cppcoreguidelines-no-malloc.Reallocations + value: '::realloc' + - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic + value: '1' + - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader + value: '' + - key: cppcoreguidelines-pro-bounds-constant-array-index.IncludeStyle + value: '0' + - key: cppcoreguidelines-pro-type-member-init.IgnoreArrays + value: '0' + - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions + value: '0' + - key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor + value: '0' + - key: google-build-namespaces.HeaderFileExtensions + value: ',h,hh,hpp,hxx' + - key: google-global-names-in-headers.HeaderFileExtensions + value: ',h,hh,hpp,hxx' + - key: google-readability-braces-around-statements.ShortStatementLines + value: '1' + - key: google-readability-function-size.BranchThreshold + value: '4294967295' + - key: google-readability-function-size.LineThreshold + value: '4294967295' + - key: google-readability-function-size.NestingThreshold + value: '4294967295' + - key: google-readability-function-size.ParameterThreshold + value: '4294967295' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: google-readability-function-size.VariableThreshold + value: '4294967295' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' + - key: google-runtime-int.SignedTypePrefix + value: int + - key: google-runtime-int.TypeSuffix + value: '' + - key: google-runtime-int.UnsignedTypePrefix + value: uint + - key: misc-definitions-in-headers.HeaderFileExtensions + value: ',h,hh,hpp,hxx' + - key: misc-definitions-in-headers.UseHeaderFileExtension + value: '1' + - key: misc-unused-parameters.StrictMode + value: '0' + - key: modernize-loop-convert.MaxCopySize + value: '16' + - key: modernize-loop-convert.MinConfidence + value: reasonable + - key: modernize-loop-convert.NamingStyle + value: CamelCase + - key: modernize-make-shared.IgnoreMacros + value: '1' + - key: modernize-make-shared.IncludeStyle + value: '0' + - key: modernize-make-shared.MakeSmartPtrFunction + value: 'std::make_shared' + - key: modernize-make-shared.MakeSmartPtrFunctionHeader + value: memory + - key: modernize-make-unique.IgnoreMacros + value: '1' + - key: modernize-make-unique.IncludeStyle + value: '0' + - key: modernize-make-unique.MakeSmartPtrFunction + value: 'std::make_unique' + - key: modernize-make-unique.MakeSmartPtrFunctionHeader + value: memory + - key: modernize-pass-by-value.IncludeStyle + value: llvm + - key: modernize-pass-by-value.ValuesOnly + value: '0' + - key: modernize-raw-string-literal.ReplaceShorterLiterals + value: '0' + - key: modernize-replace-auto-ptr.IncludeStyle + value: llvm + - key: modernize-replace-random-shuffle.IncludeStyle + value: llvm + - key: modernize-use-auto.MinTypeNameLength + value: '5' + - key: modernize-use-auto.RemoveStars + value: '0' + - key: modernize-use-emplace.ContainersWithPushBack + value: '::std::vector;::std::list;::std::deque' + - key: modernize-use-emplace.SmartPointers + value: '::std::shared_ptr;::std::unique_ptr;::std::auto_ptr;::std::weak_ptr' + - key: modernize-use-emplace.TupleMakeFunctions + value: '::std::make_pair;::std::make_tuple' + - key: modernize-use-emplace.TupleTypes + value: '::std::pair;::std::tuple' + - key: modernize-use-equals-default.IgnoreMacros + value: '1' + - key: modernize-use-equals-delete.IgnoreMacros + value: '1' + - key: modernize-use-noexcept.ReplacementString + value: '' + - key: modernize-use-noexcept.UseNoexceptFalse + value: '1' + - key: modernize-use-nullptr.NullMacros + value: 'NULL' + - key: modernize-use-transparent-functors.SafeMode + value: '0' + - key: modernize-use-using.IgnoreMacros + value: '1' + - key: performance-faster-string-find.StringLikeClasses + value: 'std::basic_string' + - key: performance-for-range-copy.AllowedTypes + value: '' + - key: performance-for-range-copy.WarnOnAllAutoCopies + value: '0' + - key: performance-inefficient-string-concatenation.StrictMode + value: '0' + - key: performance-inefficient-vector-operation.VectorLikeClasses + value: '::std::vector' + - key: performance-move-const-arg.CheckTriviallyCopyableMove + value: '1' + - key: performance-move-constructor-init.IncludeStyle + value: llvm + - key: performance-type-promotion-in-math-fn.IncludeStyle + value: llvm + - key: performance-unnecessary-copy-initialization.AllowedTypes + value: '' + - key: performance-unnecessary-value-param.AllowedTypes + value: '' + - key: performance-unnecessary-value-param.IncludeStyle + value: llvm + - key: readability-function-size.BranchThreshold + value: '4294967295' + - key: readability-function-size.LineThreshold + value: '4294967295' + - key: readability-function-size.NestingThreshold + value: '4294967295' + - key: readability-function-size.ParameterThreshold + value: '4294967295' + - key: readability-function-size.StatementThreshold + value: '800' + - key: readability-function-size.VariableThreshold + value: '4294967295' + - key: readability-identifier-naming.IgnoreFailedSplit + value: '0' + - key: readability-inconsistent-declaration-parameter-name.IgnoreMacros + value: '1' + - key: readability-inconsistent-declaration-parameter-name.Strict + value: '0' + - key: readability-redundant-smartptr-get.IgnoreMacros + value: '1' + - key: readability-simplify-boolean-expr.ChainedConditionalAssignment + value: '0' + - key: readability-simplify-boolean-expr.ChainedConditionalReturn + value: '0' +... + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..cead59a79 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,31 @@ +# +# Required environment variables in the travis config +# +# DOCKER_USERNAME +# +language: cpp + +git: + submodules: false + +stages: + - name: Build Qbs and and run autotests + +jobs: + include: + - &build-on-stretch + stage: Build Qbs and and run autotests + name: With Qbs on Debian stretch (linux_amd64) + env: + SERVICE=stretch + services: + - docker + before_install: + - docker-compose pull ${SERVICE} + script: + - docker-compose run --rm ${SERVICE} scripts/build-qbs-with-qbs.sh + + - <<: *build-on-stretch + name: With QMake on Debian stretch (linux_amd64) + script: + - docker-compose run --rm ${SERVICE} scripts/build-qbs-with-qmake.sh @@ -1 +1 @@ -1.13.2 +1.14.0 diff --git a/doc/qbs.qdoc b/doc/qbs.qdoc index 1eb1d2bec..d2c703491 100644 --- a/doc/qbs.qdoc +++ b/doc/qbs.qdoc @@ -450,7 +450,7 @@ To build \QBS from the source, you need: \list - \li Qt 5.9, or later + \li Qt 5.11, or later \li Windows: MinGW with GCC 4.9 or Microsoft Visual Studio 2015, or later \li Linux: GCC 4.9, or later, or Clang 3.9.0, or later @@ -470,7 +470,7 @@ Regenerating the man page requires the \c help2man tool. - \section1 Building + \section1 Building \QBS with QMake To build \QBS, enter the following command: @@ -488,7 +488,7 @@ make install INSTALL_ROOT=$INSTALL_DIRECTORY \endcode - \section1 Configure Options + \section2 QMake Configure Options \QBS recognizes the following qmake CONFIG options to customize the build: @@ -510,6 +510,185 @@ before running qmake to specify a custom location for \QBS to look for its system-level settings. + \section1 Building \QBS with \QBS + + It is also possible to build \QBS with the previously installed \QBS version. + To build \QBS, enter the following command in the source directory: + \code + qbs + \endcode + This will use the \c defaultProfile or pick up the Qt version and the toolchain from the \c PATH + if the \c defaultProfile is not set. See \l {Configuring Profiles and Preferences} for details + about profiles. + + To run automatic tests, the \c autotest-runner product should be built: + \code + qbs build -p autotest-runner + \endcode + \QBS will use an empty profile when running tests which means it will try to autodetect + toolchains, Qt versions and other things based on the system environment. + It is possible to specify which profile should be used during the test-run by passing the + \c QBS_AUTOTEST_PROFILE environment variable. + This variable should be set prior to building \QBS itself; otherwise the \c resolve command + should be used to update the environment stored in the buildgraph: + \code + export QBS_AUTOTEST_PROFILE=qt + qbs resolve + qbs build -p autotest-runner + \endcode + + It is also possible to set up a separate profile for a particular testsuite. + A profile for the \c tst_blackbox_android suite can be set up as follows: + \code + qbs setup-android pie + export QBS_AUTOTEST_PROFILE_BLACKBOX_ANDROID=pie + \endcode + + It might be useful to set up the directory with the \QBS settings to isolate the test + environment: + \code + export QBS_AUTOTEST_SETTINGS_DIR=~/path/to/qbs/settings + \endcode + + \section2 \QBS Build Options + + The \c qbsbuildconfig module can be used to customize the build. + Properties of that module can be passed using command line as follows: + \code + qbs build modules.qbsbuildconfig.enableAddressSanitizer:true + \endcode + + \QBS recognizes the following properties: + \table + \header + \li Property + \li Default value + \li Notes + \row + \li enableAddressSanitizer + \li \c false + \li Whether to use address sanitizer or not. Enabling this option will add the + -fsanitize=address flag. + \row + \li enableUnitTests + \li \c false + \li Enable additional autotests. Enabling this option will export some symbols that would + otherwise be private. + \row + \li enableProjectFileUpdates + \li \c false + \li Enable API for updating project files. This is required for an IDE and implies a + dependency to the Qt GUI module that would not be needed for the \QBS command-line tool. + \row + \li enableRPath + \li \c true + \li Use this property to disable the use of rpath. This can be used when packaging \QBS + for distributions which do not permit the use of rpath, such as Fedora. + \row + \li installApiHeaders + \li \c true + \li Holds whether to install the header files for the \QBS libraries or not. This option + is required to build against the \QBS libraries. + \row + \li enableBundledQt + \li \c true + \li Holds whether the Qt libraries that \QBS depends on will be bundled with \QBS during + the \c install step. This option is only implemented on macOS. + \row + \li useBundledQtScript + \li \c false + \li Use the bundled QtScript module instead of the one shipped with Qt. In that case, + QtScript should be checked out as a git submodule. + \row + \li libDirName + \li \c "lib" + \li Directory name used by \c libInstallDir and \c importLibInstallDir properties. + \row + \li appInstallDir + \li \c "bin" + \li Relative directory path under the install prefix path to put application binaries. + \row + \li libInstallDir + \li \c "bin" on Windows, \c libDirName otherwise + \li Relative directory path under the install prefix path where to put shared libraries + (excluding plugins, see the \c relativePluginsPath property). + \row + \li importLibInstallDir + \li \c libDirName + \li Relative directory path under the install prefix path where to put import libs. + \row + \li libexecInstallDir + \li \c appInstallDir on Windows, \c "libexec/qbs" otherwise + \li Relative directory path under the install prefix path where to put auxiliary binaries + executed by the \QBS libraries. + \row + \li systemSettingsDir + \li \c undefined + \li Directory that will be used by \QBS to store its settings. If not specified, a default + platform-dependent directory is used. + \row + \li installManPage + \li \c true on Unix, \c false otherwise + \li Whether to install man pages. + \row + \li installHtml + \li \c true + \li Whether to install HTML help pages. + \row + \li installQch + \li \c false + \li Whether to install qch files. See + \l{https://doc.qt.io/qt-5/qthelp-framework.html}{The Qt Help Framework} for details + about qch files. + \row + \li generatePkgConfigFiles + \li auto-detected + \li Whether to generate files for pkg-config. + \row + \li generateQbsModules + \li auto-detected + \li Whether to generate \QBS modules for the exported \QBS libraries. Use this when + building another product against \QBS libraries using \QBS as build system. + \row + \li docInstallDir + \li \c "share/doc/qbs/html" + \li Relative directory path under the install prefix path where to put documentation. + \row + \li pkgConfigInstallDir + \li \c libDirName + \c "/pkgconfig" + \li Relative directory path under the install prefix path where to put pkg-config files. + \row + \li qbsModulesBaseDir + \li \c libDirName + \c "/qbs/modules" + \li Relative directory path under the install prefix path where to put \QBS modules. + Applies only when \c generateQbsModules is \c true. + \row + \li relativeLibexecPath + \li \c "../" + \c libexecInstallDir + \li Path to the auxiliary binaries relative to the application binary. + \row + \li relativePluginsPath + \li \c "../" + \c libDirName + \li Path to plugin libraries relative to the application binary. + \row + \li relativeSearchPath + \li \c ".." + \li Relative path to the directory where to look for \QBS development modules and items. + \row + \li libRPaths + \li auto-detected + \li List of rpaths. + \row + \li resourcesInstallDir + \li \c "" + \li Relative directory path under the install prefix path where to put shared resources + like documentation, \QBS user modules and items. + \row + \li pluginsInstallDir + \li \c libDirName + \c "/qbs/plugins" + \li Relative path to the directory where to put plugins to. + \endtable + \section1 Using Docker A set of Docker images for developing \QBS (which are maintained by the \QBS team) is available @@ -523,8 +702,16 @@ The easiest way to get started is to build \QBS using a Linux container. These types of containers are supported out of the box on all the supported host platforms: Windows, macOS, - and Linux. Run the following to download the \QBS development image based on Debian 9 - \e Stretch: + and Linux. + + The images provide everything that is necessary to build and test \QBS: + + \list + \li Qt SDK for building \QBS with \c qmake + \li Latest stable release of \QBS for building \QBS with \QBS + \endlist + + Run the following command to download the \QBS development image based on Debian 9 \e Stretch: \code docker pull qbsbuild/qbsdev:stretch @@ -534,16 +721,19 @@ machine's file system, by running: \code - docker run -it -v $PWD:/qbs -w /qbs qbsbuild/qbsdev:stretch + docker run -it -v ${PWD}:/qbs -w /qbs qbsbuild/qbsdev:stretch \endcode - Or with a slightly different syntax for Windows: + 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 run -it -v %CD%:/qbs -w /qbs qbsbuild/qbsdev:stretch + docker-compose run --rm stretch \endcode - You will now be in an interactive Linux shell where you can develop and build \QBS. + This will download and run the container in one go and mount the project root directory + to \c /qbs in the container. \section2 Windows Containers @@ -1686,6 +1876,12 @@ (which maps to \l{qbs::buildVariant}{qbs.buildVariant}), and \l{qbs::profiles} {qbs.profiles} (which maps to \l{Project::profile}{Project.profile}). + For example, to build a "fat" \c iOS binary containing two architectures, use the following + command: + \code + qbs build modules.qbs.targetPlatform:ios modules.qbs.architectures:arm64,armv7a + \endcode + \note The implementation details around multiplexing are subject to change. Product multiplexing works by examining the diff --git a/doc/reference/cli/cli-options.qdocinc b/doc/reference/cli/cli-options.qdocinc index 2d35bea61..d4c3280a2 100644 --- a/doc/reference/cli/cli-options.qdocinc +++ b/doc/reference/cli/cli-options.qdocinc @@ -496,6 +496,7 @@ \li \c msvc \li \c iar \li \c keil + \li \c sdcc \endlist //! [type] diff --git a/doc/reference/items/probe/pkgconfig-probe.qdoc b/doc/reference/items/probe/pkgconfig-probe.qdoc index 1de84263e..7bdaf4e19 100644 --- a/doc/reference/items/probe/pkgconfig-probe.qdoc +++ b/doc/reference/items/probe/pkgconfig-probe.qdoc @@ -59,6 +59,20 @@ */ /*! + \qmlproperty string PkgConfigProbe::sysroot + + This property sets the value of the \c PKG_CONFIG_SYSROOT_DIR environment variable passed to + the \c pkg-config binary. This variable modifies -I and -L flags to use the directories located + in target sysroot. + + This property is useful when cross-compiling packages that use \c pkg-config to determine CFLAGS + and LDFLAGS. For example, if \c sysroot is set to \c /var/target, a \c -I/usr/include/libfoo + will become \c -I/var/target/usr/include/libfoo. + + \defaultvalue \c qbs.sysroot +*/ + +/*! \qmlproperty string PkgConfigProbe::executable The name of or the path to the pkg-config executable. @@ -125,6 +139,9 @@ List of full, non-sysrooted paths where pkg-config should search for .pc files. This overrides the built-in path (which is usually /usr/lib/pkgconfig). + This property sets the value of the \c PKG_CONFIG_LIBDIR environment variable passed to + the \c pkg-config binary. + \nodefaultvalue */ @@ -178,6 +195,9 @@ This output property contains the list of library paths that should be passed to a linker when using requested package. + This property sets the value of the PKG_CONFIG_LIBDIR environment variable passed to + the \c pkg-config binary. + \nodefaultvalue */ diff --git a/doc/reference/items/probe/sdcc-probe.qdoc b/doc/reference/items/probe/sdcc-probe.qdoc new file mode 100644 index 000000000..1353eb736 --- /dev/null +++ b/doc/reference/items/probe/sdcc-probe.qdoc @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@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 SdccProbe + \ingroup list-of-probes + \ingroup list-of-items + \keyword QML.SdccProbe + \inherits PathProbe + \brief Collects SDCC toolchain compiler information. + \since Qbs 1.14 + \internal + + Detects the version, supported architecture and the platform + endianness of the specified compiler executable file from the + \l{http://sdcc.sourceforge.net/}{SDCC} toolchain. +*/ + +/*! + \qmlproperty string SdccProbe::compilerFilePath + + An input property which is a full path to the SDCC compiler executable file. + + \nodefaultvalue +*/ + +/*! + \qmlproperty string SdccProbe::architecture + + Detected architecture of the target platform's processor. + + The possible values are \c "mcs51". + + \nodefaultvalue +*/ + +/*! + \qmlproperty string SdccProbe::endianness + + Detected endianness of the target platform's processor architecture. + + The possible values are \c "little". + + \nodefaultvalue +*/ + +/*! + \qmlproperty int SdccProbe::versionMajor + + Detected major compiler version. + + \nodefaultvalue +*/ + +/*! + \qmlproperty int SdccProbe::versionMinor + + Detected minor compiler version. + + \nodefaultvalue +*/ + +/*! + \qmlproperty int SdccProbe::versionPatch + + Detected patch compiler version. + + \nodefaultvalue +*/ diff --git a/doc/reference/modules/android-ndk-module.qdoc b/doc/reference/modules/android-ndk-module.qdoc index 8113a7c68..e3a7ca22d 100644 --- a/doc/reference/modules/android-ndk-module.qdoc +++ b/doc/reference/modules/android-ndk-module.qdoc @@ -47,7 +47,7 @@ CppApplication { name: "HelloJni" Android.sdk.packageName: "com.example.hellojni" - qbs.architectures: ["mips", "x86"] + qbs.architectures: ["arm", "x86"] files: "app/src/main/jni/hello-jni.c" } \endcode @@ -86,16 +86,9 @@ \list \li \c "c++_shared" \li \c "c++_static" - \li \c "gabi++_shared" (until r17) - \li \c "gabi++_static" (until r17) - \li \c "gnustl_shared" (until r17) - \li \c "gnustl_static" (until r17) - \li \c "stlport_shared" (until r17) - \li \c "stlport_static" (until r17) - \li \c "system" \endlist - \defaultvalue \c{"system"} + \defaultvalue \c{"c++_shared"} */ /*! @@ -111,5 +104,7 @@ The versioned platform name. - \defaultvalue \c{"android-9"} + \defaultvalue \c{"android-16"} for 32 bit arm ABIs + and \c{"android-21"} for all 64 bit ABIs and x86. + x86 ABI has broken wstring support in android-16 to android-19. */ diff --git a/doc/reference/modules/android-sdk-module.qdoc b/doc/reference/modules/android-sdk-module.qdoc index a9e06ae17..7733ae75d 100644 --- a/doc/reference/modules/android-sdk-module.qdoc +++ b/doc/reference/modules/android-sdk-module.qdoc @@ -161,6 +161,46 @@ */ /*! + \qmlproperty string Android.sdk::versionCode + + The Android Manifest version code of the respective product. The \c android:versionCode + attribute in the manifest file will be set to this value if not undefined. + + In the following example we provide an architecture-specific value + for \c android:versionCode: + + \code + // ... + property int _version: 1 + property int _patchVersion: 0 + Android.sdk.versionCode: { + switch (Android.ndk.abi) { + case "armeabi-v7a": + return 132000000 | _version * 10 + _patchVersion; + case "arm64-v8a": + return 164000000 | _version * 10 + _patchVersion; + case "x86": + return 232000000 | _version * 10 + _patchVersion; + case "x86_64": + return 264000000 | _version * 10 + _patchVersion; + } + throw "Unknown architecture"; + } + \endcode + + \defaultvalue \c undefined +*/ + +/*! + \qmlproperty string Android.sdk::versionName + + The Android Manifest version name of the respective product. The \c android:versionName + attribute in the manifest file will be set to this value if not undefined. + + \defaultvalue \c undefined +*/ + +/*! \qmlproperty string Android.sdk::resourcesDir The base directory for Android resources in the respective product. diff --git a/doc/reference/modules/pkgconfig-module.qdoc b/doc/reference/modules/pkgconfig-module.qdoc index 898349628..f30308895 100644 --- a/doc/reference/modules/pkgconfig-module.qdoc +++ b/doc/reference/modules/pkgconfig-module.qdoc @@ -67,3 +67,26 @@ \defaultvalue \c false */ + +/*! + \qmlproperty path pkgconfig::sysroot + + This property controls the value of the \l{PkgConfigProbe::sysroot}{PkgConfigProbe.sysroot} + property. + + Set this property if you need to overwrite the default search sysroot path used by + \c pkg-config. + + This can be useful if \c pkg-config files are located in the directory other than qbs.sysroot. + This is the case on macOS platform - all XCode profiles are sysrooted to the SDK + directory, but \c pkg-config is typically intalled using Brew and resides in the + \c /usr/local directory. + + Setting this property to \c undefined or empty (\c "") value will use pkg-config's default + search paths: + \code + qbs build modules.pkgconfig.sysroot:undefined + \endcode + + \defaultvalue \c "" on macOS, \c qbs.sysroot on other platforms +*/ diff --git a/doc/reference/modules/protobufcpp-module.qdoc b/doc/reference/modules/protobufcpp-module.qdoc index 688f1d9e2..63c56c6ca 100644 --- a/doc/reference/modules/protobufcpp-module.qdoc +++ b/doc/reference/modules/protobufcpp-module.qdoc @@ -36,6 +36,25 @@ The \c protobuf.cpp module provides support for generating C++ headers and sources from proto definition files using the \l protoc tool. + A simple qbs file that uses protobuf can be written as follows: + \code + CppApplication { + Depends { name: "protobuf.cpp" } + files: ["foo.proto", "main.cpp"] + } + \endcode + A generated header now can be included in the C++ sources: + \code + #include <foo.pb.h> + + int main(int argc, char* argv[]) { + Foo bar; + bar.set_answer(42); + google::protobuf::ShutdownProtobufLibrary(); + return 0; + } + \endcode + \section2 Relevant File Tags \table diff --git a/doc/reference/modules/qbs-module.qdoc b/doc/reference/modules/qbs-module.qdoc index eea67688b..9e7cc8c3c 100644 --- a/doc/reference/modules/qbs-module.qdoc +++ b/doc/reference/modules/qbs-module.qdoc @@ -182,59 +182,93 @@ where the target OS is always known (such as an Apple Watch app written in native code). - You should generally treat this property as \e{write-only} and avoid using - it to test for the current target OS. Instead, use the \l{qbs::}{targetOS} - property for conditionals. For example, instead of: - - \code - qbs.targetPlatform === "macos" || qbs.targetPlatform === "ios" || qbs.targetPlatform === "tvos" || qbs.targetPlatform === "watchos" - \endcode - - use - - \code - qbs.targetOS.contains("darwin") - - \endcode - - However, in some cases using \c targetPlatform would be acceptable, such as - when the resulting condition would be simpler while still being correct: - + For example, a profile used for building for the iOS Simulator platform will have this + property set to the \c ios-simulator value: \code - qbs.targetPlatform === "linux" + profiles.xcode-iphonesimulator.qbs.targetPlatform: "ios-simulator" \endcode - versus - \code - qbs.targetOS.contains("linux") && !qbs.targetOS.contains("android") - \endcode + You should generally treat this property as \e{write-only} and avoid using + it to test for the current target OS. Instead, use the \l{qbs::}{targetOS} + property for conditionals. - The possible values include one or more of the following: + \section2 Relation between targetPlatform and targetOS - \list + This table describes the possible values and matching between the \c targetPlatform + and the \l{qbs::}{targetOS} properties: + \table + \header + \li Target Platform + \li Target OS + \row \li \c{"aix"} + \li \c{["aix", "unix"]} + \row \li \c{"android"} + \li \c{["android", "linux", "unix"]} + \row \li \c{"freebsd"} + \li \c{["freebsd", "bsd", "unix"]} + \row \li \c{"haiku"} + \li \c{["haiku"]} + \row \li \c{"hpux"} + \li \c{["hpux", "unix"]} + \row \li \c{"hurd"} + \li \c{["hurd", "unix"]} + \row \li \c{"integrity"} + \li \c{["integrity", "unix"]} + \row \li \c{"ios"} + \li \c{["ios", "darwin", "bsd", "unix"]} + \row \li \c{"ios-simulator"} + \li \c{["ios-simulator", "ios", "darwin", "bsd", "unix"]} + \row \li \c{"linux"} + \li \c{["linux", "unix"]} + \row \li \c{"lynx"} + \li \c{["lynx"]} + \row \li \c{"macos"} + \li \c{["macos", "darwin", "bsd", "unix"]} + \row \li \c{"netbsd"} + \li \c{["netbsd", "bsd", "unix"]} + \row \li \c{"openbsd"} + \li \c{["openbsd", "bsd", "unix"]} + \row \li \c{"qnx"} + \li \c{["qnx", "unix"]} + \row \li \c{"solaris"} + \li \c{["solaris", "unix"]} + \row \li \c{"tvos"} + \li \c{["tvos", "darwin", "bsd", "unix"]} + \row \li \c{"tvos-simulator"} + \li \c{["tvos-simulator", "tvos", "darwin", "bsd", "unix"]} + \row \li \c{"vxworks"} + \li \c{["vxworks"]} + \row \li \c{"watchos"} + \li \c{["watchos", "darwin", "bsd", "unix"]} + \row \li \c{"watchos-simulator"} + \li \c{["watchos-simulator", "watchos", "darwin", "bsd", "unix"]} + \row \li \c{"windows"} - \endlist + \li \c{["windows"]} + \endtable + + \sa {Target Platforms} \nodefaultvalue */ @@ -433,14 +467,57 @@ /*! \qmlproperty stringList qbs::targetOS + \readonly - Specifies the OS you want to build the project for. + Contains the list of string values describing the OS and OS family that is + used to build a project. - Use this property to test for a particular OS or OS family in conditionals. - Do not use \l{qbs::}{targetPlatform} for this purpose. + This property is calculated based on the \l{qbs::}{targetPlatform} property and is typically + used to test for a particular OS or OS family in conditionals: + \code + Group { + // Includes all Unix-like platforms, such as: Linux, BSD, Apple platforms and others. + condition: qbs.targetOS.contains("unix") + files: ... + } + Group { + // Includes all Apple platforms, such as macOS, iOS, and iOS Simulator. + condition: qbs.targetOS.contains("darwin") + files: ... + } + Group { + // Includes only macOS + condition: qbs.targetOS.contains("macos") + files: ... + } + \endcode + Avoid using \l{qbs::}{targetPlatform} for this purpose. For example, instead of: - Possible values include one or more of \c{"bsd"}, \c{"darwin"}, and - \c{"unix"}, in addition to the possible values of \l{qbs::}{targetPlatform}. + \code + qbs.targetPlatform === "macos" || qbs.targetPlatform === "ios" || qbs.targetPlatform === "tvos" || qbs.targetPlatform === "watchos" + \endcode + + use + + \code + qbs.targetOS.contains("darwin") + + \endcode + + However, in some cases using \l{qbs::}{targetPlatform} would be acceptable, such as + when the resulting condition would be simpler while still being correct: + + \code + qbs.targetPlatform === "linux" + \endcode + + versus + \code + qbs.targetOS.contains("linux") && !qbs.targetOS.contains("android") + \endcode + + For the complete list of possible values, see + \l{Relation between targetPlatform and targetOS}. \nodefaultvalue */ @@ -537,7 +614,7 @@ The value of this property itself is relative to the \l{qbs::}{installRoot} in the context of installation. - \defaultvalue \c [] + \defaultvalue \c "/usr/local" on Unix, \c "" otherwise */ /*! diff --git a/doc/reference/modules/qt-android_support-module.qdoc b/doc/reference/modules/qt-android_support-module.qdoc index f7ec595e3..995f73ba5 100644 --- a/doc/reference/modules/qt-android_support-module.qdoc +++ b/doc/reference/modules/qt-android_support-module.qdoc @@ -77,6 +77,15 @@ */ /*! + \qmlproperty stringList Qt.android_support::extraLibs + + Additional libs to be packaged and loaded on start-up (mind the order). + Corresponds to qmake's ANDROID_EXTRA_LIBS. + + \defaultvalue \c undefined +*/ + +/*! \qmlproperty bool Qt.android_support::verboseAndroidDeployQt Enable this property if you want verbose output from the diff --git a/doc/targets/qbs-target-platforms.qdoc b/doc/targets/qbs-target-platforms.qdoc index 8f37537b4..7e556aea9 100644 --- a/doc/targets/qbs-target-platforms.qdoc +++ b/doc/targets/qbs-target-platforms.qdoc @@ -45,4 +45,7 @@ \QBS recognizes the existence of at least AIX, HP-UX, Solaris, FreeBSD, NetBSD, OpenBSD, GNU Hurd, and Haiku, but provides no explicit support (except some minimal support for FreeBSD). + + For instructions on how to setup the target platform, see the + \l {qbs::targetPlatform}{qbs.targetPlatform} property. */ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..bff8f5d87 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: "3.3" + +services: + stretch: + image: ${DOCKER_USER:-qbsbuild}/qbsdev:stretch + build: + dockerfile: Dockerfile + context: docker/stretch/ + args: + QT_VERSION: 5.11.3 + QBS_VERSION: 1.13.0 + working_dir: /qbs + volumes: + - .:/qbs + network_mode: bridge + cap_add: + - SYS_PTRACE diff --git a/docker/docker.qbs b/docker/docker.qbs index 98738a9f4..d4bf181bb 100644 --- a/docker/docker.qbs +++ b/docker/docker.qbs @@ -13,7 +13,7 @@ Project { files: [ "stretch/Dockerfile", - "stretch/qtifwsilent.qs", + "stretch/entrypoint.sh", ] } diff --git a/docker/stretch/Dockerfile b/docker/stretch/Dockerfile index 27bd668b6..d7258f97f 100644 --- a/docker/stretch/Dockerfile +++ b/docker/stretch/Dockerfile @@ -1,31 +1,184 @@ +# +# 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 as build-qt-linux-x86_64 +ARG QT_VERSION + +# Downloader dependencies +RUN apt-get update -qq && \ + apt-get install -qq -y --no-install-recommends \ + ca-certificates \ + xz-utils \ + wget + +# Download +RUN mkdir -p /qt/source && \ + wget -nv --continue --tries=20 --waitretry=10 --retry-connrefused \ + --no-dns-cache --timeout 300 -qO- \ + https://download.qt.io/official_releases/qt/${QT_VERSION%??}/${QT_VERSION}/single/qt-everywhere-src-${QT_VERSION}.tar.xz \ + | tar --strip-components=1 -C /qt/source -xJf- + +# Build dependencies +RUN apt-get update -qq && \ + apt-get install -qq -y --no-install-recommends \ + autoconf \ + automake \ + autopoint \ + binutils \ + bison \ + build-essential \ + flex \ + intltool \ + libclang-3.9-dev \ + libgdk-pixbuf2.0-dev \ + libffi-dev \ + libfontconfig1-dev \ + libfreetype6-dev \ + libgmp-dev \ + libicu-dev \ + libmpc-dev \ + libmpfr-dev \ + libtool \ + libtool-bin \ + libx11-dev \ + libxext-dev \ + libxfixes-dev \ + libxi-dev \ + libxrender-dev \ + libxcb1-dev \ + libx11-xcb-dev \ + libxcb-glx0-dev \ + libz-dev \ + python \ + openssl + +ENV LLVM_INSTALL_DIR=/usr/lib/llvm-3.9 + +# Build Qt +RUN mkdir -p qt/build && \ + cd qt/build && \ + ../source/configure \ + -prefix /opt/qt5-linux-x86_64 \ + -release \ + -shared \ + -opensource \ + -confirm-license \ + -nomake examples \ + -nomake tests \ + -platform linux-g++ \ + -no-use-gold-linker \ + -R . \ + -sysconfdir /etc/xdg \ + -qt-freetype -qt-harfbuzz -qt-pcre -qt-sqlite -qt-xcb -qt-zlib \ + -no-cups -no-dbus -no-pch -no-libudev \ + -no-feature-accessibility -no-opengl \ + -skip qtactiveqt \ + -skip qt3d \ + -skip qtcanvas3d \ + -skip qtcharts \ + -skip qtconnectivity \ + -skip qtdatavis3d \ + -skip qtdoc \ + -skip qtgamepad \ + -skip qtgraphicaleffects \ + -skip qtimageformats \ + -skip qtlocation \ + -skip qtmultimedia \ + -skip qtnetworkauth \ + -skip qtquickcontrols \ + -skip qtquickcontrols2 \ + -skip qtpurchasing \ + -skip qtremoteobjects \ + -skip qtscxml \ + -skip qtsensors \ + -skip qtserialbus \ + -skip qtspeech \ + -skip qtsvg \ + -skip qttranslations \ + -skip qtwayland \ + -skip qtvirtualkeyboard \ + -skip qtwebchannel \ + -skip qtwebengine \ + -skip qtwebsockets \ + -skip qtwebview \ + -skip qtwinextras \ + -skip qtxmlpatterns \ + -skip qtx11extras + +RUN cd qt/build && \ + make -j $(nproc --all) | stdbuf -o0 tr -cd '\n' | stdbuf -o0 tr '\n' '.' && \ + make install + +# Build a stable Qbs release FROM debian:9 -LABEL Description="Debian development environment for Qbs with Qt 5.9 and various dependencies for testing Qbs modules and functionality" - -# Dependencies of the Qt offline installer -RUN apt-get -y update && apt-get install -y \ - curl \ - libdbus-1-3 \ - libexpat1 \ - libfontconfig1 \ - libfreetype6 \ - libgl1-mesa-glx \ - libglib2.0-0 \ - libx11-6 \ - libx11-xcb1 - -COPY qtifwsilent.qs qtifwsilent.qs -RUN curl -L -O 'https://download.qt.io/official_releases/qt/5.9/5.9.3/qt-opensource-linux-x64-5.9.3.run' && \ - chmod +x qt-opensource-linux-x64-5.9.3.run && \ - QT_INSTALL_DIR=/usr/local/Qt ./qt-opensource-linux-x64-5.9.3.run --platform minimal --script qtifwsilent.qs && \ - rm -f qt-opensource-linux-x64-5.9.3.run -ENV QTDIR /usr/local/Qt/5.9.3/gcc_64 -ENV PATH="/usr/local/Qt/Tools/QtCreator/bin:${PATH}" - -RUN ls "$QTDIR" && stat "$QTDIR/lib/libQt5Script.so" && qbs --version -RUN apt-get -y update && apt-get install -y \ - g++ \ - gcc \ - git \ - help2man \ - python-pip -RUN pip install beautifulsoup4 lxml # for building the documentation +LABEL Description="Debian development environment for Qbs with Qt and various dependencies for testing Qbs modules and functionality" +ARG QBS_VERSION=1.13.0 + +# 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 \ + 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 entrypoint.sh entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] + +# Qbs build dependencies +RUN apt-get update -qq && \ + apt-get install -qq -y --no-install-recommends \ + build-essential \ + ca-certificates \ + git \ + libclang-3.9 \ + libicu57 \ + pkg-config \ + make \ + help2man \ + python-pip \ + wget && \ + pip install beautifulsoup4 lxml # for building the documentation + +# Install Qt installation from build stage +COPY --from=build-qt-linux-x86_64 /opt/qt5-linux-x86_64 /opt/qt5-linux-x86_64 +ENV PATH=/opt/qt5-linux-x86_64/bin:${PATH} +RUN echo "export PATH=/opt/qt5-linux-x86_64/bin:\${PATH}" > /etc/profile.d/qt.sh + +# Download and build Qbs +RUN mkdir -p /qbs && \ + wget -nv --continue --tries=20 --waitretry=10 --retry-connrefused \ + --no-dns-cache --timeout 300 -qO- \ + http://download.qt.io/official_releases/qbs/${QBS_VERSION}/qbs-src-${QBS_VERSION}.tar.gz \ + | tar --strip-components=1 -C /qbs -xzf- && \ + cd /qbs && \ + qmake -r qbs.pro && \ + make -j $(nproc --all) && \ + make install INSTALL_ROOT=/ && \ + rm -rf /qbs + +# Configure Qbs +USER $USER_NAME +RUN qbs-setup-toolchains --detect && \ + qbs-setup-qt /opt/qt5-linux-x86_64/bin/qmake qt5-linux-x86_64 && \ + qbs config defaultProfile qt5-linux-x86_64 + +# Switch back to root user for the entrypoint script. +USER root diff --git a/docker/stretch/entrypoint.sh b/docker/stretch/entrypoint.sh new file mode 100755 index 000000000..04504ffcc --- /dev/null +++ b/docker/stretch/entrypoint.sh @@ -0,0 +1,69 @@ +#!/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/docker/stretch/qtifwsilent.qs b/docker/stretch/qtifwsilent.qs deleted file mode 100644 index 804a4be25..000000000 --- a/docker/stretch/qtifwsilent.qs +++ /dev/null @@ -1,51 +0,0 @@ -function Controller() { - installer.autoRejectMessageBoxes(); - installer.installationFinished.connect(function() { - gui.clickButton(buttons.NextButton); - }) -} - -Controller.prototype.WelcomePageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.CredentialsPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.IntroductionPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.TargetDirectoryPageCallback = function() { - gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.environmentVariable("QT_INSTALL_DIR")); - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.ComponentSelectionPageCallback = function() { - var widget = gui.currentPageWidget(); - widget.deselectAll(); - widget.selectComponent("qt.593.gcc_64"); - widget.selectComponent("qt.593.qtscript"); - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.LicenseAgreementPageCallback = function() { - gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.StartMenuDirectoryPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.ReadyForInstallationPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.FinishedPageCallback = function() { - var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm; - if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) - checkBoxForm.launchQtCreatorCheckBox.checked = false; - gui.clickButton(buttons.FinishButton); -} diff --git a/examples/baremetal/at90can128olimex/at90can128olimex.qbs b/examples/baremetal/at90can128olimex/at90can128olimex.qbs new file mode 100644 index 000000000..dc1760fe9 --- /dev/null +++ b/examples/baremetal/at90can128olimex/at90can128olimex.qbs @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import qbs + +Project { + name: "Examples for Olimex AVR-CAN board" + references: [ + "redblink/redblink.qbs" + ] +} diff --git a/examples/baremetal/at90can128olimex/redblink/README.md b/examples/baremetal/at90can128olimex/redblink/README.md new file mode 100644 index 000000000..0e9710e57 --- /dev/null +++ b/examples/baremetal/at90can128olimex/redblink/README.md @@ -0,0 +1,9 @@ +This examples demonstrates how to build a bare-metal application using +different AVR toolchains. It is designed for the OLIMEX AVR-CAN target +board (based on at90can128 chip) and simply flashes the red LED on the +board. + +The following toolchains are supported: + + * GCC + * IAR Embedded Workbench diff --git a/examples/baremetal/at90can128olimex/redblink/gpio.c b/examples/baremetal/at90can128olimex/redblink/gpio.c new file mode 100644 index 000000000..543e31a8d --- /dev/null +++ b/examples/baremetal/at90can128olimex/redblink/gpio.c @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gpio.h" + +#if defined(__GNUC__) +#include <avr/io.h> +#elif defined (__ICCAVR__) +#include <ioavr.h> +#else +#error "Unsupported toolchain" +#endif + +// LED pin number. +#define GPIO_RED_LED_PIN_POS (4u) +// LED port direction. +#define GPIO_RED_LED_PORT_DIR (DDRE) +// LED output port. +#define GPIO_RED_LED_PORT_OUT (PORTE) + +void gpio_init_red_led(void) +{ + GPIO_RED_LED_PORT_DIR = 0xFF; +} + +void gpio_toggle_red_led(void) +{ + GPIO_RED_LED_PORT_OUT ^= (1u << GPIO_RED_LED_PIN_POS); +} diff --git a/examples/baremetal/at90can128olimex/redblink/gpio.h b/examples/baremetal/at90can128olimex/redblink/gpio.h new file mode 100644 index 000000000..246eab860 --- /dev/null +++ b/examples/baremetal/at90can128olimex/redblink/gpio.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GPIO_H +#define GPIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +void gpio_init_red_led(void); +void gpio_toggle_red_led(void); + +#ifdef __cplusplus +} +#endif + +#endif // GPIO_H diff --git a/examples/baremetal/at90can128olimex/redblink/main.c b/examples/baremetal/at90can128olimex/redblink/main.c new file mode 100644 index 000000000..d62f90350 --- /dev/null +++ b/examples/baremetal/at90can128olimex/redblink/main.c @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gpio.h" + +#include <stdint.h> + +static void some_delay(uint32_t counts) +{ + for (uint32_t index = 0u; index < counts; ++index) + __asm("nop"); +} + +int main(void) +{ + gpio_init_red_led(); + + while (1) { + gpio_toggle_red_led(); + some_delay(100000u); + } +} diff --git a/examples/baremetal/at90can128olimex/redblink/redblink.qbs b/examples/baremetal/at90can128olimex/redblink/redblink.qbs new file mode 100644 index 000000000..bbc0d7261 --- /dev/null +++ b/examples/baremetal/at90can128olimex/redblink/redblink.qbs @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import qbs + +CppApplication { + condition: { + if (!qbs.architecture.contains("avr")) + return false; + return qbs.toolchain.contains("gcc") + || qbs.toolchain.contains("iar") + } + name: "redblink" + cpp.cLanguageVersion: "c99" + cpp.positionIndependentCode: false + + // + // GCC-specific properties and sources. + // + + Properties { + condition: qbs.toolchain.contains("gcc") + cpp.driverFlags: ["-mmcu=at90can128"] + } + + // Note: We implicitly use the startup file and the linker script + // which are already linked into the avr-gcc toolchain runtime. + + // + // IAR-specific properties and sources. + // + + Properties { + condition: qbs.toolchain.contains("iar") + cpp.driverFlags: ["--cpu=can128", "-ms"] + cpp.entryPoint: "__program_start" + cpp.driverLinkerFlags: [ + "-D_..X_HEAP_SIZE=0", + "-D_..X_NEAR_HEAP_SIZE=20", + "-D_..X_CSTACK_SIZE=20", + "-D_..X_RSTACK_SIZE=20", + "-D_..X_FLASH_CODE_END=1FFFF", + "-D_..X_FLASH_BASE=_..X_INTVEC_SIZE", + "-D_..X_EXT_SRAM_BASE=_..X_SRAM_END", + "-D_..X_EXT_ROM_BASE=_..X_SRAM_END", + "-D_..X_EXT_NV_BASE=_..X_SRAM_END", + "-D_..X_CSTACK_BASE=_..X_SRAM_BASE", + "-D_..X_CSTACK_END=_..X_SRAM_END", + "-D_..X_RSTACK_BASE=_..X_SRAM_BASE", + "-D_..X_RSTACK_END=_..X_SRAM_END", + "-h'1895'(CODE)0-(_..X_INTVEC_SIZE-1)", + ] + cpp.staticLibraries: [ + // Explicitly link with the runtime dlib library (which contains + // all required startup code and other stuff). + cpp.toolchainInstallPath + "/../lib/dlib/dlAVR-3s-ec_mul-n.r90" + ] + } + + Group { + condition: qbs.toolchain.contains("iar") + name: "IAR" + prefix: "iar/" + Group { + name: "Linker Script" + prefix: cpp.toolchainInstallPath + "/../src/template/" + fileTags: ["linkerscript"] + // Explicitly use the default linker scripts for current target. + files: ["cfg3soim.xcl", "cfgcan128.xcl"] + } + } + + // + // Common code. + // + + Group { + name: "Gpio" + files: ["gpio.c", "gpio.h"] + } + + files: ["main.c"] +} diff --git a/examples/baremetal/baremetal.qbs b/examples/baremetal/baremetal.qbs new file mode 100644 index 000000000..08d41793f --- /dev/null +++ b/examples/baremetal/baremetal.qbs @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import qbs + +Project { + name: "BareMetal" + references: [ + "stm32f4discovery/stm32f4discovery.qbs", + "at90can128olimex/at90can128olimex.qbs", + "cc2540usbdongle/cc2540usbdongle.qbs" + ] +} diff --git a/examples/baremetal/cc2540usbdongle/cc2540usbdongle.qbs b/examples/baremetal/cc2540usbdongle/cc2540usbdongle.qbs new file mode 100644 index 000000000..52e1948eb --- /dev/null +++ b/examples/baremetal/cc2540usbdongle/cc2540usbdongle.qbs @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import qbs + +Project { + name: "Examples for cc2540usbdongle board" + references: [ + "greenblink/greenblink.qbs" + ] +} diff --git a/examples/baremetal/cc2540usbdongle/greenblink/README.md b/examples/baremetal/cc2540usbdongle/greenblink/README.md new file mode 100644 index 000000000..4e90293ed --- /dev/null +++ b/examples/baremetal/cc2540usbdongle/greenblink/README.md @@ -0,0 +1,9 @@ +This example demonstrates how to build a bare-metal application using +different MCS-51 toolchains. It is designed for the CC2540 usb dongle +target board (based on Texas Instruments CC2540 wireless MCU) and +simply flashes the green LED on the board. + +The following toolchains are supported: + + * IAR Embedded Workbench + * KEIL uVision diff --git a/examples/baremetal/cc2540usbdongle/greenblink/gpio.c b/examples/baremetal/cc2540usbdongle/greenblink/gpio.c new file mode 100644 index 000000000..a09471460 --- /dev/null +++ b/examples/baremetal/cc2540usbdongle/greenblink/gpio.c @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gpio.h" +#include "system.h" + +#define GPIO_GREEN_LED_PIN_POS (1u) + +void gpio_init_green_led(void) +{ + P0SEL = 0; // Choose the port. + P0DIR = 0x01; // Set pin0 to output mode. +} + +void gpio_toggle_green_led(void) +{ + P0 ^= GPIO_GREEN_LED_PIN_POS; +} diff --git a/examples/baremetal/cc2540usbdongle/greenblink/gpio.h b/examples/baremetal/cc2540usbdongle/greenblink/gpio.h new file mode 100644 index 000000000..ddeccad0e --- /dev/null +++ b/examples/baremetal/cc2540usbdongle/greenblink/gpio.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GPIO_H +#define GPIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +void gpio_init_green_led(void); +void gpio_toggle_green_led(void); + +#ifdef __cplusplus +} +#endif + +#endif // GPIO_H diff --git a/examples/baremetal/cc2540usbdongle/greenblink/greenblink.qbs b/examples/baremetal/cc2540usbdongle/greenblink/greenblink.qbs new file mode 100644 index 000000000..eb0be6b34 --- /dev/null +++ b/examples/baremetal/cc2540usbdongle/greenblink/greenblink.qbs @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import qbs + +CppApplication { + condition: { + if (!qbs.architecture.contains("mcs51")) + return false; + return qbs.toolchain.contains("iar") + || qbs.toolchain.contains("keil") + || qbs.toolchain.contains("sdcc") + } + name: "greenblink" + cpp.positionIndependentCode: false + + // + // IAR-specific properties and sources. + // + + Properties { + condition: qbs.toolchain.contains("iar") + cpp.commonCompilerFlags: ["-e"] + cpp.driverLinkerFlags: [ + "-D_IDATA_STACK_SIZE=0x40", + "-D_PDATA_STACK_SIZE=0x00", + "-D_XDATA_STACK_SIZE=0x00", + "-D_XDATA_HEAP_SIZE=0x00", + "-D_EXTENDED_STACK_SIZE=0", + "-D_EXTENDED_STACK_START=0" + ] + cpp.staticLibraries: [ + cpp.toolchainInstallPath + "/../lib/clib/cl-pli-nsid-1e16x01" + ] + } + + Group { + condition: qbs.toolchain.contains("iar") + name: "IAR" + prefix: "iar/" + Group { + name: "Linker Script" + prefix: cpp.toolchainInstallPath + "/../config/devices/_generic/" + fileTags: ["linkerscript"] + files: ["lnk51ew_8051.xcl"] + } + } + + // + // KEIL-specific properties and sources. + // + + Properties { + condition: qbs.toolchain.contains("keil") + cpp.driverLinkerFlags: [ + "RAMSIZE(256)", + "CODE(0x0000-0xFFFF)" + ] + } + + // + // SDCC-specific properties and sources. + // + + Properties { + condition: qbs.toolchain.contains("sdcc") + cpp.commonCompilerFlags: ["-mmcs51"] + } + + // + // Common code. + // + + Group { + name: "Gpio" + files: ["gpio.c", "gpio.h"] + } + + Group { + name: "System" + files: ["system.h"] + } + + files: ["main.c"] +} diff --git a/examples/baremetal/cc2540usbdongle/greenblink/main.c b/examples/baremetal/cc2540usbdongle/greenblink/main.c new file mode 100644 index 000000000..88fae04ad --- /dev/null +++ b/examples/baremetal/cc2540usbdongle/greenblink/main.c @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gpio.h" +#include "system.h" + +static void some_delay(unsigned long counts) +{ + unsigned long index = 0u; + for (index = 0u; index < counts; ++index) + system_nop(); +} + +int main(void) +{ + gpio_init_green_led(); + + while (1) { + gpio_toggle_green_led(); + some_delay(20000u); + } +} diff --git a/examples/baremetal/cc2540usbdongle/greenblink/system.h b/examples/baremetal/cc2540usbdongle/greenblink/system.h new file mode 100644 index 000000000..cdc6302d4 --- /dev/null +++ b/examples/baremetal/cc2540usbdongle/greenblink/system.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYSTEM_H +#define SYSTEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__ICC8051__) +#include <intrinsics.h> +# define system_nop() __no_operation() +# define DEFINE_SFR(name,addr) __sfr __no_init volatile unsigned char name @ addr; +#elif defined (__C51__) +#include <intrins.h> +# define system_nop() _nop_() +# define DEFINE_SFR(name, addr) sfr name = addr; +#elif defined (__SDCC_mcs51) +#include <mcs51/compiler.h> +# define DEFINE_SFR(name, addr) __sfr __at(addr) name; +# define system_nop() NOP() +#else +#error "Unsupported toolchain" +#endif + +DEFINE_SFR(P0 , 0x80u) // Port 0. +DEFINE_SFR(P0SEL, 0xF3u) // Port 0 function select. +DEFINE_SFR(P0DIR, 0xFDu) // Port 0 direction select. + +#ifdef __cplusplus +} +#endif + +#endif // SYSTEM_H diff --git a/examples/baremetal/stm32f4discovery/blueblink/README.md b/examples/baremetal/stm32f4discovery/blueblink/README.md new file mode 100644 index 000000000..d15e12515 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/README.md @@ -0,0 +1,10 @@ +This example demonstrates how to build a bare-metal application using +different ARM toolchains. It is designed for the stm32f4discovery +evaluation kit (based on stm32f407vg MCU) and simply flashes the blue +LED on the board. + +The following toolchains are supported: + + * GNU Arm Embedded Toolchain + * IAR Embedded Workbench + * KEIL Microcontroller Development Kit diff --git a/examples/baremetal/stm32f4discovery/blueblink/blueblink.qbs b/examples/baremetal/stm32f4discovery/blueblink/blueblink.qbs new file mode 100644 index 000000000..9b131fa71 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/blueblink.qbs @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import qbs + +CppApplication { + condition: { + if (!qbs.architecture.contains("arm")) + return false; + return qbs.toolchain.contains("gcc") + || qbs.toolchain.contains("iar") + || qbs.toolchain.contains("keil") + } + name: "blueblink" + cpp.cLanguageVersion: "c99" + cpp.positionIndependentCode: false + + // + // GCC-specific properties and sources. + // + + Properties { + condition: qbs.toolchain.contains("gcc") + cpp.driverFlags: [ + "-mcpu=cortex-m4", + "-mfloat-abi=hard", + "-mfpu=fpv4-sp-d16", + "-specs=nosys.specs" + ] + } + + Group { + condition: qbs.toolchain.contains("gcc") + name: "GCC" + prefix: "gcc/" + Group { + name: "Startup" + fileTags: ["asm"] + files: ["startup.s"] + } + Group { + name: "Linker Script" + fileTags: ["linkerscript"] + files: ["flash.ld"] + } + } + + // + // IAR-specific properties and sources. + // + + Properties { + condition: qbs.toolchain.contains("iar") + cpp.driverFlags: [ + "--cpu", "cortex-m4", + "--fpu", "vfpv4_sp" + ] + } + + Group { + condition: qbs.toolchain.contains("iar") + name: "IAR" + prefix: "iar/" + Group { + name: "Startup" + fileTags: ["asm"] + files: ["startup.s"] + } + Group { + name: "Linker Script" + fileTags: ["linkerscript"] + files: ["flash.icf"] + } + } + + // + // KEIL-specific properties and sources. + // + + Properties { + condition: qbs.toolchain.contains("keil") + cpp.driverFlags: [ + "--cpu", "cortex-m4.fp" + ] + } + + Group { + condition: qbs.toolchain.contains("keil") + name: "KEIL" + prefix: "keil/" + Group { + name: "Startup" + fileTags: ["asm"] + files: ["startup.s"] + } + Group { + name: "Linker Script" + fileTags: ["linkerscript"] + files: ["flash.sct"] + } + } + + // + // Common code. + // + + Group { + name: "Gpio" + files: ["gpio.c", "gpio.h"] + } + + Group { + name: "System" + files: ["system.h"] + } + + files: ["main.c"] +} diff --git a/examples/baremetal/stm32f4discovery/blueblink/gcc/flash.ld b/examples/baremetal/stm32f4discovery/blueblink/gcc/flash.ld new file mode 100644 index 000000000..2e1896f3f --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/gcc/flash.ld @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* Entry point (defined in assembled file). */ +ENTRY(reset_handler) + +/* End of RAM, it is the user mode stack pointer address. */ +_end_of_stack = 0x20020000; + +/* Generate a link error if heap and stack don't fit into RAM. */ +_size_of_heap = 0x200; /* Required amount of heap. */ +_size_of_stack = 0x400; /* Required amount of stack. */ + +MEMORY { + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K + CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K +} + +SECTIONS { + /* The vectors table goes into FLASH. */ + .isr_vector : { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code. */ + . = ALIGN(4); + } > FLASH + + /* The program code and other data goes into FLASH. */ + .text : { + . = ALIGN(4); + *(.text) + *(.text*) + *(.glue_7) /* Glue arm to thumb code. */ + *(.glue_7t) /* Glue thumb to arm code. */ + *(.eh_frame) + KEEP(*(.init)) + KEEP(*(.fini)) + . = ALIGN(4); + _end_of_text_section = .; /* Export global symbol at end of code. */ + } > FLASH + + /* Constant data goes into FLASH. */ + .rodata : { + . = ALIGN(4); + *(.rodata) + *(.rodata*) + . = ALIGN(4); + } > FLASH + + .ARM.extab : { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > FLASH + + .preinit_array : { + PROVIDE_HIDDEN(__preinit_array_start = .); + KEEP(*(.preinit_array*)) + PROVIDE_HIDDEN(__preinit_array_end = .); + } > FLASH + + .init_array : { + PROVIDE_HIDDEN(__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array*)) + PROVIDE_HIDDEN(__init_array_end = .); + } > FLASH + + .fini_array : { + PROVIDE_HIDDEN(__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array*)) + PROVIDE_HIDDEN(__fini_array_end = .); + } > FLASH + + _start_of_init_data_section = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code. */ + .data : { + . = ALIGN(4); + _start_of_data_section = .; /* Export global symbol at data start. */ + *(.data) + *(.data*) + . = ALIGN(4); + _end_of_data_section = .; /* Export global symbol at data end. */ + } > RAM AT > FLASH + + _start_of_iccm_ram_section = LOADADDR(.ccmram); + + /* CCM-RAM section. */ + .ccmram : { + . = ALIGN(4); + _start_of_ccmram_section = .; /* Export global symbol at ccmram start. */ + *(.ccmram) + *(.ccmram*) + . = ALIGN(4); + _end_of_ccmram_section = .; /* Export global symbol at ccmram end. */ + } > CCMRAM AT > FLASH + + /* Uninitialized data section. */ + . = ALIGN(4); + .bss : { + /* This is used by the startup in order to initialize the .bss secion. */ + _start_of_bss_section = .; /* Export global symbol at bss start. */ + __bss_start__ = _start_of_bss_section; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _end_of_bss_section = .; /* Export global symbol at bss end. */ + __bss_end__ = _end_of_bss_section; + } > RAM + + /* Used to check that there is enough RAM left. */ + ._user_heap_stack : { + . = ALIGN(4); + PROVIDE(end = .); + PROVIDE(_end = .); + . = . + _size_of_heap; + . = . + _size_of_stack; + . = ALIGN(4); + } > RAM + + /* Remove information from the standard libraries. */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { + *(.ARM.attributes) + } +} diff --git a/examples/baremetal/stm32f4discovery/blueblink/gcc/startup.s b/examples/baremetal/stm32f4discovery/blueblink/gcc/startup.s new file mode 100644 index 000000000..d6a2104d1 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/gcc/startup.s @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +.syntax unified +.cpu cortex-m4 +.fpu softvfp +.thumb + +// These symbols are exported from the linker script. +.word _start_of_init_data_section +.word _start_of_data_section +.word _end_of_data_section +.word _start_of_bss_section +.word _end_of_bss_section +.word _end_of_stack + +// Define the 'reset_handler' function, which is an entry point. +.section .text.reset_handler +.weak reset_handler +.type reset_handler, %function +reset_handler: + // Set the stack pointer. + ldr sp, =_end_of_stack + + // Copy the data segment initializers from flash to SRAM. + movs r1, #0 + b _loop_copy_data_init +_copy_data_init: + ldr r3, =_start_of_init_data_section + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 +_loop_copy_data_init: + ldr r0, =_start_of_data_section + ldr r3, =_end_of_data_section + adds r2, r0, r1 + cmp r2, r3 + bcc _copy_data_init + ldr r2, =_start_of_bss_section + b _loop_fill_zero_bss + + // Zero fill the bss segment. +_fill_zero_bss: + movs r3, #0 + str r3, [r2], #4 +_loop_fill_zero_bss: + ldr r3, = _end_of_bss_section + cmp r2, r3 + bcc _fill_zero_bss + + // Call the static constructors. + bl __libc_init_array + + // Call the application's entry point. + bl main + bx lr +.size reset_handler, .-reset_handler + +// Define the empty vectors table. +.section .isr_vector,"a",%progbits +.type _vectors_table, %object +.size _vectors_table, .-_vectors_table +_vectors_table: + // Generic interrupts offset. + .word _end_of_stack // Initial stack pointer value. + .word reset_handler // Reset. + .word 0 // NMI. + .word 0 // Hard fault. + .word 0 // Memory management fault. + .word 0 // Bus fault. + .word 0 // Usage fault. + .word 0 // Reserved. + .word 0 // Reserved. + .word 0 // Reserved. + .word 0 // Reserved. + .word 0 // SVC. + .word 0 // Debug monitor. + .word 0 // Reserved. + .word 0 // PendSV. + .word 0 // SysTick. + + // External interrupts offset. + .word 0 // Window WatchDog. + .word 0 // PVD through EXTI Line detection. + .word 0 // Tamper and TimeStamps through the EXTI line. + .word 0 // RTC Wakeup through the EXTI line. + .word 0 // FLASH. + .word 0 // RCC. + .word 0 // EXTI Line0. + .word 0 // EXTI Line1. + .word 0 // EXTI Line2. + .word 0 // EXTI Line3. + .word 0 // EXTI Line4. + .word 0 // DMA1 Stream 0. + .word 0 // DMA1 Stream 1. + .word 0 // DMA1 Stream 2. + .word 0 // DMA1 Stream 3. + .word 0 // DMA1 Stream 4. + .word 0 // DMA1 Stream 5. + .word 0 // DMA1 Stream 6. + .word 0 // ADC1, ADC2 and ADC3s. + .word 0 // CAN1 TX. + .word 0 // CAN1 RX0. + .word 0 // CAN1 RX1. + .word 0 // CAN1 SCE. + .word 0 // External Line[9:5]s. + .word 0 // TIM1 Break and TIM9. + .word 0 // TIM1 Update and TIM10. + .word 0 // TIM1 Trigger and Commutation and TIM11. + .word 0 // TIM1 Capture Compare. + .word 0 // TIM2. + .word 0 // TIM3. + .word 0 // TIM4. + .word 0 // I2C1 Event. + .word 0 // I2C1 Error. + .word 0 // I2C2 Event. + .word 0 // I2C2 Error. + .word 0 // SPI1. + .word 0 // SPI2. + .word 0 // USART1. + .word 0 // USART2. + .word 0 // USART3. + .word 0 // External Line[15:10]s. + .word 0 // RTC Alarm (A and B) through EXTI Line. + .word 0 // USB OTG FS Wakeup through EXTI line. + .word 0 // TIM8 Break and TIM12. + .word 0 // TIM8 Update and TIM13. + .word 0 // TIM8 Trigger and Commutation and TIM14. + .word 0 // TIM8 Capture Compare. + .word 0 // DMA1 Stream7. + .word 0 // FSMC. + .word 0 // SDIO. + .word 0 // TIM5. + .word 0 // SPI3. + .word 0 // UART4. + .word 0 // UART5. + .word 0 // TIM6 and DAC1&2 underrun errors. + .word 0 // TIM7. + .word 0 // DMA2 Stream 0. + .word 0 // DMA2 Stream 1. + .word 0 // DMA2 Stream 2. + .word 0 // DMA2 Stream 3. + .word 0 // DMA2 Stream 4. + .word 0 // Ethernet. + .word 0 // Ethernet Wakeup through EXTI line. + .word 0 // CAN2 TX. + .word 0 // CAN2 RX0. + .word 0 // CAN2 RX1. + .word 0 // CAN2 SCE. + .word 0 // USB OTG FS. + .word 0 // DMA2 Stream 5. + .word 0 // DMA2 Stream 6. + .word 0 // DMA2 Stream 7. + .word 0 // USART6. + .word 0 // I2C3 event. + .word 0 // I2C3 error. + .word 0 // USB OTG HS End Point 1 Out. + .word 0 // USB OTG HS End Point 1 In. + .word 0 // USB OTG HS Wakeup through EXTI. + .word 0 // USB OTG HS. + .word 0 // DCMI. + .word 0 // CRYP crypto. + .word 0 // Hash and Rng. + .word 0 // FPU. diff --git a/examples/baremetal/stm32f4discovery/blueblink/gpio.c b/examples/baremetal/stm32f4discovery/blueblink/gpio.c new file mode 100644 index 000000000..e337f8d24 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/gpio.c @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gpio.h" +#include "system.h" + +#define GPIO_BLUE_LED_PIN_POS (15u) +#define GPIO_BLUE_LED_PIN (1u << GPIO_BLUE_LED_PIN_POS) + +// Output push pull mode. +#define GPIO_MODE_OUTPUT_PP (0x00000001u) + +// Bit definition for RCC_AHB1ENR register. +#define RCC_AHB1ENR_GPIODEN (0x00000008u) +// Bits definition for GPIO_MODER register. +#define GPIO_MODER_MODE0 (0x00000003u) + +void gpio_init_blue_led(void) +{ + // Enable RCC clock on GPIOD port. + RCC_REGS_MAP->AHB1ENR |= RCC_AHB1ENR_GPIODEN; + // Configure GPIO pin #15 as an output. + uint32_t value = GPIOD_REGS_MAP->MODER; + value &= ~(GPIO_MODER_MODE0 << (GPIO_BLUE_LED_PIN_POS * 2u)); + value |= (GPIO_MODE_OUTPUT_PP << (GPIO_BLUE_LED_PIN_POS * 2u)); + GPIOD_REGS_MAP->MODER = value; +} + +void gpio_toggle_blue_led(void) +{ + GPIOD_REGS_MAP->ODR ^= GPIO_BLUE_LED_PIN; +} diff --git a/examples/baremetal/stm32f4discovery/blueblink/gpio.h b/examples/baremetal/stm32f4discovery/blueblink/gpio.h new file mode 100644 index 000000000..560dcbac7 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/gpio.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GPIO_H +#define GPIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +void gpio_init_blue_led(void); +void gpio_toggle_blue_led(void); + +#ifdef __cplusplus +} +#endif + +#endif // GPIO_H diff --git a/examples/baremetal/stm32f4discovery/blueblink/iar/flash.icf b/examples/baremetal/stm32f4discovery/blueblink/iar/flash.icf new file mode 100644 index 000000000..04cff04c4 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/iar/flash.icf @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +define symbol _start_of_intvec_section = 0x08000000; + +define symbol _start_of_ram_section = 0x20000000; +define symbol _end_of_ram_section = 0x2001FFFF; +define symbol _start_of_ccmram_section = 0x10000000; +define symbol _end_of_ccmram_section = 0x1000FFFF; +define symbol _start_of_flash_section = 0x08000000; +define symbol _end_of_flash_section = 0x080FFFFF; + +define symbol _min_stack_size = 0x400; +define symbol _min_heap_size = 0x200; + +define memory mem with size = 4G; +define region flash_section = mem:[from _start_of_flash_section to _end_of_flash_section]; +define region ram_section = mem:[from _start_of_ram_section to _end_of_ram_section]; +define region ccmram_section = mem:[from _start_of_ccmram_section to _end_of_ccmram_section]; + +define block CSTACK with alignment = 8, size = _min_stack_size { }; +define block HEAP with alignment = 8, size = _min_heap_size { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:_start_of_intvec_section { readonly section .intvec }; + +place in flash_section { readonly }; +place in ram_section { readwrite, block CSTACK, block HEAP }; diff --git a/examples/baremetal/stm32f4discovery/blueblink/iar/startup.s b/examples/baremetal/stm32f4discovery/blueblink/iar/startup.s new file mode 100644 index 000000000..fe88e6bc8 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/iar/startup.s @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + MODULE ?cstartup + + SECTION CSTACK:DATA:NOROOT(3) + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + + PUBLIC _vectors_table + DATA +_vectors_table + ;; Generic interrupts offset. + DCD sfe(CSTACK) ; Initial stack pointer value. + DCD reset_handler ; Reset. + DCD 0 ; NMI. + DCD 0 ; Hard fault. + DCD 0 ; Memory management fault. + DCD 0 ; Bus fault. + DCD 0 ; Usage fault. + DCD 0 ; Reserved. + DCD 0 ; Reserved. + DCD 0 ; Reserved. + DCD 0 ; Reserved. + DCD 0 ; SVC. + DCD 0 ; Debug monitor. + DCD 0 ; Reserved. + DCD 0 ; PendSV. + DCD 0 ; SysTick. + ;; External interrupts offset. + DCD 0 ; Window WatchDog. + DCD 0 ; PVD through EXTI Line detection. + DCD 0 ; Tamper and TimeStamps through the EXTI line. + DCD 0 ; RTC Wakeup through the EXTI line. + DCD 0 ; FLASH. + DCD 0 ; RCC. + DCD 0 ; EXTI Line0. + DCD 0 ; EXTI Line1. + DCD 0 ; EXTI Line2. + DCD 0 ; EXTI Line3. + DCD 0 ; EXTI Line4. + DCD 0 ; DMA1 Stream 0. + DCD 0 ; DMA1 Stream 1. + DCD 0 ; DMA1 Stream 2. + DCD 0 ; DMA1 Stream 3. + DCD 0 ; DMA1 Stream 4. + DCD 0 ; DMA1 Stream 5. + DCD 0 ; DMA1 Stream 6. + DCD 0 ; ADC1, ADC2 and ADC3s. + DCD 0 ; CAN1 TX. + DCD 0 ; CAN1 RX0. + DCD 0 ; CAN1 RX1. + DCD 0 ; CAN1 SCE. + DCD 0 ; External Line[9:5]s. + DCD 0 ; TIM1 Break and TIM9. + DCD 0 ; TIM1 Update and TIM10. + DCD 0 ; TIM1 Trigger and Commutation and TIM11. + DCD 0 ; TIM1 Capture Compare. + DCD 0 ; TIM2. + DCD 0 ; TIM3. + DCD 0 ; TIM4. + DCD 0 ; I2C1 Event. + DCD 0 ; I2C1 Error. + DCD 0 ; I2C2 Event. + DCD 0 ; I2C2 Error. + DCD 0 ; SPI1. + DCD 0 ; SPI2. + DCD 0 ; USART1. + DCD 0 ; USART2. + DCD 0 ; USART3. + DCD 0 ; External Line[15:10]s. + DCD 0 ; RTC Alarm (A and B) through EXTI Line. + DCD 0 ; USB OTG FS Wakeup through EXTI line. + DCD 0 ; TIM8 Break and TIM12. + DCD 0 ; TIM8 Update and TIM13. + DCD 0 ; TIM8 Trigger and Commutation and TIM14. + DCD 0 ; TIM8 Capture Compare. + DCD 0 ; DMA1 Stream7. + DCD 0 ; FSMC. + DCD 0 ; SDIO. + DCD 0 ; TIM5. + DCD 0 ; SPI3. + DCD 0 ; UART4. + DCD 0 ; UART5. + DCD 0 ; TIM6 and DAC1&2 underrun errors. + DCD 0 ; TIM7. + DCD 0 ; DMA2 Stream 0. + DCD 0 ; DMA2 Stream 1. + DCD 0 ; DMA2 Stream 2. + DCD 0 ; DMA2 Stream 3. + DCD 0 ; DMA2 Stream 4. + DCD 0 ; Ethernet. + DCD 0 ; Ethernet Wakeup through EXTI line. + DCD 0 ; CAN2 TX. + DCD 0 ; CAN2 RX0. + DCD 0 ; CAN2 RX1. + DCD 0 ; CAN2 SCE. + DCD 0 ; USB OTG FS. + DCD 0 ; DMA2 Stream 5. + DCD 0 ; DMA2 Stream 6. + DCD 0 ; DMA2 Stream 7. + DCD 0 ; USART6. + DCD 0 ; I2C3 event. + DCD 0 ; I2C3 error. + DCD 0 ; USB OTG HS End Point 1 Out. + DCD 0 ; USB OTG HS End Point 1 In. + DCD 0 ; USB OTG HS Wakeup through EXTI. + DCD 0 ; USB OTG HS. + DCD 0 ; DCMI. + DCD 0 ; CRYP crypto. + DCD 0 ; Hash and RNG. + DCD 0 ; FPU. + + ;; Reset handler. + THUMB + PUBWEAK reset_handler + SECTION .text:CODE:REORDER:NOROOT(2) +reset_handler + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + END diff --git a/examples/baremetal/stm32f4discovery/blueblink/keil/flash.sct b/examples/baremetal/stm32f4discovery/blueblink/keil/flash.sct new file mode 100644 index 000000000..7a5500182 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/keil/flash.sct @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +;; Load region size_region. +LR_IROM1 0x08000000 0x00100000 { + ;; Load address = execution address. + ER_IROM1 0x08000000 0x00100000 { + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + + ; RW data. + RW_IRAM1 0x20000000 0x00020000 { + .ANY (+RW +ZI) + } +} diff --git a/examples/baremetal/stm32f4discovery/blueblink/keil/startup.s b/examples/baremetal/stm32f4discovery/blueblink/keil/startup.s new file mode 100644 index 000000000..38e5b5058 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/keil/startup.s @@ -0,0 +1,184 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +;; Contact: https://www.qt.io/licensing/ +;; +;; This file is part of the examples of Qbs. +;; +;; $QT_BEGIN_LICENSE:BSD$ +;; 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. +;; +;; BSD License Usage +;; Alternatively, you may use this file under the terms of the BSD license +;; as follows: +;; +;; "Redistribution and use in source and binary forms, with or without +;; modification, are permitted provided that the following conditions are +;; met: +;; * Redistributions of source code must retain the above copyright +;; notice, this list of conditions and the following disclaimer. +;; * Redistributions in binary form must reproduce the above copyright +;; notice, this list of conditions and the following disclaimer in +;; the documentation and/or other materials provided with the +;; distribution. +;; * Neither the name of The Qt Company Ltd nor the names of its +;; contributors may be used to endorse or promote products derived +;; from this software without specific prior written permission. +;; +;; +;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +;; +;; $QT_END_LICENSE$ +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +_size_of_stack EQU 0x400 +_size_of_heap EQU 0x200 + +;; Stack configuration. + AREA STACK, NOINIT, READWRITE, ALIGN=3 +_start_of_stack SPACE _size_of_stack +_end_of_stack + +;; Heap configuration. + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +_start_of_heap SPACE _size_of_heap +_end_of_heap + + PRESERVE8 + THUMB + +;; Define the empty vectors table. + AREA RESET, DATA, READONLY +_vectors_table + ;; Generic interrupts offset. + DCD _end_of_stack ; Initial stack pointer value. + DCD reset_handler ; Reset. + DCD 0 ; NMI. + DCD 0 ; Hard fault. + DCD 0 ; Memory management fault. + DCD 0 ; Bus fault. + DCD 0 ; Usage fault. + DCD 0 ; Reserved. + DCD 0 ; Reserved. + DCD 0 ; Reserved. + DCD 0 ; Reserved. + DCD 0 ; SVC. + DCD 0 ; Debug monitor. + DCD 0 ; Reserved. + DCD 0 ; PendSV. + DCD 0 ; SysTick. + ;; External interrupts offset. + DCD 0 ; Window WatchDog. + DCD 0 ; PVD through EXTI Line detection. + DCD 0 ; Tamper and TimeStamps through the EXTI line. + DCD 0 ; RTC Wakeup through the EXTI line. + DCD 0 ; FLASH. + DCD 0 ; RCC. + DCD 0 ; EXTI Line0. + DCD 0 ; EXTI Line1. + DCD 0 ; EXTI Line2. + DCD 0 ; EXTI Line3. + DCD 0 ; EXTI Line4. + DCD 0 ; DMA1 Stream 0. + DCD 0 ; DMA1 Stream 1. + DCD 0 ; DMA1 Stream 2. + DCD 0 ; DMA1 Stream 3. + DCD 0 ; DMA1 Stream 4. + DCD 0 ; DMA1 Stream 5. + DCD 0 ; DMA1 Stream 6. + DCD 0 ; ADC1, ADC2 and ADC3s. + DCD 0 ; CAN1 TX. + DCD 0 ; CAN1 RX0. + DCD 0 ; CAN1 RX1. + DCD 0 ; CAN1 SCE. + DCD 0 ; External Line[9:5]s. + DCD 0 ; TIM1 Break and TIM9. + DCD 0 ; TIM1 Update and TIM10. + DCD 0 ; TIM1 Trigger and Commutation and TIM11. + DCD 0 ; TIM1 Capture Compare. + DCD 0 ; TIM2. + DCD 0 ; TIM3. + DCD 0 ; TIM4. + DCD 0 ; I2C1 Event. + DCD 0 ; I2C1 Error. + DCD 0 ; I2C2 Event. + DCD 0 ; I2C2 Error. + DCD 0 ; SPI1. + DCD 0 ; SPI2. + DCD 0 ; USART1. + DCD 0 ; USART2. + DCD 0 ; USART3. + DCD 0 ; External Line[15:10]s. + DCD 0 ; RTC Alarm (A and B) through EXTI Line. + DCD 0 ; USB OTG FS Wakeup through EXTI line. + DCD 0 ; TIM8 Break and TIM12. + DCD 0 ; TIM8 Update and TIM13. + DCD 0 ; TIM8 Trigger and Commutation and TIM14. + DCD 0 ; TIM8 Capture Compare. + DCD 0 ; DMA1 Stream7. + DCD 0 ; FMC. + DCD 0 ; SDIO. + DCD 0 ; TIM5. + DCD 0 ; SPI3. + DCD 0 ; UART4. + DCD 0 ; UART5. + DCD 0 ; TIM6 and DAC1&2 underrun errors. + DCD 0 ; TIM7. + DCD 0 ; DMA2 Stream 0. + DCD 0 ; DMA2 Stream 1. + DCD 0 ; DMA2 Stream 2. + DCD 0 ; DMA2 Stream 3. + DCD 0 ; DMA2 Stream 4. + DCD 0 ; Ethernet. + DCD 0 ; Ethernet Wakeup through EXTI line. + DCD 0 ; CAN2 TX. + DCD 0 ; CAN2 RX0. + DCD 0 ; CAN2 RX1. + DCD 0 ; CAN2 SCE. + DCD 0 ; USB OTG FS. + DCD 0 ; DMA2 Stream 5. + DCD 0 ; DMA2 Stream 6. + DCD 0 ; DMA2 Stream 7. + DCD 0 ; USART6. + DCD 0 ; I2C3 event. + DCD 0 ; I2C3 error. + DCD 0 ; USB OTG HS End Point 1 Out. + DCD 0 ; USB OTG HS End Point 1 In. + DCD 0 ; USB OTG HS Wakeup through EXTI. + DCD 0 ; USB OTG HS. + DCD 0 ; DCMI. + DCD 0 ; Reserved. + DCD 0 ; Hash and Rng. + DCD 0 ; FPU. +_end_of_vectors_table + +_size_of_vectors_table EQU _end_of_vectors_table - _vectors_table + + AREA |.text|, CODE, READONLY +;; Reset handler. +reset_handler PROC + EXPORT reset_handler [WEAK] + IMPORT main + LDR R0, =main + BX R0 + ENDP + ALIGN + + END diff --git a/examples/baremetal/stm32f4discovery/blueblink/main.c b/examples/baremetal/stm32f4discovery/blueblink/main.c new file mode 100644 index 000000000..ef69fc8e6 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/main.c @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gpio.h" + +#include <stdint.h> + +static void some_delay(uint32_t counts) +{ + for (uint32_t index = 0u; index < counts; ++index) + __asm("nop"); +} + +int main(void) +{ + gpio_init_blue_led(); + + while (1) { + gpio_toggle_blue_led(); + some_delay(100000u); + } +} diff --git a/examples/baremetal/stm32f4discovery/blueblink/system.h b/examples/baremetal/stm32f4discovery/blueblink/system.h new file mode 100644 index 000000000..6e7190026 --- /dev/null +++ b/examples/baremetal/stm32f4discovery/blueblink/system.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYSTEM_H +#define SYSTEM_H + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define __IO volatile + +// General purpose input/output registers map. +struct gpio_regs_map { + __IO uint32_t MODER; + __IO uint32_t OTYPER; + __IO uint32_t OSPEEDR; + __IO uint32_t PUPDR; + __IO uint32_t IDR; + __IO uint32_t ODR; + __IO uint32_t BSRR; + __IO uint32_t LCKR; + __IO uint32_t AFR[2u]; +}; + +// Reset and clock control registers map. +struct rcc_regs_map { + __IO uint32_t CR; + __IO uint32_t PLLCFGR; + __IO uint32_t CFGR; + __IO uint32_t CIR; + __IO uint32_t AHB1RSTR; + __IO uint32_t AHB2RSTR; + __IO uint32_t AHB3RSTR; + uint32_t RESERVED0; + __IO uint32_t APB1RSTR; + __IO uint32_t APB2RSTR; + uint32_t RESERVED1[2u]; + __IO uint32_t AHB1ENR; + __IO uint32_t AHB2ENR; + __IO uint32_t AHB3ENR; + uint32_t RESERVED2; + __IO uint32_t APB1ENR; + __IO uint32_t APB2ENR; + uint32_t RESERVED3[2u]; + __IO uint32_t AHB1LPENR; + __IO uint32_t AHB2LPENR; + __IO uint32_t AHB3LPENR; + uint32_t RESERVED4; + __IO uint32_t APB1LPENR; + __IO uint32_t APB2LPENR; + uint32_t RESERVED5[2u]; + __IO uint32_t BDCR; + __IO uint32_t CSR; + uint32_t RESERVED6[2u]; + __IO uint32_t SSCGR; + __IO uint32_t PLLI2SCFGR; +}; + +#define PERIPH_ADDRESS (0x40000000u) + +#define APB2PERIPH_ADDRESS (PERIPH_ADDRESS + 0x00010000u) +#define AHB1PERIPH_ADDRESS (PERIPH_ADDRESS + 0x00020000u) + +// APB2 peripherals. +#define SYSCFG_REGS_ADDRESS (APB2PERIPH_ADDRESS + 0x3800u) +#define EXTI_REGS_ADDRESS (APB2PERIPH_ADDRESS + 0x3C00u) + +// AHB1 peripherals. +#define GPIOD_REGS_ADDRESS (AHB1PERIPH_ADDRESS + 0x0C00u) +#define RCC_REGS_ADDRESS (AHB1PERIPH_ADDRESS + 0x3800u) + +#define GPIOD_REGS_MAP ((struct gpio_regs_map *)GPIOD_REGS_ADDRESS) +#define RCC_REGS_MAP ((struct rcc_regs_map *)RCC_REGS_ADDRESS) + +#ifdef __cplusplus +} +#endif + +#endif // SYSTEM_H diff --git a/examples/baremetal/stm32f4discovery/stm32f4discovery.qbs b/examples/baremetal/stm32f4discovery/stm32f4discovery.qbs new file mode 100644 index 000000000..a402848ca --- /dev/null +++ b/examples/baremetal/stm32f4discovery/stm32f4discovery.qbs @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qbs. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import qbs + +Project { + name: "Examples for stm32f4discovery board" + references: [ + "blueblink/blueblink.qbs" + ] +} diff --git a/examples/examples.qbs b/examples/examples.qbs index 4e51bdbaf..c6c1f4ac3 100644 --- a/examples/examples.qbs +++ b/examples/examples.qbs @@ -64,5 +64,6 @@ Project { "install-bundle/install-bundle.qbs", "protobuf/cpp/addressbook.qbs", "protobuf/objc/addressbook.qbs", + "baremetal/baremetal.qbs" ] } diff --git a/qbs-resources/imports/QbsProduct.qbs b/qbs-resources/imports/QbsProduct.qbs index 1685a9d4e..b3a166e42 100644 --- a/qbs-resources/imports/QbsProduct.qbs +++ b/qbs-resources/imports/QbsProduct.qbs @@ -4,7 +4,7 @@ Product { Depends { name: "qbsbuildconfig" } Depends { name: "qbsversion" } Depends { name: "Qt.core"; versionAtLeast: minimumQtVersion } - property string minimumQtVersion: "5.9.0" + property string minimumQtVersion: "5.11.0" property bool install: true property string targetInstallDir cpp.defines: { @@ -24,9 +24,9 @@ defineTest(minQtVersion) { return(false) } -!minQtVersion(5, 9, 0) { +!minQtVersion(5, 11, 0) { message("Cannot build qbs with Qt version $${QT_VERSION}.") - error("Use at least Qt 5.9.0.") + error("Use at least Qt 5.11.0.") } TEMPLATE = subdirs diff --git a/scripts/address-sanitizer-suppressions.txt b/scripts/address-sanitizer-suppressions.txt new file mode 100644 index 000000000..9381cc58e --- /dev/null +++ b/scripts/address-sanitizer-suppressions.txt @@ -0,0 +1 @@ +leak:libQt5Script.so.5 diff --git a/scripts/build-qbs-with-qbs.sh b/scripts/build-qbs-with-qbs.sh new file mode 100755 index 000000000..0808cbbef --- /dev/null +++ b/scripts/build-qbs-with-qbs.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +############################################################################# +## +## Copyright (C) 2019 Richard Weickelt. +## 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$ +## +############################################################################# +set -e + +# +# It might be desired to keep settings for Qbs testing +# in a separate folder. +# +export QBS_AUTOTEST_SETTINGS_DIR="${QBS_AUTOTEST_SETTINGS_DIR:-/tmp/qbs-settings}" + +# +# Qbs is built with the address sanitizer enabled. +# Suppress findings in some parts of Qbs / dependencies. +# +export LSAN_OPTIONS="suppressions=$( cd "$(dirname "$0")" ; pwd -P )/address-sanitizer-suppressions.txt:print_suppressions=0" + +# +# Additional build options +# +BUILD_OPTIONS="\ + ${QBS_BUILD_PROFILE:+profile:${QBS_BUILD_PROFILE}} \ + modules.qbsbuildconfig.enableAddressSanitizer:true \ + modules.qbsbuildconfig.enableProjectFileUpdates:true \ + modules.qbsbuildconfig.enableUnitTests:true \ +" + +# +# Build all default products of Qbs +# +qbs resolve ${BUILD_OPTIONS} +qbs build ${BUILD_OPTIONS} +qbs build -p "qbs documentation" ${BUILD_OPTIONS} + +# +# Set up profiles for the freshly built Qbs if not +# explicitly specified otherwise +# +if [ -z "${QBS_AUTOTEST_PROFILE}" ]; then + + export QBS_AUTOTEST_PROFILE=autotestprofile + + RUN_OPTIONS="\ + --settings-dir ${QBS_AUTOTEST_SETTINGS_DIR} \ + " + + qbs run -p qbs_app ${BUILD_OPTIONS} -- setup-toolchains \ + ${RUN_OPTIONS} \ + --detect + + qbs run -p qbs_app ${BUILD_OPTIONS} -- setup-qt \ + ${RUN_OPTIONS} \ + "${QMAKE_PATH:-$(which qmake)}" ${QBS_AUTOTEST_PROFILE} + + qbs run -p qbs_app ${BUILD_OPTIONS} -- config \ + ${RUN_OPTIONS} \ + ${QBS_AUTOTEST_PROFILE}.baseProfile gcc + + # QBS_AUTOTEST_PROFILE has been added to the environment + # which requires a resolve step + qbs resolve ${BUILD_OPTIONS} +fi + +# +# Run all autotests with QBS_AUTOTEST_PROFILE +# +qbs build -p "autotest-runner" ${BUILD_OPTIONS} diff --git a/scripts/build-qbs-with-qmake.sh b/scripts/build-qbs-with-qmake.sh new file mode 100755 index 000000000..f06501e30 --- /dev/null +++ b/scripts/build-qbs-with-qmake.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +############################################################################# +## +## Copyright (C) 2019 Richard Weickelt. +## 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$ +## +############################################################################# +set -e + +# +# It might be desired to keep settings for Qbs testing +# in a separate folder. +# +export QBS_AUTOTEST_SETTINGS_DIR="${QBS_AUTOTEST_SETTINGS_DIR:-/tmp/qbs-settings}" + +# +# Build all default products of Qbs +# +qmake -r qbs.pro \ + CONFIG+=qbs_enable_unit_tests \ + CONFIG+=qbs_enable_project_file_updates +make -j $(nproc --all) +make docs + +# +# Set up profiles for the freshly built Qbs if not +# explicitly specified otherwise +# +if [ -z "${QBS_AUTOTEST_PROFILE}" ]; then + + export QBS_AUTOTEST_PROFILE=autotestprofile + RUN_OPTIONS="\ + --settings-dir ${QBS_AUTOTEST_SETTINGS_DIR} \ + " + + ./bin/qbs setup-toolchains \ + ${RUN_OPTIONS} \ + --detect + + ./bin/qbs setup-qt \ + ${RUN_OPTIONS} \ + "${QMAKE_PATH:-$(which qmake)}" ${QBS_AUTOTEST_PROFILE} + + ./bin/qbs config \ + ${RUN_OPTIONS} \ + ${QBS_AUTOTEST_PROFILE}.baseProfile gcc + +fi + + +make check -j $(nproc --all) diff --git a/scripts/run-analyzer.sh b/scripts/run-analyzer.sh new file mode 100755 index 000000000..e3743f631 --- /dev/null +++ b/scripts/run-analyzer.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +############################################################################# +## +## Copyright (C) 2019 Ivan Komissarov +## Contact: abbapoh@gmail.com +## +## 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$ +## +############################################################################# + +set -e + +LLVM_INSTALL_DIR=${LLVM_INSTALL_DIR:-""} + +# on Debian, it might be necessary to setup which version of clang-tidy and run-clang-tidy.py +# is desired: +# update-alternatives --install /usr/bin/run-clang-tidy.py run-clang-tidy.py /usr/bin/run-clang-tidy-4.0.py 1 + +CLANG_TIDY=`which clang-tidy` +RUN_CLANG_TIDY=`which run-clang-tidy.py` + +if [ -z "$RUN_CLANG_TIDY" ] || [ -z "$CLANG_TIDY" ]; then + if [ ! -z "$LLVM_INSTALL_DIR" ]; then + CLANG_TIDY="$LLVM_INSTALL_DIR/bin/clang-tidy" + RUN_CLANG_TIDY="$LLVM_INSTALL_DIR/share/clang/run-clang-tidy.py" + else + echo "Can't find clang-tidy and/or run-clang-tidy.py in PATH, try setting LLVM_INSTALL_DIR" + exit 1 + fi +fi + +BUILD_OPTIONS="\ + ${QBS_BUILD_PROFILE:+profile:${QBS_BUILD_PROFILE}} \ + modules.qbsbuildconfig.enableProjectFileUpdates:true \ + modules.qbsbuildconfig.enableUnitTests:true \ + config:analyzer +" + +QBS_SRC_DIR=${QBS_SRC_DIR:-`pwd`} + +if [ ! -f "$QBS_SRC_DIR/qbs.qbs" ]; then + echo "Can't find qbs.qbs in $QBS_SRC_DIR, try setting QBS_SRC_DIR" + exit 1 +fi + +qbs resolve -f "$QBS_SRC_DIR/qbs.qbs" $BUILD_OPTIONS +qbs build -f "$QBS_SRC_DIR/qbs.qbs" $BUILD_OPTIONS +qbs generate -g clangdb -f "$QBS_SRC_DIR/qbs.qbs" $BUILD_OPTIONS + +"$RUN_CLANG_TIDY" -p analyzer -clang-tidy-binary "$CLANG_TIDY" -header-filter=".*qbs.*\.h" diff --git a/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs b/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs index f7abce388..4a86ee935 100644 --- a/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs +++ b/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs @@ -63,7 +63,6 @@ PathProbe { property var hostArch property stringList toolchains: [] property string ndkVersion - property string ndkPlatform configure: { function readFileContent(filePath) { @@ -93,9 +92,6 @@ PathProbe { for (j in platforms) { if (File.exists(FileInfo.joinPaths(allPaths[i], "prebuilt", platforms[j]))) { path = allPaths[i]; - var ndkPlatforms = AndroidUtils.availablePlatforms(path); - if (ndkPlatforms.length > 0) - ndkPlatform = ndkPlatforms[ndkPlatforms.length - 1]; if (File.exists(FileInfo.joinPaths(path, "samples"))) samplesDir = FileInfo.joinPaths(path, "samples"); // removed in r11 hostArch = platforms[j]; diff --git a/share/qbs/imports/qbs/Probes/ClangClProbe.qbs b/share/qbs/imports/qbs/Probes/ClangClProbe.qbs new file mode 100644 index 000000000..c7687f0e9 --- /dev/null +++ b/share/qbs/imports/qbs/Probes/ClangClProbe.qbs @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Ivan Komissarov (abbapoh@gmail.com) +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** 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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import qbs.File +import qbs.FileInfo +import qbs.ModUtils +import qbs.Utilities +import "../../../modules/cpp/gcc.js" as Gcc + +PathProbe { + // Inputs + property string compilerFilePath + property string vcvarsallFilePath + property stringList enableDefinesByLanguage + property string architecture + property string _nullDevice: qbs.nullDevice + property string _pathListSeparator: qbs.pathListSeparator + + // Outputs + property int versionMajor + property int versionMinor + property int versionPatch + property stringList includePaths + property var buildEnv + property var compilerDefinesByLanguage + + configure: { + var languages = enableDefinesByLanguage; + if (!languages || languages.length === 0) + languages = ["c"]; + + var info = languages.contains("c") + ? Utilities.clangClCompilerInfo(compilerFilePath, architecture, vcvarsallFilePath, "c") : {}; + var infoCpp = languages.contains("cpp") + ? Utilities.clangClCompilerInfo(compilerFilePath, architecture, vcvarsallFilePath, "cpp") : {}; + found = (!languages.contains("c") || + (!!info && !!info.macros && !!info.buildEnvironment)) + && (!languages.contains("cpp") || + (!!infoCpp && !!infoCpp.macros && !!infoCpp.buildEnvironment)); + + compilerDefinesByLanguage = { + "c": info.macros, + "cpp": infoCpp.macros, + }; + + var macros = info.macros || infoCpp.macros; + + versionMajor = parseInt(macros["__clang_major__"], 10); + versionMinor = parseInt(macros["__clang_minor__"], 10); + versionPatch = parseInt(macros["__clang_patchlevel__"], 10); + + buildEnv = info.buildEnvironment || infoCpp.buildEnvironment; + // clang-cl is just a wrapper around clang.exe, so the includes *should be* the same + var clangPath = FileInfo.joinPaths(FileInfo.path(compilerFilePath), "clang.exe"); + + var defaultPaths = Gcc.dumpDefaultPaths(buildEnv, clangPath, + [], _nullDevice, + _pathListSeparator, "", ""); + includePaths = defaultPaths.includePaths; + } +} diff --git a/share/qbs/imports/qbs/Probes/IarProbe.qbs b/share/qbs/imports/qbs/Probes/IarProbe.qbs index 12b3c46eb..6e7fb7d64 100644 --- a/share/qbs/imports/qbs/Probes/IarProbe.qbs +++ b/share/qbs/imports/qbs/Probes/IarProbe.qbs @@ -34,6 +34,7 @@ import "../../../modules/cpp/iar.js" as IAR PathProbe { // Inputs property string compilerFilePath; + property stringList enableDefinesByLanguage; property string _nullDevice: qbs.nullDevice @@ -43,17 +44,38 @@ PathProbe { property int versionMajor; property int versionMinor; property int versionPatch; + property stringList includePaths; + property var compilerDefinesByLanguage; configure: { + compilerDefinesByLanguage = {}; + if (!File.exists(compilerFilePath)) { found = false; return; } - var macros = IAR.dumpMacros(compilerFilePath, qbs, _nullDevice); + var languages = enableDefinesByLanguage; + if (!languages || languages.length === 0) + languages = ["c"]; + + for (var i = 0; i < languages.length; ++i) { + var tag = languages[i]; + compilerDefinesByLanguage[tag] = IAR.dumpMacros( + compilerFilePath, tag); + } + + // FIXME: Do we need dump the default paths for both C + // and C++ languages? + var defaultPaths = IAR.dumpDefaultPaths( + compilerFilePath, languages[0]); + + var macros = compilerDefinesByLanguage["c"] + || compilerDefinesByLanguage["cpp"]; architecture = IAR.guessArchitecture(macros); endianness = IAR.guessEndianness(macros); + includePaths = defaultPaths.includePaths; var version = parseInt(macros["__VER__"], 10); diff --git a/share/qbs/imports/qbs/Probes/IncludeProbe.qbs b/share/qbs/imports/qbs/Probes/IncludeProbe.qbs index fa2e44dd4..3c1059e64 100644 --- a/share/qbs/imports/qbs/Probes/IncludeProbe.qbs +++ b/share/qbs/imports/qbs/Probes/IncludeProbe.qbs @@ -29,7 +29,10 @@ ****************************************************************************/ PathProbe { - pathSuffixes: [ "include" ] + platformSearchPaths: qbs.targetOS.contains("unix") ? [ + "/usr/include", + "/usr/local/include", + ] : [] platformEnvironmentPaths: { if (qbs.toolchain.contains('msvc')) return [ "INCLUDE" ]; diff --git a/share/qbs/imports/qbs/Probes/KeilProbe.qbs b/share/qbs/imports/qbs/Probes/KeilProbe.qbs index 70712ab61..1955fe480 100644 --- a/share/qbs/imports/qbs/Probes/KeilProbe.qbs +++ b/share/qbs/imports/qbs/Probes/KeilProbe.qbs @@ -34,6 +34,7 @@ import "../../../modules/cpp/keil.js" as KEIL PathProbe { // Inputs property string compilerFilePath; + property stringList enableDefinesByLanguage; property string _nullDevice: qbs.nullDevice @@ -43,18 +44,38 @@ PathProbe { property int versionMajor; property int versionMinor; property int versionPatch; + property stringList includePaths; + property var compilerDefinesByLanguage; configure: { + compilerDefinesByLanguage = {}; + if (!File.exists(compilerFilePath)) { found = false; return; } - var macros = KEIL.dumpMacros(compilerFilePath, qbs, _nullDevice); + var languages = enableDefinesByLanguage; + if (!languages || languages.length === 0) + languages = ["c"]; + + for (var i = 0; i < languages.length; ++i) { + var tag = languages[i]; + compilerDefinesByLanguage[tag] = KEIL.dumpMacros( + compilerFilePath, tag, _nullDevice); + } + + var macros = compilerDefinesByLanguage["c"] + || compilerDefinesByLanguage["cpp"]; architecture = KEIL.guessArchitecture(macros); endianness = KEIL.guessEndianness(macros); + var defaultPaths = KEIL.dumpDefaultPaths( + compilerFilePath, architecture); + + includePaths = defaultPaths.includePaths; + var version = KEIL.guessVersion(macros); if (version) { versionMajor = version.major; diff --git a/share/qbs/imports/qbs/Probes/SdccProbe.qbs b/share/qbs/imports/qbs/Probes/SdccProbe.qbs new file mode 100644 index 000000000..b5f7d384e --- /dev/null +++ b/share/qbs/imports/qbs/Probes/SdccProbe.qbs @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** 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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import qbs.File +import "../../../modules/cpp/sdcc.js" as SDCC + +PathProbe { + // Inputs + property string compilerFilePath; + property string preferredArchitecture; + + // Outputs + property string architecture; + property string endianness; + property int versionMajor; + property int versionMinor; + property int versionPatch; + property stringList includePaths; + property var compilerDefinesByLanguage; + + configure: { + compilerDefinesByLanguage = {}; + + if (!File.exists(compilerFilePath)) { + found = false; + return; + } + + var macros = SDCC.dumpMacros(compilerFilePath, preferredArchitecture); + + // SDCC it is only the C language compiler. + compilerDefinesByLanguage["c"] = macros; + + architecture = SDCC.guessArchitecture(macros); + endianness = SDCC.guessEndianness(macros); + + var defaultPaths = SDCC.dumpDefaultPaths(compilerFilePath, architecture); + includePaths = defaultPaths.includePaths; + + versionMajor = parseInt(macros["__SDCC_VERSION_MAJOR"], 10); + versionMinor = parseInt(macros["__SDCC_VERSION_MINOR"], 10); + versionPatch = parseInt(macros["__SDCC_VERSION_PATCH"], 10); + + found = macros["SDCC"]; + } +} diff --git a/share/qbs/module-providers/Qt/templates/android_support.qbs b/share/qbs/module-providers/Qt/templates/android_support.qbs index 162bcb700..c5f842a1f 100644 --- a/share/qbs/module-providers/Qt/templates/android_support.qbs +++ b/share/qbs/module-providers/Qt/templates/android_support.qbs @@ -10,6 +10,7 @@ Module { property stringList extraPrefixDirs property stringList deploymentDependencies // qmake: ANDROID_DEPLOYMENT_DEPENDENCIES property stringList extraPlugins // qmake: ANDROID_EXTRA_PLUGINS + property stringList extraLibs // qmake: ANDROID_EXTRA_LIBS property bool verboseAndroidDeployQt: false property string _androidDeployQtFilePath: FileInfo.joinPaths(_qtInstallDir, "bin", @@ -24,6 +25,7 @@ Module { Depends { name: "Android.sdk"; condition: _enableSdkSupport } Depends { name: "Android.ndk"; condition: _enableNdkSupport } Depends { name: "java"; condition: _enableSdkSupport } + Depends { name: "cpp" } Properties { condition: _enableNdkSupport && qbs.toolchain.contains("clang") @@ -38,6 +40,10 @@ Module { Android.sdk.customManifestProcessing: true java._tagJniHeaders: false // prevent rule cycle } + Properties { + condition: _enableNdkSupport && (Android.ndk.abi === "armeabi-v7a" || Android.ndk.abi === "x86") + cpp.defines: "ANDROID_HAS_WSTRING" + } Rule { condition: _enableSdkSupport @@ -90,12 +96,9 @@ Module { f.writeLine('"sdkBuildToolsRevision": "' + product.Android.sdk.buildToolsVersion + '",'); f.writeLine('"ndk": "' + product.Android.sdk.ndkDir + '",'); - var toolPrefix = theBinary.cpp.toolchainTriple; - var toolchainPrefix = toolPrefix.startsWith("i686-") ? "x86" : toolPrefix; - f.writeLine('"toolchain-prefix": "' + toolchainPrefix + '",'); - f.writeLine('"tool-prefix": "' + toolPrefix + '",'); - f.writeLine('"toolchain-version": "' + theBinary.Android.ndk.toolchainVersion - + '",'); + f.writeLine('"toolchain-prefix": "llvm",'); + f.writeLine('"tool-prefix": "llvm",'); + f.writeLine('"useLLVM": true,'); f.writeLine('"ndk-host": "' + theBinary.Android.ndk.hostArch + '",'); f.writeLine('"target-architecture": "' + theBinary.Android.ndk.abi + '",'); f.writeLine('"qml-root-path": "' + product.Qt.android_support.qmlRootDir + '",'); @@ -105,6 +108,15 @@ Module { var extraPlugins = product.Qt.android_support.extraPlugins; if (extraPlugins && extraPlugins.length > 0) f.writeLine('"android-extra-plugins": "' + extraPlugins.join() + '",'); + var extraLibs = product.Qt.android_support.extraLibs; + if (extraLibs && extraLibs.length > 0) { + for (var i = 0; i < extraLibs.length; ++i) { + if (!FileInfo.isAbsolutePath(extraLibs[i])) { + extraLibs[i] = FileInfo.joinPaths(product.sourceDirectory, extraLibs[i]); + } + } + f.writeLine('"android-extra-libs": "' + extraLibs.join() + '",'); + } var prefixDirs = product.Qt.android_support.extraPrefixDirs; if (prefixDirs && prefixDirs.length > 0) f.writeLine('"extraPrefixDirs": ' + JSON.stringify(prefixDirs) + ','); diff --git a/share/qbs/module-providers/__fallback/fallback.qbs b/share/qbs/module-providers/__fallback/fallback.qbs index e23851951..632d1aa7a 100644 --- a/share/qbs/module-providers/__fallback/fallback.qbs +++ b/share/qbs/module-providers/__fallback/fallback.qbs @@ -50,6 +50,7 @@ Module { Probes.PkgConfigProbe { id: pkgConfigProbe condition: pkgconfig.present + sysroot: pkgconfig.sysroot name: theName executable: pkgconfig.executableFilePath libDirs: pkgconfig.libDirs diff --git a/share/qbs/modules/Android/ndk/ndk.qbs b/share/qbs/modules/Android/ndk/ndk.qbs index 5d86d6e3a..3b104558c 100644 --- a/share/qbs/modules/Android/ndk/ndk.qbs +++ b/share/qbs/modules/Android/ndk/ndk.qbs @@ -47,68 +47,33 @@ Module { readonly property string abi: NdkUtils.androidAbi(qbs.architecture) PropertyOptions { name: "abi" - description: "Corresponds to the 'APP_ABI' variable in an Android.mk file." - allowedValues: ["arm64-v8a", "armeabi", "armeabi-v7a", "mips", "mips64", "x86", "x86_64"] + description: "Supported Android ABIs" + allowedValues: ["arm64-v8a", "armeabi", "armeabi-v7a", "x86", "x86_64"] } - property string appStl: version && Utilities.versionCompare(version, "17") >= 0 - ? "c++_shared" : "system" - PropertyOptions { - name: "appStl" - description: "Corresponds to the 'APP_STL' variable in an Android.mk file." - allowedValues: [ - "system", "gabi++_static", "gabi++_shared", "stlport_static", "stlport_shared", - "gnustl_static", "gnustl_shared", "c++_static", "c++_shared" - ] - } + // See https://developer.android.com/ndk/guides/cpp-support.html + property string appStl: "c++_shared" - property string toolchainVersion: latestToolchainVersion PropertyOptions { - name: "toolchainVersion" - description: "Corresponds to the 'NDK_TOOLCHAIN_VERSION' variable in an Android.mk file." + name: "appStl" + description: "C++ Runtime Libraries." + allowedValues: ["c++_static", "c++_shared"] } property string hostArch: ndkProbe.hostArch property string ndkDir: ndkProbe.path property string ndkSamplesDir: ndkProbe.samplesDir - property string platform: ndkProbe.ndkPlatform - - property bool useUnifiedHeaders: version && Utilities.versionCompare(version, "15") >= 0 - - // Internal properties. - property stringList availableToolchains: ndkProbe.toolchains - - property stringList availableToolchainVersions: { - var tcs = availableToolchains; - var versions = []; - for (var i = 0; i < tcs.length; ++i) { - if ((qbs.toolchain.contains("clang") && tcs[i].startsWith("llvm-")) - || toolchainDirPrefixAbis.contains(tcs[i].split("-")[0])) { - var re = /\-((?:[0-9]+)\.(?:[0-9]+))$/; - var m = tcs[i].match(re); - if (m) - versions.push(m[1]); - } + property string platform: { + switch (abi) { + case "armeabi": + case "armeabi-v7a": + // case "x86": // x86 has broken wstring support + return "android-19"; + default: + return "android-21"; } - - // Sort by version number - versions.sort(function (a, b) { - var re = /^([0-9]+)\.([0-9]+)$/; - a = a.match(re); - a = {major: a[1], minor: a[2]}; - b = b.match(re); - b = {major: b[1], minor: b[2]}; - if (a.major === b.major) - return a.minor - b.minor; - return a.major - b.major; - }); - - return versions; } - property string latestToolchainVersion: availableToolchainVersions - [availableToolchainVersions.length - 1] - property int platformVersion: { if (platform) { var match = platform.match(/^android-([0-9]+)$/); @@ -120,29 +85,13 @@ Module { property stringList abis: { var list = ["armeabi", "armeabi-v7a"]; - if (platformVersion >= 9) - list.push("mips", "x86"); - if (platformVersion >= 21) - list.push("arm64-v8a", "mips64", "x86_64"); - return list; - } - - property stringList toolchainDirPrefixAbis: { - var list = ["arm"]; - if (platformVersion >= 9) - list.push("mipsel", "x86"); + if (platformVersion >= 16) + list.push("x86"); if (platformVersion >= 21) - list.push("aarch64", "mips64el", "x86_64"); + list.push("arm64-v8a", "x86_64"); return list; } - property string toolchainVersionNumber: { - var prefix = "clang"; - if (toolchainVersion && toolchainVersion.startsWith(prefix)) - return toolchainVersion.substr(prefix.length); - return toolchainVersion; - } - property string armMode: abi && abi.startsWith("armeabi") ? (qbs.buildVariant === "debug" ? "arm" : "thumb") : undefined; @@ -152,8 +101,6 @@ Module { allowedValues: ["arm", "thumb"] } - property bool haveUnifiedStl: version && Utilities.versionCompare(version, "12") >= 0 - validate: { if (!ndkDir) { throw ModUtils.ModuleError("Could not find an Android NDK at any of the following " @@ -163,15 +110,19 @@ Module { + "ANDROID_NDK_ROOT environment variable to a valid " + "Android NDK location."); } + + if (Utilities.versionCompare(version, "19") < 0) + throw ModUtils.ModuleError("Unsupported NDK version " + + Android.ndk.version + + ", please upgrade your NDK to r19+"); + if (product.aggregate && !product.multiplexConfigurationId) return; var validator = new ModUtils.PropertyValidator("Android.ndk"); validator.setRequiredProperty("abi", abi); validator.setRequiredProperty("appStl", appStl); - validator.setRequiredProperty("toolchainVersion", toolchainVersion); validator.setRequiredProperty("hostArch", hostArch); validator.setRequiredProperty("platform", platform); - validator.setRequiredProperty("toolchainVersionNumber", toolchainVersionNumber); return validator.validate(); } } diff --git a/share/qbs/modules/Android/ndk/utils.js b/share/qbs/modules/Android/ndk/utils.js index 3bc3b6d9d..739c205ae 100644 --- a/share/qbs/modules/Android/ndk/utils.js +++ b/share/qbs/modules/Android/ndk/utils.js @@ -28,6 +28,8 @@ ** ****************************************************************************/ +var Utilities = require("qbs.Utilities") + function abiNameToDirName(abiName) { switch (abiName) { case "armeabi": @@ -50,21 +52,16 @@ function androidAbi(arch) { case "armv7": case "armv7a": return "armeabi-v7a"; - case "mips": - case "mipsel": - return "mips"; - case "mips64": - case "mips64el": - return "mips64"; default: return arch; } } -function commonCompilerFlags(toolchain, buildVariant, abi, armMode) { - var flags = ["-ffunction-sections", "-funwind-tables", - "-Werror=format-security", "-fstack-protector-strong"]; +function commonCompilerFlags(toolchain, buildVariant, ndk) { + var flags = ["-Werror=format-security"]; + var abi = ndk.abi; + var armMode = ndk.armMode; if (abi === "arm64-v8a") flags.push("-fpic"); @@ -86,12 +83,17 @@ function commonCompilerFlags(toolchain, buildVariant, abi, armMode) { "-frerun-cse-after-loop", "-frename-registers"); } - if ((abi === "x86" || abi === "x86_64") && toolchain.contains("clang")) + if (abi === "x86" || abi === "x86_64") flags.push("-fPIC"); + flags.push("-fno-limit-debug-info"); + if (armMode) flags.push("-m" + armMode); + // TODO: Remove when https://github.com/android-ndk/ndk/issues/884 is fixed. + flags.push("-fno-addrsig"); + return flags; } @@ -99,8 +101,6 @@ function commonLinkerFlags(abi) { return ["-z", "noexecstack", "-z", "relro", "-z", "now"]; } -function getBinutilsPath(ndk, toolchainPrefix) { - if (["x86", "x86_64"].contains(ndk.abi)) - return ndk.abi + "-" + ndk.toolchainVersionNumber; - return toolchainPrefix + ndk.toolchainVersionNumber; +function stlFilePath(path, ndk, suffix) { + return path + ndk.appStl.slice(0, ndk.appStl.indexOf('_')) + suffix + "." + ndk.platformVersion; } diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs index 14ad92fdf..f8a046c3a 100644 --- a/share/qbs/modules/Android/sdk/sdk.qbs +++ b/share/qbs/modules/Android/sdk/sdk.qbs @@ -61,7 +61,14 @@ Module { property string platform: sdkProbe.platform // Product-specific properties and files - property string packageName: product.name + property string packageName: { + var idx = product.name.indexOf(".") + if (idx > 0 && idx < product.name.length) + return product.name; + return "com.example." + product.name; + } + property int versionCode + property string versionName property string apkBaseName: packageName property bool automaticSources: true property bool legacyLayout: false @@ -266,7 +273,10 @@ Module { + "'com.mycompany.myproduct' pattern." } rootElem.setAttribute("package", packageName); - + if (product.Android.sdk.versionCode !== undefined) + rootElem.setAttribute("android:versionCode", product.Android.sdk.versionCode); + if (product.Android.sdk.versionName !== undefined) + rootElem.setAttribute("android:versionName", product.Android.sdk.versionName); manifestData.save(output.filePath, 4); } return cmd; diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs index 01b0f8af9..35a5de4f0 100644 --- a/share/qbs/modules/cpp/CppModule.qbs +++ b/share/qbs/modules/cpp/CppModule.qbs @@ -454,42 +454,48 @@ Module { fileTags: ["hpp"] } - validate: { - var validator = new ModUtils.PropertyValidator("cpp"); - validator.setRequiredProperty("architecture", architecture, - "you might want to re-run 'qbs-setup-toolchains'"); - validator.addCustomValidator("architecture", architecture, function (value) { - return !architecture || architecture === Utilities.canonicalArchitecture(architecture); - }, "'" + architecture + "' is invalid. You must use the canonical name '" + - Utilities.canonicalArchitecture(architecture) + "'"); - validator.setRequiredProperty("endianness", endianness); - validator.setRequiredProperty("compilerDefinesByLanguage", compilerDefinesByLanguage); - validator.setRequiredProperty("compilerVersion", compilerVersion); - validator.setRequiredProperty("compilerVersionMajor", compilerVersionMajor); - validator.setRequiredProperty("compilerVersionMinor", compilerVersionMinor); - validator.setRequiredProperty("compilerVersionPatch", compilerVersionPatch); - validator.addVersionValidator("compilerVersion", compilerVersion, 3, 3); - validator.addRangeValidator("compilerVersionMajor", compilerVersionMajor, 1); - validator.addRangeValidator("compilerVersionMinor", compilerVersionMinor, 0); - validator.addRangeValidator("compilerVersionPatch", compilerVersionPatch, 0); - if (minimumWindowsVersion) { - validator.addVersionValidator("minimumWindowsVersion", minimumWindowsVersion, 2, 2); - validator.addCustomValidator("minimumWindowsVersion", minimumWindowsVersion, function (v) { - return !v || v === WindowsUtils.canonicalizeVersion(v); - }, "'" + minimumWindowsVersion + "' is invalid. Did you mean '" + - WindowsUtils.canonicalizeVersion(minimumWindowsVersion) + "'?"); - } - validator.validate(); - - if (minimumWindowsVersion && !WindowsUtils.isValidWindowsVersion(minimumWindowsVersion)) { - console.warn("Unknown Windows version '" + minimumWindowsVersion - + "'; expected one of: " - + WindowsUtils.knownWindowsVersions().map(function (a) { - return '"' + a + '"'; }).join(", ") - + ". See https://docs.microsoft.com/en-us/windows/desktop/SysInfo/operating-system-version"); + property var validateFunc: { + return function() { + var validator = new ModUtils.PropertyValidator("cpp"); + validator.setRequiredProperty("architecture", architecture, + "you might want to re-run 'qbs-setup-toolchains'"); + validator.addCustomValidator("architecture", architecture, function (value) { + return !architecture || architecture === Utilities.canonicalArchitecture(architecture); + }, "'" + architecture + "' is invalid. You must use the canonical name '" + + Utilities.canonicalArchitecture(architecture) + "'"); + validator.setRequiredProperty("endianness", endianness); + validator.setRequiredProperty("compilerDefinesByLanguage", compilerDefinesByLanguage); + validator.setRequiredProperty("compilerVersion", compilerVersion); + validator.setRequiredProperty("compilerVersionMajor", compilerVersionMajor); + validator.setRequiredProperty("compilerVersionMinor", compilerVersionMinor); + validator.setRequiredProperty("compilerVersionPatch", compilerVersionPatch); + validator.addVersionValidator("compilerVersion", compilerVersion, 3, 3); + validator.addRangeValidator("compilerVersionMajor", compilerVersionMajor, 1); + validator.addRangeValidator("compilerVersionMinor", compilerVersionMinor, 0); + validator.addRangeValidator("compilerVersionPatch", compilerVersionPatch, 0); + if (minimumWindowsVersion) { + validator.addVersionValidator("minimumWindowsVersion", minimumWindowsVersion, 2, 2); + validator.addCustomValidator("minimumWindowsVersion", minimumWindowsVersion, function (v) { + return !v || v === WindowsUtils.canonicalizeVersion(v); + }, "'" + minimumWindowsVersion + "' is invalid. Did you mean '" + + WindowsUtils.canonicalizeVersion(minimumWindowsVersion) + "'?"); + } + validator.validate(); + + if (minimumWindowsVersion && !WindowsUtils.isValidWindowsVersion(minimumWindowsVersion)) { + console.warn("Unknown Windows version '" + minimumWindowsVersion + + "'; expected one of: " + + WindowsUtils.knownWindowsVersions().map(function (a) { + return '"' + a + '"'; }).join(", ") + + ". See https://docs.microsoft.com/en-us/windows/desktop/SysInfo/operating-system-version"); + } } } + validate: { + return validateFunc(); + } + setupRunEnvironment: { SetupRunEnv.setupRunEnvironment(product, config); } diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs index b4e755a3e..f9537884e 100644 --- a/share/qbs/modules/cpp/GenericGCC.qbs +++ b/share/qbs/modules/cpp/GenericGCC.qbs @@ -729,6 +729,9 @@ CppModule { match = regexp.exec(linkerScript.readLine()); if(match) { var additionalPath = match[1]; + // path can be quoted to use non-latin letters, remove quotes if present + if (additionalPath.startsWith("\"") && additionalPath.endsWith("\"")) + additionalPath = additionalPath.slice(1, additionalPath.length - 1); retval.push(additionalPath); } } diff --git a/share/qbs/modules/cpp/android-gcc.qbs b/share/qbs/modules/cpp/android-gcc.qbs index 7079d95b4..7642b246a 100644 --- a/share/qbs/modules/cpp/android-gcc.qbs +++ b/share/qbs/modules/cpp/android-gcc.qbs @@ -39,44 +39,17 @@ import 'gcc.js' as Gcc LinuxGCC { Depends { name: "Android.ndk" } - condition: qbs.targetOS.contains("android") && - qbs.toolchain && qbs.toolchain.contains("gcc") + condition: qbs.targetOS.contains("android") && qbs.toolchain && qbs.toolchain.contains("llvm") priority: 2 rpaths: [rpathOrigin] - property string toolchainDir: { - if (qbs.toolchain && qbs.toolchain.contains("clang")) { - return Utilities.versionCompare(Android.ndk.version, "10") <= 0 - ? "llvm-" + Android.ndk.toolchainVersionNumber : "llvm"; - } - return NdkUtils.getBinutilsPath(Android.ndk, toolchainTriple + "-") - } - + cxxLanguageVersion: "c++14" property string cxxStlBaseDir: FileInfo.joinPaths(Android.ndk.ndkDir, "sources", "cxx-stl") - property string gabiBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "gabi++") - property string stlPortBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "stlport") - property string gnuStlBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "gnu-libstdc++", - Android.ndk.toolchainVersionNumber) - property string llvmStlBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "llvm-libc++") - property string stlBaseDir: { - if (Android.ndk.appStl.startsWith("gabi++_")) - return gabiBaseDir; - else if (Android.ndk.appStl.startsWith("stlport_")) - return stlPortBaseDir; - else if (Android.ndk.appStl.startsWith("gnustl_")) - return gnuStlBaseDir; - else if (Android.ndk.appStl.startsWith("c++_")) - return llvmStlBaseDir; - return undefined; - } + property string stlBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "llvm-libc++") property string stlLibsDir: { - if (stlBaseDir) { - var infix = Android.ndk.abi; - if (Android.ndk.armMode === "thumb" && !Android.ndk.haveUnifiedStl) - infix = FileInfo.joinPaths(infix, "thumb"); - return FileInfo.joinPaths(stlBaseDir, "libs", infix); - } + if (stlBaseDir) + return FileInfo.joinPaths(stlBaseDir, "libs", Android.ndk.abi); return undefined; } @@ -84,7 +57,7 @@ LinuxGCC { ? FileInfo.joinPaths(stlLibsDir, dynamicLibraryPrefix + Android.ndk.appStl + dynamicLibrarySuffix) : undefined property string staticStlFilePath: (stlLibsDir && Android.ndk.appStl.endsWith("_static")) - ? FileInfo.joinPaths(stlLibsDir, staticLibraryPrefix + Android.ndk.appStl + staticLibrarySuffix) + ? FileInfo.joinPaths(stlLibsDir, NdkUtils.stlFilePath(staticLibraryPrefix, Android.ndk, staticLibrarySuffix)) : undefined Group { @@ -104,17 +77,13 @@ LinuxGCC { } toolchainInstallPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", - toolchainDir, "prebuilt", + "llvm", "prebuilt", Android.ndk.hostArch, "bin") property string toolchainTriple: [targetAbi === "androideabi" ? "arm" : targetArch, targetSystem, targetAbi].join("-") - toolchainPrefix: { - if (qbs.toolchain && qbs.toolchain.contains("clang")) - return undefined; - return toolchainTriple + "-"; - } + toolchainPrefix: undefined machineType: { if (Android.ndk.abi === "armeabi") @@ -128,87 +97,61 @@ LinuxGCC { enableExceptions: Android.ndk.appStl !== "system" enableRtti: Android.ndk.appStl !== "system" - commonCompilerFlags: NdkUtils.commonCompilerFlags(qbs.toolchain, qbs.buildVariant, - Android.ndk.abi, Android.ndk.armMode) + commonCompilerFlags: NdkUtils.commonCompilerFlags(qbs.toolchain, qbs.buildVariant, Android.ndk) - linkerFlags: NdkUtils.commonLinkerFlags(Android.ndk.abi) + linkerFlags: NdkUtils.commonLinkerFlags(Android.ndk.abi); + driverLinkerFlags: { + var flags = ["-fuse-ld=lld", "-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libatomic.a"]; + if (Android.ndk.appStl.startsWith("c++") && Android.ndk.abi === "armeabi-v7a") + flags = flags.concat(["-Wl,--exclude-libs,libunwind.a"]); + return flags; + } - platformDriverFlags: ["-no-canonical-prefixes"] + platformDriverFlags: ["-fdata-sections", "-ffunction-sections", "-funwind-tables", + "-fstack-protector-strong", "-no-canonical-prefixes"] libraryPaths: { var prefix = FileInfo.joinPaths(sysroot, "usr"); var paths = []; - if (Android.ndk.abi === "mips64" || Android.ndk.abi === "x86_64") // no lib64 for arm64-v8a + if (Android.ndk.abi === "x86_64") // no lib64 for arm64-v8a paths.push(FileInfo.joinPaths(prefix, "lib64")); paths.push(FileInfo.joinPaths(prefix, "lib")); + paths.push(stlLibsDir); return paths; } dynamicLibraries: { var libs = ["c", "m"]; if (sharedStlFilePath) - libs.push(sharedStlFilePath); - return libs; - } - staticLibraries: { - var libs = ["gcc"]; - if (staticStlFilePath) { - libs.push(staticStlFilePath); - if (Android.ndk.appStl === "c++_static") { - var libAbi = FileInfo.joinPaths(stlLibsDir, "libc++abi.a"); - if (File.exists(libAbi)) - libs.push(libAbi); - } - } + libs.push(FileInfo.joinPaths(stlLibsDir, NdkUtils.stlFilePath(dynamicLibraryPrefix, Android.ndk, dynamicLibrarySuffix))); return libs; } + staticLibraries: staticStlFilePath systemIncludePaths: { - var includes = []; - if (Android.ndk.useUnifiedHeaders) { - // Might not be needed with Clang in a future NDK release - includes.push(FileInfo.joinPaths(sysroot, "usr", "include", toolchainTriple)); - } - if (Android.ndk.appStl === "system") { - includes.push(FileInfo.joinPaths(cxxStlBaseDir, "system", "include")); - } else if (Android.ndk.appStl.startsWith("gabi++")) { - includes.push(FileInfo.joinPaths(gabiBaseDir, "include")); - } else if (Android.ndk.appStl.startsWith("stlport")) { - includes.push(FileInfo.joinPaths(stlPortBaseDir, "stlport")); - } else if (Android.ndk.appStl.startsWith("gnustl")) { - includes.push(FileInfo.joinPaths(gnuStlBaseDir, "include")); - includes.push(FileInfo.joinPaths(gnuStlBaseDir, "libs", Android.ndk.abi, "include")); - includes.push(FileInfo.joinPaths(gnuStlBaseDir, "include", "backward")); - } else if (Android.ndk.appStl.startsWith("c++_")) { - if (Utilities.versionCompare(Android.ndk.version, "13") >= 0) { - includes.push(FileInfo.joinPaths(llvmStlBaseDir, "include")); - includes.push(FileInfo.joinPaths(llvmStlBaseDir + "abi", "include")); - } else { - includes.push(FileInfo.joinPaths(llvmStlBaseDir, "libcxx", "include")); - includes.push(FileInfo.joinPaths(llvmStlBaseDir + "abi", "libcxxabi", "include")); - } + var includes = [FileInfo.joinPaths(sysroot, "usr", "include", toolchainTriple)]; + if (Android.ndk.abi === "armeabi-v7a") { + includes.push(FileInfo.joinPaths(Android.ndk.ndkDir, "sources", "android", + "support", "include")); } + includes.push(FileInfo.joinPaths(stlBaseDir, "include")); + includes.push(FileInfo.joinPaths(stlBaseDir + "abi", "include")); return includes; } + defines: { var list = ["ANDROID"]; - if (Android.ndk.useUnifiedHeaders) { - // Might be superseded by an -mandroid-version or similar Clang compiler flag in future - list.push("__ANDROID_API__=" + Android.ndk.platformVersion); - } + // Might be superseded by an -mandroid-version or similar Clang compiler flag in future + list.push("__ANDROID_API__=" + Android.ndk.platformVersion); return list; } - binutilsPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", - NdkUtils.getBinutilsPath(Android.ndk, toolchainTriple + "-"), - "prebuilt", Android.ndk.hostArch, "bin"); - binutilsPathPrefix: Gcc.pathPrefix(binutilsPath, toolchainTriple + "-") - driverFlags: qbs.toolchain.contains("clang") - ? ["-gcc-toolchain", FileInfo.path(binutilsPath)].concat(base || []) : base + + binutilsPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", "llvm", "prebuilt", + Android.ndk.hostArch, "bin"); + binutilsPathPrefix: "llvm-" syslibroot: FileInfo.joinPaths(Android.ndk.ndkDir, "platforms", Android.ndk.platform, "arch-" + NdkUtils.abiNameToDirName(Android.ndk.abi)) - sysroot: !Android.ndk.useUnifiedHeaders - ? syslibroot - : FileInfo.joinPaths(Android.ndk.ndkDir, "sysroot") + sysroot: FileInfo.joinPaths(Android.ndk.ndkDir, "sysroot") targetArch: { switch (qbs.architecture) { @@ -222,12 +165,6 @@ LinuxGCC { return qbs.architecture; case "x86": return "i686"; - case "mips": - case "mipsel": - return "mipsel"; - case "mips64": - case "mips64el": - return "mips64el"; } } diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js index 7e25fa402..6936beb5e 100644 --- a/share/qbs/modules/cpp/gcc.js +++ b/share/qbs/modules/cpp/gcc.js @@ -440,9 +440,13 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat } var wholeArchiveActive = false; + var prevLib; for (i = 0; i < libraryDependencies.libraries.length; ++i) { var dep = libraryDependencies.libraries[i]; var lib = dep.filePath; + if (lib === prevLib) + continue; + prevLib = lib; if (dep.wholeArchive && !wholeArchiveActive) { var wholeArchiveFlag; if (isDarwin) { diff --git a/share/qbs/modules/cpp/iar.js b/share/qbs/modules/cpp/iar.js index 35ed29da3..646826e8a 100644 --- a/share/qbs/modules/cpp/iar.js +++ b/share/qbs/modules/cpp/iar.js @@ -56,16 +56,18 @@ function guessEndianness(macros) return "big" } -function dumpMacros(compilerFilePath, qbs, nullDevice) { +function dumpMacros(compilerFilePath, tag) { var tempDir = new TemporaryDir(); var inFilePath = FileInfo.fromNativeSeparators(tempDir.path() + "/empty-source.c"); var inFile = new TextFile(inFilePath, TextFile.WriteOnly); var outFilePath = FileInfo.fromNativeSeparators(tempDir.path() + "/iar-macros.predef"); - var p = new Process(); - p.exec(compilerFilePath, - [ inFilePath, "--predef_macros", outFilePath ], - true); + var args = [ inFilePath, "--predef_macros", outFilePath ]; + if (tag && tag === "cpp") + args.push("--ec++"); + + var p = new Process(); + p.exec(compilerFilePath, args, true); var outFile = new TextFile(outFilePath, TextFile.ReadOnly); var map = {}; outFile.readAll().trim().split(/\r?\n/g).map(function (line) { @@ -75,6 +77,53 @@ function dumpMacros(compilerFilePath, qbs, nullDevice) { return map; } +function dumpDefaultPaths(compilerFilePath, tag) { + var tempDir = new TemporaryDir(); + var inFilePath = FileInfo.fromNativeSeparators(tempDir.path() + "/empty-source.c"); + var inFile = new TextFile(inFilePath, TextFile.WriteOnly); + + var args = [ inFilePath, "--preinclude", "." ]; + if (tag === "cpp") + args.push("--ec++"); + + var p = new Process(); + // This process should return an error, don't throw + // an error in this case. + p.exec(compilerFilePath, args, false); + var output = p.readStdErr(); + + var includePaths = []; + var pass = 0; + for (var pos = 0; pos < output.length; ++pos) { + var searchIndex = output.indexOf("searched:", pos); + if (searchIndex === -1) + break; + var startQuoteIndex = output.indexOf('"', searchIndex + 1); + if (startQuoteIndex === -1) + break; + var endQuoteIndex = output.indexOf('"', startQuoteIndex + 1); + if (endQuoteIndex === -1) + break; + pos = endQuoteIndex + 1; + + // Ignore the first path as it is not a compiler include path. + ++pass; + if (pass === 1) + continue; + + var parts = output.substring(startQuoteIndex + 1, endQuoteIndex).split("\n"); + var includePath = ""; + for (var i in parts) + includePath += parts[i].trim(); + + includePaths.push(includePath); + } + + return { + "includePaths": includePaths + }; +} + function collectLibraryDependencies(product) { var seen = {}; var result = []; diff --git a/share/qbs/modules/cpp/iar.qbs b/share/qbs/modules/cpp/iar.qbs index 3dea255db..6d15781a5 100644 --- a/share/qbs/modules/cpp/iar.qbs +++ b/share/qbs/modules/cpp/iar.qbs @@ -50,6 +50,7 @@ CppModule { id: iarProbe condition: !_skipAllChecks compilerFilePath: compilerPath + enableDefinesByLanguage: enableCompilerDefinesByLanguage } qbs.architecture: iarProbe.found ? iarProbe.architecture : original @@ -59,7 +60,8 @@ CppModule { compilerVersionPatch: iarProbe.versionPatch endianness: iarProbe.endianness - compilerDefinesByLanguage: [] + compilerDefinesByLanguage: iarProbe.compilerDefinesByLanguage + compilerIncludePaths: iarProbe.includePaths property string toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined diff --git a/share/qbs/modules/cpp/keil.js b/share/qbs/modules/cpp/keil.js index 314d84c69..c19fdd738 100644 --- a/share/qbs/modules/cpp/keil.js +++ b/share/qbs/modules/cpp/keil.js @@ -81,7 +81,11 @@ function guessVersion(macros) // Note: The KEIL 8051 compiler does not support the predefined // macros dumping. So, we do it with following trick where we try // to compile a temporary file and to parse the console output. -function dumpC51CompilerMacros(compilerFilePath, qbs) { +function dumpC51CompilerMacros(compilerFilePath, tag) { + // C51 compiler support only C language. + if (tag === "cpp") + return {}; + function createDumpMacrosFile() { var td = new TemporaryDir(); var fn = FileInfo.fromNativeSeparators(td.path() + "/dump-macros.c"); @@ -107,11 +111,13 @@ function dumpC51CompilerMacros(compilerFilePath, qbs) { return map; } -function dumpArmCompilerMacros(compilerFilePath, qbs, nullDevice) { +function dumpArmCompilerMacros(compilerFilePath, tag, nullDevice) { + var args = [ "-E", "--list-macros", nullDevice ]; + if (tag === "cpp") + args.push("--cpp"); + var p = new Process(); - p.exec(compilerFilePath, - [ "-E", "--list-macros", nullDevice ], - false); + p.exec(compilerFilePath, args, false); var map = {}; p.readStdOut().trim().split(/\r?\n/g).map(function (line) { if (!line.startsWith("#define")) @@ -122,9 +128,9 @@ function dumpArmCompilerMacros(compilerFilePath, qbs, nullDevice) { return map; } -function dumpMacros(compilerFilePath, qbs, nullDevice) { - var map1 = dumpC51CompilerMacros(compilerFilePath, qbs); - var map2 = dumpArmCompilerMacros(compilerFilePath, qbs, nullDevice); +function dumpMacros(compilerFilePath, tag, nullDevice) { + var map1 = dumpC51CompilerMacros(compilerFilePath, tag, nullDevice); + var map2 = dumpArmCompilerMacros(compilerFilePath, tag, nullDevice); var map = {}; for (var attrname in map1) map[attrname] = map1[attrname]; @@ -133,6 +139,22 @@ function dumpMacros(compilerFilePath, qbs, nullDevice) { return map; } +function dumpDefaultPaths(compilerFilePath, architecture) { + var includePaths = []; + + if (architecture === "mcs51") { + var path = compilerFilePath.replace(/bin[\\\/](.*)$/i, "inc"); + includePaths.push(path); + } else if (architecture === "arm") { + var path = compilerFilePath.replace(/bin[\\\/](.*)$/i, "include"); + includePaths.push(path); + } + + return { + "includePaths": includePaths + }; +} + function adjustPathsToWindowsSeparators(sourcePaths) { var resulingPaths = []; sourcePaths.forEach(function(path) { diff --git a/share/qbs/modules/cpp/keil.qbs b/share/qbs/modules/cpp/keil.qbs index dab37801a..10bc39e12 100644 --- a/share/qbs/modules/cpp/keil.qbs +++ b/share/qbs/modules/cpp/keil.qbs @@ -50,6 +50,7 @@ CppModule { id: keilProbe condition: !_skipAllChecks compilerFilePath: compilerPath + enableDefinesByLanguage: enableCompilerDefinesByLanguage } qbs.architecture: keilProbe.found ? keilProbe.architecture : original @@ -59,7 +60,8 @@ CppModule { compilerVersionPatch: keilProbe.versionPatch endianness: keilProbe.endianness - compilerDefinesByLanguage: [] + compilerDefinesByLanguage: keilProbe.compilerDefinesByLanguage + compilerIncludePaths: keilProbe.includePaths property string toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js index 1864c40e1..9deffa064 100644 --- a/share/qbs/modules/cpp/msvc.js +++ b/share/qbs/modules/cpp/msvc.js @@ -62,7 +62,8 @@ function hasCxx17Option(input) { // Probably this is not the earliest version to support the flag, but we have tested this one // and it's a pain to find out the exact minimum. - return Utilities.versionCompare(input.cpp.compilerVersion, "19.12.25831") >= 0; + return Utilities.versionCompare(input.cpp.compilerVersion, "19.12.25831") >= 0 + || (input.qbs.toolchain.contains("clang-cl") && input.cpp.compilerVersionMajor >= 7); } function addLanguageVersionFlag(input, args) { @@ -72,7 +73,9 @@ function addLanguageVersionFlag(input, args) { return; // Visual C++ 2013, Update 3 - var hasStdOption = Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0; + var hasStdOption = Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0 + // or clang-cl + || input.qbs.toolchain.contains("clang-cl"); if (!hasStdOption) return; @@ -210,10 +213,20 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli var pchInputs = explicitlyDependsOn[tag + "_pch"]; if (pchOutput) { // create PCH - args.push("/Yc"); - args.push("/Fp" + FileInfo.toWindowsSeparators(pchOutput.filePath)); - args.push("/Fo" + FileInfo.toWindowsSeparators(objOutput.filePath)); - args.push(FileInfo.toWindowsSeparators(input.filePath)); + if (input.qbs.toolchain.contains("clang-cl")) { + // clang-cl does not support /Yc flag without filename + args.push("/Yc" + FileInfo.toWindowsSeparators(input.filePath)); + // clang-cl complains when pch file is not included + args.push("/FI" + FileInfo.toWindowsSeparators(input.filePath)); + args.push("/Fp" + FileInfo.toWindowsSeparators(pchOutput.filePath)); + args.push("/Fo" + FileInfo.toWindowsSeparators(objOutput.filePath)); + } else { // real msvc + args.push("/Yc"); + args.push("/Fp" + FileInfo.toWindowsSeparators(pchOutput.filePath)); + args.push("/Fo" + FileInfo.toWindowsSeparators(objOutput.filePath)); + args.push(FileInfo.toWindowsSeparators(input.filePath)); + } + } else if (pchInputs && pchInputs.length === 1 && ModUtils.moduleProperty(input, "usePrecompiledHeader", tag)) { // use PCH @@ -399,7 +412,8 @@ function prepareLinker(project, product, inputs, outputs, input, output) { 'subsystem'); if (subsystemVersion) { subsystemSwitch += ',' + subsystemVersion; - args.push('/OSVERSION:' + subsystemVersion); + if (product.cpp.linkerName !== "lld-link.exe") // llvm linker does not support /OSVERSION + args.push('/OSVERSION:' + subsystemVersion); } } @@ -435,10 +449,15 @@ function prepareLinker(project, product, inputs, outputs, input, output) { var wholeArchiveSupported = linkerSupportsWholeArchive(product); var wholeArchiveRequested = false; var libDeps = collectLibraryDependencies(product); + var prevLib; for (i = 0; i < libDeps.length; ++i) { var dep = libDeps[i]; + var lib = dep.filePath; + if (lib === prevLib) + continue; + prevLib = lib; args.push((wholeArchiveSupported && dep.wholeArchive ? "/WHOLEARCHIVE:" : "") - + FileInfo.toWindowsSeparators(dep.filePath)); + + FileInfo.toWindowsSeparators(lib)); if (dep.wholeArchive) wholeArchiveRequested = true; } diff --git a/share/qbs/modules/cpp/sdcc.js b/share/qbs/modules/cpp/sdcc.js new file mode 100644 index 000000000..2f148d2c2 --- /dev/null +++ b/share/qbs/modules/cpp/sdcc.js @@ -0,0 +1,380 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** 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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +var Cpp = require("cpp.js"); +var Environment = require("qbs.Environment"); +var File = require("qbs.File"); +var FileInfo = require("qbs.FileInfo"); +var ModUtils = require("qbs.ModUtils"); +var Process = require("qbs.Process"); +var TemporaryDir = require("qbs.TemporaryDir"); +var TextFile = require("qbs.TextFile"); +var Utilities = require("qbs.Utilities"); +var WindowsUtils = require("qbs.WindowsUtils"); + +function targetArchitectureFlag(architecture) { + if (architecture === "mcs51") + return "-mmcs51"; +} + +function guessArchitecture(macros) +{ + if (macros["__SDCC_mcs51"] === "1") + return "mcs51"; +} + +function guessEndianness(macros) +{ + // SDCC stores numbers in little-endian format. + return "little"; +} + +function dumpMacros(compilerFilePath, architecture) { + var tempDir = new TemporaryDir(); + var fakeIn = new TextFile(tempDir.path() + "/empty-source.c", TextFile.WriteOnly); + var args = [ fakeIn.filePath(), "-dM", "-E" ]; + + var targetFlag = targetArchitectureFlag(architecture); + if (targetFlag) + args.push(targetFlag); + + var p = new Process(); + p.exec(compilerFilePath, args, true); + var map = {}; + p.readStdOut().trim().split(/\r?\n/g).map(function (line) { + var parts = line.split(" ", 3); + map[parts[1]] = parts[2]; + }); + return map; +} + +function dumpDefaultPaths(compilerFilePath, architecture) { + var args = [ "--print-search-dirs" ]; + + var targetFlag = targetArchitectureFlag(architecture); + if (targetFlag) + args.push(targetFlag); + + var p = new Process(); + p.exec(compilerFilePath, args, true); + var includePaths = []; + var addIncludePaths = false; + var lines = p.readStdOut().trim().split(/\r?\n/g); + for (var i in lines) { + var line = lines[i]; + if (line.startsWith("includedir:")) { + addIncludePaths = true; + } else if (line.startsWith("programs:") + || line.startsWith("datadir:") + || line.startsWith("libdir:") + || line.startsWith("libpath:")) { + addIncludePaths = false; + } else if (addIncludePaths) { + includePaths.push(line); + } + } + + return { + "includePaths": includePaths + } +} + +function effectiveLinkerPath(product) { + if (product.cpp.linkerMode === "automatic") + return product.cpp.compilerPath; + return product.cpp.linkerPath; +} + +function useCompilerDriverLinker(product) { + var linker = effectiveLinkerPath(product); + return linker === product.cpp.compilerPath; +} + +function escapeLinkerFlags(product, linkerFlags) { + if (!linkerFlags || linkerFlags.length === 0 || !useCompilerDriverLinker(product)) + return linkerFlags; + return ["-Wl " + linkerFlags.join(",")]; +} + +function collectLibraryDependencies(product) { + var seen = {}; + var result = []; + + function addFilePath(filePath) { + result.push({ filePath: filePath }); + } + + function addArtifactFilePaths(dep, artifacts) { + if (!artifacts) + return; + var artifactFilePaths = artifacts.map(function(a) { return a.filePath; }); + artifactFilePaths.forEach(addFilePath); + } + + function addExternalStaticLibs(obj) { + if (!obj.cpp) + return; + function ensureArray(a) { + return Array.isArray(a) ? a : []; + } + function sanitizedModuleListProperty(obj, moduleName, propertyName) { + return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName)); + } + var externalLibs = [].concat( + sanitizedModuleListProperty(obj, "cpp", "staticLibraries")); + var staticLibrarySuffix = obj.moduleProperty("cpp", "staticLibrarySuffix"); + externalLibs.forEach(function(staticLibraryName) { + if (!staticLibraryName.endsWith(staticLibrarySuffix)) + staticLibraryName += staticLibrarySuffix; + addFilePath(staticLibraryName); + }); + } + + function traverse(dep) { + if (seen.hasOwnProperty(dep.name)) + return; + seen[dep.name] = true; + + if (dep.parameters.cpp && dep.parameters.cpp.link === false) + return; + + var staticLibraryArtifacts = dep.artifacts["staticlibrary"]; + if (staticLibraryArtifacts) { + dep.dependencies.forEach(traverse); + addArtifactFilePaths(dep, staticLibraryArtifacts); + addExternalStaticLibs(dep); + } + } + + product.dependencies.forEach(traverse); + addExternalStaticLibs(product); + return result; +} + +function compilerFlags(project, product, input, output, explicitlyDependsOn) { + // Determine which C-language we"re compiling. + var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags)); + + var args = []; + + args.push(input.filePath); + args.push("-c"); + args.push("-o", output.filePath); + + switch (input.cpp.optimization) { + case "small": + args.push("--opt-code-size"); + break; + case "fast": + args.push("--opt-code-speed"); + break; + case "none": + // SDCC has not option to disable the optimization. + break; + } + + if (input.cpp.debugInformation) + args.push("--debug"); + + var warnings = input.cpp.warningLevel; + if (warnings === "none") + args.push("--less-pedantic"); + + if (input.cpp.treatWarningsAsErrors) + args.push("--Werror"); + + if (tag === "c") { + if (input.cpp.cLanguageVersion === "c89") + args.push("--std-c89"); + else if (input.cpp.cLanguageVersion === "c11") + args.push("--std-c11"); + } + + var allDefines = []; + var platformDefines = input.cpp.platformDefines; + if (platformDefines) + allDefines = allDefines.uniqueConcat(platformDefines); + var defines = input.cpp.defines; + if (defines) + allDefines = allDefines.uniqueConcat(defines); + args = args.concat(allDefines.map(function(define) { return "-D" + define })); + + var allIncludePaths = []; + var includePaths = input.cpp.includePaths; + if (includePaths) + allIncludePaths = allIncludePaths.uniqueConcat(includePaths); + var systemIncludePaths = input.cpp.systemIncludePaths; + if (systemIncludePaths) + allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths); + var compilerIncludePaths = input.cpp.compilerIncludePaths; + if (compilerIncludePaths) + allIncludePaths = allIncludePaths.uniqueConcat(compilerIncludePaths); + args = args.concat(allIncludePaths.map(function(include) { return "-I" + include })); + + args = args.concat(ModUtils.moduleProperty(input, "platformFlags"), + ModUtils.moduleProperty(input, "flags"), + ModUtils.moduleProperty(input, "platformFlags", tag), + ModUtils.moduleProperty(input, "flags", tag), + ModUtils.moduleProperty(input, "driverFlags", tag)); + + return args; +} + +function assemblerFlags(project, product, input, output, explicitlyDependsOn) { + // Determine which C-language we"re compiling + var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags)); + + var args = []; + args.push(input.filePath); + args.push("-o", output.filePath); + + var allIncludePaths = []; + var systemIncludePaths = input.cpp.systemIncludePaths; + if (systemIncludePaths) + allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths); + var compilerIncludePaths = input.cpp.compilerIncludePaths; + if (compilerIncludePaths) + allIncludePaths = allIncludePaths.uniqueConcat(compilerIncludePaths); + args = args.concat(allIncludePaths.map(function(include) { return "-I" + include })); + + args = args.concat(ModUtils.moduleProperty(input, "platformFlags", tag), + ModUtils.moduleProperty(input, "flags", tag), + ModUtils.moduleProperty(input, "driverFlags", tag)); + return args; +} + +function linkerFlags(project, product, input, outputs) { + var args = []; + + var allLibraryPaths = []; + var libraryPaths = product.cpp.libraryPaths; + if (libraryPaths) + allLibraryPaths = allLibraryPaths.uniqueConcat(libraryPaths); + var distributionLibraryPaths = product.cpp.distributionLibraryPaths; + if (distributionLibraryPaths) + allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths); + + var libraryDependencies = collectLibraryDependencies(product); + + var escapableLinkerFlags = []; + + if (product.cpp.generateMapFile) + escapableLinkerFlags.push("-m"); + + if (product.cpp.platformLinkerFlags) + Array.prototype.push.apply(escapableLinkerFlags, product.cpp.platformLinkerFlags); + if (product.cpp.linkerFlags) + Array.prototype.push.apply(escapableLinkerFlags, product.cpp.linkerFlags); + + var useCompilerDriver = useCompilerDriverLinker(product); + if (useCompilerDriver) { + args.push("-o", outputs.application[0].filePath); + + if (inputs.obj) + args = args.concat(inputs.obj.map(function(obj) { return obj.filePath })); + + args = args.concat(allLibraryPaths.map(function(path) { return "-L" + path })); + + var scripts = inputs.linkerscript + ? inputs.linkerscript.map(function(scr) { return "-f" + scr.filePath; }) : []; + if (scripts) + Array.prototype.push.apply(escapableLinkerFlags, scripts); + } else { + args.push(outputs.application[0].filePath); + + if (inputs.obj) + args = args.concat(inputs.obj.map(function(obj) { return obj.filePath })); + + args = args.concat(allLibraryPaths.map(function(path) { return "-k" + path })); + + var scripts = inputs.linkerscript; + if (scripts) { + // Note: We need to split the '-f' and the file path to separate + // lines; otherwise the linking fails. + scripts.forEach(function(scr) { + escapableLinkerFlags.push("-f", scr.filePath); + }); + } + } + + if (libraryDependencies) + args = args.concat(libraryDependencies.map(function(dep) { return "-l" + dep.filePath })); + + var escapedLinkerFlags = escapeLinkerFlags(product, escapableLinkerFlags); + if (escapedLinkerFlags) + Array.prototype.push.apply(args, escapedLinkerFlags); + + return args; +} + +function archiverFlags(project, product, input, outputs) { + var args = []; + args.push(outputs.staticlibrary[0].filePath); + if (inputs.obj) + args = args.concat(inputs.obj.map(function(obj) { return obj.filePath })); + return args; +} + +function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) { + var args = compilerFlags(project, product, input, output, explicitlyDependsOn); + var compilerPath = input.cpp.compilerPath; + var cmd = new Command(compilerPath, args) + cmd.description = "compiling " + input.fileName; + cmd.highlight = "compiler"; + return [cmd]; +} + +function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) { + var args = assemblerFlags(project, product, input, output, explicitlyDependsOn); + var assemblerPath = input.cpp.assemblerPath; + var cmd = new Command(assemblerPath, args) + cmd.description = "assembling " + input.fileName; + cmd.highlight = "compiler"; + return [cmd]; +} + +function prepareLinker(project, product, inputs, outputs, input, output) { + var primaryOutput = outputs.application[0]; + var args = linkerFlags(project, product, input, outputs); + var linkerPath = effectiveLinkerPath(product); + var cmd = new Command(linkerPath, args) + cmd.description = "linking " + primaryOutput.fileName; + cmd.highlight = "linker"; + return [cmd]; +} + +function prepareArchiver(project, product, inputs, outputs, input, output) { + var args = archiverFlags(project, product, input, outputs); + var archiverPath = product.cpp.archiverPath; + var cmd = new Command(archiverPath, args) + cmd.description = "linking " + output.fileName; + cmd.highlight = "linker"; + return [cmd]; +} diff --git a/share/qbs/modules/cpp/sdcc.qbs b/share/qbs/modules/cpp/sdcc.qbs new file mode 100644 index 000000000..a0d795b40 --- /dev/null +++ b/share/qbs/modules/cpp/sdcc.qbs @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** 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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import qbs 1.0 +import qbs.File +import qbs.FileInfo +import qbs.ModUtils +import qbs.PathTools +import qbs.Probes +import qbs.Utilities +import "sdcc.js" as SDCC + +CppModule { + condition: qbs.toolchain && qbs.toolchain.contains("sdcc") + + Probes.BinaryProbe { + id: compilerPathProbe + condition: !toolchainInstallPath && !_skipAllChecks + names: ["sdcc"] + } + + Probes.SdccProbe { + id: sdccProbe + condition: !_skipAllChecks + compilerFilePath: compilerPath + preferredArchitecture: qbs.architecture + } + + qbs.architecture: sdccProbe.found ? sdccProbe.architecture : original + + compilerVersionMajor: sdccProbe.versionMajor + compilerVersionMinor: sdccProbe.versionMinor + compilerVersionPatch: sdccProbe.versionPatch + endianness: sdccProbe.endianness + + compilerDefinesByLanguage: sdccProbe.compilerDefinesByLanguage + compilerIncludePaths: sdccProbe.includePaths + + property string toolchainInstallPath: compilerPathProbe.found + ? compilerPathProbe.path : undefined + + property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : "" + + property bool generateMapFile: true + PropertyOptions { + name: "generateMapFile" + description: "produce a linker list file (enabled by default)" + } + + /* Work-around for QtCreator which expects these properties to exist. */ + property string cCompilerName: compilerName + property string cxxCompilerName: compilerName + + property string linkerMode: "automatic" + + compilerName: "sdcc" + compilerExtension + compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName) + + assemblerName: { + switch (qbs.architecture) { + case "mcs51": + return "sdas8051" + compilerExtension; + } + } + assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName) + + linkerName: { + switch (qbs.architecture) { + case "mcs51": + return "sdld" + compilerExtension; + } + } + linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName) + + property string archiverName: "sdcclib" + compilerExtension + property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName) + + runtimeLibrary: "static" + + staticLibrarySuffix: ".lib" + executableSuffix: ".ihx" + + property string objectSuffix: ".rel" + + imageFormat: "ihx" + + enableExceptions: false + enableRtti: false + + Rule { + id: assembler + inputs: ["asm"] + + Artifact { + fileTags: ["obj"] + filePath: Utilities.getHash(input.baseDir) + "/" + + input.fileName + input.cpp.objectSuffix + } + + prepare: SDCC.prepareAssembler.apply(SDCC, arguments); + } + + FileTagger { + condition: qbs.architecture === "arm"; + patterns: "*.s" + fileTags: ["asm"] + } + + FileTagger { + condition: qbs.architecture === "mcs51"; + patterns: ["*.s51", "*.asm"] + fileTags: ["asm"] + } + + Rule { + id: compiler + inputs: ["cpp", "c"] + auxiliaryInputs: ["hpp"] + + Artifact { + fileTags: ["obj"] + filePath: Utilities.getHash(input.baseDir) + "/" + + input.fileName + input.cpp.objectSuffix + } + + prepare: SDCC.prepareCompiler.apply(SDCC, arguments); + } + + Rule { + id: applicationLinker + multiplex: true + inputs: ["obj", "linkerscript"] + inputsFromDependencies: ["staticlibrary"] + + outputFileTags: { + var tags = ["application"]; + if (product.moduleProperty("cpp", "generateMapFile")) + tags.push("map_file"); + return tags; + } + outputArtifacts: { + var app = { + fileTags: ["application"], + filePath: FileInfo.joinPaths( + product.destinationDirectory, + PathTools.applicationFilePath(product)) + }; + var artifacts = [app]; + if (product.cpp.generateMapFile) { + artifacts.push({ + fileTags: ["map_file"], + filePath: FileInfo.joinPaths( + product.destinationDirectory, + product.targetName + ".map") + }); + } + return artifacts; + } + + prepare:SDCC.prepareLinker.apply(SDCC, arguments); + } + + Rule { + id: staticLibraryLinker + multiplex: true + inputs: ["obj"] + inputsFromDependencies: ["staticlibrary"] + + Artifact { + fileTags: ["staticlibrary"] + filePath: FileInfo.joinPaths( + product.destinationDirectory, + PathTools.staticLibraryFilePath(product)) + } + + prepare: SDCC.prepareArchiver.apply(SDCC, arguments); + } +} diff --git a/share/qbs/modules/cpp/windows-clang-cl.qbs b/share/qbs/modules/cpp/windows-clang-cl.qbs new file mode 100644 index 000000000..1b2833060 --- /dev/null +++ b/share/qbs/modules/cpp/windows-clang-cl.qbs @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Ivan Komissarov (abbapoh@gmail.com) +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** 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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import qbs +import qbs.ModUtils +import qbs.Probes +import qbs.FileInfo +import 'windows-msvc-base.qbs' as MsvcBaseModule + +MsvcBaseModule { + condition: qbs.hostOS.contains('windows') && + qbs.targetOS.contains('windows') && + qbs.toolchain && qbs.toolchain.contains('clang-cl') + priority: 100 + + Probes.BinaryProbe { + id: clangPathProbe + condition: !toolchainInstallPath && !_skipAllChecks + names: ["clang-cl"] + } + + Probes.ClangClProbe { + id: clangClProbe + condition: !_skipAllChecks + compilerFilePath: compilerPath + vcvarsallFilePath: vcvarsallPath + enableDefinesByLanguage: enableCompilerDefinesByLanguage + architecture: qbs.architecture + } + + compilerVersionMajor: clangClProbe.versionMajor + compilerVersionMinor: clangClProbe.versionMinor + compilerVersionPatch: clangClProbe.versionPatch + compilerIncludePaths: clangClProbe.includePaths + compilerDefinesByLanguage: clangClProbe.compilerDefinesByLanguage + + toolchainInstallPath: clangPathProbe.found ? clangPathProbe.path + : undefined + buildEnv: clangClProbe.buildEnv + + property string vcvarsallPath + + compilerName: "clang-cl.exe" + linkerName: "lld-link.exe" + linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName) + + validateFunc: { + return function() { + if (_skipAllChecks) + return; + var validator = new ModUtils.PropertyValidator("cpp"); + validator.setRequiredProperty("vcvarsallPath", vcvarsallPath); + validator.validate(); + base(); + } + } +} diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs new file mode 100644 index 000000000..d36daa99f --- /dev/null +++ b/share/qbs/modules/cpp/windows-msvc-base.qbs @@ -0,0 +1,372 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** 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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import qbs.File +import qbs.FileInfo +import qbs.ModUtils +import qbs.PathTools +import qbs.Probes +import qbs.Utilities +import qbs.WindowsUtils +import 'msvc.js' as MSVC + +CppModule { + condition: false + + windowsApiCharacterSet: "unicode" + platformDefines: { + var defines = base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet)) + .concat("WIN32"); + var def = WindowsUtils.winapiFamilyDefine(windowsApiFamily); + if (def) + defines.push("WINAPI_FAMILY=WINAPI_FAMILY_" + def); + (windowsApiAdditionalPartitions || []).map(function (name) { + defines.push("WINAPI_PARTITION_" + WindowsUtils.winapiPartitionDefine(name) + "=1"); + }); + return defines; + } + platformCommonCompilerFlags: { + var flags = base; + if (compilerVersionMajor >= 18) // 2013 + flags.push("/FS"); + return flags; + } + warningLevel: "default" + compilerName: "cl.exe" + compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName) + assemblerName: { + switch (qbs.architecture) { + case "armv7": + return "armasm.exe"; + case "arm64": + return "armasm64.exe"; + case "ia64": + return "ias.exe"; + case "x86": + return "ml.exe"; + case "x86_64": + return "ml64.exe"; + } + } + + linkerName: "link.exe" + runtimeLibrary: "dynamic" + separateDebugInformation: true + + property bool generateManifestFile: true + property string toolchainInstallPath + + architecture: qbs.architecture + endianness: "little" + staticLibrarySuffix: ".lib" + dynamicLibrarySuffix: ".dll" + executableSuffix: ".exe" + debugInfoSuffix: ".pdb" + imageFormat: "pe" + Properties { + condition: product.multiplexByQbsProperties.contains("buildVariants") + && qbs.buildVariants && qbs.buildVariants.length > 1 + && qbs.buildVariant !== "release" + && product.type.containsAny(["staticlibrary", "dynamiclibrary"]) + variantSuffix: "d" + } + + property var buildEnv + + setupBuildEnvironment: { + for (var key in product.cpp.buildEnv) { + var v = new ModUtils.EnvironmentVariable(key, ';'); + v.prepend(product.cpp.buildEnv[key]); + v.set(); + } + } + + Rule { + condition: useCPrecompiledHeader + inputs: ["c_pch_src"] + auxiliaryInputs: ["hpp"] + Artifact { + fileTags: ['obj'] + filePath: Utilities.getHash(input.completeBaseName) + '_c.obj' + } + Artifact { + fileTags: ['c_pch'] + filePath: product.name + '_c.pch' + } + prepare: { + return MSVC.prepareCompiler.apply(MSVC, arguments); + } + } + + Rule { + condition: useCxxPrecompiledHeader + inputs: ["cpp_pch_src"] + explicitlyDependsOn: ["c_pch"] // to prevent vc--0.pdb conflict + auxiliaryInputs: ["hpp"] + Artifact { + fileTags: ['obj'] + filePath: Utilities.getHash(input.completeBaseName) + '_cpp.obj' + } + Artifact { + fileTags: ['cpp_pch'] + filePath: product.name + '_cpp.pch' + } + prepare: { + return MSVC.prepareCompiler.apply(MSVC, arguments); + } + } + + Rule { + name: "compiler" + inputs: ["cpp", "c"] + auxiliaryInputs: ["hpp"] + explicitlyDependsOn: ["c_pch", "cpp_pch"] + + outputFileTags: ["obj", "intermediate_obj"] + outputArtifacts: { + var tags = input.fileTags.contains("cpp_intermediate_object") + ? ["intermediate_obj"] + : ["obj"]; + return [{ + fileTags: tags, + filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + ".obj" + }]; + } + + prepare: { + return MSVC.prepareCompiler.apply(MSVC, arguments); + } + } + + FileTagger { + patterns: ["*.manifest"] + fileTags: ["native.pe.manifest"] + } + + Rule { + name: "applicationLinker" + multiplex: true + inputs: ['obj', 'native.pe.manifest'] + inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"] + + outputFileTags: ["application", "debuginfo_app"] + outputArtifacts: { + var app = { + fileTags: ["application"], + filePath: FileInfo.joinPaths( + product.destinationDirectory, + PathTools.applicationFilePath(product)) + }; + var artifacts = [app]; + if (product.cpp.debugInformation && product.cpp.separateDebugInformation) { + artifacts.push({ + fileTags: ["debuginfo_app"], + filePath: app.filePath.substr(0, app.filePath.length - 4) + + product.cpp.debugInfoSuffix + }); + } + return artifacts; + } + + prepare: { + return MSVC.prepareLinker.apply(MSVC, arguments); + } + } + + Rule { + name: "dynamicLibraryLinker" + multiplex: true + inputs: ['obj', 'native.pe.manifest'] + inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_dll"] + + outputFileTags: ["dynamiclibrary", "dynamiclibrary_import", "debuginfo_dll"] + outputArtifacts: { + var artifacts = [ + { + fileTags: ["dynamiclibrary"], + filePath: product.destinationDirectory + "/" + PathTools.dynamicLibraryFilePath(product) + }, + { + fileTags: ["dynamiclibrary_import"], + filePath: product.destinationDirectory + "/" + PathTools.importLibraryFilePath(product), + alwaysUpdated: false + } + ]; + if (product.cpp.debugInformation && product.cpp.separateDebugInformation) { + var lib = artifacts[0]; + artifacts.push({ + fileTags: ["debuginfo_dll"], + filePath: lib.filePath.substr(0, lib.filePath.length - 4) + + product.cpp.debugInfoSuffix + }); + } + return artifacts; + } + + prepare: { + return MSVC.prepareLinker.apply(MSVC, arguments); + } + } + + Rule { + name: "libtool" + multiplex: true + inputs: ["obj"] + inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"] + outputFileTags: ["staticlibrary", "debuginfo_cl"] + outputArtifacts: { + var artifacts = [ + { + fileTags: ["staticlibrary"], + filePath: FileInfo.joinPaths(product.destinationDirectory, + PathTools.staticLibraryFilePath(product)) + } + ]; + if (product.cpp.debugInformation && product.cpp.separateDebugInformation) { + artifacts.push({ + fileTags: ["debuginfo_cl"], + filePath: product.targetName + ".cl" + product.cpp.debugInfoSuffix + }); + } + return artifacts; + } + prepare: { + var args = ['/nologo'] + var lib = outputs["staticlibrary"][0]; + var nativeOutputFileName = FileInfo.toWindowsSeparators(lib.filePath) + args.push('/OUT:' + nativeOutputFileName) + for (var i in inputs.obj) { + var fileName = FileInfo.toWindowsSeparators(inputs.obj[i].filePath) + args.push(fileName) + } + var cmd = new Command("lib.exe", args); + cmd.description = 'creating ' + lib.fileName; + cmd.highlight = 'linker'; + cmd.jobPool = "linker"; + cmd.workingDirectory = FileInfo.path(lib.filePath) + cmd.responseFileUsagePrefix = '@'; + return cmd; + } + } + + FileTagger { + patterns: ["*.rc"] + fileTags: ["rc"] + } + + Rule { + inputs: ["rc"] + auxiliaryInputs: ["hpp"] + + Artifact { + filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".res" + fileTags: ["obj"] + } + + prepare: { + var platformDefines = input.cpp.platformDefines; + var defines = input.cpp.defines; + var includePaths = input.cpp.includePaths; + var systemIncludePaths = input.cpp.systemIncludePaths; + var args = []; + var i; + var hasNoLogo = product.cpp.compilerVersionMajor >= 16; // 2010 + if (hasNoLogo) + args.push("/nologo"); + + for (i in platformDefines) { + args.push('/d'); + args.push(platformDefines[i]); + } + for (i in defines) { + args.push('/d'); + args.push(defines[i]); + } + for (i in includePaths) { + args.push('/i'); + args.push(includePaths[i]); + } + for (i in systemIncludePaths) { + args.push('/i'); + args.push(systemIncludePaths[i]); + } + + args = args.concat(['/fo', output.filePath, input.filePath]); + var cmd = new Command('rc', args); + cmd.description = 'compiling ' + input.fileName; + cmd.highlight = 'compiler'; + cmd.jobPool = "compiler"; + + if (!hasNoLogo) { + // Remove the first two lines of stdout. That's the logo. + cmd.stdoutFilterFunction = function(output) { + var idx = 0; + for (var i = 0; i < 3; ++i) + idx = output.indexOf('\n', idx + 1); + return output.substr(idx + 1); + } + } + + return cmd; + } + } + + FileTagger { + patterns: "*.asm" + fileTags: ["asm"] + } + + Rule { + inputs: ["asm"] + Artifact { + filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".obj" + fileTags: ["obj"] + } + prepare: { + var args = ["/nologo", "/c", + "/Fo" + FileInfo.toWindowsSeparators(output.filePath), + FileInfo.toWindowsSeparators(input.filePath)]; + if (product.cpp.debugInformation) + args.push("/Zi"); + args = args.concat(ModUtils.moduleProperty(input, 'platformFlags', 'asm'), + ModUtils.moduleProperty(input, 'flags', 'asm')); + var cmd = new Command(product.cpp.assemblerPath, args); + cmd.description = "assembling " + input.fileName; + cmd.jobPool = "assembler"; + cmd.inputFileName = input.fileName; + cmd.stdoutFilterFunction = function(output) { + var lines = output.split("\r\n").filter(function (s) { + return !s.endsWith(inputFileName); }); + return lines.join("\r\n"); + }; + return cmd; + } + } +} diff --git a/share/qbs/modules/cpp/windows-msvc.qbs b/share/qbs/modules/cpp/windows-msvc.qbs index 8dd6dd2c0..59032d28a 100644 --- a/share/qbs/modules/cpp/windows-msvc.qbs +++ b/share/qbs/modules/cpp/windows-msvc.qbs @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2019 Ivan Komissarov (abbapoh@gmail.com) ** Contact: http://www.qt.io/licensing ** ** This file is part of Qbs. @@ -28,19 +29,14 @@ ** ****************************************************************************/ -import qbs.File -import qbs.FileInfo -import qbs.ModUtils -import qbs.PathTools import qbs.Probes -import qbs.Utilities -import qbs.WindowsUtils -import 'msvc.js' as MSVC +import "windows-msvc-base.qbs" as MsvcBaseModule -CppModule { +MsvcBaseModule { condition: qbs.hostOS.contains('windows') && qbs.targetOS.contains('windows') && qbs.toolchain && qbs.toolchain.contains('msvc') + priority: 50 Probes.BinaryProbe { id: compilerPathProbe @@ -62,335 +58,9 @@ CppModule { compilerVersionMinor: msvcProbe.versionMinor compilerVersionPatch: msvcProbe.versionPatch compilerIncludePaths: msvcProbe.includePaths - - windowsApiCharacterSet: "unicode" - platformDefines: { - var defines = base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet)) - .concat("WIN32"); - var def = WindowsUtils.winapiFamilyDefine(windowsApiFamily); - if (def) - defines.push("WINAPI_FAMILY=WINAPI_FAMILY_" + def); - (windowsApiAdditionalPartitions || []).map(function (name) { - defines.push("WINAPI_PARTITION_" + WindowsUtils.winapiPartitionDefine(name) + "=1"); - }); - return defines; - } - platformCommonCompilerFlags: { - var flags = base; - if (compilerVersionMajor >= 18) // 2013 - flags.push("/FS"); - return flags; - } compilerDefinesByLanguage: msvcProbe.compilerDefinesByLanguage - warningLevel: "default" - compilerName: "cl.exe" - compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName) - assemblerName: { - switch (qbs.architecture) { - case "armv7": - return "armasm.exe"; - case "arm64": - return "armasm64.exe"; - case "ia64": - return "ias.exe"; - case "x86": - return "ml.exe"; - case "x86_64": - return "ml64.exe"; - } - } - - linkerName: "link.exe" - runtimeLibrary: "dynamic" - separateDebugInformation: true - - property bool generateManifestFile: true - property string toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path - : undefined - architecture: qbs.architecture - endianness: "little" - staticLibrarySuffix: ".lib" - dynamicLibrarySuffix: ".dll" - executableSuffix: ".exe" - debugInfoSuffix: ".pdb" - imageFormat: "pe" - Properties { - condition: product.multiplexByQbsProperties.contains("buildVariants") - && qbs.buildVariants && qbs.buildVariants.length > 1 - && qbs.buildVariant !== "release" - && product.type.containsAny(["staticlibrary", "dynamiclibrary"]) - variantSuffix: "d" - } - - property var buildEnv: msvcProbe.buildEnv - - setupBuildEnvironment: { - for (var key in product.cpp.buildEnv) { - var v = new ModUtils.EnvironmentVariable(key, ';'); - v.prepend(product.cpp.buildEnv[key]); - v.set(); - } - } - - Rule { - condition: useCPrecompiledHeader - inputs: ["c_pch_src"] - auxiliaryInputs: ["hpp"] - Artifact { - fileTags: ['obj'] - filePath: Utilities.getHash(input.completeBaseName) + '_c.obj' - } - Artifact { - fileTags: ['c_pch'] - filePath: product.name + '_c.pch' - } - prepare: { - return MSVC.prepareCompiler.apply(MSVC, arguments); - } - } - - Rule { - condition: useCxxPrecompiledHeader - inputs: ["cpp_pch_src"] - explicitlyDependsOn: ["c_pch"] // to prevent vc--0.pdb conflict - auxiliaryInputs: ["hpp"] - Artifact { - fileTags: ['obj'] - filePath: Utilities.getHash(input.completeBaseName) + '_cpp.obj' - } - Artifact { - fileTags: ['cpp_pch'] - filePath: product.name + '_cpp.pch' - } - prepare: { - return MSVC.prepareCompiler.apply(MSVC, arguments); - } - } - - Rule { - name: "compiler" - inputs: ["cpp", "c"] - auxiliaryInputs: ["hpp"] - explicitlyDependsOn: ["c_pch", "cpp_pch"] - - outputFileTags: ["obj", "intermediate_obj"] - outputArtifacts: { - var tags = input.fileTags.contains("cpp_intermediate_object") - ? ["intermediate_obj"] - : ["obj"]; - return [{ - fileTags: tags, - filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + ".obj" - }]; - } - - prepare: { - return MSVC.prepareCompiler.apply(MSVC, arguments); - } - } - - FileTagger { - patterns: ["*.manifest"] - fileTags: ["native.pe.manifest"] - } - - Rule { - name: "applicationLinker" - multiplex: true - inputs: ['obj', 'native.pe.manifest'] - inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"] - - outputFileTags: ["application", "debuginfo_app"] - outputArtifacts: { - var app = { - fileTags: ["application"], - filePath: FileInfo.joinPaths( - product.destinationDirectory, - PathTools.applicationFilePath(product)) - }; - var artifacts = [app]; - if (product.cpp.debugInformation && product.cpp.separateDebugInformation) { - artifacts.push({ - fileTags: ["debuginfo_app"], - filePath: app.filePath.substr(0, app.filePath.length - 4) - + product.cpp.debugInfoSuffix - }); - } - return artifacts; - } - prepare: { - return MSVC.prepareLinker.apply(MSVC, arguments); - } - } - - Rule { - name: "dynamicLibraryLinker" - multiplex: true - inputs: ['obj', 'native.pe.manifest'] - inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_dll"] - - outputFileTags: ["dynamiclibrary", "dynamiclibrary_import", "debuginfo_dll"] - outputArtifacts: { - var artifacts = [ - { - fileTags: ["dynamiclibrary"], - filePath: product.destinationDirectory + "/" + PathTools.dynamicLibraryFilePath(product) - }, - { - fileTags: ["dynamiclibrary_import"], - filePath: product.destinationDirectory + "/" + PathTools.importLibraryFilePath(product), - alwaysUpdated: false - } - ]; - if (product.cpp.debugInformation && product.cpp.separateDebugInformation) { - var lib = artifacts[0]; - artifacts.push({ - fileTags: ["debuginfo_dll"], - filePath: lib.filePath.substr(0, lib.filePath.length - 4) - + product.cpp.debugInfoSuffix - }); - } - return artifacts; - } - - prepare: { - return MSVC.prepareLinker.apply(MSVC, arguments); - } - } - - Rule { - name: "libtool" - multiplex: true - inputs: ["obj"] - inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"] - outputFileTags: ["staticlibrary", "debuginfo_cl"] - outputArtifacts: { - var artifacts = [ - { - fileTags: ["staticlibrary"], - filePath: FileInfo.joinPaths(product.destinationDirectory, - PathTools.staticLibraryFilePath(product)) - } - ]; - if (product.cpp.debugInformation && product.cpp.separateDebugInformation) { - artifacts.push({ - fileTags: ["debuginfo_cl"], - filePath: product.targetName + ".cl" + product.cpp.debugInfoSuffix - }); - } - return artifacts; - } - prepare: { - var args = ['/nologo'] - var lib = outputs["staticlibrary"][0]; - var nativeOutputFileName = FileInfo.toWindowsSeparators(lib.filePath) - args.push('/OUT:' + nativeOutputFileName) - for (var i in inputs.obj) { - var fileName = FileInfo.toWindowsSeparators(inputs.obj[i].filePath) - args.push(fileName) - } - var cmd = new Command("lib.exe", args); - cmd.description = 'creating ' + lib.fileName; - cmd.highlight = 'linker'; - cmd.jobPool = "linker"; - cmd.workingDirectory = FileInfo.path(lib.filePath) - cmd.responseFileUsagePrefix = '@'; - return cmd; - } - } - - FileTagger { - patterns: ["*.rc"] - fileTags: ["rc"] - } - - Rule { - inputs: ["rc"] - auxiliaryInputs: ["hpp"] - - Artifact { - filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".res" - fileTags: ["obj"] - } - - prepare: { - var platformDefines = input.cpp.platformDefines; - var defines = input.cpp.defines; - var includePaths = input.cpp.includePaths; - var systemIncludePaths = input.cpp.systemIncludePaths; - var args = []; - var i; - var hasNoLogo = product.cpp.compilerVersionMajor >= 16; // 2010 - if (hasNoLogo) - args.push("/nologo"); - - for (i in platformDefines) { - args.push('/d'); - args.push(platformDefines[i]); - } - for (i in defines) { - args.push('/d'); - args.push(defines[i]); - } - for (i in includePaths) { - args.push('/i'); - args.push(includePaths[i]); - } - for (i in systemIncludePaths) { - args.push('/i'); - args.push(systemIncludePaths[i]); - } - - args = args.concat(['/fo', output.filePath, input.filePath]); - var cmd = new Command('rc', args); - cmd.description = 'compiling ' + input.fileName; - cmd.highlight = 'compiler'; - cmd.jobPool = "compiler"; - - if (!hasNoLogo) { - // Remove the first two lines of stdout. That's the logo. - cmd.stdoutFilterFunction = function(output) { - var idx = 0; - for (var i = 0; i < 3; ++i) - idx = output.indexOf('\n', idx + 1); - return output.substr(idx + 1); - } - } - - return cmd; - } - } - - FileTagger { - patterns: "*.asm" - fileTags: ["asm"] - } - - Rule { - inputs: ["asm"] - Artifact { - filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".obj" - fileTags: ["obj"] - } - prepare: { - var args = ["/nologo", "/c", - "/Fo" + FileInfo.toWindowsSeparators(output.filePath), - FileInfo.toWindowsSeparators(input.filePath)]; - if (product.cpp.debugInformation) - args.push("/Zi"); - args = args.concat(ModUtils.moduleProperty(input, 'platformFlags', 'asm'), - ModUtils.moduleProperty(input, 'flags', 'asm')); - var cmd = new Command(product.cpp.assemblerPath, args); - cmd.description = "assembling " + input.fileName; - cmd.jobPool = "assembler"; - cmd.inputFileName = input.fileName; - cmd.stdoutFilterFunction = function(output) { - var lines = output.split("\r\n").filter(function (s) { - return !s.endsWith(inputFileName); }); - return lines.join("\r\n"); - }; - return cmd; - } - } + toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path + : undefined + buildEnv: msvcProbe.buildEnv } diff --git a/share/qbs/modules/pkgconfig/pkgconfig.qbs b/share/qbs/modules/pkgconfig/pkgconfig.qbs index 92e0bfb25..ec4b59188 100644 --- a/share/qbs/modules/pkgconfig/pkgconfig.qbs +++ b/share/qbs/modules/pkgconfig/pkgconfig.qbs @@ -47,6 +47,11 @@ Module { names: "pkg-config" } + property path sysroot: { + if (qbs.targetOS.contains("macos")) + return ""; + return qbs.sysroot; + } property string executableFilePath: pkgconfigProbe.filePath property stringList libDirs property bool staticMode: false diff --git a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs index 5cb3257d4..2b6e94e83 100644 --- a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs +++ b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs @@ -28,12 +28,14 @@ ProtobufBase { prepare: HelperFunctions.doPrepare(input.protobuf.cpp, product, input, outputs, "cpp") } - validate: { - baseValidate(); - if (!HelperFunctions.checkPath(includePath)) - throw "Can't find cpp protobuf include files. Please set the includePath property."; - if (!HelperFunctions.checkPath(libraryPath)) - throw "Can't find cpp protobuf library. Please set the libraryPath property."; + validateFunc: { + return function() { + base(); + if (!HelperFunctions.checkPath(includePath)) + throw "Can't find cpp protobuf include files. Please set the includePath property."; + if (!HelperFunctions.checkPath(libraryPath)) + throw "Can't find cpp protobuf library. Please set the libraryPath property."; + } } Probes.IncludeProbe { diff --git a/share/qbs/modules/protobuf/objc/protobufobjc.qbs b/share/qbs/modules/protobuf/objc/protobufobjc.qbs index c252d9949..e2c4b5260 100644 --- a/share/qbs/modules/protobuf/objc/protobufobjc.qbs +++ b/share/qbs/modules/protobuf/objc/protobufobjc.qbs @@ -43,13 +43,15 @@ ProtobufBase { prepare: HelperFunctions.doPrepare(input.protobuf.objc, product, input, outputs, "objc") } - validate: { - baseValidate(); - if (!HelperFunctions.checkPath(frameworkPath)) { - if (!HelperFunctions.checkPath(includePath)) - throw "Can't find objective-c protobuf include files. Please set the includePath or frameworkPath property."; - if (!HelperFunctions.checkPath(libraryPath)) - throw "Can't find objective-c protobuf library. Please set the libraryPath or frameworkPath property."; + validateFunc: { + return function() { + base(); + if (!HelperFunctions.checkPath(frameworkPath)) { + if (!HelperFunctions.checkPath(includePath)) + throw "Can't find objective-c protobuf include files. Please set the includePath or frameworkPath property."; + if (!HelperFunctions.checkPath(libraryPath)) + throw "Can't find objective-c protobuf library. Please set the libraryPath or frameworkPath property."; + } } } diff --git a/share/qbs/modules/protobuf/protobufbase.qbs b/share/qbs/modules/protobuf/protobufbase.qbs index 1c2e68800..0ac6c1949 100644 --- a/share/qbs/modules/protobuf/protobufbase.qbs +++ b/share/qbs/modules/protobuf/protobufbase.qbs @@ -9,9 +9,8 @@ Module { property pathList importPaths: [] property string outputDir: product.buildDirectory + "/protobuf" - readonly property string protobufRoot: FileInfo.path(FileInfo.path(protocBinary)) - readonly property var baseValidate: { + property var validateFunc: { return function() { if (!File.exists(protocBinary)) throw "Can't find protoc binary. Please set the protocBinary property or make sure it is found in PATH"; @@ -27,4 +26,8 @@ Module { id: protocProbe names: ["protoc"] } + + validate: { + validateFunc(); + } } diff --git a/src/3rdparty/python/bin/dmgbuild b/src/3rdparty/python/bin/dmgbuild index 113ae0998..4647448da 100755 --- a/src/3rdparty/python/bin/dmgbuild +++ b/src/3rdparty/python/bin/dmgbuild @@ -33,4 +33,9 @@ for d in args.defines: v = v[1:-1] defines[k] = v -dmgbuild.build_dmg(args.filename, args.volume_name, args.settings, defines=defines, lookForHiDPI=args.lookForHiDPI) +dmgbuild.build_dmg( + args.filename.decode('utf_8'), + args.volume_name.decode('utf_8'), + args.settings.decode('utf_8'), + defines=defines, + lookForHiDPI=args.lookForHiDPI) diff --git a/src/app/config-ui/commandlineparser.h b/src/app/config-ui/commandlineparser.h index dc43d33b3..b8ab1a9f0 100644 --- a/src/app/config-ui/commandlineparser.h +++ b/src/app/config-ui/commandlineparser.h @@ -59,7 +59,7 @@ private: void assignOptionArgument(const QString &option, QString &argument); [[noreturn]] void complainAboutExtraArguments(); - bool m_helpRequested; + bool m_helpRequested = false; qbs::Settings::Scope m_settingsScope = qbs::Settings::UserScope; QString m_settingsDir; QStringList m_commandLine; diff --git a/src/app/config-ui/mainwindow.cpp b/src/app/config-ui/mainwindow.cpp index 13708366a..2bf7fad5e 100644 --- a/src/app/config-ui/mainwindow.cpp +++ b/src/app/config-ui/mainwindow.cpp @@ -49,9 +49,52 @@ #include <QtGui/qkeysequence.h> #include <QtWidgets/qaction.h> +#include <QtWidgets/qlineedit.h> #include <QtWidgets/qmenu.h> #include <QtWidgets/qmenubar.h> #include <QtWidgets/qmessagebox.h> +#include <QtWidgets/qstyleditemdelegate.h> + +namespace { + +class TrimValidator : public QValidator +{ +public: + explicit TrimValidator(QObject *parent = nullptr) : QValidator(parent) {} + +public: // QValidator interface + State validate(QString &input, int &pos) const override + { + Q_UNUSED(pos); + if (input.startsWith(QLatin1Char(' ')) || input.endsWith(QLatin1Char(' '))) + return State::Intermediate; + return State::Acceptable; + } + + void fixup(QString &input) const override + { + input = input.trimmed(); + } +}; + +class SettingsItemDelegate: public QStyledItemDelegate +{ +public: + explicit SettingsItemDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {} + + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override + { + const auto editor = QStyledItemDelegate::createEditor(parent, option, index); + const auto lineEdit = qobject_cast<QLineEdit *>(editor); + if (lineEdit) + lineEdit->setValidator(new TrimValidator(lineEdit)); + return editor; + } +}; + +} // namespace MainWindow::MainWindow(const QString &settingsDir, qbs::Settings::Scope scope, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) @@ -59,6 +102,7 @@ MainWindow::MainWindow(const QString &settingsDir, qbs::Settings::Scope scope, Q ui->setupUi(this); m_model = new qbs::SettingsModel(settingsDir, scope, this); ui->treeView->setModel(m_model); + ui->treeView->setItemDelegate(new SettingsItemDelegate(ui->treeView)); ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->treeView, &QTreeView::expanded, this, &MainWindow::adjustColumns); connect(ui->treeView, &QWidget::customContextMenuRequested, diff --git a/src/app/config-ui/mainwindow.h b/src/app/config-ui/mainwindow.h index 567a183f1..b8a12d61f 100644 --- a/src/app/config-ui/mainwindow.h +++ b/src/app/config-ui/mainwindow.h @@ -57,9 +57,9 @@ class MainWindow : public QMainWindow public: explicit MainWindow(const QString &settingsDir, qbs::Settings::Scope scope, QWidget *parent = nullptr); - ~MainWindow(); + ~MainWindow() override; - bool eventFilter(QObject *watched, QEvent *event); + bool eventFilter(QObject *watched, QEvent *event) override; private: void adjustColumns(); diff --git a/src/app/config/configcommandlineparser.h b/src/app/config/configcommandlineparser.h index 22f6906f9..b567134fd 100644 --- a/src/app/config/configcommandlineparser.h +++ b/src/app/config/configcommandlineparser.h @@ -73,7 +73,7 @@ private: ConfigCommand m_command; qbs::Settings::Scopes m_scope = qbs::Settings::allScopes(); - bool m_helpRequested; + bool m_helpRequested = false; QString m_settingsDir; QStringList m_commandLine; }; diff --git a/src/app/qbs-create-project/createproject.h b/src/app/qbs-create-project/createproject.h index 95df434d9..efc217b68 100644 --- a/src/app/qbs-create-project/createproject.h +++ b/src/app/qbs-create-project/createproject.h @@ -82,7 +82,7 @@ private: std::vector<ProjectPtr> subProjects; }; Project m_topLevelProject; - ProjectStructure m_projectStructure; + ProjectStructure m_projectStructure = ProjectStructure::Flat; QList<QRegExp> m_whiteList; QList<QRegExp> m_blackList; }; diff --git a/src/app/qbs-setup-android/android-setup.cpp b/src/app/qbs-setup-android/android-setup.cpp index 4a3c8aef9..029628419 100644 --- a/src/app/qbs-setup-android/android-setup.cpp +++ b/src/app/qbs-setup-android/android-setup.cpp @@ -68,12 +68,6 @@ static QStringList expectedArchs() QStringLiteral("x86"), QStringLiteral("x86_64")}; } - -static QString subProfileName(const QString &mainProfileName, const QString &arch) -{ - return mainProfileName + QLatin1Char('-') + arch; -} - void setupSdk(qbs::Settings *settings, const QString &profileName, const QString &sdkDirPath) { if (!QDir(sdkDirPath).exists()) { @@ -145,8 +139,8 @@ static QtInfoPerArch getQtAndroidInfo(const QString &qtSdkDir) QDirIterator dit(qtSdkDir, QStringList() << QStringLiteral("android_*"), QDir::Dirs); while (dit.hasNext()) qtDirs << dit.next(); - for (auto it = qtDirs.cbegin(); it != qtDirs.cend(); ++it) { - const QtAndroidInfo info = getInfoForQtDir(*it); + for (const auto &qtDir : qtDirs) { + const QtAndroidInfo info = getInfoForQtDir(qtDir); if (info.isValid()) archs.insert(info.arch, info); } @@ -227,25 +221,7 @@ static void setupNdk(qbs::Settings *settings, const QString &profileName, const const QtAndroidInfo qtAndroidInfo = infoPerArch.value(arch); if (!qtAndroidInfo.isValid()) continue; - const QString subProName = subProfileName(profileName, arch); - const QString setupQtPath = qApp->applicationDirPath() + qls("/qbs-setup-qt"); - QProcess setupQt; - setupQt.start(setupQtPath, QStringList({ qtAndroidInfo.qmakePath, subProName })); - if (!setupQt.waitForStarted()) { - throw ErrorInfo(Tr::tr("Setting up Qt profile failed: '%1' " - "could not be started.").arg(setupQtPath)); - } - if (!setupQt.waitForFinished()) { - throw ErrorInfo(Tr::tr("Setting up Qt profile failed: Error running '%1' (%2)") - .arg(setupQtPath, setupQt.errorString())); - } - if (setupQt.exitCode() != 0) { - throw ErrorInfo(Tr::tr("Setting up Qt profile failed: '%1' returned with " - "exit code %2.").arg(setupQtPath).arg(setupQt.exitCode())); - } - settings->sync(); - qbs::Internal::TemporaryProfile p(subProName, settings); - qmakeFilePaths << p.p.value(qls("moduleProviders.Qt.qmakeFilePaths")).toStringList(); + qmakeFilePaths << qtAndroidInfo.qmakePath; platform = maximumPlatform(platform, qtAndroidInfo.platform); } if (!qmakeFilePaths.empty()) diff --git a/src/app/qbs-setup-android/commandlineparser.h b/src/app/qbs-setup-android/commandlineparser.h index 729f28cb9..3ce3eeb40 100644 --- a/src/app/qbs-setup-android/commandlineparser.h +++ b/src/app/qbs-setup-android/commandlineparser.h @@ -63,7 +63,7 @@ private: void assignOptionArgument(const QString &option, QString &argument); [[noreturn]] void complainAboutExtraArguments(); - bool m_helpRequested; + bool m_helpRequested = false; QString m_sdkDir; QString m_ndkDir; QString m_qtSdkDir; diff --git a/src/app/qbs-setup-qt/commandlineparser.h b/src/app/qbs-setup-qt/commandlineparser.h index a9ecb55c8..c766a9df2 100644 --- a/src/app/qbs-setup-qt/commandlineparser.h +++ b/src/app/qbs-setup-qt/commandlineparser.h @@ -63,8 +63,8 @@ private: void assignOptionArgument(const QString &option, QString &argument); [[noreturn]] void complainAboutExtraArguments(); - bool m_helpRequested; - bool m_autoDetectionMode; + bool m_helpRequested = false; + bool m_autoDetectionMode = false; qbs::Settings::Scope m_settingsScope = qbs::Settings::UserScope; QString m_qmakePath; QString m_profileName; diff --git a/src/app/qbs-setup-toolchains/clangclprobe.cpp b/src/app/qbs-setup-toolchains/clangclprobe.cpp new file mode 100644 index 000000000..89075c5e8 --- /dev/null +++ b/src/app/qbs-setup-toolchains/clangclprobe.cpp @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Ivan Komissarov (abbapoh@gmail.com) +** Contact: http://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$ +** +****************************************************************************/ + +#include "clangclprobe.h" +#include "msvcprobe.h" +#include "probe.h" + +#include "../shared/logging/consolelogger.h" + +#include <logging/translator.h> +#include <tools/hostosinfo.h> +#include <tools/profile.h> +#include <tools/qttools.h> +#include <tools/settings.h> + +#include <QtCore/qdir.h> +#include <QtCore/qfileinfo.h> + +using qbs::Settings; +using qbs::Profile; +using qbs::Internal::HostOsInfo; + +using qbs::Internal::Tr; + +namespace { + +QString getToolchainInstallPath(const QString &compilerFilePath) +{ + return QFileInfo(compilerFilePath).path(); // 1 level up +} + +Profile createProfileHelper( + Settings *settings, + const QString &profileName, + const QString &toolchainInstallPath, + const QString &vcvarsallPath, + const QString &architecture) +{ + Profile profile(profileName, settings); + profile.removeProfile(); + profile.setValue(QStringLiteral("qbs.architecture"), architecture); + profile.setValue( + QStringLiteral("qbs.toolchain"), + QStringList{QStringLiteral("clang-cl"), QStringLiteral("msvc")}); + profile.setValue(QStringLiteral("cpp.toolchainInstallPath"), toolchainInstallPath); + profile.setValue(QStringLiteral("cpp.vcvarsallPath"), vcvarsallPath); + qbsInfo() << Tr::tr("Profile '%1' created for '%2'.") + .arg(profile.name(), QDir::toNativeSeparators(toolchainInstallPath)); + return profile; +} + +std::vector<MSVCInstallInfo> compatibleMsvcs() +{ + auto msvcs = installedMSVCs(); + auto filter = [](const MSVCInstallInfo &info) + { + const auto versions = info.version.split(QLatin1Char('.')); + if (versions.empty()) + return true; + bool ok = false; + const int major = versions.at(0).toInt(&ok); + return !(ok && major >= 15); // support MSVC2017 and above + }; + const auto it = std::remove_if(msvcs.begin(), msvcs.end(), filter); + msvcs.erase(it, msvcs.end()); + for (const auto &msvc: msvcs) { + auto vcvarsallPath = msvc.findVcvarsallBat(); + if (vcvarsallPath.isEmpty()) + continue; + } + return msvcs; +} + +QString findCompatibleVcsarsallBat() +{ + for (const auto &msvc: compatibleMsvcs()) { + const auto vcvarsallPath = msvc.findVcvarsallBat(); + if (!vcvarsallPath.isEmpty()) + return vcvarsallPath; + } + return {}; +} + +} // namespace + +void createClangClProfile( + const QString &profileName, const QString &compilerFilePath, Settings *settings) +{ + const auto compilerName = QStringLiteral("clang-cl"); + const auto vcvarsallPath = findCompatibleVcsarsallBat(); + if (vcvarsallPath.isEmpty()) { + qbsWarning() + << Tr::tr("%1 requires installed Visual Studio 2017 or newer, but none was found.") + .arg(compilerName); + return; + } + + const auto toolchainInstallPath = getToolchainInstallPath(compilerFilePath); + const auto hostArch = QString::fromStdString(HostOsInfo::hostOSArchitecture()); + createProfileHelper(settings, profileName, toolchainInstallPath, vcvarsallPath, hostArch); +} + +/*! + \brief Creates a clang-cl profile based on auto-detected vsversion. + \internal +*/ +void clangClProbe(Settings *settings, QList<Profile> &profiles) +{ + const auto compilerName = QStringLiteral("clang-cl"); + qbsInfo() << Tr::tr("Trying to detect %1...").arg(compilerName); + const auto compilerFilePath = findExecutable(HostOsInfo::appendExecutableSuffix(compilerName)); + if (compilerFilePath.isEmpty()) { + qbsInfo() << Tr::tr("%1 was not found.").arg(compilerName); + return; + } + + const auto vcvarsallPath = findCompatibleVcsarsallBat(); + if (vcvarsallPath.isEmpty()) { + qbsWarning() + << Tr::tr("%1 requires installed Visual Studio 2017 or newer, but none was found.") + .arg(compilerName); + return; + } + + const QString architectures[] = { + QStringLiteral("x86_64"), + QStringLiteral("x86") + }; + const auto toolchainInstallPath = getToolchainInstallPath(compilerFilePath); + for (const auto &arch: architectures) { + const auto profileName = QStringLiteral("clang-cl-%1").arg(arch); + auto profile = createProfileHelper( + settings, profileName, toolchainInstallPath, vcvarsallPath, arch); + profiles.push_back(std::move(profile)); + } +} diff --git a/src/app/qbs-setup-toolchains/clangclprobe.h b/src/app/qbs-setup-toolchains/clangclprobe.h new file mode 100644 index 000000000..1e7724fbf --- /dev/null +++ b/src/app/qbs-setup-toolchains/clangclprobe.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Ivan Komissarov (abbapoh@gmail.com) +** Contact: http://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$ +** +****************************************************************************/ + +#ifndef CLANGCLPROBE_H +#define CLANGCLPROBE_H + +#include <QtCore/qlist.h> + +namespace qbs { +class Profile; +class Settings; +} + +void createClangClProfile( + const QString &profileName, const QString &compilerFilePath, qbs::Settings *settings); + +void clangClProbe(qbs::Settings *settings, QList<qbs::Profile> &profiles); + +#endif // CLANGCLPROBE_H diff --git a/src/app/qbs-setup-toolchains/commandlineparser.h b/src/app/qbs-setup-toolchains/commandlineparser.h index cb0949bf1..9d5b0c246 100644 --- a/src/app/qbs-setup-toolchains/commandlineparser.h +++ b/src/app/qbs-setup-toolchains/commandlineparser.h @@ -64,8 +64,8 @@ private: void assignOptionArgument(const QString &option, QString &argument); [[noreturn]] void complainAboutExtraArguments(); - bool m_helpRequested; - bool m_autoDetectionMode; + bool m_helpRequested = false; + bool m_autoDetectionMode = false; qbs::Settings::Scope m_settingsScope = qbs::Settings::UserScope; QString m_compilerPath; QString m_toolchainType; diff --git a/src/app/qbs-setup-toolchains/iarewprobe.cpp b/src/app/qbs-setup-toolchains/iarewprobe.cpp new file mode 100644 index 000000000..5d3785759 --- /dev/null +++ b/src/app/qbs-setup-toolchains/iarewprobe.cpp @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** 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$ +** +****************************************************************************/ + +#include "probe.h" +#include "iarewprobe.h" + +#include "../shared/logging/consolelogger.h" + +#include <logging/translator.h> + +#include <tools/hostosinfo.h> +#include <tools/profile.h> + +#include <QtCore/qfileinfo.h> +#include <QtCore/qlist.h> +#include <QtCore/qsettings.h> + +using namespace qbs; +using Internal::Tr; +using Internal::HostOsInfo; + +static QStringList knownIarCompilerNames() +{ + return {QStringLiteral("icc8051"), QStringLiteral("iccarm"), QStringLiteral("iccavr")}; +} + +static QString guessIarArchitecture(const QFileInfo &compiler) +{ + const auto baseName = compiler.baseName(); + if (baseName == QLatin1String("icc8051")) + return QStringLiteral("mcs51"); + if (baseName == QLatin1String("iccarm")) + return QStringLiteral("arm"); + if (baseName == QLatin1String("iccavr")) + return QStringLiteral("avr"); + return {}; +} + +static Profile createIarProfileHelper(const QFileInfo &compiler, Settings *settings, + QString profileName = QString()) +{ + const QString architecture = guessIarArchitecture(compiler); + + // In case the profile is auto-detected. + if (profileName.isEmpty()) + profileName = QLatin1String("iar-") + architecture; + + Profile profile(profileName, settings); + profile.setValue(QLatin1String("cpp.toolchainInstallPath"), compiler.absolutePath()); + profile.setValue(QLatin1String("qbs.toolchainType"), QLatin1String("iar")); + if (!architecture.isEmpty()) + profile.setValue(QLatin1String("qbs.architecture"), architecture); + + qbsInfo() << Tr::tr("Profile '%1' created for '%2'.").arg( + profile.name(), compiler.absoluteFilePath()); + return profile; +} + +static std::vector<IarInstallInfo> installedIarsFromPath() +{ + std::vector<IarInstallInfo> infos; + const auto compilerNames = knownIarCompilerNames(); + for (const QString &compilerName : compilerNames) { + const QFileInfo iarPath( + findExecutable( + HostOsInfo::appendExecutableSuffix(compilerName))); + if (!iarPath.exists()) + continue; + infos.push_back({iarPath.absoluteFilePath(), {}}); + } + return infos; +} + +static std::vector<IarInstallInfo> installedIarsFromRegistry() +{ + std::vector<IarInstallInfo> infos; + + if (HostOsInfo::isWindowsHost()) { + +#ifdef Q_OS_WIN64 + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\IAR Systems\\Embedded Workbench"; +#else + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\IAR Systems\\Embedded Workbench"; +#endif + + // Dictionary for know toolchains. + static const struct Entry { + QString registryKey; + QString subExePath; + } knowToolchains[] = { + {QStringLiteral("EWARM"), QStringLiteral("\\arm\\bin\\iccarm.exe")}, + {QStringLiteral("EWAVR"), QStringLiteral("\\avr\\bin\\iccavr.exe")}, + {QStringLiteral("EW8051"), QStringLiteral("\\8051\\bin\\icc8051.exe")}, + }; + + QSettings registry(QLatin1String(kRegistryNode), QSettings::NativeFormat); + const auto oneLevelGroups = registry.childGroups(); + for (const QString &oneLevelKey : oneLevelGroups) { + registry.beginGroup(oneLevelKey); + const auto twoLevelGroups = registry.childGroups(); + for (const Entry &entry : knowToolchains) { + if (twoLevelGroups.contains(entry.registryKey)) { + registry.beginGroup(entry.registryKey); + const auto threeLevelGroups = registry.childGroups(); + for (const QString &threeLevelKey : threeLevelGroups) { + registry.beginGroup(threeLevelKey); + const QString rootPath = registry.value( + QStringLiteral("InstallPath")).toString(); + if (!rootPath.isEmpty()) { + // Build full compiler path. + const QFileInfo iarPath(rootPath + entry.subExePath); + if (iarPath.exists()) { + // Note: threeLevelKey is a guessed toolchain version. + const QString version = threeLevelKey; + infos.push_back({iarPath.absoluteFilePath(), version}); + } + } + registry.endGroup(); + } + registry.endGroup(); + } + } + registry.endGroup(); + } + + } + + return infos; +} + +bool isIarCompiler(const QString &compilerName) +{ + return Internal::any_of(knownIarCompilerNames(), [compilerName]( + const QString &knownName) { + return compilerName.contains(knownName); + }); +} + +void createIarProfile(const QFileInfo &compiler, Settings *settings, + QString profileName) +{ + createIarProfileHelper(compiler, settings, profileName); +} + +void iarProbe(Settings *settings, QList<Profile> &profiles) +{ + qbsInfo() << Tr::tr("Trying to detect IAR toolchains..."); + + std::vector<IarInstallInfo> allInfos = installedIarsFromRegistry(); + const std::vector<IarInstallInfo> pathInfos = installedIarsFromPath(); + allInfos.insert(std::end(allInfos), std::begin(pathInfos), std::end(pathInfos)); + + for (const IarInstallInfo &info : allInfos) { + const auto profile = createIarProfileHelper(info.compilerPath, settings); + profiles.push_back(profile); + } + + if (allInfos.empty()) + qbsInfo() << Tr::tr("No IAR toolchains found."); +} diff --git a/src/app/qbs-setup-toolchains/iarewprobe.h b/src/app/qbs-setup-toolchains/iarewprobe.h new file mode 100644 index 000000000..f5caf61ed --- /dev/null +++ b/src/app/qbs-setup-toolchains/iarewprobe.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** 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$ +** +****************************************************************************/ + +#ifndef IAREWPROBE_H +#define IAREWPROBE_H + +#include <QtCore/qlist.h> + +QT_BEGIN_NAMESPACE +class QFileInfo; +QT_END_NAMESPACE + +namespace qbs { +class Profile; +class Settings; +} + +struct IarInstallInfo +{ + QString compilerPath; + QString version; +}; + +bool isIarCompiler(const QString &compilerName); + +void createIarProfile(const QFileInfo &compiler, qbs::Settings *settings, + QString profileName); + +void iarProbe(qbs::Settings *settings, QList<qbs::Profile> &profiles); + +#endif // IAREWPROBE_H diff --git a/src/app/qbs-setup-toolchains/keilprobe.cpp b/src/app/qbs-setup-toolchains/keilprobe.cpp new file mode 100644 index 000000000..dc327d2ee --- /dev/null +++ b/src/app/qbs-setup-toolchains/keilprobe.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** 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$ +** +****************************************************************************/ + +#include "probe.h" +#include "keilprobe.h" + +#include "../shared/logging/consolelogger.h" + +#include <logging/translator.h> + +#include <tools/hostosinfo.h> +#include <tools/profile.h> + +#include <QtCore/qfileinfo.h> +#include <QtCore/qlist.h> +#include <QtCore/qsettings.h> + +using namespace qbs; +using Internal::Tr; +using Internal::HostOsInfo; + +static QStringList knownKeilCompilerNames() +{ + return {QStringLiteral("c51"), QStringLiteral("armcc")}; +} + +static QString guessKeilArchitecture(const QFileInfo &compiler) +{ + const auto baseName = compiler.baseName(); + if (baseName == QLatin1String("c51")) + return QStringLiteral("mcs51"); + if (baseName == QLatin1String("armcc")) + return QStringLiteral("arm"); + return {}; +} + +static Profile createKeilProfileHelper(const QFileInfo &compiler, Settings *settings, + QString profileName = QString()) +{ + const QString architecture = guessKeilArchitecture(compiler); + + // In case the profile is auto-detected. + if (profileName.isEmpty()) + profileName = QLatin1String("keil-") + architecture; + + Profile profile(profileName, settings); + profile.setValue(QStringLiteral("cpp.toolchainInstallPath"), compiler.absolutePath()); + profile.setValue(QStringLiteral("qbs.toolchainType"), QStringLiteral("keil")); + if (!architecture.isEmpty()) + profile.setValue(QStringLiteral("qbs.architecture"), architecture); + + qbsInfo() << Tr::tr("Profile '%1' created for '%2'.").arg( + profile.name(), compiler.absoluteFilePath()); + return profile; +} + +static std::vector<KeilInstallInfo> installedKeilsFromPath() +{ + std::vector<KeilInstallInfo> infos; + const auto compilerNames = knownKeilCompilerNames(); + for (const QString &compilerName : compilerNames) { + const QFileInfo keilPath( + findExecutable( + HostOsInfo::appendExecutableSuffix(compilerName))); + if (!keilPath.exists()) + continue; + infos.push_back({keilPath.absoluteFilePath(), {}}); + } + return infos; +} + +static std::vector<KeilInstallInfo> installedKeilsFromRegistry() +{ + std::vector<KeilInstallInfo> infos; + + if (HostOsInfo::isWindowsHost()) { + +#ifdef Q_OS_WIN64 + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Keil\\Products"; +#else + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Keil\\Products"; +#endif + + // Dictionary for know toolchains. + static const struct Entry { + QString productKey; + QString subExePath; + } knowToolchains[] = { + {QStringLiteral("MDK"), QStringLiteral("\\ARMCC\\bin\\armcc.exe")}, + {QStringLiteral("C51"), QStringLiteral("\\BIN\\c51.exe")}, + }; + + QSettings registry(QLatin1String(kRegistryNode), QSettings::NativeFormat); + const auto productGroups = registry.childGroups(); + for (const QString &productKey : productGroups) { + const auto entryEnd = std::end(knowToolchains); + const auto entryIt = std::find_if(std::begin(knowToolchains), entryEnd, + [productKey](const Entry &entry) { + return entry.productKey == productKey; + }); + if (entryIt == entryEnd) + continue; + + registry.beginGroup(productKey); + const QString rootPath = registry.value(QStringLiteral("Path")) + .toString(); + if (!rootPath.isEmpty()) { + // Build full compiler path. + const QFileInfo keilPath(rootPath + entryIt->subExePath); + if (keilPath.exists()) { + QString version = registry.value(QStringLiteral("Version")) + .toString(); + if (version.startsWith(QLatin1Char('V'))) + version.remove(0, 1); + infos.push_back({keilPath.absoluteFilePath(), version}); + } + } + registry.endGroup(); + } + + } + + return infos; +} + +bool isKeilCompiler(const QString &compilerName) +{ + return Internal::any_of(knownKeilCompilerNames(), [compilerName]( + const QString &knownName) { + return compilerName.contains(knownName); + }); +} + +void createKeilProfile(const QFileInfo &compiler, Settings *settings, + QString profileName) +{ + createKeilProfileHelper(compiler, settings, profileName); +} + +void keilProbe(Settings *settings, QList<Profile> &profiles) +{ + qbsInfo() << Tr::tr("Trying to detect KEIL toolchains..."); + + std::vector<KeilInstallInfo> allInfos = installedKeilsFromRegistry(); + const std::vector<KeilInstallInfo> pathInfos = installedKeilsFromPath(); + allInfos.insert(std::end(allInfos), std::begin(pathInfos), std::end(pathInfos)); + + for (const KeilInstallInfo &info : allInfos) { + const auto profile = createKeilProfileHelper(info.compilerPath, settings); + profiles.push_back(profile); + } + + if (allInfos.empty()) + qbsInfo() << Tr::tr("No KEIL toolchains found."); +} diff --git a/src/app/qbs-setup-toolchains/keilprobe.h b/src/app/qbs-setup-toolchains/keilprobe.h new file mode 100644 index 000000000..6a897b84b --- /dev/null +++ b/src/app/qbs-setup-toolchains/keilprobe.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** 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$ +** +****************************************************************************/ + +#ifndef KEILPROBE_H +#define KEILPROBE_H + +#include <QtCore/qlist.h> + +QT_BEGIN_NAMESPACE +class QFileInfo; +QT_END_NAMESPACE + +namespace qbs { +class Profile; +class Settings; +} + +struct KeilInstallInfo +{ + QString compilerPath; + QString version; +}; + +bool isKeilCompiler(const QString &compilerName); + +void createKeilProfile(const QFileInfo &compiler, qbs::Settings *settings, + QString profileName); + +void keilProbe(qbs::Settings *settings, QList<qbs::Profile> &profiles); + +#endif // KEILPROBE_H diff --git a/src/app/qbs-setup-toolchains/msvcprobe.cpp b/src/app/qbs-setup-toolchains/msvcprobe.cpp index a6292d860..d0b60a7fe 100644 --- a/src/app/qbs-setup-toolchains/msvcprobe.cpp +++ b/src/app/qbs-setup-toolchains/msvcprobe.cpp @@ -160,12 +160,6 @@ static QString wow6432Key() #endif } -struct MSVCInstallInfo -{ - QString version; - QString installDir; -}; - static QString vswhereFilePath() { static const std::vector<const char *> envVarCandidates{"ProgramFiles", "ProgramFiles(x86)"}; @@ -213,7 +207,8 @@ static std::vector<MSVCInstallInfo> retrieveInstancesFromVSWhere(ProductType pro .arg(parseError.errorString()); return result; } - for (const QJsonValue &v : jsonOutput.array()) { + const auto jsonArray = jsonOutput.array(); + for (const QJsonValue &v : jsonArray) { const QJsonObject o = v.toObject(); MSVCInstallInfo info; info.version = o.value(QStringLiteral("installationVersion")).toString(); @@ -287,7 +282,28 @@ static std::vector<MSVCInstallInfo> installedMSVCsFromRegistry() return result; } -static std::vector<MSVC> installedMSVCs() +QString MSVCInstallInfo::findVcvarsallBat() const +{ + static const auto vcvarsall2017 = QStringLiteral("VC/Auxiliary/Build/vcvarsall.bat"); + // 2015, 2013 and 2012 + static const auto vcvarsallOld = QStringLiteral("VC/vcvarsall.bat"); + QDir dir(installDir); + if (dir.exists(vcvarsall2017)) + return dir.absoluteFilePath(vcvarsall2017); + if (dir.exists(vcvarsallOld)) + return dir.absoluteFilePath(vcvarsallOld); + return {}; +} + +std::vector<MSVCInstallInfo> installedMSVCs() +{ + const auto installInfos = installedMSVCsFromVsWhere(); + if (installInfos.empty()) + return installedMSVCsFromRegistry(); + return installInfos; +} + +static std::vector<MSVC> installedCompilers() { std::vector<MSVC> msvcs; std::vector<MSVCInstallInfo> installInfos = installedMSVCsFromVsWhere(); @@ -384,7 +400,7 @@ void msvcProbe(Settings *settings, QList<Profile> &profiles) // 2) Installed MSVCs std::vector<MSVC> msvcs; - const auto instMsvcs = installedMSVCs(); + const auto instMsvcs = installedCompilers(); for (const MSVC &msvc : instMsvcs) { if (msvc.internalVsVersion.majorVersion() < 15) { // Check existence of various install scripts @@ -451,7 +467,7 @@ void msvcProbe(Settings *settings, QList<Profile> &profiles) void createMsvcProfile(const QString &profileName, const QString &compilerFilePath, Settings *settings) { - MSVC msvc(compilerFilePath); + MSVC msvc(compilerFilePath, MSVC::architectureFromClPath(compilerFilePath)); msvc.init(); QList<Profile> dummy; addMSVCPlatform(settings, dummy, profileName, &msvc); diff --git a/src/app/qbs-setup-toolchains/msvcprobe.h b/src/app/qbs-setup-toolchains/msvcprobe.h index 0fa209548..4fa2cde48 100644 --- a/src/app/qbs-setup-toolchains/msvcprobe.h +++ b/src/app/qbs-setup-toolchains/msvcprobe.h @@ -42,11 +42,23 @@ #include <QtCore/qlist.h> +#include <vector> + namespace qbs { class Profile; class Settings; } +struct MSVCInstallInfo +{ + QString version; + QString installDir; + + QString findVcvarsallBat() const; +}; + +std::vector<MSVCInstallInfo> installedMSVCs(); + void createMsvcProfile(const QString &profileName, const QString &compilerFilePath, qbs::Settings *settings); diff --git a/src/app/qbs-setup-toolchains/probe.cpp b/src/app/qbs-setup-toolchains/probe.cpp index e90bafec2..3fae20a6e 100644 --- a/src/app/qbs-setup-toolchains/probe.cpp +++ b/src/app/qbs-setup-toolchains/probe.cpp @@ -38,7 +38,11 @@ ****************************************************************************/ #include "probe.h" +#include "clangclprobe.h" +#include "iarewprobe.h" +#include "keilprobe.h" #include "msvcprobe.h" +#include "sdccprobe.h" #include "xcodeprobe.h" #include <logging/translator.h> @@ -66,7 +70,7 @@ using Internal::Tr; static QTextStream qStdout(stdout); static QTextStream qStderr(stderr); -static QString findExecutable(const QString &fileName) +QString findExecutable(const QString &fileName) { QString fullFileName = fileName; if (HostOsInfo::isWindowsHost() @@ -107,34 +111,12 @@ static QStringList validMinGWMachines() QStringLiteral("i586-mingw32msvc"), QStringLiteral("amd64-mingw32msvc")}; } -static QStringList knownIarCompilerNames() -{ - return {QStringLiteral("icc8051"), QStringLiteral("iccarm"), QStringLiteral("iccavr")}; -} - -static bool isIarCompiler(const QString &compilerName) -{ - return Internal::any_of(knownIarCompilerNames(), [compilerName](const QString &knownName) { - return compilerName.contains(knownName); - }); -} - -static QStringList knownKeilCompilerNames() -{ - return {QStringLiteral("c51"), QStringLiteral("armcc")}; -} - -static bool isKeilCompiler(const QString &compilerName) -{ - return Internal::any_of(knownKeilCompilerNames(), [compilerName](const QString &knownName) { - return compilerName.contains(knownName); - }); -} - static QStringList toolchainTypeFromCompilerName(const QString &compilerName) { if (compilerName == QLatin1String("cl.exe")) return canonicalToolchain(QStringLiteral("msvc")); + if (compilerName == QLatin1String("clang-cl.exe")) + return canonicalToolchain(QLatin1String("clang-cl")); const auto types = { QStringLiteral("clang"), QStringLiteral("llvm"), QStringLiteral("mingw"), QStringLiteral("gcc") }; for (const auto &type : types) { @@ -147,6 +129,8 @@ static QStringList toolchainTypeFromCompilerName(const QString &compilerName) return canonicalToolchain(QStringLiteral("iar")); if (isKeilCompiler(compilerName)) return canonicalToolchain(QStringLiteral("keil")); + if (isSdccCompiler(compilerName)) + return canonicalToolchain(QStringLiteral("sdcc")); return {}; } @@ -191,8 +175,10 @@ static void setCommonProperties(Profile &profile, const QString &compilerFilePat class ToolPathSetup { public: - ToolPathSetup(Profile *profile, const QString &path, const QString &toolchainPrefix) - : m_profile(profile), m_compilerDirPath(path), m_toolchainPrefix(toolchainPrefix) + ToolPathSetup(Profile *profile, QString path, QString toolchainPrefix) + : m_profile(profile), + m_compilerDirPath(std::move(path)), + m_toolchainPrefix(std::move(toolchainPrefix)) { } @@ -262,70 +248,6 @@ static Profile createGccProfile(const QString &compilerFilePath, Settings *setti return profile; } -static QString guessIarArchitecture(const QFileInfo &compiler) -{ - const auto baseName = compiler.baseName(); - if (baseName == QLatin1String("icc8051")) - return QStringLiteral("mcs51"); - if (baseName == QLatin1String("iccarm")) - return QStringLiteral("arm"); - if (baseName == QLatin1String("iccavr")) - return QStringLiteral("avr"); - return {}; -} - -static Profile createIarProfile(const QFileInfo &compiler, Settings *settings, - QString profileName = QString()) -{ - const QString architecture = guessIarArchitecture(compiler); - - // In case the profile is auto-detected. - if (profileName.isEmpty()) - profileName = QLatin1String("iar-") + architecture; - - Profile profile(profileName, settings); - profile.setValue(QLatin1String("cpp.toolchainInstallPath"), compiler.absolutePath()); - profile.setValue(QLatin1String("qbs.toolchainType"), QLatin1String("iar")); - if (!architecture.isEmpty()) - profile.setValue(QLatin1String("qbs.architecture"), architecture); - - qStdout << Tr::tr("Profile '%1' created for '%2'.").arg( - profile.name(), compiler.absoluteFilePath()) - << endl; - return profile; -} - -static QString guessKeilArchitecture(const QFileInfo &compiler) -{ - const auto baseName = compiler.baseName(); - if (baseName == QLatin1String("c51")) - return QStringLiteral("mcs51"); - if (baseName == QLatin1String("armcc")) - return QStringLiteral("arm"); - return {}; -} - -static Profile createKeilProfile(const QFileInfo &compiler, Settings *settings, - QString profileName = QString()) -{ - const QString architecture = guessKeilArchitecture(compiler); - - // In case the profile is auto-detected. - if (profileName.isEmpty()) - profileName = QLatin1String("keil-") + architecture; - - Profile profile(profileName, settings); - profile.setValue(QStringLiteral("cpp.toolchainInstallPath"), compiler.absolutePath()); - profile.setValue(QStringLiteral("qbs.toolchainType"), QStringLiteral("keil")); - if (!architecture.isEmpty()) - profile.setValue(QStringLiteral("qbs.architecture"), architecture); - - qStdout << Tr::tr("Profile '%1' created for '%2'.").arg( - profile.name(), compiler.absoluteFilePath()) - << endl; - return profile; -} - static void gccProbe(Settings *settings, QList<Profile> &profiles, const QString &compilerName) { qStdout << Tr::tr("Trying to detect %1...").arg(compilerName) << endl; @@ -364,47 +286,12 @@ static void mingwProbe(Settings *settings, QList<Profile> &profiles) } } -static void iarProbe(Settings *settings, QList<Profile> &profiles) -{ - qStdout << Tr::tr("Trying to detect IAR toolchains...") << endl; - - bool isFound = false; - for (const QString &compilerName : knownIarCompilerNames()) { - const QString iarPath = findExecutable(HostOsInfo::appendExecutableSuffix(compilerName)); - if (!iarPath.isEmpty()) { - const auto profile = createIarProfile(iarPath, settings); - profiles.push_back(profile); - isFound = true; - } - } - - if (!isFound) - qStdout << Tr::tr("No IAR toolchains found.") << endl; -} - -static void keilProbe(Settings *settings, QList<Profile> &profiles) -{ - qStdout << Tr::tr("Trying to detect KEIL toolchains...") << endl; - - bool isFound = false; - for (const QString &compilerName : knownKeilCompilerNames()) { - const QString keilPath = findExecutable(HostOsInfo::appendExecutableSuffix(compilerName)); - if (!keilPath.isEmpty()) { - const auto profile = createKeilProfile(keilPath, settings); - profiles.push_back(profile); - isFound = true; - } - } - - if (!isFound) - qStdout << Tr::tr("No KEIL toolchains found.") << endl; -} - void probe(Settings *settings) { QList<Profile> profiles; if (HostOsInfo::isWindowsHost()) { msvcProbe(settings, profiles); + clangClProbe(settings, profiles); } else { gccProbe(settings, profiles, QStringLiteral("gcc")); gccProbe(settings, profiles, QStringLiteral("clang")); @@ -417,6 +304,7 @@ void probe(Settings *settings) mingwProbe(settings, profiles); iarProbe(settings, profiles); keilProbe(settings, profiles); + sdccProbe(settings, profiles); if (profiles.empty()) { qStderr << Tr::tr("Could not detect any toolchains. No profile created.") << endl; @@ -447,12 +335,16 @@ void createProfile(const QString &profileName, const QString &toolchainType, if (toolchainTypes.contains(QLatin1String("msvc"))) createMsvcProfile(profileName, compiler.absoluteFilePath(), settings); + else if (toolchainTypes.contains(QLatin1String("clang-cl"))) + createClangClProfile(profileName, compiler.absoluteFilePath(), settings); else if (toolchainTypes.contains(QLatin1String("gcc"))) createGccProfile(compiler.absoluteFilePath(), settings, toolchainTypes, profileName); else if (toolchainTypes.contains(QLatin1String("iar"))) createIarProfile(compiler, settings, profileName); else if (toolchainTypes.contains(QLatin1String("keil"))) createKeilProfile(compiler, settings, profileName); + else if (toolchainTypes.contains(QLatin1String("sdcc"))) + createSdccProfile(compiler, settings, profileName); else throw qbs::ErrorInfo(Tr::tr("Cannot create profile: Unknown toolchain type.")); } diff --git a/src/app/qbs-setup-toolchains/probe.h b/src/app/qbs-setup-toolchains/probe.h index 5c8774ddb..510747ef7 100644 --- a/src/app/qbs-setup-toolchains/probe.h +++ b/src/app/qbs-setup-toolchains/probe.h @@ -48,6 +48,8 @@ QT_END_NAMESPACE namespace qbs { class Settings; } +QString findExecutable(const QString &fileName); + void createProfile(const QString &profileName, const QString &toolchainType, const QString &compilerFilePath, qbs::Settings *settings); diff --git a/src/app/qbs-setup-toolchains/qbs-setup-toolchains.pro b/src/app/qbs-setup-toolchains/qbs-setup-toolchains.pro index f395c5458..e83a9c716 100644 --- a/src/app/qbs-setup-toolchains/qbs-setup-toolchains.pro +++ b/src/app/qbs-setup-toolchains/qbs-setup-toolchains.pro @@ -3,17 +3,25 @@ include(../app.pri) TARGET = qbs-setup-toolchains HEADERS += \ + clangclprobe.h \ commandlineparser.h \ + iarewprobe.h \ + keilprobe.h \ msvcprobe.h \ probe.h \ - xcodeprobe.h + sdccprobe.h \ + xcodeprobe.h \ SOURCES += \ + clangclprobe.cpp \ commandlineparser.cpp \ + iarewprobe.cpp \ + keilprobe.cpp \ main.cpp \ msvcprobe.cpp \ probe.cpp \ - xcodeprobe.cpp + sdccprobe.cpp \ + xcodeprobe.cpp \ mingw { RC_FILE = qbs-setup-toolchains.rc diff --git a/src/app/qbs-setup-toolchains/qbs-setup-toolchains.qbs b/src/app/qbs-setup-toolchains/qbs-setup-toolchains.qbs index 1b7cb6526..fd3043a28 100644 --- a/src/app/qbs-setup-toolchains/qbs-setup-toolchains.qbs +++ b/src/app/qbs-setup-toolchains/qbs-setup-toolchains.qbs @@ -4,13 +4,21 @@ QbsApp { name: "qbs-setup-toolchains" cpp.dynamicLibraries: qbs.targetOS.contains("windows") ? base.concat("shell32") : base files: [ + "clangclprobe.cpp", + "clangclprobe.h", "commandlineparser.cpp", "commandlineparser.h", + "iarewprobe.cpp", + "iarewprobe.h", + "keilprobe.cpp", + "keilprobe.h", "main.cpp", "msvcprobe.cpp", "msvcprobe.h", "probe.cpp", "probe.h", + "sdccprobe.cpp", + "sdccprobe.h", "xcodeprobe.cpp", "xcodeprobe.h", ] diff --git a/src/app/qbs-setup-toolchains/sdccprobe.cpp b/src/app/qbs-setup-toolchains/sdccprobe.cpp new file mode 100644 index 000000000..751e872ee --- /dev/null +++ b/src/app/qbs-setup-toolchains/sdccprobe.cpp @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** 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$ +** +****************************************************************************/ + +#include "probe.h" +#include "sdccprobe.h" + +#include "../shared/logging/consolelogger.h" + +#include <logging/translator.h> + +#include <tools/hostosinfo.h> +#include <tools/profile.h> + +#include <QtCore/qfileinfo.h> +#include <QtCore/qlist.h> +#include <QtCore/qsettings.h> + +using namespace qbs; +using Internal::Tr; +using Internal::HostOsInfo; + +static QStringList knownSdccCompilerNames() +{ + return {QStringLiteral("sdcc")}; +} + +static QString guessSdccArchitecture(const QFileInfo &compiler) +{ + const auto baseName = compiler.baseName(); + if (baseName == QLatin1String("sdcc")) + return QStringLiteral("mcs51"); + return {}; +} + +static Profile createSdccProfileHelper(const QFileInfo &compiler, Settings *settings, + QString profileName = QString()) +{ + const QString architecture = guessSdccArchitecture(compiler); + + // In case the profile is auto-detected. + if (profileName.isEmpty()) + profileName = QLatin1String("sdcc-") + architecture; + + Profile profile(profileName, settings); + profile.setValue(QStringLiteral("cpp.toolchainInstallPath"), compiler.absolutePath()); + profile.setValue(QStringLiteral("qbs.toolchainType"), QStringLiteral("sdcc")); + if (!architecture.isEmpty()) + profile.setValue(QStringLiteral("qbs.architecture"), architecture); + + qbsInfo() << Tr::tr("Profile '%1' created for '%2'.").arg( + profile.name(), compiler.absoluteFilePath()); + return profile; +} + +static std::vector<SdccInstallInfo> installedSdccsFromPath() +{ + std::vector<SdccInstallInfo> infos; + const auto compilerNames = knownSdccCompilerNames(); + for (const QString &compilerName : compilerNames) { + const QFileInfo sdccPath( + findExecutable( + HostOsInfo::appendExecutableSuffix(compilerName))); + if (!sdccPath.exists()) + continue; + infos.push_back({sdccPath.absoluteFilePath(), {}}); + } + return infos; +} + +static std::vector<SdccInstallInfo> installedSdccsFromRegistry() +{ + std::vector<SdccInstallInfo> infos; + + if (HostOsInfo::isWindowsHost()) { + +#ifdef Q_OS_WIN64 + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\SDCC"; +#else + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\SDCC"; +#endif + + QSettings registry(QLatin1String(kRegistryNode), QSettings::NativeFormat); + QString rootPath = registry.value(QStringLiteral("Default")).toString(); + if (!rootPath.isEmpty()) { + // Build full compiler path. + const QFileInfo sdccPath(rootPath + QLatin1String("\\bin\\sdcc.exe")); + if (sdccPath.exists()) { + // Build compiler version. + const QString version = QStringLiteral("%1.%2.%3").arg( + registry.value(QStringLiteral("VersionMajor")).toString(), + registry.value(QStringLiteral("VersionMinor")).toString(), + registry.value(QStringLiteral("VersionRevision")).toString()); + infos.push_back({sdccPath.absoluteFilePath(), version}); + } + } + } + + return infos; +} + +bool isSdccCompiler(const QString &compilerName) +{ + return Internal::any_of(knownSdccCompilerNames(), [compilerName]( + const QString &knownName) { + return compilerName.contains(knownName); + }); +} + +void createSdccProfile(const QFileInfo &compiler, Settings *settings, + QString profileName) +{ + createSdccProfileHelper(compiler, settings, profileName); +} + +void sdccProbe(Settings *settings, QList<Profile> &profiles) +{ + qbsInfo() << Tr::tr("Trying to detect SDCC toolchains..."); + + std::vector<SdccInstallInfo> allInfos = installedSdccsFromRegistry(); + const std::vector<SdccInstallInfo> pathInfos = installedSdccsFromPath(); + allInfos.insert(std::end(allInfos), std::begin(pathInfos), std::end(pathInfos)); + + for (const SdccInstallInfo &info : allInfos) { + const auto profile = createSdccProfileHelper(info.compilerPath, settings); + profiles.push_back(profile); + } + + if (allInfos.empty()) + qbsInfo() << Tr::tr("No SDCC toolchains found."); +} diff --git a/src/app/qbs-setup-toolchains/sdccprobe.h b/src/app/qbs-setup-toolchains/sdccprobe.h new file mode 100644 index 000000000..7f4219b5a --- /dev/null +++ b/src/app/qbs-setup-toolchains/sdccprobe.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** 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$ +** +****************************************************************************/ + +#ifndef SDCCPROBE_H +#define SDCCPROBE_H + +#include <QtCore/qlist.h> + +QT_BEGIN_NAMESPACE +class QFileInfo; +QT_END_NAMESPACE + +namespace qbs { +class Profile; +class Settings; +} + +struct SdccInstallInfo +{ + QString compilerPath; + QString version; +}; + +bool isSdccCompiler(const QString &compilerName); + +void createSdccProfile(const QFileInfo &compiler, qbs::Settings *settings, + QString profileName); + +void sdccProbe(qbs::Settings *settings, QList<qbs::Profile> &profiles); + +#endif // SDCCPROBE_H diff --git a/src/app/qbs-setup-toolchains/xcodeprobe.cpp b/src/app/qbs-setup-toolchains/xcodeprobe.cpp index 227dc00f3..a0f6f80d1 100644 --- a/src/app/qbs-setup-toolchains/xcodeprobe.cpp +++ b/src/app/qbs-setup-toolchains/xcodeprobe.cpp @@ -59,12 +59,54 @@ using namespace qbs; using Internal::Tr; -namespace { static const QString defaultDeveloperPath = QStringLiteral("/Applications/Xcode.app/Contents/Developer"); static const std::regex defaultDeveloperPathRegex( "^/Applications/Xcode([a-zA-Z0-9 _-]+)\\.app/Contents/Developer$"); +static QString targetOS(const QString &applePlatformName) +{ + if (applePlatformName == QStringLiteral("macosx")) + return QStringLiteral("macos"); + if (applePlatformName == QStringLiteral("iphoneos")) + return QStringLiteral("ios"); + if (applePlatformName == QStringLiteral("iphonesimulator")) + return QStringLiteral("ios-simulator"); + if (applePlatformName == QStringLiteral("appletvos")) + return QStringLiteral("tvos"); + if (applePlatformName == QStringLiteral("appletvsimulator")) + return QStringLiteral("tvos-simulator"); + if (applePlatformName == QStringLiteral("watchos")) + return QStringLiteral("watchos"); + if (applePlatformName == QStringLiteral("watchsimulator")) + return QStringLiteral("watchos-simulator"); + return {}; +} + +static QStringList archList(const QString &applePlatformName) +{ + QStringList archs; + if (applePlatformName == QStringLiteral("macosx") + || applePlatformName == QStringLiteral("iphonesimulator") + || applePlatformName == QStringLiteral("appletvsimulator") + || applePlatformName == QStringLiteral("watchsimulator")) { + if (applePlatformName != QStringLiteral("appletvsimulator")) + archs << QStringLiteral("x86"); + if (applePlatformName != QStringLiteral("watchsimulator")) + archs << QStringLiteral("x86_64"); + } else if (applePlatformName == QStringLiteral("iphoneos") + || applePlatformName == QStringLiteral("appletvos")) { + if (applePlatformName != QStringLiteral("appletvos")) + archs << QStringLiteral("armv7a"); + archs << QStringLiteral("arm64"); + } else if (applePlatformName == QStringLiteral("watchos")) { + archs << QStringLiteral("armv7k"); + } + + return archs; +} + +namespace { class XcodeProbe { public: @@ -117,54 +159,13 @@ void XcodeProbe::detectDeveloperPaths() if (!launchServices.waitForFinished(-1) || launchServices.exitCode()) { qbsInfo() << Tr::tr("Could not detect additional Xcode installations with /usr/bin/mdfind"); } else { - for (const QString &path : QString::fromLocal8Bit(launchServices.readAllStandardOutput()) - .split(QLatin1Char('\n'), QString::SkipEmptyParts)) + const auto paths = QString::fromLocal8Bit(launchServices.readAllStandardOutput()) + .split(QLatin1Char('\n'), QString::SkipEmptyParts); + for (const QString &path : paths) addDeveloperPath(path + QStringLiteral("/Contents/Developer")); } } -static QString targetOS(const QString &applePlatformName) -{ - if (applePlatformName == QStringLiteral("macosx")) - return QStringLiteral("macos"); - if (applePlatformName == QStringLiteral("iphoneos")) - return QStringLiteral("ios"); - if (applePlatformName == QStringLiteral("iphonesimulator")) - return QStringLiteral("ios-simulator"); - if (applePlatformName == QStringLiteral("appletvos")) - return QStringLiteral("tvos"); - if (applePlatformName == QStringLiteral("appletvsimulator")) - return QStringLiteral("tvos-simulator"); - if (applePlatformName == QStringLiteral("watchos")) - return QStringLiteral("watchos"); - if (applePlatformName == QStringLiteral("watchsimulator")) - return QStringLiteral("watchos-simulator"); - return {}; -} - -static QStringList archList(const QString &applePlatformName) -{ - QStringList archs; - if (applePlatformName == QStringLiteral("macosx") - || applePlatformName == QStringLiteral("iphonesimulator") - || applePlatformName == QStringLiteral("appletvsimulator") - || applePlatformName == QStringLiteral("watchsimulator")) { - if (applePlatformName != QStringLiteral("appletvsimulator")) - archs << QStringLiteral("x86"); - if (applePlatformName != QStringLiteral("watchsimulator")) - archs << QStringLiteral("x86_64"); - } else if (applePlatformName == QStringLiteral("iphoneos") - || applePlatformName == QStringLiteral("appletvos")) { - if (applePlatformName != QStringLiteral("appletvos")) - archs << QStringLiteral("armv7a"); - archs << QStringLiteral("arm64"); - } else if (applePlatformName == QStringLiteral("watchos")) { - archs << QStringLiteral("armv7k"); - } - - return archs; -} - void XcodeProbe::setupDefaultToolchains(const QString &devPath, const QString &xcodeName) { qbsInfo() << Tr::tr("Profile '%1' created for '%2'.").arg(xcodeName).arg(devPath); @@ -188,14 +189,15 @@ void XcodeProbe::setupDefaultToolchains(const QString &devPath, const QString &x << QStringLiteral("appletvsimulator") << QStringLiteral("watchos") << QStringLiteral("watchsimulator"); - for (const QString &platform : platforms) { + for (const QString &platform : qAsConst(platforms)) { Profile platformProfile(xcodeName + QLatin1Char('-') + platform, settings); platformProfile.removeProfile(); platformProfile.setBaseProfile(installationProfile.name()); platformProfile.setValue(QStringLiteral("qbs.targetPlatform"), targetOS(platform)); profiles.push_back(platformProfile); - for (const QString &arch : archList(platform)) { + const auto architectures = archList(platform); + for (const QString &arch : architectures) { Profile archProfile(xcodeName + QLatin1Char('-') + platform + QLatin1Char('-') + arch, settings); archProfile.removeProfile(); @@ -211,7 +213,7 @@ void XcodeProbe::detectAll() { int i = 1; detectDeveloperPaths(); - for (const QString &developerPath : developerPaths) { + for (const QString &developerPath : qAsConst(developerPaths)) { QString profileName = QStringLiteral("xcode"); if (developerPath != defaultDeveloperPath) { const auto devPath = developerPath.toStdString(); diff --git a/src/app/qbs/commandlinefrontend.cpp b/src/app/qbs/commandlinefrontend.cpp index 1a8e1757d..95c3c10bc 100644 --- a/src/app/qbs/commandlinefrontend.cpp +++ b/src/app/qbs/commandlinefrontend.cpp @@ -230,7 +230,7 @@ void CommandLineFrontend::handleJobFinished(bool success, AbstractJob *job) return; } cancel(); - } else if (SetupProjectJob * const setupJob = qobject_cast<SetupProjectJob *>(job)) { + } else if (const auto setupJob = qobject_cast<SetupProjectJob * const>(job)) { m_resolveJobs.removeOne(job); m_projects.push_back(setupJob->project()); if (m_observer && resolvingMultipleProjects()) @@ -611,7 +611,7 @@ void CommandLineFrontend::connectBuildJob(AbstractJob *job) { connectJob(job); - BuildJob *bjob = qobject_cast<BuildJob *>(job); + const auto bjob = qobject_cast<const BuildJob *>(job); if (!bjob) return; diff --git a/src/app/qbs/commandlinefrontend.h b/src/app/qbs/commandlinefrontend.h index 363e0b040..5f598cb35 100644 --- a/src/app/qbs/commandlinefrontend.h +++ b/src/app/qbs/commandlinefrontend.h @@ -67,7 +67,7 @@ class CommandLineFrontend : public QObject public: explicit CommandLineFrontend(const CommandLineParser &parser, Settings *settings, QObject *parent = nullptr); - ~CommandLineFrontend(); + ~CommandLineFrontend() override; void cancel(); void start(); @@ -111,16 +111,16 @@ private: QList<AbstractJob *> m_buildJobs; QList<Project> m_projects; - ConsoleProgressObserver *m_observer; + ConsoleProgressObserver *m_observer = nullptr; enum CancelStatus { CancelStatusNone, CancelStatusRequested, CancelStatusCanceling }; - CancelStatus m_cancelStatus; + CancelStatus m_cancelStatus = CancelStatus::CancelStatusNone; QTimer * const m_cancelTimer; - int m_buildEffortsNeeded; - int m_buildEffortsRetrieved; - int m_totalBuildEffort; - int m_currentBuildEffort; + int m_buildEffortsNeeded = 0; + int m_buildEffortsRetrieved = 0; + int m_totalBuildEffort = 0; + int m_currentBuildEffort = 0; QHash<AbstractJob *, int> m_buildEfforts; std::shared_ptr<ProjectGenerator> m_generator; }; diff --git a/src/app/qbs/qbstool.h b/src/app/qbs/qbstool.h index c1d7f75d8..e6d230361 100644 --- a/src/app/qbs/qbstool.h +++ b/src/app/qbs/qbstool.h @@ -57,8 +57,8 @@ public: int *exitCode = 0); private: - bool m_failedToStart; - int m_exitCode; + bool m_failedToStart = false; + int m_exitCode = 0; QString m_stdout; QString m_stderr; }; diff --git a/src/app/shared/logging/consolelogger.h b/src/app/shared/logging/consolelogger.h index d362cfc29..db7a705f5 100644 --- a/src/app/shared/logging/consolelogger.h +++ b/src/app/shared/logging/consolelogger.h @@ -55,7 +55,7 @@ public: void setEnabled(bool enabled) { m_enabled = enabled; } private: - void doPrintMessage(qbs::LoggerLevel level, const QString &message, const QString &tag); + void doPrintMessage(qbs::LoggerLevel level, const QString &message, const QString &tag) override; void fprintfWrapper(TextColor color, FILE *file, const char *str, ...); private: diff --git a/src/lib/corelib/api/internaljobs.cpp b/src/lib/corelib/api/internaljobs.cpp index f07927c71..c74c3d8a4 100644 --- a/src/lib/corelib/api/internaljobs.cpp +++ b/src/lib/corelib/api/internaljobs.cpp @@ -70,8 +70,8 @@ namespace Internal { class JobObserver : public ProgressObserver { public: - JobObserver(InternalJob *job) : m_canceled(false), m_job(job), m_timedLogger(nullptr) { } - ~JobObserver() { delete m_timedLogger; } + JobObserver(InternalJob *job) : m_job(job) { } + ~JobObserver() override { delete m_timedLogger; } void cancel() { @@ -116,20 +116,20 @@ private: return m_canceled; } - int m_value; - int m_maximum; + int m_value = 0; + int m_maximum = 0; mutable std::mutex m_cancelMutex; - bool m_canceled; + bool m_canceled = false; InternalJob * const m_job; - TimedActivityLogger *m_timedLogger; + TimedActivityLogger *m_timedLogger = nullptr; }; -InternalJob::InternalJob(const Logger &logger, QObject *parent) +InternalJob::InternalJob(Logger logger, QObject *parent) : QObject(parent) , m_observer(new JobObserver(this)) , m_ownsObserver(true) - , m_logger(logger) + , m_logger(std::move(logger)) , m_timed(false) { } @@ -162,7 +162,8 @@ void InternalJob::storeBuildGraph(const TopLevelProjectPtr &project) project->store(logger()); } catch (const ErrorInfo &error) { ErrorInfo fullError = this->error(); - for (const ErrorItem &item : error.items()) + const auto items = error.items(); + for (const ErrorItem &item : items) fullError.append(item); setError(fullError); } diff --git a/src/lib/corelib/api/internaljobs.h b/src/lib/corelib/api/internaljobs.h index 71e6615bf..58127eb05 100644 --- a/src/lib/corelib/api/internaljobs.h +++ b/src/lib/corelib/api/internaljobs.h @@ -68,7 +68,7 @@ class InternalJob : public QObject Q_OBJECT friend class JobObserver; public: - ~InternalJob(); + ~InternalJob() override; void cancel(); virtual void start() {} @@ -80,7 +80,7 @@ public: void shareObserverWith(InternalJob *otherJob); protected: - explicit InternalJob(const Logger &logger, QObject *parent = nullptr); + explicit InternalJob(Logger logger, QObject *parent = nullptr); JobObserver *observer() const { return m_observer; } void setTimed(bool timed) { m_timed = timed; } @@ -106,7 +106,7 @@ class InternalJobThreadWrapper : public InternalJob Q_OBJECT public: InternalJobThreadWrapper(InternalJob *synchronousJob, QObject *parent = nullptr); - ~InternalJobThreadWrapper(); + ~InternalJobThreadWrapper() override; void start() override; InternalJob *synchronousJob() const { return m_job; } @@ -127,7 +127,7 @@ class InternalSetupProjectJob : public InternalJob Q_OBJECT public: InternalSetupProjectJob(const Logger &logger); - ~InternalSetupProjectJob(); + ~InternalSetupProjectJob() override; void init(const TopLevelProjectPtr &existingProject, const SetupProjectParameters ¶meters); void reportError(const ErrorInfo &error); @@ -160,7 +160,7 @@ signals: protected: BuildGraphTouchingJob(const Logger &logger, QObject *parent = nullptr); - ~BuildGraphTouchingJob(); + ~BuildGraphTouchingJob() override; void setup(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, bool dryRun); @@ -211,7 +211,7 @@ class InternalInstallJob : public InternalJob Q_OBJECT public: InternalInstallJob(const Logger &logger); - ~InternalInstallJob(); + ~InternalInstallJob() override; void init(const TopLevelProjectPtr &project, const std::vector<ResolvedProductPtr> &products, const InstallOptions &options); diff --git a/src/lib/corelib/api/jobs.h b/src/lib/corelib/api/jobs.h index f121cc403..36c6b7a80 100644 --- a/src/lib/corelib/api/jobs.h +++ b/src/lib/corelib/api/jobs.h @@ -66,7 +66,7 @@ class QBS_EXPORT AbstractJob : public QObject { Q_OBJECT public: - ~AbstractJob(); + ~AbstractJob() override; enum State { StateRunning, StateCanceling, StateFinished }; State state() const { return m_state; } diff --git a/src/lib/corelib/api/project.cpp b/src/lib/corelib/api/project.cpp index 42591ce2f..3ffd6b2e9 100644 --- a/src/lib/corelib/api/project.cpp +++ b/src/lib/corelib/api/project.cpp @@ -233,7 +233,8 @@ ResolvedProductPtr ProjectPrivate::internalProduct(const ProductData &product) c ProductData ProjectPrivate::findProductData(const ProductData &product) const { - for (const ProductData &p : m_projectData.allProducts()) { + const auto products = m_projectData.allProducts(); + for (const ProductData &p : products) { if (p.name() == product.name() && p.profile() == product.profile() && p.multiplexConfigurationId() == product.multiplexConfigurationId()) { @@ -246,7 +247,8 @@ ProductData ProjectPrivate::findProductData(const ProductData &product) const QList<ProductData> ProjectPrivate::findProductsByName(const QString &name) const { QList<ProductData> list; - for (const ProductData &p : m_projectData.allProducts()) { + const auto products = m_projectData.allProducts(); + for (const ProductData &p : products) { if (p.name() == name) list.push_back(p); } @@ -255,7 +257,8 @@ QList<ProductData> ProjectPrivate::findProductsByName(const QString &name) const GroupData ProjectPrivate::findGroupData(const ProductData &product, const QString &groupName) const { - for (const GroupData &g : product.groups()) { + const auto groups = product.groups(); + for (const GroupData &g : groups) { if (g.name() == groupName) return g; } @@ -708,11 +711,14 @@ void ProjectPrivate::updateExternalCodeLocations(const ProjectData &project, if (lineOffset == 0) return; updateLocationIfNecessary(project.d->location, changeLocation, lineOffset); - for (const ProjectData &subProject : project.subProjects()) + const auto subProjects = project.subProjects(); + for (const ProjectData &subProject : subProjects) updateExternalCodeLocations(subProject, changeLocation, lineOffset); - for (const ProductData &product : project.products()) { + const auto products = project.products(); + for (const ProductData &product : products) { updateLocationIfNecessary(product.d->location, changeLocation, lineOffset); - for (const GroupData &group : product.groups()) + const auto groups = product.groups(); + for (const GroupData &group : groups) updateLocationIfNecessary(group.d->location, changeLocation, lineOffset); } } @@ -788,7 +794,8 @@ ProjectTransformerData ProjectPrivate::transformerData() if (!m_projectData.isValid()) retrieveProjectData(m_projectData, internalProject); ProjectTransformerData projectTransformerData; - for (const ProductData &productData : m_projectData.allProducts()) { + const auto allProducts = m_projectData.allProducts(); + for (const ProductData &productData : allProducts) { if (!productData.isEnabled()) continue; const ResolvedProductConstPtr product = internalProduct(productData); diff --git a/src/lib/corelib/api/projectdata.cpp b/src/lib/corelib/api/projectdata.cpp index 0c3ba186d..56700b8be 100644 --- a/src/lib/corelib/api/projectdata.cpp +++ b/src/lib/corelib/api/projectdata.cpp @@ -63,19 +63,15 @@ GroupData::GroupData() : d(new Internal::GroupDataPrivate) { } -GroupData::GroupData(const GroupData &other) : d(other.d) -{ -} +GroupData::GroupData(const GroupData &other) = default; -GroupData &GroupData::operator=(const GroupData &other) -{ - d = other.d; - return *this; -} +GroupData::GroupData(GroupData &&) Q_DECL_NOEXCEPT = default; -GroupData::~GroupData() -{ -} +GroupData &GroupData::operator=(const GroupData &other) = default; + +GroupData &GroupData::operator=(GroupData &&) Q_DECL_NOEXCEPT = default; + +GroupData::~GroupData() = default; /*! * \brief Returns true if and only if the Group holds data that was initialized by Qbs. @@ -212,19 +208,15 @@ ArtifactData::ArtifactData() : d(new Internal::ArtifactDataPrivate) { } -ArtifactData::ArtifactData(const ArtifactData &other) : d(other.d) -{ -} +ArtifactData::ArtifactData(const ArtifactData &other) = default; -ArtifactData &ArtifactData::operator=(const ArtifactData &other) -{ - d = other.d; - return *this; -} +ArtifactData::ArtifactData(ArtifactData &&) Q_DECL_NOEXCEPT = default; -ArtifactData::~ArtifactData() -{ -} +ArtifactData &ArtifactData::operator=(const ArtifactData &other) = default; + +ArtifactData &ArtifactData::operator=(ArtifactData &&) Q_DECL_NOEXCEPT = default; + +ArtifactData::~ArtifactData() = default; /*! * \brief Returns true if and only if this object holds data that was initialized by Qbs. @@ -321,19 +313,15 @@ InstallData::InstallData() : d(new Internal::InstallDataPrivate) { } -InstallData::InstallData(const InstallData &other) : d(other.d) -{ -} +InstallData::InstallData(const InstallData &other) = default; -InstallData &InstallData::operator=(const InstallData &other) -{ - d = other.d; - return *this; -} +InstallData::InstallData(InstallData &&) Q_DECL_NOEXCEPT = default; -InstallData::~InstallData() -{ -} +InstallData &InstallData::operator=(const InstallData &other) = default; + +InstallData &InstallData::operator=(InstallData &&) Q_DECL_NOEXCEPT = default; + +InstallData::~InstallData() = default; /*! * \brief Returns true if and only if this object holds data that was initialized by Qbs. @@ -408,19 +396,15 @@ ProductData::ProductData() : d(new Internal::ProductDataPrivate) { } -ProductData::ProductData(const ProductData &other) : d(other.d) -{ -} +ProductData::ProductData(const ProductData &other) = default; -ProductData &ProductData::operator=(const ProductData &other) -{ - d = other.d; - return *this; -} +ProductData::ProductData(ProductData &&) Q_DECL_NOEXCEPT = default; -ProductData::~ProductData() -{ -} +ProductData &ProductData::operator=(const ProductData &other) = default; + +ProductData &ProductData::operator=(ProductData &&) Q_DECL_NOEXCEPT = default; + +ProductData::~ProductData() = default; /*! * \brief Returns true if and only if the Product holds data that was initialized by Qbs. @@ -538,13 +522,14 @@ QList<ArtifactData> ProductData::targetArtifacts() const QList<ArtifactData> ProductData::installableArtifacts() const { QList<ArtifactData> artifacts; - for (const GroupData &g : groups()) { - for (const ArtifactData &a : g.allSourceArtifacts()) { + for (const GroupData &g : qAsConst(d->groups)) { + const auto sourceArtifacts = g.allSourceArtifacts(); + for (const ArtifactData &a : sourceArtifacts) { if (a.installData().isInstallable()) artifacts << a; } } - for (const ArtifactData &a : generatedArtifacts()) { + for (const ArtifactData &a : qAsConst(d->generatedArtifacts)) { if (a.installData().isInstallable()) artifacts << a; } @@ -560,7 +545,8 @@ QString ProductData::targetExecutable() const QBS_ASSERT(isValid(), return {}); if (d->moduleProperties.getModuleProperty(QStringLiteral("bundle"), QStringLiteral("isBundle")).toBool()) { - for (const ArtifactData &ta : targetArtifacts()) { + const auto artifacts = targetArtifacts(); + for (const ArtifactData &ta : artifacts) { if (ta.fileTags().contains(QLatin1String("bundle.application-executable"))) { if (ta.installData().isInstallable()) return ta.installData().localInstallFilePath(); @@ -568,7 +554,8 @@ QString ProductData::targetExecutable() const } } } - for (const ArtifactData &ta : targetArtifacts()) { + const auto artifacts = targetArtifacts(); + for (const ArtifactData &ta : artifacts) { if (ta.isExecutable()) { if (ta.installData().isInstallable()) return ta.installData().localInstallFilePath(); @@ -678,19 +665,15 @@ ProjectData::ProjectData() : d(new Internal::ProjectDataPrivate) { } -ProjectData::ProjectData(const ProjectData &other) : d(other.d) -{ -} +ProjectData::ProjectData(const ProjectData &other) = default; -ProjectData &ProjectData::operator =(const ProjectData &other) -{ - d = other.d; - return *this; -} +ProjectData::ProjectData(ProjectData &&) Q_DECL_NOEXCEPT = default; -ProjectData::~ProjectData() -{ -} +ProjectData &ProjectData::operator =(const ProjectData &other) = default; + +ProjectData &ProjectData::operator=(ProjectData &&) Q_DECL_NOEXCEPT = default; + +ProjectData::~ProjectData() = default; /*! * \brief Returns true if and only if the Project holds data that was initialized by Qbs. @@ -758,7 +741,7 @@ QList<ProjectData> ProjectData::subProjects() const QList<ProductData> ProjectData::allProducts() const { QList<ProductData> productList = products(); - for (const ProjectData &pd : subProjects()) + for (const ProjectData &pd : qAsConst(d->subProjects)) productList << pd.allProducts(); return productList; } @@ -769,7 +752,8 @@ QList<ProductData> ProjectData::allProducts() const QList<ArtifactData> ProjectData::installableArtifacts() const { QList<ArtifactData> artifacts; - for (const ProductData &p : allProducts()) + const auto products = allProducts(); + for (const ProductData &p : products) artifacts << p.installableArtifacts(); return artifacts; } @@ -804,31 +788,30 @@ bool operator<(const ProjectData &lhs, const ProjectData &rhs) */ PropertyMap::PropertyMap() - : d(new Internal::PropertyMapPrivate) + : d(std::make_unique<Internal::PropertyMapPrivate>()) { static Internal::PropertyMapPtr defaultInternalMap = Internal::PropertyMapInternal::create(); d->m_map = defaultInternalMap; } PropertyMap::PropertyMap(const PropertyMap &other) - : d(new Internal::PropertyMapPrivate(*other.d)) + : d(std::make_unique<Internal::PropertyMapPrivate>(*other.d)) { } -PropertyMap::~PropertyMap() -{ - delete d; -} +PropertyMap::PropertyMap(PropertyMap &&other) Q_DECL_NOEXCEPT = default; + +PropertyMap::~PropertyMap() = default; PropertyMap &PropertyMap::operator =(const PropertyMap &other) { - if (this != &other) { - delete d; - d = new Internal::PropertyMapPrivate(*other.d); - } + if (this != &other) + d = std::make_unique<Internal::PropertyMapPrivate>(*other.d); return *this; } +PropertyMap &PropertyMap::operator =(PropertyMap &&other) Q_DECL_NOEXCEPT = default; + /*! * \brief Returns the names of all properties. */ diff --git a/src/lib/corelib/api/projectdata.h b/src/lib/corelib/api/projectdata.h index 91bcf7d9d..3bd1c4540 100644 --- a/src/lib/corelib/api/projectdata.h +++ b/src/lib/corelib/api/projectdata.h @@ -48,6 +48,7 @@ #include <QtCore/qstringlist.h> #include <QtCore/qvariant.h> +#include <memory> #include <utility> namespace qbs { @@ -75,9 +76,11 @@ class QBS_EXPORT PropertyMap public: PropertyMap(); PropertyMap(const PropertyMap &other); + PropertyMap(PropertyMap &&other) Q_DECL_NOEXCEPT; ~PropertyMap(); PropertyMap &operator =(const PropertyMap &other); + PropertyMap &operator =(PropertyMap &&other) Q_DECL_NOEXCEPT; QStringList allProperties() const; QVariant getProperty(const QString &name) const; @@ -90,7 +93,7 @@ public: QString toString() const; private: - Internal::PropertyMapPrivate *d; + std::unique_ptr<Internal::PropertyMapPrivate> d; }; class InstallData; @@ -101,7 +104,9 @@ class QBS_EXPORT ArtifactData public: ArtifactData(); ArtifactData(const ArtifactData &other); + ArtifactData(ArtifactData &&) Q_DECL_NOEXCEPT; ArtifactData &operator=(const ArtifactData &other); + ArtifactData &operator=(ArtifactData &&) Q_DECL_NOEXCEPT; ~ArtifactData(); bool isValid() const; @@ -124,7 +129,9 @@ class QBS_EXPORT InstallData public: InstallData(); InstallData(const InstallData &other); + InstallData(InstallData &&) Q_DECL_NOEXCEPT; InstallData &operator=(const InstallData &other); + InstallData &operator=(InstallData &&) Q_DECL_NOEXCEPT; ~InstallData(); bool isValid() const; @@ -149,7 +156,9 @@ class QBS_EXPORT GroupData public: GroupData(); GroupData(const GroupData &other); + GroupData(GroupData &&) Q_DECL_NOEXCEPT; GroupData &operator=(const GroupData &other); + GroupData &operator=(GroupData &&) Q_DECL_NOEXCEPT; ~GroupData(); bool isValid() const; @@ -178,7 +187,9 @@ class QBS_EXPORT ProductData public: ProductData(); ProductData(const ProductData &other); + ProductData(ProductData &&) Q_DECL_NOEXCEPT; ProductData &operator=(const ProductData &other); + ProductData &operator=(ProductData &&) Q_DECL_NOEXCEPT; ~ProductData(); bool isValid() const; @@ -218,7 +229,9 @@ class QBS_EXPORT ProjectData public: ProjectData(); ProjectData(const ProjectData &other); + ProjectData(ProjectData &&) Q_DECL_NOEXCEPT; ProjectData &operator=(const ProjectData &other); + ProjectData &operator=(ProjectData &&) Q_DECL_NOEXCEPT; ~ProjectData(); bool isValid() const; diff --git a/src/lib/corelib/api/projectdata_p.h b/src/lib/corelib/api/projectdata_p.h index 69b046b0c..834aeec23 100644 --- a/src/lib/corelib/api/projectdata_p.h +++ b/src/lib/corelib/api/projectdata_p.h @@ -50,61 +50,49 @@ namespace Internal { class InstallDataPrivate : public QSharedData { public: - InstallDataPrivate() : isValid(false) {} - QString installFilePath; QString installRoot; - bool isValid; - bool isInstallable; + bool isValid = false; + bool isInstallable = false; }; class ArtifactDataPrivate : public QSharedData { public: - ArtifactDataPrivate() : isValid(false) {} - QString filePath; QStringList fileTags; PropertyMap properties; InstallData installData; - bool isValid; - bool isGenerated; - bool isTargetArtifact; + bool isValid = false; + bool isGenerated = false; + bool isTargetArtifact = false; }; class GroupDataPrivate : public QSharedData { public: - GroupDataPrivate() : isValid(false) - { } - QString name; QString prefix; CodeLocation location; QList<ArtifactData> sourceArtifacts; QList<ArtifactData> sourceArtifactsFromWildcards; PropertyMap properties; - bool isEnabled; - bool isValid; + bool isEnabled = false; + bool isValid = false; }; class InstallableFilePrivate: public QSharedData { public: - InstallableFilePrivate() : isValid(false) {} - QString sourceFilePath; QString targetFilePath; QStringList fileTags; - bool isValid; + bool isValid = false; }; class ProductDataPrivate : public QSharedData { public: - ProductDataPrivate() : isValid(false) - { } - QStringList type; QStringList dependencies; QString name; @@ -117,22 +105,19 @@ public: QVariantMap properties; PropertyMap moduleProperties; QList<ArtifactData> generatedArtifacts; - bool isEnabled; - bool isRunnable; - bool isMultiplexed; - bool isValid; + bool isEnabled = false; + bool isRunnable = false; + bool isMultiplexed = false; + bool isValid = false; }; class ProjectDataPrivate : public QSharedData { public: - ProjectDataPrivate() : isValid(false) - { } - QString name; CodeLocation location; - bool enabled; - bool isValid; + bool enabled = false; + bool isValid = false; QList<ProductData> products; QList<ProjectData> subProjects; QString buildDir; diff --git a/src/lib/corelib/api/projectfileupdater.cpp b/src/lib/corelib/api/projectfileupdater.cpp index 944de7161..04f8e630f 100644 --- a/src/lib/corelib/api/projectfileupdater.cpp +++ b/src/lib/corelib/api/projectfileupdater.cpp @@ -119,6 +119,8 @@ ProjectFileUpdater::ProjectFileUpdater(const QString &projectFile) : m_projectFi { } +ProjectFileUpdater::~ProjectFileUpdater() = default; + ProjectFileUpdater::LineEndingType ProjectFileUpdater::guessLineEndingType(const QByteArray &text) { char before = 0; diff --git a/src/lib/corelib/api/projectfileupdater.h b/src/lib/corelib/api/projectfileupdater.h index bc8de30eb..c0d46c747 100644 --- a/src/lib/corelib/api/projectfileupdater.h +++ b/src/lib/corelib/api/projectfileupdater.h @@ -54,6 +54,7 @@ namespace Internal { class ProjectFileUpdater { public: + virtual ~ProjectFileUpdater(); void apply(); CodeLocation itemPosition() const { return m_itemPosition; } diff --git a/src/lib/corelib/api/runenvironment.cpp b/src/lib/corelib/api/runenvironment.cpp index 989918207..df5b4337d 100644 --- a/src/lib/corelib/api/runenvironment.cpp +++ b/src/lib/corelib/api/runenvironment.cpp @@ -71,16 +71,16 @@ using namespace Internal; class RunEnvironment::RunEnvironmentPrivate { public: - RunEnvironmentPrivate(const ResolvedProductPtr &product, const TopLevelProjectConstPtr &project, - const InstallOptions &installOptions, const QProcessEnvironment &environment, - const QStringList &setupRunEnvConfig, Settings *settings, const Logger &logger) - : resolvedProduct(product) - , project(project) - , installOptions(installOptions) + RunEnvironmentPrivate(ResolvedProductPtr product, TopLevelProjectConstPtr project, + InstallOptions installOptions, const QProcessEnvironment &environment, + QStringList setupRunEnvConfig, Settings *settings, Logger logger) + : resolvedProduct(std::move(product)) + , project(std::move(project)) + , installOptions(std::move(installOptions)) , environment(environment) - , setupRunEnvConfig(setupRunEnvConfig) + , setupRunEnvConfig(std::move(setupRunEnvConfig)) , settings(settings) - , logger(logger) + , logger(std::move(logger)) , evalContext(this->logger) { } @@ -184,7 +184,8 @@ int RunEnvironment::doRunShell() #if defined(Q_OS_LINUX) clearenv(); #endif - for (const QString &key : environment.keys()) + const auto keys = environment.keys(); + for (const QString &key : keys) qputenv(key.toLocal8Bit().constData(), environment.value(key).toLocal8Bit()); QString command; if (HostOsInfo::isWindowsHost()) { @@ -260,7 +261,8 @@ static QString findMainIntent(const QString &aapt, const QString &apkFilePath) << QStringLiteral("badging") << apkFilePath); if (aaptProcess.waitForFinished(-1)) { - for (auto line : aaptProcess.readAllStandardOutput().split('\n')) { + const auto lines = aaptProcess.readAllStandardOutput().split('\n'); + for (const auto &line : lines) { if (line.startsWith(QByteArrayLiteral("package:"))) packageId = QString::fromStdString(readAaptBadgingAttribute(line.toStdString())); else if (line.startsWith(QByteArrayLiteral("launchable-activity:"))) diff --git a/src/lib/corelib/buildgraph/abstractcommandexecutor.cpp b/src/lib/corelib/buildgraph/abstractcommandexecutor.cpp index 4626c6a1a..1a1d51f11 100644 --- a/src/lib/corelib/buildgraph/abstractcommandexecutor.cpp +++ b/src/lib/corelib/buildgraph/abstractcommandexecutor.cpp @@ -49,14 +49,14 @@ namespace qbs { namespace Internal { -AbstractCommandExecutor::AbstractCommandExecutor(const Logger &logger, QObject *parent) +AbstractCommandExecutor::AbstractCommandExecutor(Logger logger, QObject *parent) : QObject(parent) , m_echoMode(defaultCommandEchoMode()) , m_command(nullptr) , m_transformer(nullptr) , m_mainThreadScriptEngine(nullptr) , m_dryRun(false) - , m_logger(logger) + , m_logger(std::move(logger)) { } diff --git a/src/lib/corelib/buildgraph/abstractcommandexecutor.h b/src/lib/corelib/buildgraph/abstractcommandexecutor.h index f140b5d82..60b2b40b2 100644 --- a/src/lib/corelib/buildgraph/abstractcommandexecutor.h +++ b/src/lib/corelib/buildgraph/abstractcommandexecutor.h @@ -58,7 +58,7 @@ class AbstractCommandExecutor : public QObject { Q_OBJECT public: - explicit AbstractCommandExecutor(const Internal::Logger &logger, QObject *parent = nullptr); + explicit AbstractCommandExecutor(Internal::Logger logger, QObject *parent = nullptr); void setMainThreadScriptEngine(ScriptEngine *engine) { m_mainThreadScriptEngine = engine; } void setDryRunEnabled(bool enabled) { m_dryRun = enabled; } diff --git a/src/lib/corelib/buildgraph/artifact.h b/src/lib/corelib/buildgraph/artifact.h index 32527caf3..ee3acea59 100644 --- a/src/lib/corelib/buildgraph/artifact.h +++ b/src/lib/corelib/buildgraph/artifact.h @@ -72,7 +72,7 @@ class QBS_AUTOTEST_EXPORT Artifact : public FileResourceBase, public BuildGraphN { public: Artifact(); - ~Artifact(); + ~Artifact() override; Type type() const override { return ArtifactNodeType; } FileType fileType() const override { return FileTypeArtifact; } diff --git a/src/lib/corelib/buildgraph/artifactcleaner.cpp b/src/lib/corelib/buildgraph/artifactcleaner.cpp index 232591e10..000dfda02 100644 --- a/src/lib/corelib/buildgraph/artifactcleaner.cpp +++ b/src/lib/corelib/buildgraph/artifactcleaner.cpp @@ -1,3 +1,5 @@ +#include <utility> + /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. @@ -98,12 +100,12 @@ static void removeArtifactFromDisk(Artifact *artifact, bool dryRun, const Logger class CleanupVisitor : public ArtifactVisitor { public: - CleanupVisitor(const CleanOptions &options, const ProgressObserver *observer, - const Logger &logger) + CleanupVisitor(CleanOptions options, const ProgressObserver *observer, + Logger logger) : ArtifactVisitor(Artifact::Generated) - , m_options(options) + , m_options(std::move(options)) , m_observer(observer) - , m_logger(logger) + , m_logger(std::move(logger)) , m_hasError(false) { } @@ -154,8 +156,8 @@ private: Set<QString> m_directories; }; -ArtifactCleaner::ArtifactCleaner(const Logger &logger, ProgressObserver *observer) - : m_logger(logger), m_observer(observer) +ArtifactCleaner::ArtifactCleaner(Logger logger, ProgressObserver *observer) + : m_logger(std::move(logger)), m_observer(observer) { } diff --git a/src/lib/corelib/buildgraph/artifactcleaner.h b/src/lib/corelib/buildgraph/artifactcleaner.h index 4d8c86ea8..5112a75d6 100644 --- a/src/lib/corelib/buildgraph/artifactcleaner.h +++ b/src/lib/corelib/buildgraph/artifactcleaner.h @@ -53,7 +53,7 @@ class ProgressObserver; class ArtifactCleaner { public: - ArtifactCleaner(const Logger &logger, ProgressObserver *observer); + ArtifactCleaner(Logger logger, ProgressObserver *observer); void cleanup(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, const CleanOptions &options); @@ -62,8 +62,8 @@ private: bool *isEmpty = nullptr); Logger m_logger; - bool m_hasError; - ProgressObserver *m_observer; + bool m_hasError = false; + ProgressObserver *m_observer = nullptr; }; } // namespace Internal diff --git a/src/lib/corelib/buildgraph/buildgraph.cpp b/src/lib/corelib/buildgraph/buildgraph.cpp index 616658a18..3726c654d 100644 --- a/src/lib/corelib/buildgraph/buildgraph.cpp +++ b/src/lib/corelib/buildgraph/buildgraph.cpp @@ -118,7 +118,7 @@ private: } getProduct(object); - QBS_ASSERT(m_product, {}); + QBS_ASSERT(m_product, return {}); const auto it = m_product->productProperties.find(name); @@ -572,13 +572,10 @@ Artifact *lookupArtifact(const ResolvedProductConstPtr &product, const ProjectBuildData *projectBuildData, const QString &dirPath, const QString &fileName, bool compareByName) { - const QList<FileResourceBase *> lookupResults - = projectBuildData->lookupFiles(dirPath, fileName); - for (QList<FileResourceBase *>::const_iterator it = lookupResults.constBegin(); - it != lookupResults.constEnd(); ++it) { - if ((*it)->fileType() != FileResourceBase::FileTypeArtifact) + for (const auto &fileResource : projectBuildData->lookupFiles(dirPath, fileName)) { + if (fileResource->fileType() != FileResourceBase::FileTypeArtifact) continue; - auto artifact = static_cast<Artifact *>(*it); + const auto artifact = static_cast<Artifact *>(fileResource); if (compareByName ? artifact->product->uniqueName() == product->uniqueName() : artifact->product == product) { diff --git a/src/lib/corelib/buildgraph/buildgraphloader.cpp b/src/lib/corelib/buildgraph/buildgraphloader.cpp index fc0492ef3..bf6c30dcd 100644 --- a/src/lib/corelib/buildgraph/buildgraphloader.cpp +++ b/src/lib/corelib/buildgraph/buildgraphloader.cpp @@ -76,8 +76,8 @@ namespace qbs { namespace Internal { -BuildGraphLoader::BuildGraphLoader(const Logger &logger) : - m_logger(logger) +BuildGraphLoader::BuildGraphLoader(Logger logger) : + m_logger(std::move(logger)) { } @@ -438,11 +438,10 @@ void BuildGraphLoader::trackProjectChanges() allNewlyResolvedProducts); } - for (auto it = m_changedSourcesByProduct.cbegin(); it != m_changedSourcesByProduct.cend(); - ++it) { - const ResolvedProductPtr product = m_freshProductsByName.value(it->first); + for (const auto &kv : m_changedSourcesByProduct) { + const ResolvedProductPtr product = m_freshProductsByName.value(kv.first); QBS_CHECK(!!product); - for (const SourceArtifactConstPtr &sa : it->second) + for (const SourceArtifactConstPtr &sa : kv.second) updateArtifactFromSourceArtifact(product, sa); } diff --git a/src/lib/corelib/buildgraph/buildgraphloader.h b/src/lib/corelib/buildgraph/buildgraphloader.h index 94eb01c5d..9363b8358 100644 --- a/src/lib/corelib/buildgraph/buildgraphloader.h +++ b/src/lib/corelib/buildgraph/buildgraphloader.h @@ -72,7 +72,7 @@ public: class BuildGraphLoader { public: - BuildGraphLoader(const Logger &logger); + BuildGraphLoader(Logger logger); ~BuildGraphLoader(); BuildGraphLoadResult load(const TopLevelProjectPtr &existingProject, @@ -141,8 +141,8 @@ private: QStringList m_artifactsRemovedFromDisk; std::unordered_map<QString, std::vector<SourceArtifactConstPtr>> m_changedSourcesByProduct; Set<QString> m_productsWhoseArtifactsNeedUpdate; - qint64 m_wildcardExpansionEffort; - qint64 m_propertyComparisonEffort; + qint64 m_wildcardExpansionEffort = 0; + qint64 m_propertyComparisonEffort = 0; // These must only be deleted at the end so we can still peek into the old look-up table. QList<FileResourceBase *> m_objectsToDelete; diff --git a/src/lib/corelib/buildgraph/buildgraphvisitor.h b/src/lib/corelib/buildgraph/buildgraphvisitor.h index 216e16a8c..cc2dde792 100644 --- a/src/lib/corelib/buildgraph/buildgraphvisitor.h +++ b/src/lib/corelib/buildgraph/buildgraphvisitor.h @@ -55,6 +55,7 @@ class RuleNode; class BuildGraphVisitor { public: + virtual ~BuildGraphVisitor() = default; virtual bool visit(Artifact *) { return true; } virtual void endVisit(Artifact *) { } virtual bool visit(RuleNode *) { return true; } diff --git a/src/lib/corelib/buildgraph/cycledetector.cpp b/src/lib/corelib/buildgraph/cycledetector.cpp index 95afba87d..5daed55fd 100644 --- a/src/lib/corelib/buildgraph/cycledetector.cpp +++ b/src/lib/corelib/buildgraph/cycledetector.cpp @@ -51,8 +51,8 @@ namespace qbs { namespace Internal { -CycleDetector::CycleDetector(const Logger &logger) - : m_parent(nullptr), m_logger(logger) +CycleDetector::CycleDetector(Logger logger) + : m_parent(nullptr), m_logger(std::move(logger)) { } @@ -80,7 +80,8 @@ bool CycleDetector::visitNode(BuildGraphNode *node) { if (Q_UNLIKELY(m_nodesInCurrentPath.contains(node))) { ErrorInfo error(Tr::tr("Cycle in build graph detected.")); - for (const BuildGraphNode * const n : cycle(node)) + const auto nodes = cycle(node); + for (const BuildGraphNode * const n : nodes) error.append(n->toString()); throw error; } diff --git a/src/lib/corelib/buildgraph/cycledetector.h b/src/lib/corelib/buildgraph/cycledetector.h index fffe6ed2f..5bfb44ef8 100644 --- a/src/lib/corelib/buildgraph/cycledetector.h +++ b/src/lib/corelib/buildgraph/cycledetector.h @@ -52,7 +52,7 @@ class BuildGraphNode; class QBS_AUTOTEST_EXPORT CycleDetector : private BuildGraphVisitor { public: - CycleDetector(const Logger &logger); + CycleDetector(Logger logger); void visitProject(const TopLevelProjectConstPtr &project); void visitProduct(const ResolvedProductConstPtr &product); diff --git a/src/lib/corelib/buildgraph/depscanner.cpp b/src/lib/corelib/buildgraph/depscanner.cpp index a2a39e4b2..0bf644286 100644 --- a/src/lib/corelib/buildgraph/depscanner.cpp +++ b/src/lib/corelib/buildgraph/depscanner.cpp @@ -154,9 +154,9 @@ bool PluginDependencyScanner::areModulePropertiesCompatible(const PropertyMapCon return true; } -UserDependencyScanner::UserDependencyScanner(const ResolvedScannerConstPtr &scanner, +UserDependencyScanner::UserDependencyScanner(ResolvedScannerConstPtr scanner, ScriptEngine *engine) - : m_scanner(scanner), + : m_scanner(std::move(scanner)), m_engine(engine), m_product(nullptr) { diff --git a/src/lib/corelib/buildgraph/depscanner.h b/src/lib/corelib/buildgraph/depscanner.h index b8f8721aa..ffc0b83de 100644 --- a/src/lib/corelib/buildgraph/depscanner.h +++ b/src/lib/corelib/buildgraph/depscanner.h @@ -102,7 +102,7 @@ private: class UserDependencyScanner : public DependencyScanner { public: - UserDependencyScanner(const ResolvedScannerConstPtr &scanner, ScriptEngine *engine); + UserDependencyScanner(ResolvedScannerConstPtr scanner, ScriptEngine *engine); private: QStringList collectSearchPaths(Artifact *artifact) override; diff --git a/src/lib/corelib/buildgraph/emptydirectoriesremover.cpp b/src/lib/corelib/buildgraph/emptydirectoriesremover.cpp index b3cc6c840..ebbcf67a7 100644 --- a/src/lib/corelib/buildgraph/emptydirectoriesremover.cpp +++ b/src/lib/corelib/buildgraph/emptydirectoriesremover.cpp @@ -49,8 +49,8 @@ namespace qbs { namespace Internal { EmptyDirectoriesRemover::EmptyDirectoriesRemover(const TopLevelProject *project, - const Logger &logger) - : m_project(project), m_logger(logger) + Logger logger) + : m_project(project), m_logger(std::move(logger)) { } diff --git a/src/lib/corelib/buildgraph/emptydirectoriesremover.h b/src/lib/corelib/buildgraph/emptydirectoriesremover.h index 6ec42c627..7d73fb819 100644 --- a/src/lib/corelib/buildgraph/emptydirectoriesremover.h +++ b/src/lib/corelib/buildgraph/emptydirectoriesremover.h @@ -53,7 +53,7 @@ class TopLevelProject; class EmptyDirectoriesRemover { public: - EmptyDirectoriesRemover(const TopLevelProject *project, const Logger &logger); + EmptyDirectoriesRemover(const TopLevelProject *project, Logger logger); void removeEmptyParentDirectories(const QStringList &artifactFilePaths); void removeEmptyParentDirectories(const ArtifactSet &artifacts); diff --git a/src/lib/corelib/buildgraph/environmentscriptrunner.h b/src/lib/corelib/buildgraph/environmentscriptrunner.h index 344a764d0..221314798 100644 --- a/src/lib/corelib/buildgraph/environmentscriptrunner.h +++ b/src/lib/corelib/buildgraph/environmentscriptrunner.h @@ -69,7 +69,7 @@ private: const QProcessEnvironment m_env; QStringList m_runEnvConfig; - enum EnvType { BuildEnv, RunEnv } m_envType; + enum EnvType { BuildEnv, RunEnv } m_envType = EnvType::BuildEnv; }; } // namespace Internal diff --git a/src/lib/corelib/buildgraph/executor.cpp b/src/lib/corelib/buildgraph/executor.cpp index 8f71e1ea3..de81ada20 100644 --- a/src/lib/corelib/buildgraph/executor.cpp +++ b/src/lib/corelib/buildgraph/executor.cpp @@ -86,10 +86,10 @@ bool Executor::ComparePriority::operator() (const BuildGraphNode *x, const Build } -Executor::Executor(const Logger &logger, QObject *parent) +Executor::Executor(Logger logger, QObject *parent) : QObject(parent) , m_productInstaller(nullptr) - , m_logger(logger) + , m_logger(std::move(logger)) , m_progressObserver(nullptr) , m_state(ExecutorIdle) , m_cancelationTimer(new QTimer(this)) @@ -105,7 +105,8 @@ Executor::~Executor() // jobs must be destroyed before deleting the shared scan result cache for (ExecutorJob *job : qAsConst(m_availableJobs)) delete job; - for (ExecutorJob *job : m_processingJobs.keys()) + const auto processingJobs = m_processingJobs.keys(); + for (ExecutorJob *job : processingJobs) delete job; delete m_inputArtifactScanContext; delete m_productInstaller; @@ -180,7 +181,7 @@ void Executor::setProducts(const std::vector<ResolvedProductPtr> &productsToBuil class ProductPrioritySetter { const std::vector<ResolvedProductPtr> &m_allProducts; - unsigned int m_priority; + unsigned int m_priority = 0; Set<ResolvedProductPtr> m_seenProducts; public: ProductPrioritySetter(const std::vector<ResolvedProductPtr> &allProducts) // TODO: Use only products to build? @@ -242,8 +243,7 @@ void Executor::doBuild() const QStringList &filesToConsider = m_buildOptions.filesToConsider(); if (!filesToConsider.empty()) { for (const QString &fileToConsider : filesToConsider) { - const QList<FileResourceBase *> &files - = m_project->buildData->lookupFiles(fileToConsider); + const auto &files = m_project->buildData->lookupFiles(fileToConsider); for (const FileResourceBase * const file : files) { if (file->fileType() != FileResourceBase::FileTypeArtifact) continue; @@ -392,7 +392,7 @@ bool Executor::schedulingBlockedByJobLimit(const BuildGraphNode *node) { if (node->type() != BuildGraphNode::ArtifactNodeType) return false; - const Artifact * const artifact = static_cast<const Artifact *>(node); + const auto artifact = static_cast<const Artifact *>(node); if (artifact->artifactType == Artifact::SourceFile) return false; @@ -412,7 +412,8 @@ bool Executor::schedulingBlockedByJobLimit(const BuildGraphNode *node) // running transformers. if (jobLimitIsExceeded(transformer)) return true; - for (const ExecutorJob * const runningJob : m_processingJobs.keys()) { + const auto runningJobs = m_processingJobs.keys(); + for (const ExecutorJob * const runningJob : runningJobs) { if (!runningJob->jobPools().contains(jobPool)) continue; const Transformer * const runningTransformer = runningJob->transformer(); @@ -684,7 +685,8 @@ bool Executor::transformerHasMatchingInputFiles(const TransformerConstPtr &trans if (transformer->inputs.empty()) return true; for (const Artifact * const input : qAsConst(transformer->inputs)) { - for (const QString &filePath : m_buildOptions.filesToConsider()) { + const auto files = m_buildOptions.filesToConsider(); + for (const QString &filePath : files) { if (input->filePath() == filePath || input->fileTags().intersects(m_tagsNeededForFilesToConsider)) { return true; @@ -725,7 +727,8 @@ void Executor::cancelJobs() return; qCDebug(lcExec) << "Canceling all jobs."; setState(ExecutorCanceling); - for (ExecutorJob *job : m_processingJobs.keys()) + const auto jobs = m_processingJobs.keys(); + for (ExecutorJob *job : jobs) job->cancel(); } @@ -734,7 +737,7 @@ void Executor::setupProgressObserver() if (!m_progressObserver) return; int totalEffort = 1; // For the effort after the last rule application; - for (const ResolvedProductConstPtr &product : m_productsToBuild) { + for (const ResolvedProductConstPtr &product : qAsConst(m_productsToBuild)) { QBS_CHECK(product->buildData); const auto filtered = filterByType<RuleNode>(product->buildData->allNodes()); totalEffort += std::distance(filtered.begin(), filtered.end()); @@ -746,7 +749,7 @@ void Executor::doSanityChecks() { QBS_CHECK(m_project); QBS_CHECK(!m_productsToBuild.empty()); - for (const ResolvedProductConstPtr &product : m_productsToBuild) { + for (const ResolvedProductConstPtr &product : qAsConst(m_productsToBuild)) { QBS_CHECK(product->buildData); QBS_CHECK(product->topLevelProject() == m_project.get()); } @@ -754,7 +757,8 @@ void Executor::doSanityChecks() void Executor::handleError(const ErrorInfo &error) { - for (const ErrorItem &ei : error.items()) + const auto items = error.items(); + for (const ErrorItem &ei : items) m_error.append(ei); if (m_processingJobs.empty()) finish(); @@ -833,7 +837,7 @@ void Executor::rescueOldBuildData(Artifact *artifact, bool *childrenAdded = null childrenToConnect.push_back(child); } for (const QString &depPath : rad.fileDependencies) { - const QList<FileResourceBase *> depList = m_project->buildData->lookupFiles(depPath); + const auto &depList = m_project->buildData->lookupFiles(depPath); if (depList.empty()) { canRescue = false; qCDebug(lcBuildGraph) << "File dependency" << depPath @@ -1079,7 +1083,7 @@ void Executor::checkForUnbuiltProducts() { if (m_buildOptions.executeRulesOnly()) return; - QList<ResolvedProductPtr> unbuiltProducts; + std::vector<ResolvedProductPtr> unbuiltProducts; for (const ResolvedProductPtr &product : m_productsToBuild) { bool productBuilt = true; for (BuildGraphNode *rootNode : qAsConst(product->buildData->rootNodes())) { diff --git a/src/lib/corelib/buildgraph/executor.h b/src/lib/corelib/buildgraph/executor.h index 003ba9a22..1fd591176 100644 --- a/src/lib/corelib/buildgraph/executor.h +++ b/src/lib/corelib/buildgraph/executor.h @@ -77,8 +77,8 @@ class Executor : public QObject, private BuildGraphVisitor public: void build(); - Executor(const Logger &logger, QObject *parent = nullptr); - ~Executor(); + Executor(Logger logger, QObject *parent = nullptr); + ~Executor() override; void setProject(const TopLevelProjectPtr &project); void setProducts(const std::vector<ResolvedProductPtr> &productsToBuild); @@ -180,17 +180,17 @@ private: Leaves m_leaves; InputArtifactScannerContext *m_inputArtifactScanContext; ErrorInfo m_error; - bool m_explicitlyCanceled; + bool m_explicitlyCanceled = false; FileTags m_activeFileTags; FileTags m_tagsOfFilesToConsider; FileTags m_tagsNeededForFilesToConsider; QList<ResolvedProductPtr> m_productsOfFilesToConsider; QTimer * const m_cancelationTimer; QStringList m_artifactsRemovedFromDisk; - bool m_partialBuild; - qint64 m_elapsedTimeRules; - qint64 m_elapsedTimeScanners; - qint64 m_elapsedTimeInstalling; + bool m_partialBuild = false; + qint64 m_elapsedTimeRules = 0; + qint64 m_elapsedTimeScanners = 0; + qint64 m_elapsedTimeInstalling = 0; }; } // namespace Internal diff --git a/src/lib/corelib/buildgraph/executorjob.h b/src/lib/corelib/buildgraph/executorjob.h index e28d42f7f..bc8954072 100644 --- a/src/lib/corelib/buildgraph/executorjob.h +++ b/src/lib/corelib/buildgraph/executorjob.h @@ -66,7 +66,7 @@ class ExecutorJob : public QObject Q_OBJECT public: ExecutorJob(const Logger &logger, QObject *parent); - ~ExecutorJob(); + ~ExecutorJob() override; void setMainThreadScriptEngine(ScriptEngine *engine); void setDryRun(bool enabled); @@ -88,12 +88,12 @@ private: void setFinished(); void reset(); - AbstractCommandExecutor *m_currentCommandExecutor; - ProcessCommandExecutor *m_processCommandExecutor; - JsCommandExecutor *m_jsCommandExecutor; - Transformer *m_transformer; + AbstractCommandExecutor *m_currentCommandExecutor = nullptr; + ProcessCommandExecutor *m_processCommandExecutor = nullptr; + JsCommandExecutor *m_jsCommandExecutor = nullptr; + Transformer *m_transformer = nullptr; Set<QString> m_jobPools; - int m_currentCommandIdx; + int m_currentCommandIdx = 0; ErrorInfo m_error; }; diff --git a/src/lib/corelib/buildgraph/filedependency.h b/src/lib/corelib/buildgraph/filedependency.h index b9a7caf57..802654e9f 100644 --- a/src/lib/corelib/buildgraph/filedependency.h +++ b/src/lib/corelib/buildgraph/filedependency.h @@ -85,7 +85,7 @@ class FileDependency : public FileResourceBase { public: FileDependency(); - ~FileDependency(); + ~FileDependency() override; FileType fileType() const override { return FileTypeDependency; } }; diff --git a/src/lib/corelib/buildgraph/inputartifactscanner.cpp b/src/lib/corelib/buildgraph/inputartifactscanner.cpp index 68f3b744b..c8b2cb779 100644 --- a/src/lib/corelib/buildgraph/inputartifactscanner.cpp +++ b/src/lib/corelib/buildgraph/inputartifactscanner.cpp @@ -77,8 +77,9 @@ static void resolveDepencency(const RawScannedDependency &dependency, FileDependency *fileDependencyArtifact = nullptr; Artifact *dependencyInProduct = nullptr; Artifact *dependencyInOtherProduct = nullptr; - for (FileResourceBase *lookupResult : project->topLevelProject() - ->buildData->lookupFiles(absDirPath, dependency.fileName())) { + const auto files = project->topLevelProject() + ->buildData->lookupFiles(absDirPath, dependency.fileName()); + for (FileResourceBase *lookupResult : files) { switch (lookupResult->fileType()) { case FileResourceBase::FileTypeDependency: fileDependencyArtifact = static_cast<FileDependency *>(lookupResult); @@ -115,12 +116,12 @@ static void resolveDepencency(const RawScannedDependency &dependency, } InputArtifactScanner::InputArtifactScanner(Artifact *artifact, InputArtifactScannerContext *ctx, - const Logger &logger) + Logger logger) : m_artifact(artifact), m_rawScanResults(artifact->product->topLevelProject()->buildData->rawScanResults), m_context(ctx), m_newDependencyAdded(false), - m_logger(logger) + m_logger(std::move(logger)) { } @@ -274,7 +275,7 @@ void InputArtifactScanner::resolveScanResultDependencies(const Artifact *inputAr } // try include paths - for (const QString &includePath : cache.searchPaths) { + for (const QString &includePath : qAsConst(cache.searchPaths)) { resolveDepencency(dependency, inputArtifact->product.get(), &resolvedDependency, includePath); if (resolvedDependency.isValid()) diff --git a/src/lib/corelib/buildgraph/inputartifactscanner.h b/src/lib/corelib/buildgraph/inputartifactscanner.h index 92d5f516f..ac51af579 100644 --- a/src/lib/corelib/buildgraph/inputartifactscanner.h +++ b/src/lib/corelib/buildgraph/inputartifactscanner.h @@ -118,7 +118,7 @@ class InputArtifactScanner { public: InputArtifactScanner(Artifact *artifact, InputArtifactScannerContext *ctx, - const Logger &logger); + Logger logger); void scan(); bool newDependencyAdded() const { return m_newDependencyAdded; } diff --git a/src/lib/corelib/buildgraph/jscommandexecutor.cpp b/src/lib/corelib/buildgraph/jscommandexecutor.cpp index 4b7adb221..30970779c 100644 --- a/src/lib/corelib/buildgraph/jscommandexecutor.cpp +++ b/src/lib/corelib/buildgraph/jscommandexecutor.cpp @@ -62,7 +62,7 @@ namespace Internal { struct JavaScriptCommandResult { - bool success; + bool success = false; QString errorMessage; CodeLocation errorLocation; }; @@ -71,8 +71,8 @@ class JsCommandExecutorThreadObject : public QObject { Q_OBJECT public: - JsCommandExecutorThreadObject(const Logger &logger) - : m_logger(logger) + JsCommandExecutorThreadObject(Logger logger) + : m_logger(std::move(logger)) , m_scriptEngine(nullptr) { } diff --git a/src/lib/corelib/buildgraph/jscommandexecutor.h b/src/lib/corelib/buildgraph/jscommandexecutor.h index 207e18097..0170c5231 100644 --- a/src/lib/corelib/buildgraph/jscommandexecutor.h +++ b/src/lib/corelib/buildgraph/jscommandexecutor.h @@ -56,7 +56,7 @@ class JsCommandExecutor : public AbstractCommandExecutor Q_OBJECT public: explicit JsCommandExecutor(const Logger &logger, QObject *parent = nullptr); - ~JsCommandExecutor(); + ~JsCommandExecutor() override; signals: void startRequested(const JavaScriptCommand *cmd, Transformer *transformer); diff --git a/src/lib/corelib/buildgraph/nodetreedumper.h b/src/lib/corelib/buildgraph/nodetreedumper.h index 3ad3ca592..4175ce727 100644 --- a/src/lib/corelib/buildgraph/nodetreedumper.h +++ b/src/lib/corelib/buildgraph/nodetreedumper.h @@ -74,7 +74,7 @@ private: QIODevice &m_outDevice; ResolvedProductPtr m_currentProduct; NodeSet m_visited; - unsigned int m_indentation; + unsigned int m_indentation = 0; }; } // namespace Internal diff --git a/src/lib/corelib/buildgraph/processcommandexecutor.cpp b/src/lib/corelib/buildgraph/processcommandexecutor.cpp index 0818e1200..c34a734b4 100644 --- a/src/lib/corelib/buildgraph/processcommandexecutor.cpp +++ b/src/lib/corelib/buildgraph/processcommandexecutor.cpp @@ -89,7 +89,8 @@ static QProcessEnvironment mergeEnvironments(const QProcessEnvironment &baseEnv, QStringLiteral("DYLD_LIBRARY_PATH"), QStringLiteral("DYLD_FRAMEWORK_PATH"), }; - for (const QString &key : additionalEnv.keys()) { + const auto keys = additionalEnv.keys(); + for (const QString &key : keys) { QString newValue = additionalEnv.value(key); if (pathListVariables.contains(key, HostOsInfo::fileNameCaseSensitivity())) { const QString &oldValue = baseEnv.value(key); @@ -108,7 +109,8 @@ void ProcessCommandExecutor::doSetup() transformer()->product()->buildEnvironment) .findExecutable(cmd->program(), cmd->workingDir()); cmd->clearRelevantEnvValues(); - for (const QString &key : cmd->relevantEnvVars()) + const auto keys = cmd->relevantEnvVars(); + for (const QString &key : keys) cmd->addRelevantEnvValue(key, transformer()->product()->buildEnvironment.value(key)); m_commandEnvironment = mergeEnvironments(m_buildEnvironment, cmd->environment()); diff --git a/src/lib/corelib/buildgraph/productbuilddata.h b/src/lib/corelib/buildgraph/productbuilddata.h index bcc500de8..a7660af27 100644 --- a/src/lib/corelib/buildgraph/productbuilddata.h +++ b/src/lib/corelib/buildgraph/productbuilddata.h @@ -106,7 +106,7 @@ private: AllRescuableArtifactData m_rescuableArtifactData; // Do not store, initialized in executor. Higher prioritized artifacts are built first. - unsigned int m_buildPriority; + unsigned int m_buildPriority = 0; ArtifactSetByFileTag m_artifactsByFileTag; mutable std::mutex m_artifactsMapMutex; diff --git a/src/lib/corelib/buildgraph/productinstaller.cpp b/src/lib/corelib/buildgraph/productinstaller.cpp index cfd74c205..d4acc9ace 100644 --- a/src/lib/corelib/buildgraph/productinstaller.cpp +++ b/src/lib/corelib/buildgraph/productinstaller.cpp @@ -59,14 +59,14 @@ namespace qbs { namespace Internal { -ProductInstaller::ProductInstaller(const TopLevelProjectPtr &project, - const std::vector<ResolvedProductPtr> &products, const InstallOptions &options, - ProgressObserver *observer, const Logger &logger) - : m_project(project), - m_products(products), - m_options(options), +ProductInstaller::ProductInstaller(TopLevelProjectPtr project, + std::vector<ResolvedProductPtr> products, InstallOptions options, + ProgressObserver *observer, Logger logger) + : m_project(std::move(project)), + m_products(std::move(products)), + m_options(std::move(options)), m_observer(observer), - m_logger(logger) + m_logger(std::move(logger)) { if (!m_options.installRoot().isEmpty()) { QFileInfo installRootFileInfo(m_options.installRoot()); @@ -85,7 +85,7 @@ ProductInstaller::ProductInstaller(const TopLevelProjectPtr &project, if (m_options.removeExistingInstallation()) throw ErrorInfo(Tr::tr("Refusing to remove sysroot.")); } - initInstallRoot(project.get(), m_options); + initInstallRoot(m_project.get(), m_options); } void ProductInstaller::install() diff --git a/src/lib/corelib/buildgraph/productinstaller.h b/src/lib/corelib/buildgraph/productinstaller.h index 8379adb4c..09828cfe9 100644 --- a/src/lib/corelib/buildgraph/productinstaller.h +++ b/src/lib/corelib/buildgraph/productinstaller.h @@ -55,9 +55,9 @@ class ProgressObserver; class ProductInstaller { public: - ProductInstaller(const TopLevelProjectPtr &project, - const std::vector<ResolvedProductPtr> &products, - const InstallOptions &options, ProgressObserver *observer, const Logger &logger); + ProductInstaller(TopLevelProjectPtr project, + std::vector<ResolvedProductPtr> products, + InstallOptions options, ProgressObserver *observer, Logger logger); void install(); static QString targetFilePath(const TopLevelProject *project, const QString &productSourceDir, diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp index dcb10b45b..31012e23e 100644 --- a/src/lib/corelib/buildgraph/projectbuilddata.cpp +++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp @@ -96,8 +96,7 @@ QString ProjectBuildData::deriveBuildGraphFilePath(const QString &buildDir, cons void ProjectBuildData::insertIntoLookupTable(FileResourceBase *fileres) { - QList<FileResourceBase *> &lst - = m_artifactLookupTable[fileres->fileName()][fileres->dirPath()]; + auto &lst = m_artifactLookupTable[{fileres->fileName(), fileres->dirPath()}]; const auto * const artifact = fileres->fileType() == FileResourceBase::FileTypeArtifact ? static_cast<Artifact *>(fileres) : nullptr; if (artifact && artifact->artifactType == Artifact::Generated) { @@ -117,30 +116,32 @@ void ProjectBuildData::insertIntoLookupTable(FileResourceBase *fileres) throw error; } } - QBS_CHECK(!lst.contains(fileres)); + QBS_CHECK(!contains(lst, fileres)); lst.push_back(fileres); m_isDirty = true; } void ProjectBuildData::removeFromLookupTable(FileResourceBase *fileres) { - m_artifactLookupTable[fileres->fileName()][fileres->dirPath()].removeOne(fileres); + removeOne(m_artifactLookupTable[{fileres->fileName(), fileres->dirPath()}], fileres); } -QList<FileResourceBase *> ProjectBuildData::lookupFiles(const QString &filePath) const +const std::vector<FileResourceBase *> &ProjectBuildData::lookupFiles(const QString &filePath) const { QString dirPath, fileName; FileInfo::splitIntoDirectoryAndFileName(filePath, &dirPath, &fileName); return lookupFiles(dirPath, fileName); } -QList<FileResourceBase *> ProjectBuildData::lookupFiles(const QString &dirPath, +const std::vector<FileResourceBase *> &ProjectBuildData::lookupFiles(const QString &dirPath, const QString &fileName) const { - return m_artifactLookupTable.value(fileName).value(dirPath); + static const std::vector<FileResourceBase *> emptyResult; + const auto it = m_artifactLookupTable.find({fileName, dirPath}); + return it != m_artifactLookupTable.end() ? it->second : emptyResult; } -QList<FileResourceBase *> ProjectBuildData::lookupFiles(const Artifact *artifact) const +const std::vector<FileResourceBase *> &ProjectBuildData::lookupFiles(const Artifact *artifact) const { return lookupFiles(artifact->dirPath(), artifact->fileName()); } @@ -266,7 +267,7 @@ void ProjectBuildData::store(PersistentPool &pool) } -BuildDataResolver::BuildDataResolver(const Logger &logger) : m_logger(logger) +BuildDataResolver::BuildDataResolver(Logger logger) : m_logger(std::move(logger)) { } diff --git a/src/lib/corelib/buildgraph/projectbuilddata.h b/src/lib/corelib/buildgraph/projectbuilddata.h index 785a86cbb..930344435 100644 --- a/src/lib/corelib/buildgraph/projectbuilddata.h +++ b/src/lib/corelib/buildgraph/projectbuilddata.h @@ -45,13 +45,15 @@ #include <logging/logger.h> #include <tools/persistence.h> #include <tools/set.h> +#include <tools/qttools.h> -#include <QtCore/qhash.h> #include <QtCore/qlist.h> #include <QtCore/qstring.h> #include <QtScript/qscriptvalue.h> +#include <unordered_map> + namespace qbs { namespace Internal { class BuildGraphNode; @@ -70,9 +72,9 @@ public: void insertIntoLookupTable(FileResourceBase *fileres); void removeFromLookupTable(FileResourceBase *fileres); - QList<FileResourceBase *> lookupFiles(const QString &filePath) const; - QList<FileResourceBase *> lookupFiles(const QString &dirPath, const QString &fileName) const; - QList<FileResourceBase *> lookupFiles(const Artifact *artifact) const; + const std::vector<FileResourceBase *> &lookupFiles(const QString &filePath) const; + const std::vector<FileResourceBase *> &lookupFiles(const QString &dirPath, const QString &fileName) const; + const std::vector<FileResourceBase *> &lookupFiles(const Artifact *artifact) const; void insertFileDependency(FileDependency *dependency); void removeArtifactAndExclusiveDependents(Artifact *artifact, const Logger &logger, bool removeFromProduct = true, ArtifactSet *removedArtifacts = nullptr); @@ -99,9 +101,10 @@ private: pool.serializationOp<opType>(fileDependencies, rawScanResults); } - using ResultsPerDirectory = QHash<QString, QList<FileResourceBase *>>; - using ArtifactLookupTable = QHash<QString, ResultsPerDirectory>; + using ArtifactKey = std::pair<QString /*fileName*/, QString /*dirName*/>; + using ArtifactLookupTable = std::unordered_map<ArtifactKey, std::vector<FileResourceBase *>>; ArtifactLookupTable m_artifactLookupTable; + bool m_doCleanupInDestructor = true; bool m_isDirty = true; }; @@ -110,7 +113,7 @@ private: class BuildDataResolver { public: - BuildDataResolver(const Logger &logger); + BuildDataResolver(Logger logger); void resolveBuildData(const TopLevelProjectPtr &resolvedProject, const RulesEvaluationContextPtr &evalContext); void resolveProductBuildDataForExistingProject(const TopLevelProjectPtr &project, diff --git a/src/lib/corelib/buildgraph/rawscanneddependency.h b/src/lib/corelib/buildgraph/rawscanneddependency.h index e1cb5015c..4871bea62 100644 --- a/src/lib/corelib/buildgraph/rawscanneddependency.h +++ b/src/lib/corelib/buildgraph/rawscanneddependency.h @@ -72,7 +72,7 @@ private: QString m_dirPath; QString m_fileName; - bool m_isClean; + bool m_isClean = 0; }; bool operator==(const RawScannedDependency &d1, const RawScannedDependency &d2); diff --git a/src/lib/corelib/buildgraph/requestedartifacts.cpp b/src/lib/corelib/buildgraph/requestedartifacts.cpp index 7fbaf65f1..e4730d2f1 100644 --- a/src/lib/corelib/buildgraph/requestedartifacts.cpp +++ b/src/lib/corelib/buildgraph/requestedartifacts.cpp @@ -55,9 +55,8 @@ bool RequestedArtifacts::isUpToDate(const TopLevelProject *project) const if (m_requestedArtifactsPerProduct.empty()) return true; const std::vector<ResolvedProductPtr> &allProducts = project->allProducts(); - for (auto it = m_requestedArtifactsPerProduct.cbegin(); - it != m_requestedArtifactsPerProduct.cend(); ++it) { - const QString &productName = it->first; + for (const auto &kv : m_requestedArtifactsPerProduct) { + const QString &productName = kv.first; const auto findProduct = [productName](const ResolvedProductConstPtr &p) { return p->uniqueName() == productName; }; @@ -67,7 +66,7 @@ bool RequestedArtifacts::isUpToDate(const TopLevelProject *project) const << "does not exist anymore"; return false; } - if (!it->second.isUpToDate(productIt->get())) + if (!kv.second.isUpToDate(productIt->get())) return false; } return true; @@ -110,18 +109,14 @@ void RequestedArtifacts::setArtifactsEnumerated(const ResolvedProduct *product) void RequestedArtifacts::unite(const RequestedArtifacts &other) { - for (auto it = other.m_requestedArtifactsPerProduct.begin(); - it != other.m_requestedArtifactsPerProduct.end(); ++it) { - m_requestedArtifactsPerProduct[it->first].unite(it->second); - } + for (const auto &kv : other.m_requestedArtifactsPerProduct) + m_requestedArtifactsPerProduct[kv.first].unite(kv.second); } void RequestedArtifacts::doSanityChecks() const { - for (auto it = m_requestedArtifactsPerProduct.cbegin(); - it != m_requestedArtifactsPerProduct.cend(); ++it) { - it->second.doSanityChecks(); - } + for (const auto &kv : m_requestedArtifactsPerProduct) + kv.second.doSanityChecks(); } void RequestedArtifacts::load(PersistentPool &pool) @@ -147,17 +142,17 @@ bool RequestedArtifacts::RequestedArtifactsPerProduct::isUpToDate( return true; const ArtifactSetByFileTag currentArtifacts = product->buildData->artifactsByFileTag(); - for (auto reqIt = requestedTags.cbegin(); reqIt != requestedTags.cend(); ++reqIt) { - const FileTag tag = FileTag(reqIt->first.toUtf8()); + for (const auto &kv : requestedTags) { + const FileTag tag = FileTag(kv.first.toUtf8()); const auto currentIt = currentArtifacts.constFind(tag); Set<QString> currentFilePathsForTag; if (currentIt != currentArtifacts.constEnd()) { for (const Artifact * const a : currentIt.value()) currentFilePathsForTag.insert(a->filePath()); } - if (currentFilePathsForTag != reqIt->second) { + if (currentFilePathsForTag != kv.second) { qCDebug(lcBuildGraph) << "artifacts map not up to date: requested artifact set for " - "file tag" << reqIt->first << "in product" + "file tag" << kv.first << "in product" << product->uniqueName() << "differs from the current one"; return false; } @@ -185,14 +180,14 @@ void RequestedArtifacts::RequestedArtifactsPerProduct::unite( return; } allTags = other.allTags; - for (auto it = other.requestedTags.begin(); it != other.requestedTags.end(); ++it) - requestedTags[it->first] = it->second; + for (const auto &kv : other.requestedTags) + requestedTags[kv.first] = kv.second; } void RequestedArtifacts::RequestedArtifactsPerProduct::doSanityChecks() const { - for (auto it = requestedTags.begin(); it != requestedTags.end(); ++it) - QBS_CHECK(allTags.contains(it->first) || it->second.empty()); + for (const auto &kv : requestedTags) + QBS_CHECK(allTags.contains(kv.first) || kv.second.empty()); } void RequestedArtifacts::RequestedArtifactsPerProduct::load(PersistentPool &pool) diff --git a/src/lib/corelib/buildgraph/rulegraph.h b/src/lib/corelib/buildgraph/rulegraph.h index fe2fc4c3b..4ce5ecea8 100644 --- a/src/lib/corelib/buildgraph/rulegraph.h +++ b/src/lib/corelib/buildgraph/rulegraph.h @@ -56,6 +56,7 @@ namespace Internal { class RuleGraphVisitor { public: + virtual ~RuleGraphVisitor() = default; virtual void visit(const RuleConstPtr &parentRule, const RuleConstPtr &rule) = 0; virtual void endVisit(const RuleConstPtr &rule) { Q_UNUSED(rule); } }; diff --git a/src/lib/corelib/buildgraph/rulenode.h b/src/lib/corelib/buildgraph/rulenode.h index 0585678ec..cfb2039d6 100644 --- a/src/lib/corelib/buildgraph/rulenode.h +++ b/src/lib/corelib/buildgraph/rulenode.h @@ -58,7 +58,7 @@ class RuleNode : public BuildGraphNode { public: RuleNode(); - ~RuleNode(); + ~RuleNode() override; void setRule(const RuleConstPtr &rule) { m_rule = rule; } const RuleConstPtr &rule() const { return m_rule; } diff --git a/src/lib/corelib/buildgraph/rulesapplicator.cpp b/src/lib/corelib/buildgraph/rulesapplicator.cpp index 7ff64a9ef..16aa0c001 100644 --- a/src/lib/corelib/buildgraph/rulesapplicator.cpp +++ b/src/lib/corelib/buildgraph/rulesapplicator.cpp @@ -1,3 +1,5 @@ +#include <utility> + /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. @@ -76,15 +78,15 @@ namespace qbs { namespace Internal { RulesApplicator::RulesApplicator( - const ResolvedProductPtr &product, - const std::unordered_map<QString, const ResolvedProduct *> &productsByName, - const std::unordered_map<QString, const ResolvedProject *> &projectsByName, - const Logger &logger) - : m_product(product) - , m_productsByName(productsByName) - , m_projectsByName(projectsByName) + ResolvedProductPtr product, + std::unordered_map<QString, const ResolvedProduct *> productsByName, + std::unordered_map<QString, const ResolvedProject *> projectsByName, + Logger logger) + : m_product(std::move(product)) + , m_productsByName(std::move(productsByName)) + , m_projectsByName(std::move(projectsByName)) , m_mocScanner(nullptr) - , m_logger(logger) + , m_logger(std::move(logger)) { } @@ -186,7 +188,7 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p qCDebug(lcBuildGraph) << "apply rule" << m_rule->toString() << toStringList(inputArtifacts).join(QLatin1String(",\n ")); - QList<std::pair<const RuleArtifact *, OutputArtifactInfo>> ruleArtifactArtifactMap; + std::vector<std::pair<const RuleArtifact *, OutputArtifactInfo>> ruleArtifactArtifactMap; QList<Artifact *> outputArtifacts; m_transformer = Transformer::create(); @@ -308,7 +310,7 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p || m_oldTransformer->commands != m_transformer->commands || commandsNeedRerun(m_transformer.get(), m_product.get(), m_productsByName, m_projectsByName)) { - for (Artifact * const output : outputArtifacts) { + for (Artifact * const output : qAsConst(outputArtifacts)) { output->clearTimestamp(); m_invalidatedArtifacts += output; } @@ -545,8 +547,8 @@ class ArtifactBindingsExtractor { struct Entry { - Entry(const QString &module, const QString &name, const QVariant &value) - : module(module), name(name), value(value) + Entry(QString module, QString name, QVariant value) + : module(std::move(module)), name(std::move(name)), value(std::move(value)) {} QString module; @@ -558,9 +560,9 @@ class ArtifactBindingsExtractor static Set<QString> getArtifactItemPropertyNames() { Set<QString> s; - for (const PropertyDeclaration &pd : - BuiltinDeclarations::instance().declarationsForType( - ItemType::Artifact).properties()) { + const auto properties = BuiltinDeclarations::instance().declarationsForType( + ItemType::Artifact).properties(); + for (const PropertyDeclaration &pd : properties) { s.insert(pd.name()); } s.insert(StringConstants::explicitlyDependsOnProperty()); diff --git a/src/lib/corelib/buildgraph/rulesapplicator.h b/src/lib/corelib/buildgraph/rulesapplicator.h index f6fadb1ec..1160f3d09 100644 --- a/src/lib/corelib/buildgraph/rulesapplicator.h +++ b/src/lib/corelib/buildgraph/rulesapplicator.h @@ -62,10 +62,10 @@ class ScriptEngine; class RulesApplicator { public: - RulesApplicator(const ResolvedProductPtr &product, - const std::unordered_map<QString, const ResolvedProduct *> &productsByName, - const std::unordered_map<QString, const ResolvedProject *> &projectsByName, - const Logger &logger); + RulesApplicator(ResolvedProductPtr product, + std::unordered_map<QString, const ResolvedProduct *> productsByName, + std::unordered_map<QString, const ResolvedProject *> projectsByName, + Logger logger); ~RulesApplicator(); const NodeSet &createdArtifacts() const { return m_createdArtifacts; } diff --git a/src/lib/corelib/buildgraph/rulesevaluationcontext.cpp b/src/lib/corelib/buildgraph/rulesevaluationcontext.cpp index c81e40c4f..6ae230329 100644 --- a/src/lib/corelib/buildgraph/rulesevaluationcontext.cpp +++ b/src/lib/corelib/buildgraph/rulesevaluationcontext.cpp @@ -53,8 +53,8 @@ namespace qbs { namespace Internal { -RulesEvaluationContext::RulesEvaluationContext(const Logger &logger) - : m_logger(logger), +RulesEvaluationContext::RulesEvaluationContext(Logger logger) + : m_logger(std::move(logger)), m_engine(ScriptEngine::create(m_logger, EvalContext::RuleExecution)), m_observer(nullptr), m_initScopeCalls(0) diff --git a/src/lib/corelib/buildgraph/rulesevaluationcontext.h b/src/lib/corelib/buildgraph/rulesevaluationcontext.h index d3bf0e5bd..a5d81ce61 100644 --- a/src/lib/corelib/buildgraph/rulesevaluationcontext.h +++ b/src/lib/corelib/buildgraph/rulesevaluationcontext.h @@ -56,7 +56,7 @@ class ScriptEngine; class RulesEvaluationContext { public: - RulesEvaluationContext(const Logger &logger); + RulesEvaluationContext(Logger logger); ~RulesEvaluationContext(); class Scope diff --git a/src/lib/corelib/buildgraph/transformer.cpp b/src/lib/corelib/buildgraph/transformer.cpp index d737e908b..cc0b4c923 100644 --- a/src/lib/corelib/buildgraph/transformer.cpp +++ b/src/lib/corelib/buildgraph/transformer.cpp @@ -242,7 +242,8 @@ AbstractCommandPtr Transformer::createCommandFromScriptValue(const QScriptValue if (className == StringConstants::commandType()) { auto procCmd = static_cast<ProcessCommand *>(cmdBase.get()); procCmd->clearRelevantEnvValues(); - for (const QString &key : procCmd->relevantEnvVars()) + const auto envVars = procCmd->relevantEnvVars(); + for (const QString &key : envVars) procCmd->addRelevantEnvValue(key, product()->buildEnvironment.value(key)); } return cmdBase; diff --git a/src/lib/corelib/buildgraph/transformerchangetracking.cpp b/src/lib/corelib/buildgraph/transformerchangetracking.cpp index 08875b742..505f0cbba 100644 --- a/src/lib/corelib/buildgraph/transformerchangetracking.cpp +++ b/src/lib/corelib/buildgraph/transformerchangetracking.cpp @@ -209,8 +209,8 @@ bool TrafoChangeTracker::isExportedModuleUpToDate(const QString &productName, bool TrafoChangeTracker::areExportedModulesUpToDate( const std::unordered_map<QString, ExportedModule> exportedModules) const { - for (auto it = exportedModules.begin(); it != exportedModules.end(); ++it) { - if (!isExportedModuleUpToDate(it->first, it->second)) + for (const auto &kv : exportedModules) { + if (!isExportedModuleUpToDate(kv.first, kv.second)) return false; } return true; @@ -226,8 +226,7 @@ const Artifact *TrafoChangeTracker::getArtifact(const QString &filePath, const ResolvedProduct * const product = getProduct(productName); if (!product) return nullptr; - const QList<FileResourceBase *> &candidates - = product->topLevelProject()->buildData->lookupFiles(filePath); + const auto &candidates = product->topLevelProject()->buildData->lookupFiles(filePath); const Artifact *artifact = nullptr; for (const FileResourceBase * const candidate : candidates) { if (candidate->fileType() == FileResourceBase::FileTypeArtifact) { @@ -338,7 +337,8 @@ bool TrafoChangeTracker::commandsNeedRerun() const if (c->type() != AbstractCommand::ProcessCommandType) continue; const ProcessCommandPtr &processCmd = std::static_pointer_cast<ProcessCommand>(c); - for (const QString &var : processCmd->relevantEnvVars()) { + const auto envVars = processCmd->relevantEnvVars(); + for (const QString &var : envVars) { const QString &oldValue = processCmd->relevantEnvValue(var); const QString &newValue = m_product->buildEnvironment.value(var); if (oldValue != newValue) { diff --git a/src/lib/corelib/corelib.qbs b/src/lib/corelib/corelib.qbs index db00a7005..a9ca5131a 100644 --- a/src/lib/corelib/corelib.qbs +++ b/src/lib/corelib/corelib.qbs @@ -37,7 +37,7 @@ QbsLibrary { Properties { condition: qbs.targetOS.contains("windows") - cpp.dynamicLibraries: base.concat(["Psapi", "shell32"]) + cpp.dynamicLibraries: base.concat(["psapi", "shell32"]) } cpp.dynamicLibraries: base diff --git a/src/lib/corelib/generators/generatableprojectiterator.cpp b/src/lib/corelib/generators/generatableprojectiterator.cpp index c6d990f02..7267662e8 100644 --- a/src/lib/corelib/generators/generatableprojectiterator.cpp +++ b/src/lib/corelib/generators/generatableprojectiterator.cpp @@ -41,8 +41,8 @@ namespace qbs { -GeneratableProjectIterator::GeneratableProjectIterator(const GeneratableProject &project) - : project(project) +GeneratableProjectIterator::GeneratableProjectIterator(GeneratableProject project) + : project(std::move(project)) { } diff --git a/src/lib/corelib/generators/generatableprojectiterator.h b/src/lib/corelib/generators/generatableprojectiterator.h index 793627512..993144ce3 100644 --- a/src/lib/corelib/generators/generatableprojectiterator.h +++ b/src/lib/corelib/generators/generatableprojectiterator.h @@ -49,7 +49,7 @@ class QBS_EXPORT GeneratableProjectIterator { GeneratableProject project; public: - GeneratableProjectIterator(const GeneratableProject &project); + GeneratableProjectIterator(GeneratableProject project); void accept(IGeneratableProjectVisitor *visitor); private: diff --git a/src/lib/corelib/generators/generator.cpp b/src/lib/corelib/generators/generator.cpp index 24da95e41..90bebdcaa 100644 --- a/src/lib/corelib/generators/generator.cpp +++ b/src/lib/corelib/generators/generator.cpp @@ -213,7 +213,7 @@ const GeneratableProject ProjectGenerator::project() const { QMap<QString, ProjectData> rootProjects; GeneratableProject proj; - for (const auto &project : projects()) { + for (const auto &project : qAsConst(d->projects)) { const QString configurationName = _configurationName(project); rootProjects.insert(configurationName, project.projectData()); proj.projects.insert(configurationName, project); diff --git a/src/lib/corelib/generators/generator.h b/src/lib/corelib/generators/generator.h index 8d4e4f21b..775469f18 100644 --- a/src/lib/corelib/generators/generator.h +++ b/src/lib/corelib/generators/generator.h @@ -59,7 +59,7 @@ class QBS_EXPORT ProjectGenerator : public QObject Q_OBJECT Q_DISABLE_COPY(ProjectGenerator) public: - ~ProjectGenerator(); + ~ProjectGenerator() override; /*! * Returns the name of the generator used to create the external build system files. diff --git a/src/lib/corelib/jsextensions/binaryfile.cpp b/src/lib/corelib/jsextensions/binaryfile.cpp index 92f07d88d..5f28f689b 100644 --- a/src/lib/corelib/jsextensions/binaryfile.cpp +++ b/src/lib/corelib/jsextensions/binaryfile.cpp @@ -67,7 +67,7 @@ public: }; static QScriptValue ctor(QScriptContext *context, QScriptEngine *engine); - ~BinaryFile(); + ~BinaryFile() override; Q_INVOKABLE void close(); Q_INVOKABLE QString filePath(); diff --git a/src/lib/corelib/jsextensions/environmentextension.cpp b/src/lib/corelib/jsextensions/environmentextension.cpp index 22c4f069b..cf17c938b 100644 --- a/src/lib/corelib/jsextensions/environmentextension.cpp +++ b/src/lib/corelib/jsextensions/environmentextension.cpp @@ -127,7 +127,8 @@ QScriptValue EnvironmentExtension::js_currentEnv(QScriptContext *context, QScrip if (!procenv) procenv = &env; QScriptValue envObject = engine->newObject(); - for (const QString &key : procenv->keys()) { + const auto keys = procenv->keys(); + for (const QString &key : keys) { const QString keyName = HostOsInfo::isWindowsHost() ? key.toUpper() : key; envObject.setProperty(keyName, QScriptValue(procenv->value(key))); } diff --git a/src/lib/corelib/jsextensions/moduleproperties.cpp b/src/lib/corelib/jsextensions/moduleproperties.cpp index 91169d24b..c0fd8ca84 100644 --- a/src/lib/corelib/jsextensions/moduleproperties.cpp +++ b/src/lib/corelib/jsextensions/moduleproperties.cpp @@ -130,7 +130,7 @@ private: } setup(object); - QBS_ASSERT(m_product || m_artifact, return {}); + QBS_ASSERT(m_product, return {}); bool isPresent; m_result = getModuleProperty(m_product, m_artifact, static_cast<ScriptEngine *>(engine()), m_moduleName, name, &isPresent); @@ -336,8 +336,10 @@ QScriptValue ModuleProperties::moduleProperty(QScriptContext *context, QScriptEn const ResolvedProduct *product = nullptr; const Artifact *artifact = nullptr; if (typeScriptValue.toString() == StringConstants::productValue()) { + QBS_ASSERT(ptr, return {}); product = static_cast<const ResolvedProduct *>(ptr); } else if (typeScriptValue.toString() == artifactType()) { + QBS_ASSERT(ptr, return {}); artifact = static_cast<const Artifact *>(ptr); product = artifact->product.get(); } else { diff --git a/src/lib/corelib/jsextensions/process.cpp b/src/lib/corelib/jsextensions/process.cpp index 5148f9468..064297a32 100644 --- a/src/lib/corelib/jsextensions/process.cpp +++ b/src/lib/corelib/jsextensions/process.cpp @@ -63,7 +63,7 @@ class Process : public QObject, public QScriptable, public ResourceAcquiringScri public: static QScriptValue ctor(QScriptContext *context, QScriptEngine *engine); Process(QScriptContext *context); - ~Process(); + ~Process() override; Q_INVOKABLE QString getEnv(const QString &name); Q_INVOKABLE void setEnv(const QString &name, const QString &value); diff --git a/src/lib/corelib/jsextensions/propertylist.mm b/src/lib/corelib/jsextensions/propertylist.mm index d73cd742d..6ac9d56c9 100644 --- a/src/lib/corelib/jsextensions/propertylist.mm +++ b/src/lib/corelib/jsextensions/propertylist.mm @@ -70,7 +70,7 @@ class PropertyList : public QObject, public QScriptable public: static QScriptValue ctor(QScriptContext *context, QScriptEngine *engine); PropertyList(QScriptContext *context); - ~PropertyList(); + ~PropertyList() override; Q_INVOKABLE bool isEmpty() const; Q_INVOKABLE void clear(); Q_INVOKABLE void readFromObject(const QScriptValue &value); diff --git a/src/lib/corelib/jsextensions/textfile.cpp b/src/lib/corelib/jsextensions/textfile.cpp index 51688677f..7c67f9019 100644 --- a/src/lib/corelib/jsextensions/textfile.cpp +++ b/src/lib/corelib/jsextensions/textfile.cpp @@ -68,7 +68,7 @@ public: }; static QScriptValue ctor(QScriptContext *context, QScriptEngine *engine); - ~TextFile(); + ~TextFile() override; Q_INVOKABLE void close(); Q_INVOKABLE QString filePath(); diff --git a/src/lib/corelib/jsextensions/utilitiesextension.cpp b/src/lib/corelib/jsextensions/utilitiesextension.cpp index 5abaccad9..b425bb4a2 100644 --- a/src/lib/corelib/jsextensions/utilitiesextension.cpp +++ b/src/lib/corelib/jsextensions/utilitiesextension.cpp @@ -109,6 +109,7 @@ public: static QScriptValue js_certificateInfo(QScriptContext *context, QScriptEngine *engine); static QScriptValue js_signingIdentities(QScriptContext *context, QScriptEngine *engine); static QScriptValue js_msvcCompilerInfo(QScriptContext *context, QScriptEngine *engine); + static QScriptValue js_clangClCompilerInfo(QScriptContext *context, QScriptEngine *engine); static QScriptValue js_versionCompare(QScriptContext *context, QScriptEngine *engine); @@ -235,7 +236,7 @@ static inline QString escapedString(const Char *begin, int length, bool isUnicod // Surrogate characters are category Cs (Other_Surrogate), so isPrintable = false for them int runLength = 0; while (p + runLength != end && - isPrintable(p[runLength]) && p[runLength] != '\\' && p[runLength] != '"') + QChar::isPrint(p[runLength]) && p[runLength] != '\\' && p[runLength] != '"') ++runLength; if (runLength) { out += QString(reinterpret_cast<const QChar *>(p), runLength); @@ -287,7 +288,7 @@ static inline QString escapedString(const Char *begin, int length, bool isUnicod if ((p + 1) != end && QChar::isLowSurrogate(p[1])) { // properly-paired surrogates uint ucs4 = QChar::surrogateToUcs4(*p, p[1]); - if (isPrintable(ucs4)) { + if (QChar::isPrint(ucs4)) { buf[0] = *p; buf[1] = p[1]; buflen = 2; @@ -455,6 +456,37 @@ QScriptValue UtilitiesExtension::js_signingIdentities(QScriptContext *context, #endif } +#ifdef Q_OS_WIN +static std::pair<QVariantMap /*result*/, QString /*error*/> msvcCompilerInfoHelper( + const QString &compilerFilePath, + MSVC::CompilerLanguage language, + const QString &vcvarsallPath, + const QString &arch) +{ + MSVC msvc(compilerFilePath, arch); + VsEnvironmentDetector envdetector(vcvarsallPath); + if (!envdetector.start(&msvc)) + return { {}, QStringLiteral("Detecting the MSVC build environment failed: ") + + envdetector.errorString() }; + + try { + QVariantMap envMap; + for (const QString &key : msvc.environment.keys()) + envMap.insert(key, msvc.environment.value(key)); + + return { + QVariantMap { + {QStringLiteral("buildEnvironment"), envMap}, + {QStringLiteral("macros"), msvc.compilerDefines(compilerFilePath, language)}, + }, + {} + }; + } catch (const qbs::ErrorInfo &info) { + return { {}, info.toString() }; + } +} +#endif + QScriptValue UtilitiesExtension::js_msvcCompilerInfo(QScriptContext *context, QScriptEngine *engine) { #ifndef Q_OS_WIN @@ -462,14 +494,12 @@ QScriptValue UtilitiesExtension::js_msvcCompilerInfo(QScriptContext *context, QS return context->throwError(QScriptContext::UnknownError, QStringLiteral("msvcCompilerInfo is not available on this platform")); #else - if (Q_UNLIKELY(context->argumentCount() < 1)) + if (Q_UNLIKELY(context->argumentCount() < 2)) return context->throwError(QScriptContext::SyntaxError, - QStringLiteral("msvcCompilerInfo expects at least 1 argument")); + QStringLiteral("msvcCompilerInfo expects 2 arguments")); const QString compilerFilePath = context->argument(0).toString(); - const QString compilerLanguage = context->argumentCount() > 1 - ? context->argument(1).toString() - : QString(); + const QString compilerLanguage = context->argument(1).toString(); MSVC::CompilerLanguage language; if (compilerLanguage == QStringLiteral("c")) language = MSVC::CLanguage; @@ -479,26 +509,45 @@ QScriptValue UtilitiesExtension::js_msvcCompilerInfo(QScriptContext *context, QS return context->throwError(QScriptContext::TypeError, QStringLiteral("msvcCompilerInfo expects \"c\" or \"cpp\" as its second argument")); - MSVC msvc(compilerFilePath); - VsEnvironmentDetector envdetector; - if (!envdetector.start(&msvc)) - return context->throwError(QScriptContext::UnknownError, - QStringLiteral("Detecting the MSVC build environment failed: ") - + envdetector.errorString()); + const auto result = msvcCompilerInfoHelper( + compilerFilePath, language, {}, MSVC::architectureFromClPath(compilerFilePath)); + if (result.first.isEmpty()) + return context->throwError(QScriptContext::UnknownError, result.second); + return engine->toScriptValue(result.first); +#endif +} - try { - QVariantMap envMap; - for (const QString &key : msvc.environment.keys()) - envMap.insert(key, msvc.environment.value(key)); +QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context, QScriptEngine *engine) +{ +#ifndef Q_OS_WIN + Q_UNUSED(engine); + return context->throwError(QScriptContext::UnknownError, + QStringLiteral("clangClCompilerInfo is not available on this platform")); +#else + if (Q_UNLIKELY(context->argumentCount() < 4)) + return context->throwError(QScriptContext::SyntaxError, + QStringLiteral("clangClCompilerInfo expects 4 arguments")); - return engine->toScriptValue(QVariantMap { - {QStringLiteral("buildEnvironment"), envMap}, - {QStringLiteral("macros"), msvc.compilerDefines(compilerFilePath, language)}, - }); - } catch (const qbs::ErrorInfo &info) { - return context->throwError(QScriptContext::UnknownError, - info.toString()); - } + const QString compilerFilePath = context->argument(0).toString(); + QString arch = context->argument(1).toString(); + QString vcvarsallPath = context->argument(2).toString(); + const QString compilerLanguage = context->argumentCount() > 3 + ? context->argument(3).toString() + : QString(); + MSVC::CompilerLanguage language; + if (compilerLanguage == QStringLiteral("c")) + language = MSVC::CLanguage; + else if (compilerLanguage == StringConstants::cppLang()) + language = MSVC::CPlusPlusLanguage; + else + return context->throwError(QScriptContext::TypeError, + QStringLiteral("clangClCompilerInfo expects \"c\" or \"cpp\" as its fourth argument")); + + const auto result = msvcCompilerInfoHelper( + compilerFilePath, language, vcvarsallPath, arch); + if (result.first.isEmpty()) + return context->throwError(QScriptContext::UnknownError, result.second); + return engine->toScriptValue(result.first); #endif } @@ -800,6 +849,8 @@ void initializeJsExtensionUtilities(QScriptValue extensionObject) engine->newFunction(UtilitiesExtension::js_signingIdentities, 0)); environmentObj.setProperty(QStringLiteral("msvcCompilerInfo"), engine->newFunction(UtilitiesExtension::js_msvcCompilerInfo, 1)); + environmentObj.setProperty(QStringLiteral("clangClCompilerInfo"), + engine->newFunction(UtilitiesExtension::js_clangClCompilerInfo, 1)); environmentObj.setProperty(QStringLiteral("versionCompare"), engine->newFunction(UtilitiesExtension::js_versionCompare, 2)); environmentObj.setProperty(QStringLiteral("qmlTypeInfo"), diff --git a/src/lib/corelib/language/astimportshandler.cpp b/src/lib/corelib/language/astimportshandler.cpp index 960af4cda..d634af7e4 100644 --- a/src/lib/corelib/language/astimportshandler.cpp +++ b/src/lib/corelib/language/astimportshandler.cpp @@ -69,7 +69,8 @@ ASTImportsHandler::ASTImportsHandler(ItemReaderVisitorState &visitorState, Logge void ASTImportsHandler::handleImports(const QbsQmlJS::AST::UiImportList *uiImportList) { - for (const QString &searchPath : m_file->searchPaths()) + const auto searchPaths = m_file->searchPaths(); + for (const QString &searchPath : searchPaths) collectPrototypes(searchPath + QStringLiteral("/imports"), QString()); // files in the same directory are available as prototypes @@ -191,7 +192,8 @@ void ASTImportsHandler::handleImport(const QbsQmlJS::AST::UiImport *import, bool ? QStringLiteral("qbs/base") : importUri.join(QDir::separator()); bool found = m_typeNameToFile.contains(importUri); if (!found) { - for (const QString &searchPath : m_file->searchPaths()) { + const auto searchPaths = m_file->searchPaths(); + for (const QString &searchPath : searchPaths) { const QFileInfo fi(FileInfo::resolvePath( FileInfo::resolvePath(searchPath, StringConstants::importsDir()), diff --git a/src/lib/corelib/language/builtindeclarations.cpp b/src/lib/corelib/language/builtindeclarations.cpp index ee1b2d56e..68355df51 100644 --- a/src/lib/corelib/language/builtindeclarations.cpp +++ b/src/lib/corelib/language/builtindeclarations.cpp @@ -150,7 +150,8 @@ QStringList BuiltinDeclarations::argumentNamesForScriptFunction(ItemType itemTyp const QString &scriptName) const { const ItemDeclaration itemDecl = declarationsForType(itemType); - for (const PropertyDeclaration &propDecl : itemDecl.properties()) { + const auto properties = itemDecl.properties(); + for (const PropertyDeclaration &propDecl : properties) { if (propDecl.name() == scriptName) return propDecl.functionArgumentNames(); } diff --git a/src/lib/corelib/language/evaluationdata.h b/src/lib/corelib/language/evaluationdata.h index efd504a11..791b2f234 100644 --- a/src/lib/corelib/language/evaluationdata.h +++ b/src/lib/corelib/language/evaluationdata.h @@ -55,8 +55,8 @@ class Item; class EvaluationData { public: - Evaluator *evaluator; - const Item *item; + Evaluator *evaluator = nullptr; + const Item *item = nullptr; mutable QHash<QScriptString, QScriptValue> valueCache; }; diff --git a/src/lib/corelib/language/identifiersearch.h b/src/lib/corelib/language/identifiersearch.h index d9769266c..7d99c0f13 100644 --- a/src/lib/corelib/language/identifiersearch.h +++ b/src/lib/corelib/language/identifiersearch.h @@ -61,7 +61,7 @@ private: bool visit(QbsQmlJS::AST::IdentifierExpression *e) override; QMap<QString, bool *> m_requests; - int m_numberOfFoundIds; + int m_numberOfFoundIds = 0; }; } // namespace Internal diff --git a/src/lib/corelib/language/item.cpp b/src/lib/corelib/language/item.cpp index 39dc39370..9f754bdd7 100644 --- a/src/lib/corelib/language/item.cpp +++ b/src/lib/corelib/language/item.cpp @@ -249,7 +249,8 @@ bool Item::isPresentModule() const void Item::setupForBuiltinType(Logger &logger) { const BuiltinDeclarations &builtins = BuiltinDeclarations::instance(); - for (const PropertyDeclaration &pd : builtins.declarationsForType(type()).properties()) { + const auto properties = builtins.declarationsForType(type()).properties(); + for (const PropertyDeclaration &pd : properties) { m_propertyDeclarations.insert(pd.name(), pd); const ValuePtr value = m_properties.value(pd.name()); if (!value) { diff --git a/src/lib/corelib/language/itemobserver.h b/src/lib/corelib/language/itemobserver.h index 82a3aed24..fca3a2d85 100644 --- a/src/lib/corelib/language/itemobserver.h +++ b/src/lib/corelib/language/itemobserver.h @@ -48,6 +48,7 @@ class Item; class ItemObserver { public: + virtual ~ItemObserver() = default; virtual void onItemPropertyChanged(Item *item) = 0; }; diff --git a/src/lib/corelib/language/itempool.cpp b/src/lib/corelib/language/itempool.cpp index 8ec6b63d1..3da8b947b 100644 --- a/src/lib/corelib/language/itempool.cpp +++ b/src/lib/corelib/language/itempool.cpp @@ -49,8 +49,8 @@ ItemPool::ItemPool() ItemPool::~ItemPool() { - for (ItemVector::const_iterator it = m_items.cbegin(); it != m_items.cend(); ++it) - (*it)->~Item(); + for (Item *item : m_items) + item->~Item(); } Item *ItemPool::allocateItem(const ItemType &type) diff --git a/src/lib/corelib/language/itempool.h b/src/lib/corelib/language/itempool.h index 8ee8562d7..ef4be7639 100644 --- a/src/lib/corelib/language/itempool.h +++ b/src/lib/corelib/language/itempool.h @@ -43,7 +43,7 @@ #include <parser/qmljsmemorypool_p.h> #include <tools/qbs_export.h> -#include <QtCore/qlist.h> +#include <vector> namespace qbs { namespace Internal { @@ -62,8 +62,7 @@ public: private: QbsQmlJS::MemoryPool m_pool; - using ItemVector = QList<Item *>; - ItemVector m_items; + std::vector<Item *> m_items; }; } // namespace Internal diff --git a/src/lib/corelib/language/itemreaderastvisitor.cpp b/src/lib/corelib/language/itemreaderastvisitor.cpp index 2ea306138..901772d16 100644 --- a/src/lib/corelib/language/itemreaderastvisitor.cpp +++ b/src/lib/corelib/language/itemreaderastvisitor.cpp @@ -67,9 +67,9 @@ namespace qbs { namespace Internal { ItemReaderASTVisitor::ItemReaderASTVisitor(ItemReaderVisitorState &visitorState, - const FileContextPtr &file, ItemPool *itemPool, Logger &logger) + FileContextPtr file, ItemPool *itemPool, Logger &logger) : m_visitorState(visitorState) - , m_file(file) + , m_file(std::move(file)) , m_itemPool(itemPool) , m_logger(logger) { diff --git a/src/lib/corelib/language/itemreaderastvisitor.h b/src/lib/corelib/language/itemreaderastvisitor.h index 4a0bedc91..963b78471 100644 --- a/src/lib/corelib/language/itemreaderastvisitor.h +++ b/src/lib/corelib/language/itemreaderastvisitor.h @@ -60,7 +60,7 @@ class ItemReaderVisitorState; class ItemReaderASTVisitor : public QbsQmlJS::AST::Visitor { public: - ItemReaderASTVisitor(ItemReaderVisitorState &visitorState, const FileContextPtr &file, + ItemReaderASTVisitor(ItemReaderVisitorState &visitorState, FileContextPtr file, ItemPool *itemPool, Logger &logger); void checkItemTypes() { doCheckItemTypes(rootItem()); } diff --git a/src/lib/corelib/language/language.cpp b/src/lib/corelib/language/language.cpp index f21f724f1..d888700c5 100644 --- a/src/lib/corelib/language/language.cpp +++ b/src/lib/corelib/language/language.cpp @@ -91,8 +91,8 @@ template<typename T> bool equals(const T *v1, const T *v2) * \brief The \c FileTagger class maps 1:1 to the respective item in a qbs source file. */ -FileTagger::FileTagger(const QStringList &patterns, const FileTags &fileTags, int priority) - : m_fileTags(fileTags), m_priority(priority) +FileTagger::FileTagger(const QStringList &patterns, FileTags fileTags, int priority) + : m_fileTags(std::move(fileTags)), m_priority(priority) { setPatterns(patterns); } diff --git a/src/lib/corelib/language/language.h b/src/lib/corelib/language/language.h index 297fedf1c..65879dd56 100644 --- a/src/lib/corelib/language/language.h +++ b/src/lib/corelib/language/language.h @@ -98,7 +98,7 @@ public: } private: - FileTagger(const QStringList &patterns, const FileTags &fileTags, int priority); + FileTagger(const QStringList &patterns, FileTags fileTags, int priority); FileTagger() {} void setPatterns(const QStringList &patterns); @@ -162,7 +162,7 @@ private: QVariantMap m_properties; QVariantMap m_initialProperties; std::vector<QString> m_importedFilesUsed; - bool m_condition; + bool m_condition = false; }; class RuleArtifact @@ -280,14 +280,14 @@ public: CodeLocation location; QString name; - bool enabled; + bool enabled = true; QString prefix; std::vector<SourceArtifactPtr> files; std::unique_ptr<SourceWildCards> wildcards; PropertyMapPtr properties; FileTags fileTags; QString targetOfModule; - bool overrideTags; + bool overrideTags = false; std::vector<SourceArtifactPtr> allFiles() const; @@ -295,10 +295,6 @@ public: void store(PersistentPool &pool); private: - ResolvedGroup() - : enabled(true) - {} - template<PersistentPool::OpType opType> void serializationOp(PersistentPool &pool) { pool.serializationOp<opType>(name, enabled, location, prefix, files, wildcards, properties, @@ -370,7 +366,7 @@ public: PrivateScriptFunction setupBuildEnvironmentScript; PrivateScriptFunction setupRunEnvironmentScript; ResolvedProduct *product = nullptr; - bool isProduct; + bool isProduct = false; static QStringList argumentNamesForSetupBuildEnv(); static QStringList argumentNamesForSetupRunEnv(); @@ -414,13 +410,13 @@ public: FileTags inputsFromDependencies; FileTags explicitlyDependsOn; FileTags explicitlyDependsOnFromDependencies; - bool multiplex; - bool requiresInputs; + bool multiplex = false; + bool requiresInputs = false; std::vector<RuleArtifactPtr> artifacts; // unused, if outputFileTags/outputArtifactsScript is non-empty - bool alwaysRun; + bool alwaysRun = false; // members that we don't need to save - int ruleGraphId; + int ruleGraphId = -1; static QStringList argumentNamesForOutputArtifacts(); static QStringList argumentNamesForPrepare(); @@ -440,7 +436,7 @@ public: requiresInputs, alwaysRun, artifacts); } private: - Rule() : multiplex(false), alwaysRun(false), ruleGraphId(-1) {} + Rule() = default; }; bool operator==(const Rule &r1, const Rule &r2); inline bool operator!=(const Rule &r1, const Rule &r2) { return !(r1 == r2); } @@ -477,7 +473,7 @@ public: } QString fullName; - PropertyDeclaration::Type type; + PropertyDeclaration::Type type = PropertyDeclaration::Type::UnknownType; QString sourceCode; bool isBuiltin = false; }; diff --git a/src/lib/corelib/language/loader.cpp b/src/lib/corelib/language/loader.cpp index e27ccca74..f248fbb1a 100644 --- a/src/lib/corelib/language/loader.cpp +++ b/src/lib/corelib/language/loader.cpp @@ -61,8 +61,8 @@ namespace qbs { namespace Internal { -Loader::Loader(ScriptEngine *engine, const Logger &logger) - : m_logger(logger) +Loader::Loader(ScriptEngine *engine, Logger logger) + : m_logger(std::move(logger)) , m_progressObserver(nullptr) , m_engine(engine) { @@ -167,7 +167,7 @@ TopLevelProjectPtr Loader::loadProject(const SetupProjectParameters &_parameters moduleLoader.setStoredProfiles(m_storedProfiles); moduleLoader.setStoredModuleProviderInfo(m_storedModuleProviderInfo); const ModuleLoaderResult loadResult = moduleLoader.load(parameters); - ProjectResolver resolver(&evaluator, loadResult, parameters, m_logger); + ProjectResolver resolver(&evaluator, loadResult, std::move(parameters), m_logger); resolver.setProgressObserver(m_progressObserver); const TopLevelProjectPtr project = resolver.resolve(); project->lastStartResolveTime = resolveTime; diff --git a/src/lib/corelib/language/loader.h b/src/lib/corelib/language/loader.h index 48a0b6065..d172a74ed 100644 --- a/src/lib/corelib/language/loader.h +++ b/src/lib/corelib/language/loader.h @@ -57,7 +57,7 @@ class ScriptEngine; class QBS_AUTOTEST_EXPORT Loader { public: - Loader(ScriptEngine *engine, const Logger &logger); + Loader(ScriptEngine *engine, Logger logger); void setProgressObserver(ProgressObserver *observer); void setSearchPaths(const QStringList &searchPaths); diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index d7fb9b75d..67d60e05d 100644 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -294,7 +294,8 @@ ModuleLoaderResult ModuleLoader::load(const SetupProjectParameters ¶meters) m_probesEncountered = m_probesRun = m_probesCachedCurrent = m_probesCachedOld = 0; m_settings.reset(new Settings(parameters.settingsDirectory())); - for (const QString &key : m_parameters.overriddenValues().keys()) { + const auto keys = m_parameters.overriddenValues().keys(); + for (const QString &key : keys) { static const QStringList prefixes({ StringConstants::projectPrefix(), QStringLiteral("projects"), QStringLiteral("products"), QStringLiteral("modules"), @@ -695,7 +696,7 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult, if (child->type() == ItemType::Product) multiplexedProducts << multiplexProductItem(&dummyProductContext, child); } - for (Item * const additionalProductItem : multiplexedProducts) + for (Item * const additionalProductItem : qAsConst(multiplexedProducts)) Item::addChild(projectItem, additionalProductItem); resolveProbes(&dummyProductContext, projectItem); @@ -2121,12 +2122,12 @@ void ModuleLoader::checkProductNamesInOverrides() if (m_erroneousProducts.contains(productNameInOverride)) continue; bool found = false; - for (auto it = m_productsByName.cbegin(); it != m_productsByName.cend(); ++it) { + for (const auto &kv : m_productsByName) { // In an override string such as "a.b.c:d, we cannot tell whether we have a product // "a" and a module "b.c" or a product "a.b" and a module "c", so we need to take // care not to emit false positives here. - if (it->first == productNameInOverride - || it->first.startsWith(productNameInOverride + StringConstants::dot())) { + if (kv.first == productNameInOverride + || kv.first.startsWith(productNameInOverride + StringConstants::dot())) { found = true; break; } @@ -2653,7 +2654,7 @@ void ModuleLoader::resolveDependsItem(DependsContext *dependsContext, Item *pare profiles.push_back(QString()); } for (const QString &profile : qAsConst(profiles)) { - for (const QString &multiplexId : multiplexConfigurationIds) { + for (const QString &multiplexId : qAsConst(multiplexConfigurationIds)) { ModuleLoaderResult::ProductInfo::Dependency dependency; dependency.name = moduleName.toString(); dependency.profile = profile; @@ -3405,7 +3406,8 @@ void ModuleLoader::instantiateModule(ProductContext *productContext, Item *expor // create ids from from the prototype in the instance if (modulePrototype->file()->idScope()) { - for (Item * const itemWithId : collectItemsWithId(modulePrototype)) { + const auto items = collectItemsWithId(modulePrototype); + for (Item * const itemWithId : items) { Item *idProto = itemWithId; Item *idInstance = prototypeInstanceMap.value(idProto); QBS_ASSERT(idInstance, continue); @@ -4029,9 +4031,8 @@ void ModuleLoader::handleProductError(const ErrorInfo &error, << "in product" << productContext->name; return; } - const auto &deps = productContext->productModuleDependencies; - for (auto it = deps.cbegin(); it != deps.cend(); ++it) { - const auto rangeForName = m_productsByName.equal_range(it->first); + for (const auto &kv : productContext->productModuleDependencies) { + const auto rangeForName = m_productsByName.equal_range(kv.first); for (auto rangeIt = rangeForName.first; rangeIt != rangeForName.second; ++rangeIt) { const ProductContext * const dep = rangeIt->second; if (dep->info.delayedError.hasError()) { @@ -4044,7 +4045,8 @@ void ModuleLoader::handleProductError(const ErrorInfo &error, } } } - for (const ErrorItem &ei : error.items()) + const auto errorItems = error.items(); + for (const ErrorItem &ei : errorItems) productContext->info.delayedError.append(ei.description(), ei.codeLocation()); productContext->project->result->productInfos.insert(productContext->item, productContext->info); diff --git a/src/lib/corelib/language/moduleloader.h b/src/lib/corelib/language/moduleloader.h index a8190596d..85a2467f2 100644 --- a/src/lib/corelib/language/moduleloader.h +++ b/src/lib/corelib/language/moduleloader.h @@ -175,7 +175,7 @@ private: class ProductContext : public ContextBase { public: - ProjectContext *project; + ProjectContext *project = nullptr; ModuleLoaderResult::ProductInfo info; QString profileName; QString multiplexConfigurationId; @@ -201,8 +201,8 @@ private: class ProjectContext : public ContextBase { public: - TopLevelProjectContext *topLevelProject; - ModuleLoaderResult *result; + TopLevelProjectContext *topLevelProject = nullptr; + ModuleLoaderResult *result = nullptr; std::vector<ProductContext> products; std::vector<QStringList> searchPathsStack; }; @@ -232,7 +232,7 @@ private: public: ProductContext *product = nullptr; Item *exportingProductItem = nullptr; - ProductDependencies *productDependencies; + ProductDependencies *productDependencies = nullptr; }; void handleTopLevelProject(ModuleLoaderResult *loadResult, Item *projectItem, @@ -457,16 +457,16 @@ private: Version m_qbsVersion; Item *m_tempScopeItem = nullptr; - qint64 m_elapsedTimeProbes; - qint64 m_elapsedTimePrepareProducts; - qint64 m_elapsedTimeProductDependencies; - qint64 m_elapsedTimeTransitiveDependencies; - qint64 m_elapsedTimeHandleProducts; - qint64 m_elapsedTimePropertyChecking; - quint64 m_probesEncountered; - quint64 m_probesRun; - quint64 m_probesCachedCurrent; - quint64 m_probesCachedOld; + qint64 m_elapsedTimeProbes = 0; + qint64 m_elapsedTimePrepareProducts = 0; + qint64 m_elapsedTimeProductDependencies = 0; + qint64 m_elapsedTimeTransitiveDependencies = 0; + qint64 m_elapsedTimeHandleProducts = 0; + qint64 m_elapsedTimePropertyChecking = 0; + quint64 m_probesEncountered = 0; + quint64 m_probesRun = 0; + quint64 m_probesCachedCurrent = 0; + quint64 m_probesCachedOld = 0; Set<QString> m_projectNamesUsedInOverrides; Set<QString> m_productNamesUsedInOverrides; Set<QString> m_disabledProjects; diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp index 0bbf8d37a..049472310 100644 --- a/src/lib/corelib/language/projectresolver.cpp +++ b/src/lib/corelib/language/projectresolver.cpp @@ -98,7 +98,7 @@ struct ProjectResolver::ProductContext { ResolvedProductPtr product; QString buildDirectory; - Item *item; + Item *item = nullptr; using ArtifactPropertiesInfo = std::pair<ArtifactPropertiesPtr, std::vector<CodeLocation>>; QHash<QStringList, ArtifactPropertiesInfo> artifactPropertiesPerFilter; ProjectResolver::FileLocations sourceArtifactLocations; @@ -114,14 +114,14 @@ struct ProjectResolver::ModuleContext class CancelException { }; -ProjectResolver::ProjectResolver(Evaluator *evaluator, const ModuleLoaderResult &loadResult, - const SetupProjectParameters &setupParameters, Logger &logger) +ProjectResolver::ProjectResolver(Evaluator *evaluator, ModuleLoaderResult loadResult, + SetupProjectParameters setupParameters, Logger &logger) : m_evaluator(evaluator) , m_logger(logger) , m_engine(m_evaluator->engine()) , m_progressObserver(nullptr) - , m_setupParams(setupParameters) - , m_loadResult(loadResult) + , m_setupParams(std::move(setupParameters)) + , m_loadResult(std::move(loadResult)) { QBS_CHECK(FileInfo::isAbsolute(m_setupParams.buildRoot())); } @@ -826,7 +826,7 @@ void ProjectResolver::resolveGroupFully(Item *item, ProjectResolver::ProjectCont &m_productContext->sourceArtifactLocations, &fileError); } - for (const QString &fileName : files) { + for (const QString &fileName : qAsConst(files)) { createSourceArtifact(m_productContext->product, fileName, group, false, filesLocation, &m_productContext->sourceArtifactLocations, &fileError); } @@ -1022,7 +1022,8 @@ void ProjectResolver::setupExportedProperties(const Item *item, const QString &n const ItemDeclaration itemDecl = BuiltinDeclarations::instance().declarationsForType(item->type()); PropertyDeclaration propertyDecl; - for (const PropertyDeclaration &decl : itemDecl.properties()) { + const auto itemProperties = itemDecl.properties(); + for (const PropertyDeclaration &decl : itemProperties) { if (decl.name() == it.key()) { propertyDecl = decl; exportedProperty.isBuiltin = true; @@ -1109,7 +1110,8 @@ void ProjectResolver::resolveExport(Item *exportItem, ProjectContext *) exportItem->file()->content()); } } - for (const QString &builtinImport: JsExtensions::extensionNames()) { + const auto builtInImports = JsExtensions::extensionNames(); + for (const QString &builtinImport: builtInImports) { if (usesImport(exportedModule, builtinImport)) exportedModule.importStatements << QStringLiteral("import qbs.") + builtinImport; } diff --git a/src/lib/corelib/language/projectresolver.h b/src/lib/corelib/language/projectresolver.h index 0732b1c9b..428ba144d 100644 --- a/src/lib/corelib/language/projectresolver.h +++ b/src/lib/corelib/language/projectresolver.h @@ -67,8 +67,8 @@ class ScriptEngine; class ProjectResolver { public: - ProjectResolver(Evaluator *evaluator, const ModuleLoaderResult &loadResult, - const SetupProjectParameters &setupParameters, Logger &logger); + ProjectResolver(Evaluator *evaluator, ModuleLoaderResult loadResult, + SetupProjectParameters setupParameters, Logger &logger); ~ProjectResolver(); void setProgressObserver(ProgressObserver *observer); @@ -172,12 +172,12 @@ private: void setupExportedProperties(const Item *item, const QString &namePrefix, std::vector<ExportedProperty> &properties); - Evaluator *m_evaluator; + Evaluator *m_evaluator = nullptr; Logger &m_logger; - ScriptEngine *m_engine; - ProgressObserver *m_progressObserver; - ProductContext *m_productContext; - ModuleContext *m_moduleContext; + ScriptEngine *m_engine = nullptr; + ProgressObserver *m_progressObserver = nullptr; + ProductContext *m_productContext = nullptr; + ModuleContext *m_moduleContext = nullptr; QMap<QString, ResolvedProductPtr> m_productsByName; QHash<FileTag, QList<ResolvedProductPtr> > m_productsByType; QHash<ResolvedProductPtr, Item *> m_productItemMap; @@ -185,14 +185,14 @@ private: mutable QHash<CodeLocation, ScriptFunctionPtr> m_scriptFunctionMap; mutable QHash<std::pair<QStringRef, QStringList>, QString> m_scriptFunctions; mutable QHash<QStringRef, QString> m_sourceCode; - const SetupProjectParameters &m_setupParams; + const SetupProjectParameters m_setupParams; ModuleLoaderResult m_loadResult; Set<CodeLocation> m_groupLocationWarnings; std::vector<std::pair<ResolvedProductPtr, Item *>> m_productExportInfo; std::vector<ErrorInfo> m_queuedErrors; - qint64 m_elapsedTimeModPropEval; - qint64 m_elapsedTimeAllPropEval; - qint64 m_elapsedTimeGroups; + qint64 m_elapsedTimeModPropEval = 0; + qint64 m_elapsedTimeAllPropEval = 0; + qint64 m_elapsedTimeGroups = 0; typedef void (ProjectResolver::*ItemFuncPtr)(Item *item, ProjectContext *projectContext); using ItemFuncMap = QMap<ItemType, ItemFuncPtr>; diff --git a/src/lib/corelib/language/scriptengine.cpp b/src/lib/corelib/language/scriptengine.cpp index 1c6d0cb0d..7c531e764 100644 --- a/src/lib/corelib/language/scriptengine.cpp +++ b/src/lib/corelib/language/scriptengine.cpp @@ -609,8 +609,8 @@ Set<QString> ScriptEngine::imports() const for (const QString &filePath : jsImport.filePaths) filePaths << filePath; } - for (auto it = m_filePathsPerImport.cbegin(); it != m_filePathsPerImport.cend(); ++it) { - for (const QString &fp : it->second) + for (const auto &kv : m_filePathsPerImport) { + for (const QString &fp : kv.second) filePaths << fp; } return filePaths; @@ -817,9 +817,11 @@ void ScriptEngine::uninstallImportFunctions() globalObject().setProperty(requireString(), QScriptValue()); } -ScriptEngine::PropertyCacheKey::PropertyCacheKey(const QString &moduleName, - const QString &propertyName, const PropertyMapConstPtr &propertyMap) - : m_moduleName(moduleName), m_propertyName(propertyName), m_propertyMap(propertyMap) +ScriptEngine::PropertyCacheKey::PropertyCacheKey(QString moduleName, + QString propertyName, PropertyMapConstPtr propertyMap) + : m_moduleName(std::move(moduleName)) + , m_propertyName(std::move(propertyName)) + , m_propertyMap(std::move(propertyMap)) { } diff --git a/src/lib/corelib/language/scriptengine.h b/src/lib/corelib/language/scriptengine.h index 89863189a..24e133dff 100644 --- a/src/lib/corelib/language/scriptengine.h +++ b/src/lib/corelib/language/scriptengine.h @@ -93,6 +93,7 @@ using DubiousContextList = std::vector<DubiousContext>; class ResourceAcquiringScriptObject { public: + virtual ~ResourceAcquiringScriptObject() = default; virtual void releaseResources() = 0; }; @@ -104,7 +105,7 @@ class QBS_AUTOTEST_EXPORT ScriptEngine : public QScriptEngine ScriptEngine(Logger &logger, EvalContext evalContext, QObject *parent = nullptr); public: static ScriptEngine *create(Logger &logger, EvalContext evalContext, QObject *parent = nullptr); - ~ScriptEngine(); + ~ScriptEngine() override; Logger &logger() const { return m_logger; } void import(const FileContextBaseConstPtr &fileCtx, QScriptValue &targetObject, @@ -302,8 +303,8 @@ private: class PropertyCacheKey { public: - PropertyCacheKey(const QString &moduleName, const QString &propertyName, - const PropertyMapConstPtr &propertyMap); + PropertyCacheKey(QString moduleName, QString propertyName, + PropertyMapConstPtr propertyMap); private: const QString m_moduleName; const QString m_propertyName; diff --git a/src/lib/corelib/language/scriptimporter.cpp b/src/lib/corelib/language/scriptimporter.cpp index c5dc887b7..9c6d4d38e 100644 --- a/src/lib/corelib/language/scriptimporter.cpp +++ b/src/lib/corelib/language/scriptimporter.cpp @@ -109,8 +109,8 @@ private: m_suffix += name; } - bool m_first; - bool m_barrier; + bool m_first = false; + bool m_barrier = false; QString m_suffix; }; diff --git a/src/lib/corelib/language/value.cpp b/src/lib/corelib/language/value.cpp index 16cbbeeff..656f38874 100644 --- a/src/lib/corelib/language/value.cpp +++ b/src/lib/corelib/language/value.cpp @@ -183,9 +183,9 @@ ValuePtr ItemValue::clone() const return create(m_item->clone(), createdByPropertiesBlock()); } -VariantValue::VariantValue(const QVariant &v) +VariantValue::VariantValue(QVariant v) : Value(VariantValueType, false) - , m_value(v) + , m_value(std::move(v)) { } diff --git a/src/lib/corelib/language/value.h b/src/lib/corelib/language/value.h index b9a869d73..f27406f2d 100644 --- a/src/lib/corelib/language/value.h +++ b/src/lib/corelib/language/value.h @@ -115,7 +115,7 @@ class JSSourceValue : public Value public: static JSSourceValuePtr QBS_AUTOTEST_EXPORT create(bool createdByPropertiesBlock = false); - ~JSSourceValue(); + ~JSSourceValue() override; void apply(ValueHandler *handler) override { handler->handle(this); } ValuePtr clone() const override; @@ -207,7 +207,7 @@ private: class VariantValue : public Value { - VariantValue(const QVariant &v); + VariantValue(QVariant v); public: static VariantValuePtr create(const QVariant &v = QVariant()); diff --git a/src/lib/corelib/logging/ilogsink.cpp b/src/lib/corelib/logging/ilogsink.cpp index bc2f36e61..4eb930cbf 100644 --- a/src/lib/corelib/logging/ilogsink.cpp +++ b/src/lib/corelib/logging/ilogsink.cpp @@ -78,13 +78,12 @@ QString logLevelName(LoggerLevel level) class ILogSink::ILogSinkPrivate { public: - LoggerLevel logLevel; + LoggerLevel logLevel = defaultLogLevel(); std::mutex mutex; }; ILogSink::ILogSink() : d(new ILogSinkPrivate) { - d->logLevel = defaultLogLevel(); } ILogSink::~ILogSink() diff --git a/src/lib/corelib/logging/logger.cpp b/src/lib/corelib/logging/logger.cpp index c3b11094d..71ca6a96c 100644 --- a/src/lib/corelib/logging/logger.cpp +++ b/src/lib/corelib/logging/logger.cpp @@ -165,7 +165,8 @@ LogWriter operator<<(LogWriter w, const QVariant &variant) QString str = QLatin1String(variant.typeName()) + QLatin1Char('('); if (variant.type() == QVariant::List) { bool firstLoop = true; - for (const QVariant &item : variant.toList()) { + const auto list = variant.toList(); + for (const QVariant &item : list) { str += item.toString(); if (firstLoop) firstLoop = false; diff --git a/src/lib/corelib/parser/qmljsast_p.h b/src/lib/corelib/parser/qmljsast_p.h index d7b627a4b..8c6f32140 100644 --- a/src/lib/corelib/parser/qmljsast_p.h +++ b/src/lib/corelib/parser/qmljsast_p.h @@ -247,7 +247,7 @@ class QML_PARSER_EXPORT ExpressionNode: public Node public: ExpressionNode() {} - virtual ExpressionNode *expressionCast(); + ExpressionNode *expressionCast() override; }; class QML_PARSER_EXPORT Statement: public Node @@ -255,7 +255,7 @@ class QML_PARSER_EXPORT Statement: public Node public: Statement() {} - virtual Statement *statementCast(); + Statement *statementCast() override; }; class QML_PARSER_EXPORT NestedExpression: public ExpressionNode @@ -267,12 +267,12 @@ public: : expression(expression) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return lparenToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rparenToken; } // attributes @@ -288,12 +288,12 @@ public: ThisExpression() { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return thisToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return thisToken; } // attributes @@ -308,12 +308,12 @@ public: IdentifierExpression(const QStringRef &n): name (n) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return identifierToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return identifierToken; } // attributes @@ -328,12 +328,12 @@ public: NullExpression() { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return nullToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return nullToken; } // attributes @@ -347,12 +347,12 @@ public: TrueLiteral() { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return trueToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return trueToken; } // attributes @@ -366,12 +366,12 @@ public: FalseLiteral() { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return falseToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return falseToken; } // attributes @@ -386,12 +386,12 @@ public: NumericLiteral(double v): value(v) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return literalToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return literalToken; } // attributes: @@ -407,12 +407,12 @@ public: StringLiteral(const QStringRef &v): value (v) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return literalToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return literalToken; } // attributes: @@ -428,12 +428,12 @@ public: RegExpLiteral(const QStringRef &p, int f): pattern (p), flags (f) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return literalToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return literalToken; } // attributes: @@ -459,12 +459,12 @@ public: elements (elts), elision (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return lbracketToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rbracketToken; } // attributes @@ -486,12 +486,12 @@ public: ObjectLiteral(PropertyNameAndValueList *plist): properties (plist) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return lbraceToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rbraceToken; } // attributes @@ -515,12 +515,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return commaToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : commaToken; } inline Elision *finish () @@ -559,16 +559,16 @@ public: return front; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { if (elision) return elision->firstSourceLocation(); return expression->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { if (next) return next->lastSourceLocation(); @@ -589,10 +589,10 @@ public: PropertyName() { kind = K; } - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return propertyNameToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return propertyNameToken; } // attributes @@ -616,12 +616,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return name->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { if (next) return next->lastSourceLocation(); @@ -651,7 +651,7 @@ public: IdentifierPropertyName(const QStringRef &n): id (n) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; // attributes QStringRef id; @@ -665,7 +665,7 @@ public: StringLiteralPropertyName(const QStringRef &n): id (n) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; // attributes QStringRef id; @@ -679,7 +679,7 @@ public: NumericLiteralPropertyName(double n): id (n) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; // attributes double id; @@ -694,12 +694,12 @@ public: base (b), expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return base->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rbracketToken; } // attributes @@ -718,12 +718,12 @@ public: base (b), name (n) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return base->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return identifierToken; } // attributes @@ -742,12 +742,12 @@ public: base (b), arguments (a) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return newToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rparenToken; } // attributes @@ -766,12 +766,12 @@ public: NewExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return newToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); } // attributes @@ -788,12 +788,12 @@ public: base (b), arguments (a) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return base->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rparenToken; } // attributes @@ -820,12 +820,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return expression->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { if (next) return next->lastSourceLocation(); @@ -853,12 +853,12 @@ public: PostIncrementExpression(ExpressionNode *b): base (b) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return base->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return incrementToken; } // attributes @@ -874,12 +874,12 @@ public: PostDecrementExpression(ExpressionNode *b): base (b) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return base->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return decrementToken; } // attributes @@ -895,12 +895,12 @@ public: DeleteExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return deleteToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); } // attributes @@ -916,12 +916,12 @@ public: VoidExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return voidToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); } // attributes @@ -937,12 +937,12 @@ public: TypeOfExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return typeofToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); } // attributes @@ -958,12 +958,12 @@ public: PreIncrementExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return incrementToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); } // attributes @@ -979,12 +979,12 @@ public: PreDecrementExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return decrementToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); } // attributes @@ -1000,12 +1000,12 @@ public: UnaryPlusExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return plusToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); } // attributes @@ -1021,12 +1021,12 @@ public: UnaryMinusExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return minusToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); } // attributes @@ -1042,12 +1042,12 @@ public: TildeExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return tildeToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); } // attributes @@ -1063,12 +1063,12 @@ public: NotExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return notToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression->lastSourceLocation(); } // attributes @@ -1085,14 +1085,14 @@ public: left (l), op (o), right (r) { kind = K; } - virtual BinaryExpression *binaryExpressionCast(); + BinaryExpression *binaryExpressionCast() override; - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return left->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return right->lastSourceLocation(); } // attributes @@ -1111,12 +1111,12 @@ public: expression (e), ok (t), ko (f) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return expression->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return ko->lastSourceLocation(); } // attributes @@ -1135,12 +1135,12 @@ public: Expression(ExpressionNode *l, ExpressionNode *r): left (l), right (r) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return left->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return right->lastSourceLocation(); } // attributes @@ -1157,12 +1157,12 @@ public: Block(StatementList *slist): statements (slist) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return lbraceToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rbraceToken; } // attributes @@ -1188,12 +1188,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return statement->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : statement->lastSourceLocation(); } inline StatementList *finish () @@ -1217,12 +1217,12 @@ public: declarations (vlist) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return declarationKindToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return semicolonToken; } // attributes @@ -1240,12 +1240,12 @@ public: name (n), expression (e), readOnly(false) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return identifierToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return expression ? expression->lastSourceLocation() : identifierToken; } // attributes @@ -1272,12 +1272,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return declaration->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { if (next) return next->lastSourceLocation(); @@ -1309,12 +1309,12 @@ public: EmptyStatement() { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return semicolonToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return semicolonToken; } // attributes @@ -1329,12 +1329,12 @@ public: ExpressionStatement(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return expression->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return semicolonToken; } // attributes @@ -1351,12 +1351,12 @@ public: expression (e), ok (t), ko (f) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return ifToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { if (ko) return ko->lastSourceLocation(); @@ -1383,12 +1383,12 @@ public: statement (stmt), expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return doToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return semicolonToken; } // attributes @@ -1410,12 +1410,12 @@ public: expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return whileToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } // attributes @@ -1435,12 +1435,12 @@ public: initialiser (i), condition (c), expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return forToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } // attributes @@ -1464,12 +1464,12 @@ public: declarations (vlist), condition (c), expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return forToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } // attributes @@ -1494,12 +1494,12 @@ public: initialiser (i), expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return forToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } // attributes @@ -1521,12 +1521,12 @@ public: declaration (v), expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return forToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } // attributes @@ -1548,12 +1548,12 @@ public: ContinueStatement(const QStringRef &l = QStringRef()): label (l) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return continueToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return semicolonToken; } // attributes @@ -1571,12 +1571,12 @@ public: BreakStatement(const QStringRef &l): label (l) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return breakToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return semicolonToken; } // attributes @@ -1594,12 +1594,12 @@ public: ReturnStatement(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return returnToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return semicolonToken; } // attributes @@ -1617,12 +1617,12 @@ public: expression (e), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return withToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } // attributes @@ -1642,12 +1642,12 @@ public: clauses (c), defaultClause (d), moreClauses (r) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return lbraceToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rbraceToken; } // attributes @@ -1667,12 +1667,12 @@ public: expression (e), block (b) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return switchToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return block->rbraceToken; } // attributes @@ -1692,12 +1692,12 @@ public: expression (e), statements (slist) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return caseToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statements ? statements->lastSourceLocation() : colonToken; } // attributes @@ -1724,12 +1724,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return clause->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : clause->lastSourceLocation(); } inline CaseClauses *finish () @@ -1753,12 +1753,12 @@ public: statements (slist) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return defaultToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statements ? statements->lastSourceLocation() : colonToken; } // attributes @@ -1776,12 +1776,12 @@ public: label (l), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return identifierToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } // attributes @@ -1799,12 +1799,12 @@ public: ThrowStatement(ExpressionNode *e): expression (e) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return throwToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return semicolonToken; } // attributes @@ -1822,12 +1822,12 @@ public: name (n), statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return catchToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } // attributes @@ -1848,12 +1848,12 @@ public: statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return finallyToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement ? statement->lastSourceLocation() : finallyToken; } // attributes @@ -1878,12 +1878,12 @@ public: statement (stmt), catchExpression (c), finallyExpression (nullptr) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return tryToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { if (finallyExpression) return finallyExpression->statement->rbraceToken; @@ -1909,12 +1909,12 @@ public: name (n), formals (f), body (b) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return functionToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rbraceToken; } // attributes @@ -1938,7 +1938,7 @@ public: FunctionExpression(n, f, b) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; }; class QML_PARSER_EXPORT FormalParameterList: public Node @@ -1958,12 +1958,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return identifierToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : identifierToken; } inline FormalParameterList *finish () @@ -2006,12 +2006,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return element->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : element->lastSourceLocation(); } inline SourceElements *finish () @@ -2035,12 +2035,12 @@ public: elements (elts) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return elements ? elements->firstSourceLocation() : SourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return elements ? elements->lastSourceLocation() : SourceLocation(); } // attributes @@ -2056,12 +2056,12 @@ public: elements (elts) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return elements ? elements->firstSourceLocation() : SourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return elements ? elements->lastSourceLocation() : SourceLocation(); } // attributes @@ -2077,12 +2077,12 @@ public: declaration (f) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return declaration->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return declaration->lastSourceLocation(); } // attributes @@ -2098,12 +2098,12 @@ public: statement (stmt) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return statement->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } // attributes @@ -2118,12 +2118,12 @@ public: DebuggerStatement() { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return debuggerToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return semicolonToken; } // attributes @@ -2155,12 +2155,12 @@ public: return head; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return identifierToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : identifierToken; } // attributes @@ -2182,12 +2182,12 @@ public: : importUri(uri) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return importToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return semicolonToken; } // attributes @@ -2227,12 +2227,12 @@ public: return head; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return import->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : import->lastSourceLocation(); } // attributes @@ -2243,10 +2243,10 @@ public: class QML_PARSER_EXPORT UiObjectMember: public Node { public: - virtual SourceLocation firstSourceLocation() const = 0; - virtual SourceLocation lastSourceLocation() const = 0; + SourceLocation firstSourceLocation() const override = 0; + SourceLocation lastSourceLocation() const override = 0; - virtual UiObjectMember *uiObjectMemberCast(); + UiObjectMember *uiObjectMemberCast() override; }; class QML_PARSER_EXPORT UiObjectMemberList: public Node @@ -2266,12 +2266,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return member->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : member->lastSourceLocation(); } UiObjectMemberList *finish() @@ -2295,9 +2295,9 @@ public: : imports(imports), members(members) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { if (imports) return imports->firstSourceLocation(); @@ -2306,7 +2306,7 @@ public: return SourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { if (members) return members->lastSourceLocation(); @@ -2337,12 +2337,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return member->firstSourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : member->lastSourceLocation(); } UiArrayMemberList *finish() @@ -2367,12 +2367,12 @@ public: : members(members) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return lbraceToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rbraceToken; } // attributes @@ -2398,12 +2398,12 @@ public: previous->next = this; } - virtual void accept0(Visitor *) {} + void accept0(Visitor *) override {} - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return propertyTypeToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : identifierToken; } inline UiParameterList *finish () @@ -2438,9 +2438,9 @@ public: : type(Property), memberType(memberType), name(name), statement(statement), binding(nullptr), isDefaultMember(false), isReadonlyMember(false), parameters(nullptr) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { if (defaultToken.isValid()) return defaultToken; @@ -2450,7 +2450,7 @@ public: return propertyToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { if (binding) return binding->lastSourceLocation(); @@ -2490,12 +2490,12 @@ public: : qualifiedTypeNameId(qualifiedTypeNameId), initializer(initializer) { kind = K; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return qualifiedTypeNameId->identifierToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return initializer->rbraceToken; } // attributes @@ -2512,27 +2512,27 @@ public: : sourceElement(sourceElement) { kind = K; } - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { - if (FunctionDeclaration *funDecl = cast<FunctionDeclaration *>(sourceElement)) + if (const auto funDecl = cast<const FunctionDeclaration *>(sourceElement)) return funDecl->firstSourceLocation(); - else if (VariableStatement *varStmt = cast<VariableStatement *>(sourceElement)) + else if (const auto varStmt = cast<const VariableStatement *>(sourceElement)) return varStmt->firstSourceLocation(); return SourceLocation(); } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { - if (FunctionDeclaration *funDecl = cast<FunctionDeclaration *>(sourceElement)) + if (const auto funDecl = cast<const FunctionDeclaration *>(sourceElement)) return funDecl->lastSourceLocation(); - else if (VariableStatement *varStmt = cast<VariableStatement *>(sourceElement)) + else if (const auto varStmt = cast<const VariableStatement *>(sourceElement)) return varStmt->lastSourceLocation(); return SourceLocation(); } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; // attributes @@ -2553,7 +2553,7 @@ public: hasOnToken(false) { kind = K; } - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { if (hasOnToken && qualifiedTypeNameId) return qualifiedTypeNameId->identifierToken; @@ -2561,10 +2561,10 @@ public: return qualifiedId->identifierToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return initializer->rbraceToken; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; // attributes @@ -2586,13 +2586,13 @@ public: statement(statement) { kind = K; } - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return qualifiedId->identifierToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; // attributes UiQualifiedId *qualifiedId; @@ -2611,13 +2611,13 @@ public: members(members) { kind = K; } - virtual SourceLocation firstSourceLocation() const + SourceLocation firstSourceLocation() const override { return qualifiedId->identifierToken; } - virtual SourceLocation lastSourceLocation() const + SourceLocation lastSourceLocation() const override { return rbracketToken; } - virtual void accept0(Visitor *visitor); + void accept0(Visitor *visitor) override; // attributes UiQualifiedId *qualifiedId; diff --git a/src/lib/corelib/parser/qmljsparser.cpp b/src/lib/corelib/parser/qmljsparser.cpp index 71cff876d..6390c8a9d 100644 --- a/src/lib/corelib/parser/qmljsparser.cpp +++ b/src/lib/corelib/parser/qmljsparser.cpp @@ -114,13 +114,13 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr) QVarLengthArray<AST::SourceLocation, 4> locations; AST::ExpressionNode *it = expr; - while (AST::FieldMemberExpression *m = AST::cast<AST::FieldMemberExpression *>(it)) { + while (const auto m = AST::cast<AST::FieldMemberExpression *>(it)) { nameIds.append(m->name); locations.append(m->identifierToken); it = m->base; } - if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(it)) { + if (const auto idExpr = AST::cast<AST::IdentifierExpression *>(it)) { const auto q = new (pool) AST::UiQualifiedId(idExpr->name); q->identifierToken = idExpr->identifierToken; @@ -1150,7 +1150,7 @@ case 212: { } break; case 214: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, + const auto node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::And, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; diff --git a/src/lib/corelib/parser/qmljsparser_p.h b/src/lib/corelib/parser/qmljsparser_p.h index 05e22074b..c761bb25b 100644 --- a/src/lib/corelib/parser/qmljsparser_p.h +++ b/src/lib/corelib/parser/qmljsparser_p.h @@ -212,13 +212,13 @@ protected: enum { TOKEN_BUFFER_SIZE = 3 }; struct SavedToken { - int token; - double dval; + int token = 0; + double dval = 0.0; AST::SourceLocation loc; QStringRef spell; }; - double yylval; + double yylval = 0.0; QStringRef yytokenspell; AST::SourceLocation yylloc; AST::SourceLocation yyprevlloc; diff --git a/src/lib/corelib/tools/applecodesignutils.cpp b/src/lib/corelib/tools/applecodesignutils.cpp index 67c4f5238..feae266bf 100644 --- a/src/lib/corelib/tools/applecodesignutils.cpp +++ b/src/lib/corelib/tools/applecodesignutils.cpp @@ -80,7 +80,8 @@ QVariantMap certificateInfo(const QByteArray &data) // Also potentially useful, but these are for signing pkgs which aren't used here // 1.2.840.113635.100.4.9 - 3rd Party Mac Developer Installer: <name> // 1.2.840.113635.100.4.13 - Developer ID Installer: <name> - for (const auto &extension : cert.extensions()) { + const auto extensions = cert.extensions(); + for (const auto &extension : extensions) { if (extension.name() == QStringLiteral("extendedKeyUsage")) { if (!extension.value().toStringList().contains(QStringLiteral("Code Signing"))) return {}; @@ -89,7 +90,8 @@ QVariantMap certificateInfo(const QByteArray &data) const auto subjectInfo = [](const QSslCertificate &cert) { QVariantMap map; - for (const auto &attr : cert.subjectInfoAttributes()) + const auto attributes = cert.subjectInfoAttributes(); + for (const auto &attr : attributes) map.insert(QString::fromUtf8(attr), cert.subjectInfo(attr).front()); return map; }; diff --git a/src/lib/corelib/tools/buildgraphlocker.cpp b/src/lib/corelib/tools/buildgraphlocker.cpp index c166c6e2d..28a58e3f4 100644 --- a/src/lib/corelib/tools/buildgraphlocker.cpp +++ b/src/lib/corelib/tools/buildgraphlocker.cpp @@ -55,8 +55,8 @@ namespace qbs { namespace Internal { -DirectoryManager::DirectoryManager(const QString &dir, const Logger &logger) - : m_dir(dir), m_logger(logger) +DirectoryManager::DirectoryManager(QString dir, Logger logger) + : m_dir(std::move(dir)), m_logger(std::move(logger)) { rememberCreatedDirectories(); } diff --git a/src/lib/corelib/tools/buildgraphlocker.h b/src/lib/corelib/tools/buildgraphlocker.h index 17d452130..f85fc0768 100644 --- a/src/lib/corelib/tools/buildgraphlocker.h +++ b/src/lib/corelib/tools/buildgraphlocker.h @@ -55,7 +55,7 @@ class ProgressObserver; class DirectoryManager { public: - DirectoryManager(const QString &dir, const Logger &logger); + DirectoryManager(QString dir, Logger logger); ~DirectoryManager(); QString dir() const { return m_dir; } diff --git a/src/lib/corelib/tools/codelocation.cpp b/src/lib/corelib/tools/codelocation.cpp index 57b577711..2c6ade3b0 100644 --- a/src/lib/corelib/tools/codelocation.cpp +++ b/src/lib/corelib/tools/codelocation.cpp @@ -68,8 +68,8 @@ public: } QString filePath; - int line; - int column; + int line = 0; + int column = 0; }; CodeLocation::CodeLocation() diff --git a/src/lib/corelib/tools/executablefinder.cpp b/src/lib/corelib/tools/executablefinder.cpp index 7c5d1210e..4342c82f0 100644 --- a/src/lib/corelib/tools/executablefinder.cpp +++ b/src/lib/corelib/tools/executablefinder.cpp @@ -64,10 +64,9 @@ static QStringList populateExecutableSuffixes() QStringList ExecutableFinder::m_executableSuffixes = populateExecutableSuffixes(); -ExecutableFinder::ExecutableFinder(const ResolvedProductPtr &m_product, - const QProcessEnvironment &env) - : m_product(m_product) - , m_environment(env) +ExecutableFinder::ExecutableFinder(ResolvedProductPtr product, QProcessEnvironment env) + : m_product(std::move(product)) + , m_environment(std::move(env)) { } diff --git a/src/lib/corelib/tools/executablefinder.h b/src/lib/corelib/tools/executablefinder.h index cb965b5d1..9467756fc 100644 --- a/src/lib/corelib/tools/executablefinder.h +++ b/src/lib/corelib/tools/executablefinder.h @@ -53,7 +53,7 @@ namespace Internal { class ExecutableFinder { public: - ExecutableFinder(const ResolvedProductPtr &product, const QProcessEnvironment &env); + ExecutableFinder(ResolvedProductPtr product, QProcessEnvironment env); QString findExecutable(const QString &path, const QString &workingDirPath); @@ -68,7 +68,7 @@ private: void cacheFilePath(const QString &filePaht, const QString &filePath) const; ResolvedProductPtr m_product; - const QProcessEnvironment &m_environment; + const QProcessEnvironment m_environment; }; } // namespace Internal diff --git a/src/lib/corelib/tools/fileinfo.cpp b/src/lib/corelib/tools/fileinfo.cpp index cec6b2660..8b0eedc27 100644 --- a/src/lib/corelib/tools/fileinfo.cpp +++ b/src/lib/corelib/tools/fileinfo.cpp @@ -404,8 +404,9 @@ bool removeFileRecursion(const QFileInfo &f, QString *errorMessage) const QDir dir(f.absoluteFilePath()); // QDir::System is needed for broken symlinks. - for (const QFileInfo &fi : dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot - | QDir::Hidden | QDir::System)) + const auto fileInfos = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot + | QDir::Hidden | QDir::System); + for (const QFileInfo &fi : fileInfos) removeFileRecursion(fi, errorMessage); QDir parent = f.absoluteDir(); if (!parent.rmdir(f.fileName())) { diff --git a/src/lib/corelib/tools/fileinfo.h b/src/lib/corelib/tools/fileinfo.h index 723d83424..9813b69a7 100644 --- a/src/lib/corelib/tools/fileinfo.h +++ b/src/lib/corelib/tools/fileinfo.h @@ -96,7 +96,7 @@ private: #else # error unknown platform #endif - InternalStatType m_stat; + InternalStatType m_stat{}; }; bool removeFileRecursion(const QFileInfo &f, QString *errorMessage); diff --git a/src/lib/corelib/tools/filesaver.cpp b/src/lib/corelib/tools/filesaver.cpp index 0fd652657..5a0a68c1f 100644 --- a/src/lib/corelib/tools/filesaver.cpp +++ b/src/lib/corelib/tools/filesaver.cpp @@ -48,8 +48,8 @@ namespace qbs { namespace Internal { -FileSaver::FileSaver(const std::string &filePath, bool overwriteIfUnchanged) - : m_filePath(filePath), m_overwriteIfUnchanged(overwriteIfUnchanged) +FileSaver::FileSaver(std::string filePath, bool overwriteIfUnchanged) + : m_filePath(std::move(filePath)), m_overwriteIfUnchanged(overwriteIfUnchanged) { } diff --git a/src/lib/corelib/tools/filesaver.h b/src/lib/corelib/tools/filesaver.h index 275ad0f01..8b4c01669 100644 --- a/src/lib/corelib/tools/filesaver.h +++ b/src/lib/corelib/tools/filesaver.h @@ -55,7 +55,7 @@ namespace Internal { */ class QBS_EXPORT FileSaver { public: - FileSaver(const std::string &filePath, bool overwriteIfUnchanged = false); + FileSaver(std::string filePath, bool overwriteIfUnchanged = false); std::ostream *device(); bool open(); diff --git a/src/lib/corelib/tools/filetime.h b/src/lib/corelib/tools/filetime.h index 7daec6415..f9a15f794 100644 --- a/src/lib/corelib/tools/filetime.h +++ b/src/lib/corelib/tools/filetime.h @@ -115,7 +115,7 @@ public: } private: - InternalType m_fileTime; + InternalType m_fileTime{}; }; } // namespace Internal diff --git a/src/lib/corelib/tools/hostosinfo.h b/src/lib/corelib/tools/hostosinfo.h index cae451638..d7f718c19 100644 --- a/src/lib/corelib/tools/hostosinfo.h +++ b/src/lib/corelib/tools/hostosinfo.h @@ -74,6 +74,7 @@ public: enum HostOs { HostOsWindows, HostOsLinux, HostOsMacos, HostOsOtherUnix, HostOsOther }; static inline std::string hostOSIdentifier(); + static inline std::string hostOSArchitecture(); static inline std::vector<std::string> hostOSIdentifiers(); static inline std::vector<std::string> canonicalOSIdentifiers(const std::string &os); static inline HostOs hostOs(); @@ -177,6 +178,14 @@ std::string HostOsInfo::hostOSIdentifier() #endif } +std::string HostOsInfo::hostOSArchitecture() +{ + const auto cpuArch = QSysInfo::currentCpuArchitecture(); + if (cpuArch == QLatin1String("i386")) + return "x86"; + return cpuArch.toStdString(); +} + std::vector<std::string> HostOsInfo::hostOSIdentifiers() { return canonicalOSIdentifiers(hostOSIdentifier()); diff --git a/src/lib/corelib/tools/id.cpp b/src/lib/corelib/tools/id.cpp index 9d31d3776..6dd1147f2 100644 --- a/src/lib/corelib/tools/id.cpp +++ b/src/lib/corelib/tools/id.cpp @@ -69,9 +69,7 @@ namespace Internal { class StringHolder { public: - StringHolder() - : n(0), str(nullptr) - {} + StringHolder() = default; StringHolder(const char *s, int length) : n(length), str(s) @@ -85,9 +83,9 @@ public: h &= 0x0fffffff; } } - int n; - const char *str; - uint h; + int n = 0; + const char *str = nullptr; + uint h = 0; }; static bool operator==(const StringHolder &sh1, const StringHolder &sh2) diff --git a/src/lib/corelib/tools/joblimits.cpp b/src/lib/corelib/tools/joblimits.cpp index 3b1fde83d..912b15a65 100644 --- a/src/lib/corelib/tools/joblimits.cpp +++ b/src/lib/corelib/tools/joblimits.cpp @@ -118,8 +118,7 @@ JobLimits::~JobLimits() {} void JobLimits::setJobLimit(const JobLimit &limit) { - for (std::size_t i = 0; i < d->jobLimits.size(); ++i) { - JobLimit ¤tLimit = d->jobLimits.at(i); + for (auto ¤tLimit : d->jobLimits) { if (currentLimit.pool() == limit.pool()) { if (currentLimit.limit() != limit.limit()) currentLimit = limit; diff --git a/src/lib/corelib/tools/jsliterals.cpp b/src/lib/corelib/tools/jsliterals.cpp index bf9720493..74328006c 100644 --- a/src/lib/corelib/tools/jsliterals.cpp +++ b/src/lib/corelib/tools/jsliterals.cpp @@ -77,7 +77,8 @@ QString toJSLiteral(const QVariant &val) return Internal::StringConstants::undefinedValue(); if (val.type() == QVariant::List || val.type() == QVariant::StringList) { QString res; - for (const QVariant &child : val.toList()) { + const auto list = val.toList(); + for (const QVariant &child : list) { if (res.length()) res.append(QLatin1String(", ")); res.append(toJSLiteral(child)); } diff --git a/src/lib/corelib/tools/launcherinterface.cpp b/src/lib/corelib/tools/launcherinterface.cpp index b16c8563c..f4e80c5e2 100644 --- a/src/lib/corelib/tools/launcherinterface.cpp +++ b/src/lib/corelib/tools/launcherinterface.cpp @@ -67,7 +67,7 @@ private: void setupChildProcess() override { #ifdef Q_OS_UNIX - const pid_t pid = static_cast<pid_t>(processId()); + const auto pid = static_cast<pid_t>(processId()); setpgid(pid, pid); #endif } diff --git a/src/lib/corelib/tools/launcherinterface.h b/src/lib/corelib/tools/launcherinterface.h index c497e7415..f3aca9bf4 100644 --- a/src/lib/corelib/tools/launcherinterface.h +++ b/src/lib/corelib/tools/launcherinterface.h @@ -57,7 +57,7 @@ class LauncherInterface : public QObject Q_OBJECT public: static LauncherInterface &instance(); - ~LauncherInterface(); + ~LauncherInterface() override; static void startLauncher() { instance().doStart(); } static void stopLauncher() { instance().doStop(); } diff --git a/src/lib/corelib/tools/launcherpackets.h b/src/lib/corelib/tools/launcherpackets.h index 0988761e7..4306718fd 100644 --- a/src/lib/corelib/tools/launcherpackets.h +++ b/src/lib/corelib/tools/launcherpackets.h @@ -73,8 +73,8 @@ public: private: QDataStream m_stream; - LauncherPacketType m_type; - quintptr m_token; + LauncherPacketType m_type = LauncherPacketType::Shutdown; + quintptr m_token = 0; QByteArray m_packetData; int m_sizeOfNextPacket = -1; }; @@ -95,7 +95,7 @@ public: void deserialize(const QByteArray &data); const LauncherPacketType type; - const quintptr token; + const quintptr token = 0; protected: LauncherPacket(LauncherPacketType type, quintptr token) : type(type), token(token) { } @@ -161,9 +161,9 @@ public: QString errorString; QByteArray stdOut; QByteArray stdErr; - QProcess::ExitStatus exitStatus; - QProcess::ProcessError error; - int exitCode; + QProcess::ExitStatus exitStatus = QProcess::ExitStatus::NormalExit; + QProcess::ProcessError error = QProcess::ProcessError::UnknownError; + int exitCode = 0; private: void doSerialize(QDataStream &stream) const override; diff --git a/src/lib/corelib/tools/msvcinfo.cpp b/src/lib/corelib/tools/msvcinfo.cpp index f51ba8ba2..cffec85b2 100644 --- a/src/lib/corelib/tools/msvcinfo.cpp +++ b/src/lib/corelib/tools/msvcinfo.cpp @@ -70,7 +70,8 @@ public: TemporaryEnvChanger(const QProcessEnvironment &envChanges) : m_locker(envMutex) { QProcessEnvironment currentEnv = QProcessEnvironment::systemEnvironment(); - for (const QString &key : envChanges.keys()) { + const auto keys = envChanges.keys(); + for (const QString &key : keys) { m_changesToRestore.insert(key, currentEnv.value(key)); qputenv(qPrintable(key), qPrintable(envChanges.value(key))); } @@ -78,7 +79,8 @@ public: ~TemporaryEnvChanger() { - for (const QString &key : m_changesToRestore.keys()) + const auto keys = m_changesToRestore.keys(); + for (const QString &key : keys) qputenv(qPrintable(key), qPrintable(m_changesToRestore.value(key))); } @@ -119,7 +121,7 @@ static QByteArray runProcess(const QString &exeFilePath, const QStringList &args class DummyFile { public: - DummyFile(const QString &fp) : filePath(fp) { } + DummyFile(QString fp) : filePath(std::move(fp)) { } ~DummyFile() { QFile::remove(filePath); } const QString filePath; }; @@ -196,11 +198,88 @@ static QVariantMap getMsvcDefines(const QString &compilerFilePath, #endif } +/*! + \internal + clang-cl does not support gcc and msvc ways to dump a macros, so we have to use original + clang.exe directly +*/ +static QVariantMap getClangClDefines( + const QString &compilerFilePath, + const QProcessEnvironment &compilerEnv, + MSVC::CompilerLanguage language) +{ +#ifdef Q_OS_WIN + QFileInfo clInfo(compilerFilePath); + QFileInfo clangInfo(clInfo.absolutePath() + QLatin1String("/clang.exe")); + if (!clangInfo.exists()) + throw ErrorInfo(QStringLiteral("%1 does not exist").arg(clangInfo.absoluteFilePath())); + + QString languageSwitch; + switch (language) { + case MSVC::CLanguage: + languageSwitch = QStringLiteral("c"); + break; + case MSVC::CPlusPlusLanguage: + languageSwitch = QStringLiteral("c++"); + break; + } + QStringList args = { + QStringLiteral("-dM"), + QStringLiteral("-E"), + QStringLiteral("-x"), + languageSwitch, + QStringLiteral("NUL"), + }; + const auto lines = QString::fromLocal8Bit( + runProcess( + clangInfo.absoluteFilePath(), + args, + compilerEnv, + true)).split(QLatin1Char('\n')); + QVariantMap result; + for (const auto &line: lines) { + static const auto defineString = QLatin1String("#define "); + if (!line.startsWith(defineString)) { + throw ErrorInfo(QStringLiteral("Unexpected compiler frontend output: ") + + lines.join(QLatin1Char('\n'))); + } + QStringView view(line.data() + defineString.size()); + const auto it = std::find(view.begin(), view.end(), QLatin1Char(' ')); + if (it == view.end()) { + throw ErrorInfo(QStringLiteral("Unexpected compiler frontend output: ") + + lines.join(QLatin1Char('\n'))); + } + QStringView key(view.begin(), it); + QStringView value(it + 1, view.end()); + result.insert(key.toString(), value.isEmpty() ? QVariant() : QVariant(value.toString())); + } + return result; +#else + Q_UNUSED(compilerFilePath); + Q_UNUSED(compilerEnv); + Q_UNUSED(language); + return {}; +#endif +} + void MSVC::init() { determineCompilerVersion(); } +/*! + \internal + Returns the architecture detected from the compiler path. +*/ +QString MSVC::architectureFromClPath(const QString &clPath) +{ + const auto parentDir = QFileInfo(clPath).absolutePath(); + const auto parentDirName = QFileInfo(parentDir).fileName().toLower(); + if (parentDirName == QLatin1String("bin")) + return QStringLiteral("x86"); + return parentDirName; +} + QString MSVC::binPathForArchitecture(const QString &arch) const { QString archSubDir; @@ -220,6 +299,9 @@ QString MSVC::clPathForArchitecture(const QString &arch) const QVariantMap MSVC::compilerDefines(const QString &compilerFilePath, MSVC::CompilerLanguage language) const { + const auto compilerName = QFileInfo(compilerFilePath).fileName().toLower(); + if (compilerName == QLatin1String("clang-cl.exe")) + return getClangClDefines(compilerFilePath, environment, language); return getMsvcDefines(compilerFilePath, environment, language); } diff --git a/src/lib/corelib/tools/msvcinfo.h b/src/lib/corelib/tools/msvcinfo.h index 61a19dc4f..b5cf04e84 100644 --- a/src/lib/corelib/tools/msvcinfo.h +++ b/src/lib/corelib/tools/msvcinfo.h @@ -77,20 +77,19 @@ public: MSVC() { } - MSVC(const QString &clPath) + MSVC(const QString &clPath, QString arch): + architecture(std::move(arch)) { QDir parentDir = QFileInfo(clPath).dir(); binPath = parentDir.absolutePath(); QString parentDirName = parentDir.dirName().toLower(); - if (parentDirName == QLatin1String("bin")) - parentDirName = QStringLiteral("x86"); - else + if (parentDirName != QLatin1String("bin")) parentDir.cdUp(); - architecture = parentDirName; vcInstallPath = parentDir.path(); } QBS_EXPORT void init(); + QBS_EXPORT static QString architectureFromClPath(const QString &clPath); QBS_EXPORT QString binPathForArchitecture(const QString &arch) const; QBS_EXPORT QString clPathForArchitecture(const QString &arch) const; QBS_EXPORT QVariantMap compilerDefines(const QString &compilerFilePath, @@ -103,7 +102,7 @@ private: class WinSDK : public MSVC { public: - bool isDefault; + bool isDefault = false; WinSDK() { diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp index dfa7fb683..3b69926f6 100644 --- a/src/lib/corelib/tools/persistence.cpp +++ b/src/lib/corelib/tools/persistence.cpp @@ -150,7 +150,7 @@ void PersistentPool::closeStream() void PersistentPool::storeVariant(const QVariant &variant) { - const quint32 type = static_cast<quint32>(variant.type()); + const auto type = static_cast<quint32>(variant.type()); m_stream << type; switch (type) { case QMetaType::QString: @@ -172,7 +172,7 @@ void PersistentPool::storeVariant(const QVariant &variant) QVariant PersistentPool::loadVariant() { - const quint32 type = load<quint32>(); + const auto type = load<quint32>(); QVariant value; switch (type) { case QMetaType::QString: diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h index 6be0ae8e4..4bda59f7c 100644 --- a/src/lib/corelib/tools/persistence.h +++ b/src/lib/corelib/tools/persistence.h @@ -171,18 +171,18 @@ private: HeadData m_headData; std::vector<void *> m_loadedRaw; std::vector<std::shared_ptr<void>> m_loaded; - QHash<const void*, int> m_storageIndices; - PersistentObjectId m_lastStoredObjectId; + std::unordered_map<const void*, int> m_storageIndices; + PersistentObjectId m_lastStoredObjectId = 0; std::vector<QString> m_stringStorage; QHash<QString, int> m_inverseStringStorage; - PersistentObjectId m_lastStoredStringId; + PersistentObjectId m_lastStoredStringId = 0; std::vector<QProcessEnvironment> m_envStorage; QHash<QProcessEnvironment, int> m_inverseEnvStorage; - PersistentObjectId m_lastStoredEnvId; + PersistentObjectId m_lastStoredEnvId = 0; std::vector<QStringList> m_stringListStorage; QHash<QStringList, int> m_inverseStringListStorage; - PersistentObjectId m_lastStoredStringListId; + PersistentObjectId m_lastStoredStringListId = 0; Logger &m_logger; template<typename T, typename Enable> @@ -198,14 +198,14 @@ template<typename T> inline void PersistentPool::storeSharedObject(const T *obje return; } const void * const addr = uniqueAddress(object); - PersistentObjectId id = m_storageIndices.value(addr, -1); - if (id < 0) { - id = m_lastStoredObjectId++; - m_storageIndices.insert(addr, id); + const auto found = m_storageIndices.find(addr); + if (found == m_storageIndices.end()) { + PersistentObjectId id = m_lastStoredObjectId++; + m_storageIndices[addr] = id; m_stream << id; store(*object); } else { - m_stream << id; + m_stream << found->second; } } diff --git a/src/lib/corelib/tools/preferences.cpp b/src/lib/corelib/tools/preferences.cpp index ca3fe8378..4db271758 100644 --- a/src/lib/corelib/tools/preferences.cpp +++ b/src/lib/corelib/tools/preferences.cpp @@ -1,3 +1,5 @@ +#include <utility> + /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. @@ -51,13 +53,13 @@ namespace qbs { * If a non-empty \c profileName is given, the profile's preferences take precedence over global * ones. Otherwise, the global preferences are used. */ -Preferences::Preferences(Settings *settings, const QString &profileName) - : m_settings(settings), m_profile(profileName) +Preferences::Preferences(Settings *settings, QString profileName) + : m_settings(settings), m_profile(std::move(profileName)) { } -Preferences::Preferences(Settings *settings, const QVariantMap &profileContents) - : m_settings(settings), m_profileContents(profileContents) +Preferences::Preferences(Settings *settings, QVariantMap profileContents) + : m_settings(settings), m_profileContents(std::move(profileContents)) { } @@ -131,14 +133,16 @@ JobLimits Preferences::jobLimits() const { const QString prefix = QStringLiteral("preferences.jobLimit"); JobLimits limits; - for (const QString &key : m_settings->allKeysWithPrefix(prefix, Settings::allScopes())) { + const auto keys = m_settings->allKeysWithPrefix(prefix, Settings::allScopes()); + for (const QString &key : keys) { limits.setJobLimit(key, m_settings->value(prefix + QLatin1Char('.') + key, Settings::allScopes()).toInt()); } const QString fullPrefix = prefix + QLatin1Char('.'); if (!m_profile.isEmpty()) { Profile p(m_profile, m_settings, m_profileContents); - for (const QString &key : p.allKeys(Profile::KeySelectionRecursive)) { + const auto keys = p.allKeys(Profile::KeySelectionRecursive); + for (const QString &key : keys) { if (!key.startsWith(fullPrefix)) continue; const QString jobPool = key.mid(fullPrefix.size()); diff --git a/src/lib/corelib/tools/preferences.h b/src/lib/corelib/tools/preferences.h index 661b39d7f..2824ebf2c 100644 --- a/src/lib/corelib/tools/preferences.h +++ b/src/lib/corelib/tools/preferences.h @@ -54,8 +54,8 @@ class Settings; class QBS_EXPORT Preferences { public: - explicit Preferences(Settings *settings, const QString &profileName = QString()); - Preferences(Settings *settings, const QVariantMap &profileContents); + explicit Preferences(Settings *settings, QString profileName = QString()); + Preferences(Settings *settings, QVariantMap profileContents); bool useColoredOutput() const; int jobs() const; diff --git a/src/lib/corelib/tools/processresult_p.h b/src/lib/corelib/tools/processresult_p.h index 141dd9301..69ccb8598 100644 --- a/src/lib/corelib/tools/processresult_p.h +++ b/src/lib/corelib/tools/processresult_p.h @@ -48,14 +48,14 @@ namespace Internal { class ProcessResultPrivate : public QSharedData { public: - bool success; + bool success = false; QString executableFilePath; QStringList arguments; QString workingDirectory; - QProcess::ProcessError error; - int exitCode; + QProcess::ProcessError error = QProcess::ProcessError::UnknownError; + int exitCode = 0; QStringList stdOut; QStringList stdErr; }; diff --git a/src/lib/corelib/tools/processutils.cpp b/src/lib/corelib/tools/processutils.cpp index 060a0577e..04a061e0c 100644 --- a/src/lib/corelib/tools/processutils.cpp +++ b/src/lib/corelib/tools/processutils.cpp @@ -42,7 +42,7 @@ #if defined(Q_OS_WIN) # define PSAPI_VERSION 1 // To use GetModuleFileNameEx from Psapi.lib on all Win versions. # include <QtCore/qt_windows.h> -# include <Psapi.h> +# include <psapi.h> #elif defined(Q_OS_DARWIN) # include <libproc.h> #elif defined(Q_OS_LINUX) diff --git a/src/lib/corelib/tools/qbsprocess.h b/src/lib/corelib/tools/qbsprocess.h index 07f344e8a..2181818f0 100644 --- a/src/lib/corelib/tools/qbsprocess.h +++ b/src/lib/corelib/tools/qbsprocess.h @@ -95,7 +95,7 @@ private: QString m_errorString; QProcess::ProcessError m_error = QProcess::UnknownError; QProcess::ProcessState m_state = QProcess::NotRunning; - int m_exitCode; + int m_exitCode = 0; int m_connectionAttempts = 0; bool m_socketError = false; }; diff --git a/src/lib/corelib/tools/qttools.h b/src/lib/corelib/tools/qttools.h index 2252c12d3..4cb39527e 100644 --- a/src/lib/corelib/tools/qttools.h +++ b/src/lib/corelib/tools/qttools.h @@ -53,7 +53,15 @@ namespace std { template<> struct hash<QString> { std::size_t operator()(const QString &s) const { return qHash(s); } }; -} + +template<typename T1, typename T2> struct hash<std::pair<T1, T2>> +{ + size_t operator()(const pair<T1, T2> &x) const + { + return std::hash<T1>()(x.first) ^ std::hash<T2>()(x.second); + } +}; +} // namespace std QT_BEGIN_NAMESPACE uint qHash(const QStringList &list); diff --git a/src/lib/corelib/tools/scripttools.h b/src/lib/corelib/tools/scripttools.h index 2d8f54204..4a258b98f 100644 --- a/src/lib/corelib/tools/scripttools.h +++ b/src/lib/corelib/tools/scripttools.h @@ -76,7 +76,7 @@ void attachPointerTo(QScriptValue &scriptValue, T *ptr) template <class T> T *attachedPointer(const QScriptValue &scriptValue) { - const quintptr ptr = scriptValue.data().toVariant().value<quintptr>(); + const auto ptr = scriptValue.data().toVariant().value<quintptr>(); return reinterpret_cast<T *>(ptr); } diff --git a/src/lib/corelib/tools/set.h b/src/lib/corelib/tools/set.h index 322074b0d..eb3bf6632 100644 --- a/src/lib/corelib/tools/set.h +++ b/src/lib/corelib/tools/set.h @@ -179,8 +179,8 @@ template<typename T> Set<T>::Set(const std::initializer_list<T> &list) : m_data( template<typename T> Set<T> &Set<T>::intersect(const Set<T> &other) { - iterator it = begin(); - const_iterator otherIt = other.cbegin(); + auto it = begin(); + auto otherIt = other.cbegin(); while (it != end()) { if (otherIt == other.cend()) { m_data.erase(it, end()); @@ -207,8 +207,8 @@ template<typename T> std::pair<typename Set<T>::iterator, bool> Set<T>::insert(c template<typename T> bool Set<T>::contains(const Set<T> &other) const { - const_iterator it = cbegin(); - const_iterator otherIt = other.cbegin(); + auto it = cbegin(); + auto otherIt = other.cbegin(); while (otherIt != other.cend()) { if (it == cend() || *otherIt < *it) return false; diff --git a/src/lib/corelib/tools/settingscreator.cpp b/src/lib/corelib/tools/settingscreator.cpp index 8479a67dc..eaaf2802c 100644 --- a/src/lib/corelib/tools/settingscreator.cpp +++ b/src/lib/corelib/tools/settingscreator.cpp @@ -1,3 +1,5 @@ +#include <utility> + /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. @@ -56,8 +58,9 @@ static QSettings::Format format() } -SettingsCreator::SettingsCreator(const QString &baseDir) - : m_settingsBaseDir(baseDir), m_qbsVersion(Version::fromString(QLatin1String(QBS_VERSION))) +SettingsCreator::SettingsCreator(QString baseDir) + : m_settingsBaseDir(std::move(baseDir)) + , m_qbsVersion(Version::fromString(QLatin1String(QBS_VERSION))) { } @@ -102,7 +105,8 @@ void SettingsCreator::migrate() // that's only preferences.qbsSearchPaths as written by libqtprofilesetup, but we don't want // to hardcode that here. m_settings.reset(new QSettings(m_newSettingsFilePath, format())); - for (const QString &key : m_settings->allKeys()) { + const auto allKeys = m_settings->allKeys(); + for (const QString &key : allKeys) { QVariant v = m_settings->value(key); if (v.type() == QVariant::String) { QString s = v.toString(); diff --git a/src/lib/corelib/tools/settingscreator.h b/src/lib/corelib/tools/settingscreator.h index 6bc2a5cb7..39da80a7f 100644 --- a/src/lib/corelib/tools/settingscreator.h +++ b/src/lib/corelib/tools/settingscreator.h @@ -56,7 +56,7 @@ namespace Internal { class SettingsCreator { public: - SettingsCreator(const QString &baseDir); + SettingsCreator(QString baseDir); QSettings *getQSettings(); diff --git a/src/lib/corelib/tools/settingsmodel.cpp b/src/lib/corelib/tools/settingsmodel.cpp index 4a90773eb..d67f1da5c 100644 --- a/src/lib/corelib/tools/settingsmodel.cpp +++ b/src/lib/corelib/tools/settingsmodel.cpp @@ -327,7 +327,8 @@ void SettingsModel::SettingsModelPrivate::readSettings() { qDeleteAll(rootNode.children); rootNode.children.clear(); - for (const QString &topLevelKey : settings->directChildren(QString(), scope())) + const auto topLevelKeys = settings->directChildren(QString(), scope()); + for (const QString &topLevelKey : topLevelKeys) addNodeFromSettings(&rootNode, topLevelKey); for (QVariantMap::ConstIterator it = additionalProperties.constBegin(); it != additionalProperties.constEnd(); ++it) { @@ -353,7 +354,8 @@ void SettingsModel::SettingsModelPrivate::addNodeFromSettings(Node *parentNode, = fullyQualifiedName.mid(fullyQualifiedName.lastIndexOf(QLatin1Char('.')) + 1); Node * const node = createNode(parentNode, nodeName); node->value = settingsValueToRepresentation(settings->value(fullyQualifiedName, scope())); - for (const QString &childKey : settings->directChildren(fullyQualifiedName, scope())) + const auto childKeys = settings->directChildren(fullyQualifiedName, scope()); + for (const QString &childKey : childKeys) addNodeFromSettings(node, fullyQualifiedName + QLatin1Char('.') + childKey); dirty = true; } diff --git a/src/lib/corelib/tools/settingsmodel.h b/src/lib/corelib/tools/settingsmodel.h index 27936ba52..1bd59737c 100644 --- a/src/lib/corelib/tools/settingsmodel.h +++ b/src/lib/corelib/tools/settingsmodel.h @@ -53,7 +53,7 @@ class QBS_EXPORT SettingsModel : public QAbstractItemModel Q_OBJECT public: SettingsModel(const QString &settingsDir, Settings::Scope scope, QObject *parent = nullptr); - ~SettingsModel(); + ~SettingsModel() override; int keyColumn() const { return 0; } int valueColumn() const { return 1; } diff --git a/src/lib/corelib/tools/setupprojectparameters.cpp b/src/lib/corelib/tools/setupprojectparameters.cpp index 6b13570d7..6d817c8f3 100644 --- a/src/lib/corelib/tools/setupprojectparameters.cpp +++ b/src/lib/corelib/tools/setupprojectparameters.cpp @@ -109,6 +109,8 @@ SetupProjectParameters::SetupProjectParameters(const SetupProjectParameters &oth { } +SetupProjectParameters::SetupProjectParameters(SetupProjectParameters &&other) Q_DECL_NOEXCEPT = default; + SetupProjectParameters::~SetupProjectParameters() { } @@ -119,6 +121,8 @@ SetupProjectParameters &SetupProjectParameters::operator=(const SetupProjectPara return *this; } +SetupProjectParameters &SetupProjectParameters::operator=(SetupProjectParameters &&other) Q_DECL_NOEXCEPT = default; + /*! * \brief Returns the name of the top-level profile for building the project. */ diff --git a/src/lib/corelib/tools/setupprojectparameters.h b/src/lib/corelib/tools/setupprojectparameters.h index c462ca212..cf3b200cb 100644 --- a/src/lib/corelib/tools/setupprojectparameters.h +++ b/src/lib/corelib/tools/setupprojectparameters.h @@ -65,9 +65,11 @@ class QBS_EXPORT SetupProjectParameters public: SetupProjectParameters(); SetupProjectParameters(const SetupProjectParameters &other); + SetupProjectParameters(SetupProjectParameters &&other) Q_DECL_NOEXCEPT; ~SetupProjectParameters(); SetupProjectParameters &operator=(const SetupProjectParameters &other); + SetupProjectParameters &operator=(SetupProjectParameters &&other) Q_DECL_NOEXCEPT; QString topLevelProfile() const; void setTopLevelProfile(const QString &profile); diff --git a/src/lib/corelib/tools/shellutils.h b/src/lib/corelib/tools/shellutils.h index c148db4b8..6f1d82afb 100644 --- a/src/lib/corelib/tools/shellutils.h +++ b/src/lib/corelib/tools/shellutils.h @@ -83,7 +83,7 @@ private: bool shouldQuote = true; }; - bool m_isRawProgram; + bool m_isRawProgram = false; QString m_program; std::vector<Argument> m_arguments; }; diff --git a/src/lib/corelib/tools/version.cpp b/src/lib/corelib/tools/version.cpp index 7ea2fda75..d2b337d3a 100644 --- a/src/lib/corelib/tools/version.cpp +++ b/src/lib/corelib/tools/version.cpp @@ -107,12 +107,11 @@ Version Version::fromString(const QString &versionString, bool buildNumberAllowe QString Version::toString() const { - QString s; - if (m_build) - s.sprintf("%d.%d.%d-%d", m_major, m_minor, m_patch, m_build); - else - s.sprintf("%d.%d.%d", m_major, m_minor, m_patch); - return s; + if (m_build) { + return QString(QStringLiteral("%1.%2.%3-%4")) + .arg(m_major).arg(m_minor).arg(m_patch).arg(m_build); + } + return QString(QStringLiteral("%1.%2.%3")).arg(m_major).arg(m_minor).arg(m_patch); } int compare(const Version &lhs, const Version &rhs) diff --git a/src/lib/corelib/tools/vsenvironmentdetector.cpp b/src/lib/corelib/tools/vsenvironmentdetector.cpp index b91a8ff74..f8f98e7b7 100644 --- a/src/lib/corelib/tools/vsenvironmentdetector.cpp +++ b/src/lib/corelib/tools/vsenvironmentdetector.cpp @@ -53,7 +53,7 @@ #ifdef Q_OS_WIN #include <QtCore/qt_windows.h> -#include <ShlObj.h> +#include <shlobj.h> #endif namespace qbs { @@ -69,8 +69,9 @@ static QString windowsSystem32Path() return {}; } -VsEnvironmentDetector::VsEnvironmentDetector() +VsEnvironmentDetector::VsEnvironmentDetector(QString vcvarsallPath) : m_windowsSystemDirPath(windowsSystem32Path()) + , m_vcvarsallPath(std::move(vcvarsallPath)) { } @@ -137,7 +138,15 @@ QString VsEnvironmentDetector::findVcVarsAllBat(const MSVC &msvc, bool VsEnvironmentDetector::startDetection(const std::vector<MSVC *> &compatibleMSVCs) { std::vector<QString> searchedPaths; - const QString vcvarsallbat = findVcVarsAllBat(**compatibleMSVCs.begin(), searchedPaths); + + if (!m_vcvarsallPath.isEmpty() && !QFileInfo::exists(m_vcvarsallPath)) { + m_errorString = Tr::tr("%1 does not exist.").arg(m_vcvarsallPath); + return false; + } + + const auto vcvarsallbat = !m_vcvarsallPath.isEmpty() + ? m_vcvarsallPath + : findVcVarsAllBat(**compatibleMSVCs.begin(), searchedPaths); if (vcvarsallbat.isEmpty()) { if (!searchedPaths.empty()) { m_errorString = Tr::tr( @@ -201,9 +210,12 @@ static QString vcArchitecture(const MSVC *msvc) if (msvc->architecture == StringConstants::x86_64Arch()) vcArch = StringConstants::amd64Arch(); - for (const QString &hostPrefix : - QStringList({StringConstants::x86Arch(), QStringLiteral("amd64_"), - QStringLiteral("x86_")})) { + const QString hostPrefixes[] = { + StringConstants::x86Arch(), + QStringLiteral("amd64_"), + QStringLiteral("x86_") + }; + for (const QString &hostPrefix : hostPrefixes) { if (QFile::exists(msvc->clPathForArchitecture(hostPrefix + vcArch))) { vcArch.prepend(hostPrefix); break; @@ -237,7 +249,8 @@ void VsEnvironmentDetector::parseBatOutput(const QByteArray &output, std::vector { QString arch; QProcessEnvironment *targetEnv = nullptr; - for (QByteArray line : output.split('\n')) { + const auto lines = output.split('\n'); + for (QByteArray line : lines) { line = line.trimmed(); if (line.isEmpty()) continue; diff --git a/src/lib/corelib/tools/vsenvironmentdetector.h b/src/lib/corelib/tools/vsenvironmentdetector.h index 1970273ee..7fa152cb6 100644 --- a/src/lib/corelib/tools/vsenvironmentdetector.h +++ b/src/lib/corelib/tools/vsenvironmentdetector.h @@ -57,7 +57,7 @@ class MSVC; class QBS_EXPORT VsEnvironmentDetector { public: - VsEnvironmentDetector(); + explicit VsEnvironmentDetector(QString vcvarsallPath = QString()); bool start(MSVC *msvc); bool start(std::vector<MSVC *> msvcs); @@ -70,6 +70,7 @@ private: void parseBatOutput(const QByteArray &output, std::vector<MSVC *> msvcs); const QString m_windowsSystemDirPath; + const QString m_vcvarsallPath; QString m_errorString; }; diff --git a/src/libexec/qbs_processlauncher/launchersockethandler.cpp b/src/libexec/qbs_processlauncher/launchersockethandler.cpp index a6f7843ec..53bd81a9a 100644 --- a/src/libexec/qbs_processlauncher/launchersockethandler.cpp +++ b/src/libexec/qbs_processlauncher/launchersockethandler.cpp @@ -97,9 +97,9 @@ private: enum class StopState { Inactive, Terminating, Killing } m_stopState = StopState::Inactive; }; -LauncherSocketHandler::LauncherSocketHandler(const QString &serverPath, QObject *parent) +LauncherSocketHandler::LauncherSocketHandler(QString serverPath, QObject *parent) : QObject(parent), - m_serverPath(serverPath), + m_serverPath(std::move(serverPath)), m_socket(new QLocalSocket(this)) { m_packetParser.setDevice(m_socket); diff --git a/src/libexec/qbs_processlauncher/launchersockethandler.h b/src/libexec/qbs_processlauncher/launchersockethandler.h index e96c02e13..b2d571870 100644 --- a/src/libexec/qbs_processlauncher/launchersockethandler.h +++ b/src/libexec/qbs_processlauncher/launchersockethandler.h @@ -58,8 +58,8 @@ class LauncherSocketHandler : public QObject { Q_OBJECT public: - explicit LauncherSocketHandler(const QString &socketPath, QObject *parent = nullptr); - ~LauncherSocketHandler(); + explicit LauncherSocketHandler(QString socketPath, QObject *parent = nullptr); + ~LauncherSocketHandler() override; void start(); diff --git a/src/packages/archive/archive.qbs b/src/packages/archive/archive.qbs index 3a49fea1d..0e0663090 100644 --- a/src/packages/archive/archive.qbs +++ b/src/packages/archive/archive.qbs @@ -8,9 +8,12 @@ QbsProduct { Depends { name: "qbs_processlauncher" } Depends { name: "qbscore" } Depends { name: "bundledqt" } - Depends { name: "qbs documentation" } + Depends { name: "qbs documentation"; condition: project.withDocumentation } Depends { name: "qbs resources" } - Depends { name: "qbs man page"; condition: qbs.targetOS.contains("unix") } + Depends { + name: "qbs man page" + condition: qbs.targetOS.contains("unix") && project.withDocumentation + } Depends { productTypes: ["qbsapplication", "qbsplugin"] } Depends { name: "archiver" } diff --git a/src/plugins/generator/clangcompilationdb/clangcompilationdbgenerator.cpp b/src/plugins/generator/clangcompilationdb/clangcompilationdbgenerator.cpp index 0f94f2b2b..bc13ec480 100644 --- a/src/plugins/generator/clangcompilationdb/clangcompilationdbgenerator.cpp +++ b/src/plugins/generator/clangcompilationdb/clangcompilationdbgenerator.cpp @@ -69,14 +69,18 @@ QString ClangCompilationDatabaseGenerator::generatorName() const void ClangCompilationDatabaseGenerator::generate() { - for (const Project &theProject : project().projects.values()) { + const auto projects = project().projects.values(); + for (const Project &theProject : projects) { QJsonArray database; const ProjectData projectData = theProject.projectData(); const QString buildDir = projectData.buildDirectory(); - for (const ProductData &productData : projectData.allProducts()) { - for (const GroupData &groupData : productData.groups()) { - for (const ArtifactData &sourceArtifact : groupData.allSourceArtifacts()) { + const auto products = projectData.allProducts(); + for (const ProductData &productData : products) { + const auto groups = productData.groups(); + for (const GroupData &groupData : groups) { + const auto sourceArtifacts = groupData.allSourceArtifacts(); + for (const ArtifactData &sourceArtifact : sourceArtifacts) { if (!hasValidInputFileTag(sourceArtifact.fileTags())) continue; diff --git a/src/plugins/generator/makefilegenerator/makefilegenerator.cpp b/src/plugins/generator/makefilegenerator/makefilegenerator.cpp index f186b5244..24aff5a33 100644 --- a/src/plugins/generator/makefilegenerator/makefilegenerator.cpp +++ b/src/plugins/generator/makefilegenerator/makefilegenerator.cpp @@ -156,7 +156,8 @@ static QString removeCommand() void qbs::MakefileGenerator::generate() { - for (const Project &theProject : project().projects.values()) { + const auto projects = project().projects.values(); + for (const Project &theProject : projects) { const QString makefileFilePath = theProject.projectData().buildDirectory() + QLatin1String("/Makefile"); QFile makefile(makefileFilePath); @@ -241,16 +242,19 @@ void qbs::MakefileGenerator::generate() allDefaultTargets.push_back(productTarget); allTargets.push_back(productTarget); stream << productTarget << ':'; - for (const ArtifactData &ta : productData.targetArtifacts()) + const auto targetArtifacts = productData.targetArtifacts(); + for (const ArtifactData &ta : targetArtifacts) stream << ' ' << transformedOutputFilePath(ta); stream << '\n'; for (const TransformerData &transformerData : productTransformerData) { stream << transformedOutputFilePath(transformerData.outputs().constFirst()) << ":"; - for (const ArtifactData &input : transformerData.inputs()) + const auto inputs = transformerData.inputs(); + for (const ArtifactData &input : inputs) stream << ' ' << transformedArtifactFilePath(input); stream << '\n'; Set<QString> createdDirs; - for (const ArtifactData &output : transformerData.outputs()) { + const auto outputs = transformerData.outputs(); + for (const ArtifactData &output : outputs) { const QString outputDir = QFileInfo(output.filePath()).path(); if (createdDirs.insert(outputDir).second) stream << "\t" << mkdirCmdLine(QDir::toNativeSeparators( @@ -258,7 +262,8 @@ void qbs::MakefileGenerator::generate() << '\n'; } bool processCommandEncountered = false; - for (const RuleCommand &command : transformerData.commands()) { + const auto commands = transformerData.commands(); + for (const RuleCommand &command : commands) { if (command.type() == RuleCommand::JavaScriptCommandType) { jsCommandsEncountered = true; continue; @@ -268,7 +273,8 @@ void qbs::MakefileGenerator::generate() quote(bruteForcePathReplace(command.executable(), srcDir, buildDir, installRoot))); // TODO: Optionally use environment? - for (const QString &arg : command.arguments()) { + const auto args = command.arguments(); + for (const QString &arg : args) { stream << ' ' << quote(bruteForcePathReplace(arg, srcDir, buildDir, installRoot)); } @@ -279,13 +285,15 @@ void qbs::MakefileGenerator::generate() << transformedOutputFilePath(transformerData.outputs().at(i-1)) << '\n'; } if (!processCommandEncountered && builtByDefault) { - for (const ArtifactData &output : transformerData.outputs()) + const auto outputs = transformerData.outputs(); + for (const ArtifactData &output : outputs) filesCreatedByJsCommands.push_back(output.filePath()); } } stream << "install-" << productTarget << ": " << productTarget << '\n'; Set<QString> createdDirs; - for (const ArtifactData &artifact : productData.installableArtifacts()) { + const auto installableArtifacts = productData.installableArtifacts(); + for (const ArtifactData &artifact : installableArtifacts) { const QString &outputDir = artifact.installData().localInstallDir(); if (outputDir.contains(QLatin1Char(' '))) { logger().qbsWarning() << Tr::tr("Skipping installation of '%1', because " @@ -311,7 +319,8 @@ void qbs::MakefileGenerator::generate() << transformedInputFilePath << ' ' << transformedOutputDir << '\n'; } stream << "clean-" << productTarget << ":\n"; - for (const ArtifactData &artifact : productData.generatedArtifacts()) { + const auto generatedArtifacts = productData.generatedArtifacts(); + for (const ArtifactData &artifact : generatedArtifacts) { const QFileInfo fileInfo(artifact.filePath()); const QString transformedFilePath = QDir::toNativeSeparators( prefixifiedBuildDirPath(fileInfo.path()) @@ -324,15 +333,15 @@ void qbs::MakefileGenerator::generate() } stream << "all:"; - for (const QString &target : allDefaultTargets) + for (const QString &target : qAsConst(allDefaultTargets)) stream << ' ' << target; stream << '\n'; stream << "install:"; - for (const QString &target : allDefaultTargets) + for (const QString &target : qAsConst(allDefaultTargets)) stream << ' ' << "install-" << target; stream << '\n'; stream << "clean:"; - for (const QString &target : allTargets) + for (const QString &target : qAsConst(allTargets)) stream << ' ' << "clean-" << target; stream << '\n'; if (!filesCreatedByJsCommands.empty()) { diff --git a/src/plugins/generator/visualstudio/io/msbuildprojectwriter.cpp b/src/plugins/generator/visualstudio/io/msbuildprojectwriter.cpp index c5684e5ba..634bb2381 100644 --- a/src/plugins/generator/visualstudio/io/msbuildprojectwriter.cpp +++ b/src/plugins/generator/visualstudio/io/msbuildprojectwriter.cpp @@ -51,7 +51,7 @@ static const QString kMSBuildSchemaURI = class MSBuildProjectWriterPrivate : public IMSBuildNodeVisitor { public: - std::ostream *device; + std::ostream *device = nullptr; QByteArray buffer; std::unique_ptr<QXmlStreamWriter> writer; diff --git a/src/plugins/generator/visualstudio/io/visualstudiosolutionwriter.cpp b/src/plugins/generator/visualstudio/io/visualstudiosolutionwriter.cpp index 4c0495316..e980249d6 100644 --- a/src/plugins/generator/visualstudio/io/visualstudiosolutionwriter.cpp +++ b/src/plugins/generator/visualstudio/io/visualstudiosolutionwriter.cpp @@ -54,7 +54,7 @@ using namespace Internal; class VisualStudioSolutionWriterPrivate { public: - std::ostream *device; + std::ostream *device = nullptr; std::string baseDir; }; @@ -87,7 +87,8 @@ bool VisualStudioSolutionWriter::write(const VisualStudioSolution *solution) << solution->versionInfo().version().majorVersion() << u8"\n"; - for (const auto &project : solution->fileProjects()) { + const auto fileProjects = solution->fileProjects(); + for (const auto &project : fileProjects) { auto projectFilePath = project->filePath().toStdString(); // Try to make the project file path relative to the @@ -126,7 +127,8 @@ bool VisualStudioSolutionWriter::write(const VisualStudioSolution *solution) out << u8"EndProject\n"; } - for (const auto &project : solution->folderProjects()) { + const auto folderProjects = solution->folderProjects(); + for (const auto &project : folderProjects) { out << u8"Project(\"" << project->projectTypeGuid().toString().toStdString() << u8"\") = \"" @@ -142,7 +144,8 @@ bool VisualStudioSolutionWriter::write(const VisualStudioSolution *solution) out << u8"Global\n"; - for (const auto &globalSection : solution->globalSections()) { + const auto globalSections = solution->globalSections(); + for (const auto &globalSection : globalSections) { out << u8"\tGlobalSection(" << globalSection->name().toStdString() << u8") = " diff --git a/src/plugins/generator/visualstudio/msbuild/imsbuildgroup.h b/src/plugins/generator/visualstudio/msbuild/imsbuildgroup.h index 848c855ef..3d9115643 100644 --- a/src/plugins/generator/visualstudio/msbuild/imsbuildgroup.h +++ b/src/plugins/generator/visualstudio/msbuild/imsbuildgroup.h @@ -45,7 +45,7 @@ class IMSBuildGroup : public QObject Q_OBJECT public: explicit IMSBuildGroup(MSBuildProject *parent = nullptr); - virtual ~IMSBuildGroup(); + ~IMSBuildGroup() override; QString condition() const; void setCondition(const QString &condition); diff --git a/src/plugins/generator/visualstudio/msbuild/imsbuildproperty.h b/src/plugins/generator/visualstudio/msbuild/imsbuildproperty.h index 2e9405dfa..13f26f070 100644 --- a/src/plugins/generator/visualstudio/msbuild/imsbuildproperty.h +++ b/src/plugins/generator/visualstudio/msbuild/imsbuildproperty.h @@ -47,7 +47,7 @@ protected: explicit IMSBuildProperty(QObject *parent = nullptr); public: - virtual ~IMSBuildProperty(); + ~IMSBuildProperty() override; QString condition() const; void setCondition(const QString &condition); diff --git a/src/plugins/generator/visualstudio/msbuild/items/msbuildfileitem.h b/src/plugins/generator/visualstudio/msbuild/items/msbuildfileitem.h index df1fc8201..f34ac119a 100644 --- a/src/plugins/generator/visualstudio/msbuild/items/msbuildfileitem.h +++ b/src/plugins/generator/visualstudio/msbuild/items/msbuildfileitem.h @@ -40,7 +40,7 @@ class MSBuildFileItemPrivate; class MSBuildFileItem : public MSBuildItem { public: - virtual ~MSBuildFileItem(); + ~MSBuildFileItem() override; QString filePath() const; void setFilePath(const QString &filePath); diff --git a/src/plugins/generator/visualstudio/msbuild/items/msbuildfilter.cpp b/src/plugins/generator/visualstudio/msbuild/items/msbuildfilter.cpp index 3a5d98a98..f7c506651 100644 --- a/src/plugins/generator/visualstudio/msbuild/items/msbuildfilter.cpp +++ b/src/plugins/generator/visualstudio/msbuild/items/msbuildfilter.cpp @@ -44,8 +44,8 @@ public: QList<QString> extensions; bool parseFiles = true; bool sourceControlFiles = true; - MSBuildItemMetadata *identifierMetadata; - MSBuildItemMetadata *extensionsMetadata; + MSBuildItemMetadata *identifierMetadata = nullptr; + MSBuildItemMetadata *extensionsMetadata = nullptr; }; MSBuildFilter::MSBuildFilter(IMSBuildItemGroup *parent) diff --git a/src/plugins/generator/visualstudio/msbuild/items/msbuildfilter.h b/src/plugins/generator/visualstudio/msbuild/items/msbuildfilter.h index 59be8d5fe..fb977f1cc 100644 --- a/src/plugins/generator/visualstudio/msbuild/items/msbuildfilter.h +++ b/src/plugins/generator/visualstudio/msbuild/items/msbuildfilter.h @@ -45,7 +45,7 @@ public: explicit MSBuildFilter(IMSBuildItemGroup *parent = nullptr); MSBuildFilter(const QString &name, const QList<QString> &extensions, IMSBuildItemGroup *parent = nullptr); - ~MSBuildFilter(); + ~MSBuildFilter() override; QUuid identifier() const; void setIdentifier(const QUuid &identifier); diff --git a/src/plugins/generator/visualstudio/msbuild/msbuildimport.h b/src/plugins/generator/visualstudio/msbuild/msbuildimport.h index a6e4c4488..65f9bc056 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuildimport.h +++ b/src/plugins/generator/visualstudio/msbuild/msbuildimport.h @@ -53,7 +53,7 @@ class MSBuildImport : public QObject, public IMSBuildNode public: explicit MSBuildImport(MSBuildProject *parent); explicit MSBuildImport(MSBuildImportGroup *parent); - virtual ~MSBuildImport(); + ~MSBuildImport() override; QString project() const; void setProject(const QString &project); @@ -61,7 +61,7 @@ public: QString condition() const; void setCondition(const QString &condition); - void accept(IMSBuildNodeVisitor *visitor) const; + void accept(IMSBuildNodeVisitor *visitor) const override; private: std::unique_ptr<MSBuildImportPrivate> d; diff --git a/src/plugins/generator/visualstudio/msbuild/msbuildimportgroup.cpp b/src/plugins/generator/visualstudio/msbuild/msbuildimportgroup.cpp index 56c48049e..73e1922db 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuildimportgroup.cpp +++ b/src/plugins/generator/visualstudio/msbuild/msbuildimportgroup.cpp @@ -66,7 +66,7 @@ void MSBuildImportGroup::accept(IMSBuildNodeVisitor *visitor) const visitor->visitStart(this); for (const auto &child : children()) { - if (const MSBuildImport *import = qobject_cast<const MSBuildImport *>(child)) + if (const auto import = qobject_cast<const MSBuildImport *>(child)) import->accept(visitor); } diff --git a/src/plugins/generator/visualstudio/msbuild/msbuildimportgroup.h b/src/plugins/generator/visualstudio/msbuild/msbuildimportgroup.h index 829f5dd08..a21cb5a54 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuildimportgroup.h +++ b/src/plugins/generator/visualstudio/msbuild/msbuildimportgroup.h @@ -50,12 +50,12 @@ class MSBuildImportGroup : public IMSBuildGroup, public IMSBuildNode Q_DISABLE_COPY(MSBuildImportGroup) public: explicit MSBuildImportGroup(MSBuildProject *parent = nullptr); - virtual ~MSBuildImportGroup(); + ~MSBuildImportGroup() override; QString label() const; void setLabel(const QString &label); - void accept(IMSBuildNodeVisitor *visitor) const; + void accept(IMSBuildNodeVisitor *visitor) const override; private: std::unique_ptr<MSBuildImportGroupPrivate> d; diff --git a/src/plugins/generator/visualstudio/msbuild/msbuilditem.cpp b/src/plugins/generator/visualstudio/msbuild/msbuilditem.cpp index 9a2ffb734..b11b62295 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuilditem.cpp +++ b/src/plugins/generator/visualstudio/msbuild/msbuilditem.cpp @@ -85,7 +85,7 @@ void MSBuildItem::accept(IMSBuildNodeVisitor *visitor) const visitor->visitStart(this); for (const auto &child : children()) { - if (MSBuildItemMetadata *itemMetadata = qobject_cast<MSBuildItemMetadata *>(child)) + if (const auto itemMetadata = qobject_cast<const MSBuildItemMetadata *>(child)) itemMetadata->accept(visitor); } diff --git a/src/plugins/generator/visualstudio/msbuild/msbuilditem.h b/src/plugins/generator/visualstudio/msbuild/msbuilditem.h index 48c07f9e7..d01a357a2 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuilditem.h +++ b/src/plugins/generator/visualstudio/msbuild/msbuilditem.h @@ -53,7 +53,7 @@ class MSBuildItem : public QObject, public IMSBuildNode Q_OBJECT public: explicit MSBuildItem(const QString &name, IMSBuildItemGroup *parent = nullptr); - virtual ~MSBuildItem(); + ~MSBuildItem() override; QString name() const; void setName(const QString &name); @@ -63,7 +63,7 @@ public: void appendProperty(const QString &name, const QVariant &value); - void accept(IMSBuildNodeVisitor *visitor) const; + void accept(IMSBuildNodeVisitor *visitor) const override; private: std::unique_ptr<MSBuildItemPrivate> d; diff --git a/src/plugins/generator/visualstudio/msbuild/msbuilditemdefinitiongroup.h b/src/plugins/generator/visualstudio/msbuild/msbuilditemdefinitiongroup.h index 4fb95c4c6..3c324699d 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuilditemdefinitiongroup.h +++ b/src/plugins/generator/visualstudio/msbuild/msbuilditemdefinitiongroup.h @@ -49,9 +49,9 @@ class MSBuildItemDefinitionGroup : public IMSBuildItemGroup, public IMSBuildNode Q_OBJECT public: explicit MSBuildItemDefinitionGroup(MSBuildProject *parent = nullptr); - ~MSBuildItemDefinitionGroup(); + ~MSBuildItemDefinitionGroup() override; - void accept(IMSBuildNodeVisitor *visitor) const; + void accept(IMSBuildNodeVisitor *visitor) const override; }; } // namespace qbs diff --git a/src/plugins/generator/visualstudio/msbuild/msbuilditemgroup.h b/src/plugins/generator/visualstudio/msbuild/msbuilditemgroup.h index a77e55e57..bbbdb0e69 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuilditemgroup.h +++ b/src/plugins/generator/visualstudio/msbuild/msbuilditemgroup.h @@ -52,12 +52,12 @@ class MSBuildItemGroup : public IMSBuildItemGroup, public IMSBuildNode Q_DISABLE_COPY(MSBuildItemGroup) public: explicit MSBuildItemGroup(MSBuildProject *parent = nullptr); - ~MSBuildItemGroup(); + ~MSBuildItemGroup() override; QString label() const; void setLabel(const QString &label); - void accept(IMSBuildNodeVisitor *visitor) const; + void accept(IMSBuildNodeVisitor *visitor) const override; private: std::unique_ptr<MSBuildItemGroupPrivate> d; diff --git a/src/plugins/generator/visualstudio/msbuild/msbuilditemmetadata.h b/src/plugins/generator/visualstudio/msbuild/msbuilditemmetadata.h index f1768b286..09da2649c 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuilditemmetadata.h +++ b/src/plugins/generator/visualstudio/msbuild/msbuilditemmetadata.h @@ -52,7 +52,7 @@ public: MSBuildItemMetadata(const QString &name, const QVariant &value = QVariant(), MSBuildItem *parent = nullptr); - void accept(IMSBuildNodeVisitor *visitor) const; + void accept(IMSBuildNodeVisitor *visitor) const override; }; } // namespace qbs diff --git a/src/plugins/generator/visualstudio/msbuild/msbuildproject.h b/src/plugins/generator/visualstudio/msbuild/msbuildproject.h index 820c0ecbd..5281f615d 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuildproject.h +++ b/src/plugins/generator/visualstudio/msbuild/msbuildproject.h @@ -51,7 +51,7 @@ class MSBuildProject : public QObject, public IMSBuildNode Q_DISABLE_COPY(MSBuildProject) public: explicit MSBuildProject(QObject *parent = nullptr); - ~MSBuildProject(); + ~MSBuildProject() override; QString defaultTargets() const; void setDefaultTargets(const QString &defaultTargets); @@ -59,7 +59,7 @@ public: QString toolsVersion() const; void setToolsVersion(const QString &toolsVersion); - void accept(IMSBuildNodeVisitor *visitor) const; + void accept(IMSBuildNodeVisitor *visitor) const override; private: std::unique_ptr<MSBuildProjectPrivate> d; diff --git a/src/plugins/generator/visualstudio/msbuild/msbuildproperty.h b/src/plugins/generator/visualstudio/msbuild/msbuildproperty.h index f1382406c..de2c52394 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuildproperty.h +++ b/src/plugins/generator/visualstudio/msbuild/msbuildproperty.h @@ -51,7 +51,7 @@ public: MSBuildProperty(const QString &name, const QVariant &value = QVariant(), MSBuildPropertyGroup *parent = nullptr); - void accept(IMSBuildNodeVisitor *visitor) const; + void accept(IMSBuildNodeVisitor *visitor) const override; }; } // namespace qbs diff --git a/src/plugins/generator/visualstudio/msbuild/msbuildpropertygroup.h b/src/plugins/generator/visualstudio/msbuild/msbuildpropertygroup.h index c3289457c..60bdb008e 100644 --- a/src/plugins/generator/visualstudio/msbuild/msbuildpropertygroup.h +++ b/src/plugins/generator/visualstudio/msbuild/msbuildpropertygroup.h @@ -50,14 +50,14 @@ class MSBuildPropertyGroup : public IMSBuildGroup, public IMSBuildNode Q_DISABLE_COPY(MSBuildPropertyGroup) public: explicit MSBuildPropertyGroup(MSBuildProject *parent = nullptr); - ~MSBuildPropertyGroup(); + ~MSBuildPropertyGroup() override; QString label() const; void setLabel(const QString &label); void appendProperty(const QString &name, const QVariant &value); - void accept(IMSBuildNodeVisitor *visitor) const; + void accept(IMSBuildNodeVisitor *visitor) const override; private: std::unique_ptr<MSBuildPropertyGroupPrivate> d; diff --git a/src/plugins/generator/visualstudio/msbuildfiltersproject.cpp b/src/plugins/generator/visualstudio/msbuildfiltersproject.cpp index 7d633ca44..1cd2573c3 100644 --- a/src/plugins/generator/visualstudio/msbuildfiltersproject.cpp +++ b/src/plugins/generator/visualstudio/msbuildfiltersproject.cpp @@ -45,8 +45,6 @@ namespace qbs { -namespace { - static QStringList sourceFileExtensions() { return {QStringLiteral("c"), QStringLiteral("C"), QStringLiteral("cpp"), @@ -91,8 +89,6 @@ static bool matchesFilter(const MSBuildFilter *filter, const QString &filePath) return filter->extensions().contains(QFileInfo(filePath).completeSuffix()); } -} - MSBuildFiltersProject::MSBuildFiltersProject(const GeneratableProductData &product, QObject *parent) : MSBuildProject(parent) @@ -110,8 +106,10 @@ MSBuildFiltersProject::MSBuildFiltersProject(const GeneratableProductData &produ } Internal::Set<QString> allFiles; - for (const auto &productData : product.data.values()) { - for (const auto &groupData : productData.groups()) + const auto productDatas = product.data.values(); + for (const auto &productData : productDatas) { + const auto groups = productData.groups(); + for (const auto &groupData : groups) if (groupData.isEnabled()) allFiles.unite(Internal::Set<QString>::fromList(groupData.allFilePaths())); } diff --git a/src/plugins/generator/visualstudio/msbuildqbsproductproject.cpp b/src/plugins/generator/visualstudio/msbuildqbsproductproject.cpp index ed41dfb33..2d679ceb1 100644 --- a/src/plugins/generator/visualstudio/msbuildqbsproductproject.cpp +++ b/src/plugins/generator/visualstudio/msbuildqbsproductproject.cpp @@ -176,7 +176,8 @@ void MSBuildQbsProductProject::addConfiguration(const GeneratableProject &projec .runEnvironment(); if (!env.isEmpty()) { const auto systemEnv = QProcessEnvironment::systemEnvironment(); - for (const auto &key : systemEnv.keys()) { + const auto keys = systemEnv.keys(); + for (const auto &key : keys) { if (!env.contains(key)) continue; @@ -364,8 +365,10 @@ void MSBuildQbsProductProject::addFiles(const GeneratableProject &project, QMapIterator<QString, qbs::ProductData> productDataIt(product.data); while (productDataIt.hasNext()) { productDataIt.next(); - for (const auto &group : productDataIt.value().groups()) { - for (const auto &sourceArtifact : group.allSourceArtifacts()) { + const auto groups = productDataIt.value().groups(); + for (const auto &group : groups) { + const auto sourceArtifacts = group.allSourceArtifacts(); + for (const auto &sourceArtifact : sourceArtifacts) { const auto filePath = sourceArtifact.filePath(); if (sourceFileNodes.find(filePath) == sourceFileNodes.end()) { sourceFileNodes.insert({ diff --git a/src/plugins/generator/visualstudio/msbuildtargetproject.cpp b/src/plugins/generator/visualstudio/msbuildtargetproject.cpp index 08315cc08..154f8dccc 100644 --- a/src/plugins/generator/visualstudio/msbuildtargetproject.cpp +++ b/src/plugins/generator/visualstudio/msbuildtargetproject.cpp @@ -46,8 +46,8 @@ class MSBuildTargetProjectPrivate public: MSBuildTargetProjectPrivate(const Internal::VisualStudioVersionInfo &versionInfo) : versionInfo(versionInfo) {} - MSBuildPropertyGroup *globalsPropertyGroup; - MSBuildProperty *projectGuidProperty; + MSBuildPropertyGroup *globalsPropertyGroup = nullptr; + MSBuildProperty *projectGuidProperty = nullptr; const Internal::VisualStudioVersionInfo &versionInfo; }; diff --git a/src/plugins/generator/visualstudio/msbuildtargetproject.h b/src/plugins/generator/visualstudio/msbuildtargetproject.h index 647f0dc91..496441a88 100644 --- a/src/plugins/generator/visualstudio/msbuildtargetproject.h +++ b/src/plugins/generator/visualstudio/msbuildtargetproject.h @@ -53,7 +53,7 @@ protected: VisualStudioGenerator *parent = nullptr); public: - ~MSBuildTargetProject(); + ~MSBuildTargetProject() override; const Internal::VisualStudioVersionInfo &versionInfo() const; diff --git a/src/plugins/generator/visualstudio/solution/ivisualstudiosolutionproject.h b/src/plugins/generator/visualstudio/solution/ivisualstudiosolutionproject.h index b53f39ee1..6f8574aed 100644 --- a/src/plugins/generator/visualstudio/solution/ivisualstudiosolutionproject.h +++ b/src/plugins/generator/visualstudio/solution/ivisualstudiosolutionproject.h @@ -48,7 +48,7 @@ protected: explicit IVisualStudioSolutionProject(QObject *parent = nullptr); public: - virtual ~IVisualStudioSolutionProject(); + ~IVisualStudioSolutionProject() override; virtual QUuid projectTypeGuid() const = 0; diff --git a/src/plugins/generator/visualstudio/solution/visualstudiosolution.cpp b/src/plugins/generator/visualstudio/solution/visualstudiosolution.cpp index fbd6a3848..c09ef1f4f 100644 --- a/src/plugins/generator/visualstudio/solution/visualstudiosolution.cpp +++ b/src/plugins/generator/visualstudio/solution/visualstudiosolution.cpp @@ -74,7 +74,7 @@ QList<IVisualStudioSolutionProject *> VisualStudioSolution::projects() const QList<VisualStudioSolutionFileProject *> VisualStudioSolution::fileProjects() const { QList<VisualStudioSolutionFileProject *> list; - for (const auto &project : d->projects) + for (const auto &project : qAsConst(d->projects)) if (auto fileProject = qobject_cast<VisualStudioSolutionFileProject *>(project)) list.push_back(fileProject); return list; @@ -83,7 +83,7 @@ QList<VisualStudioSolutionFileProject *> VisualStudioSolution::fileProjects() co QList<VisualStudioSolutionFolderProject *> VisualStudioSolution::folderProjects() const { QList<VisualStudioSolutionFolderProject *> list; - for (const auto &project : d->projects) + for (const auto &project : qAsConst(d->projects)) if (auto folderProject = qobject_cast<VisualStudioSolutionFolderProject *>(project)) list.push_back(folderProject); return list; diff --git a/src/plugins/generator/visualstudio/solution/visualstudiosolution.h b/src/plugins/generator/visualstudio/solution/visualstudiosolution.h index 67fcbbe01..ba304c00c 100644 --- a/src/plugins/generator/visualstudio/solution/visualstudiosolution.h +++ b/src/plugins/generator/visualstudio/solution/visualstudiosolution.h @@ -55,7 +55,7 @@ class VisualStudioSolution : public QObject public: explicit VisualStudioSolution(const Internal::VisualStudioVersionInfo &versionInfo, QObject *parent = nullptr); - ~VisualStudioSolution(); + ~VisualStudioSolution() override; Internal::VisualStudioVersionInfo versionInfo() const; diff --git a/src/plugins/generator/visualstudio/solution/visualstudiosolutionfileproject.h b/src/plugins/generator/visualstudio/solution/visualstudiosolutionfileproject.h index 22848b8fb..2039146b6 100644 --- a/src/plugins/generator/visualstudio/solution/visualstudiosolutionfileproject.h +++ b/src/plugins/generator/visualstudio/solution/visualstudiosolutionfileproject.h @@ -45,7 +45,7 @@ class VisualStudioSolutionFileProject : public IVisualStudioSolutionProject Q_OBJECT public: explicit VisualStudioSolutionFileProject(const QString &filePath, QObject *parent = nullptr); - ~VisualStudioSolutionFileProject(); + ~VisualStudioSolutionFileProject() override; QString name() const override; diff --git a/src/plugins/generator/visualstudio/solution/visualstudiosolutionglobalsection.h b/src/plugins/generator/visualstudio/solution/visualstudiosolutionglobalsection.h index 3cc8a8702..6d383e7d4 100644 --- a/src/plugins/generator/visualstudio/solution/visualstudiosolutionglobalsection.h +++ b/src/plugins/generator/visualstudio/solution/visualstudiosolutionglobalsection.h @@ -45,7 +45,7 @@ class VisualStudioSolutionGlobalSection : public QObject Q_DISABLE_COPY(VisualStudioSolutionGlobalSection) public: explicit VisualStudioSolutionGlobalSection(const QString &name, QObject *parent = nullptr); - ~VisualStudioSolutionGlobalSection(); + ~VisualStudioSolutionGlobalSection() override; QString name() const; void setName(const QString &name); diff --git a/src/plugins/generator/visualstudio/visualstudiogenerator.cpp b/src/plugins/generator/visualstudio/visualstudiogenerator.cpp index 47f0363a6..ace55b6e6 100644 --- a/src/plugins/generator/visualstudio/visualstudiogenerator.cpp +++ b/src/plugins/generator/visualstudio/visualstudiogenerator.cpp @@ -130,7 +130,8 @@ public: const GeneratableProductData &productData) override { Q_UNUSED(project); Q_UNUSED(projectData); - for (const auto &dep : productData.dependencies()) { + const auto dependencies = productData.dependencies(); + for (const auto &dep : dependencies) { generator->d->solution->addDependency( generator->d->solutionProjects.value(productData.name()), generator->d->solutionProjects.value(dep)); @@ -143,8 +144,8 @@ public: } private: - VisualStudioGenerator *generator; - VisualStudioSolutionGlobalSection *nestedProjects; + VisualStudioGenerator *generator = nullptr; + VisualStudioSolutionGlobalSection *nestedProjects = nullptr; }; VisualStudioGenerator::VisualStudioGenerator(const VisualStudioVersionInfo &versionInfo) @@ -190,7 +191,7 @@ void VisualStudioGenerator::addPropertySheets(const GeneratableProject &project) void VisualStudioGenerator::addPropertySheets( const std::shared_ptr<MSBuildTargetProject> &targetProject) { - for (const auto &pair : d->propertySheetNames) { + for (const auto &pair : qAsConst(d->propertySheetNames)) { targetProject->appendPropertySheet( QStringLiteral("$(SolutionDir)\\") + pair.first, pair.second); } @@ -221,7 +222,8 @@ static void addDefaultGlobalSections(const GeneratableProject &topLevelProject, QStringLiteral("ProjectConfigurationPlatforms"), solution); solution->appendGlobalSection(projectConfigurationPlatformsSection); projectConfigurationPlatformsSection->setPost(true); - for (const auto project : solution->projects()) { + const auto projects = solution->projects(); + for (const auto project : projects) { for (const auto &qbsProject : topLevelProject.projects) { projectConfigurationPlatformsSection->appendProperty( QStringLiteral("%1.%2.ActiveCfg") diff --git a/src/plugins/generator/visualstudio/visualstudiogenerator.h b/src/plugins/generator/visualstudio/visualstudiogenerator.h index 898ae0b9c..e104ca427 100644 --- a/src/plugins/generator/visualstudio/visualstudiogenerator.h +++ b/src/plugins/generator/visualstudio/visualstudiogenerator.h @@ -57,15 +57,15 @@ class VisualStudioGenerator : public ProjectGenerator, private IGeneratableProje friend class SolutionDependenciesVisitor; public: explicit VisualStudioGenerator(const Internal::VisualStudioVersionInfo &versionInfo); - ~VisualStudioGenerator(); + ~VisualStudioGenerator() override; QString generatorName() const override; void generate() override; private: - virtual void visitProject(const GeneratableProject &project) override; - virtual void visitProjectData(const GeneratableProject &project, + void visitProject(const GeneratableProject &project) override; + void visitProjectData(const GeneratableProject &project, const GeneratableProjectData &projectData) override; - virtual void visitProduct(const GeneratableProject &project, + void visitProduct(const GeneratableProject &project, const GeneratableProjectData &projectData, const GeneratableProductData &productData) override; diff --git a/src/plugins/scanner/cpp/Lexer.h b/src/plugins/scanner/cpp/Lexer.h index 2b843a14a..1cf829ebb 100644 --- a/src/plugins/scanner/cpp/Lexer.h +++ b/src/plugins/scanner/cpp/Lexer.h @@ -145,17 +145,17 @@ private: unsigned _objCEnabled: 1; }; - const char *_firstChar; - const char *_currentChar; - const char *_lastChar; - const char *_tokenStart; - unsigned char _yychar; - int _state; + const char *_firstChar = nullptr; + const char *_currentChar = nullptr; + const char *_lastChar = nullptr; + const char *_tokenStart = nullptr; + unsigned char _yychar = 0; + int _state = 0; union { unsigned _flags; Flags f; }; - unsigned _currentLine; + unsigned _currentLine = 0; }; } // end of namespace CPlusPlus diff --git a/src/plugins/scanner/cpp/Token.h b/src/plugins/scanner/cpp/Token.h index 286c71a48..846aa5a12 100644 --- a/src/plugins/scanner/cpp/Token.h +++ b/src/plugins/scanner/cpp/Token.h @@ -353,7 +353,7 @@ public: Flags f; }; - unsigned offset; + unsigned offset = 0; union { void *ptr; diff --git a/src/plugins/scanner/qt/qtscanner.cpp b/src/plugins/scanner/qt/qtscanner.cpp index 51faadab3..40d062e1f 100644 --- a/src/plugins/scanner/qt/qtscanner.cpp +++ b/src/plugins/scanner/qt/qtscanner.cpp @@ -68,24 +68,16 @@ struct OpaqQrc { #ifdef Q_OS_UNIX - int fd; - int mapl; + int fd = 0; + int mapl = 0; #else - QFile *file; + QFile *file = nullptr; #endif - char *map; - QXmlStreamReader *xml; + char *map = nullptr; + QXmlStreamReader *xml = nullptr; QByteArray current; - OpaqQrc() -#ifdef Q_OS_UNIX - : fd (0), -#else - : file(nullptr), -#endif - map(nullptr), - xml(nullptr) - {} + OpaqQrc() = default; ~OpaqQrc() { diff --git a/src/shared/json/json.cpp b/src/shared/json/json.cpp index 82b7467c8..3a838a177 100644 --- a/src/shared/json/json.cpp +++ b/src/shared/json/json.cpp @@ -542,7 +542,7 @@ public: } char *raw = (char *)malloc(size); memcpy(raw + sizeof(Header), b, b->size); - Header *h = (Header *)raw; + const auto h = (Header *)raw; h->tag = JsonDocument::BinaryFormatTag; h->version = 1; const auto d = new Data(raw, size); @@ -1251,8 +1251,8 @@ JsonArray::JsonArray() JsonArray::JsonArray(std::initializer_list<JsonValue> args) : d(nullptr), a(nullptr) { - for (auto i = args.begin(); i != args.end(); ++i) - append(*i); + for (const auto &arg : args) + append(arg); } /*! @@ -2284,8 +2284,8 @@ JsonObject::JsonObject() JsonObject::JsonObject(std::initializer_list<std::pair<std::string, JsonValue> > args) : d(nullptr), o(nullptr) { - for (auto i = args.begin(); i != args.end(); ++i) - insert(i->first, i->second); + for (const auto &arg : args) + insert(arg.first, arg.second); } /*! @@ -3521,7 +3521,7 @@ bool JsonDocument::isArray() const if (!d) return false; - Internal::Header *h = (Internal::Header *)d->rawData; + const auto h = (Internal::Header *)d->rawData; return h->root()->isArray(); } @@ -3535,7 +3535,7 @@ bool JsonDocument::isObject() const if (!d) return false; - Internal::Header *h = (Internal::Header *)d->rawData; + const auto h = (Internal::Header *)d->rawData; return h->root()->isObject(); } @@ -3731,7 +3731,7 @@ static std::string escapedString(const std::string &in) static void valueToJson(const Base *b, const Value &v, std::string &json, int indent, bool compact) { - JsonValue::Type type = (JsonValue::Type)(uint32_t)v.type; + const auto type = (JsonValue::Type)(uint32_t)v.type; switch (type) { case JsonValue::Bool: json += v.toBoolean() ? "true" : "false"; @@ -4013,7 +4013,7 @@ JsonDocument Parser::parse(JsonParseError *error) data = (char *)malloc(dataLength); // fill in Header data - Header *h = (Header *)data; + const auto h = (Header *)data; h->tag = JsonDocument::BinaryFormatTag; h->version = 1u; @@ -4065,7 +4065,7 @@ error: void Parser::ParsedObject::insert(uint32_t offset) { - const Entry *newEntry = reinterpret_cast<const Entry *>(parser->data + objectPosition + offset); + const auto newEntry = reinterpret_cast<const Entry *>(parser->data + objectPosition + offset); size_t min = 0; size_t n = offsets.size(); while (n > 0) { @@ -4133,7 +4133,7 @@ bool Parser::parseObject() memcpy(data + table, &*parsedObject.offsets.begin(), tableSize); } - Object *o = (Object *)(data + objectOffset); + const auto o = (Object *)(data + objectOffset); o->tableOffset = table - objectOffset; o->size = current - objectOffset; o->is_object = true; @@ -4166,7 +4166,7 @@ bool Parser::parseMember(int baseOffset) return false; // finalize the entry - Entry *e = (Entry *)(data + entryOffset); + const auto e = (Entry *)(data + entryOffset); e->value = val; END; @@ -4224,7 +4224,7 @@ bool Parser::parseArray() memcpy(data + table, values.data(), tableSize); } - Array *a = (Array *)(data + arrayOffset); + const auto a = (Array *)(data + arrayOffset); a->tableOffset = table - arrayOffset; a->size = current - arrayOffset; a->is_object = false; @@ -4632,7 +4632,7 @@ void Data::compact() int size = sizeof(Base) + reserve + base->length*sizeof(offset); int alloc = sizeof(Header) + size; - Header *h = (Header *) malloc(alloc); + const auto h = (Header *) malloc(alloc); h->tag = JsonDocument::BinaryFormatTag; h->version = 1; Base *b = h->root(); diff --git a/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs b/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs index a366e0ce0..4cc25ad66 100644 --- a/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs +++ b/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs @@ -28,6 +28,7 @@ Project { Properties { condition: qbs.toolchain.contains("msvc") cpp.entryPoint: "main" + cpp.dynamicLibraries: ["ucrt", "kernel32"] } cpp.entryPoint: undefined diff --git a/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs b/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs index 7633b3ebe..fe3cacd6d 100644 --- a/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs +++ b/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs @@ -92,7 +92,7 @@ Project { Rule { multiplex: true explicitlyDependsOnFromDependencies: "the_tag" - excludedAuxiliaryInputs: "the_other_tag" + excludedInputs: "the_other_tag" Artifact { filePath: "dummy3.txt" fileTags: "p_type" diff --git a/tests/auto/api/testdata/precompiled-header-dynamic/autogen.h.in b/tests/auto/api/testdata/precompiled-header-dynamic/autogen.h.in index c5c182c8f..becfbba89 100644 --- a/tests/auto/api/testdata/precompiled-header-dynamic/autogen.h.in +++ b/tests/auto/api/testdata/precompiled-header-dynamic/autogen.h.in @@ -1 +1,6 @@ +#ifndef AUTOGEN_IN_H +#define AUTOGEN_IN_H + inline void f() { } + +#endif // AUTOGEN_IN_H diff --git a/tests/auto/api/tst_api.cpp b/tests/auto/api/tst_api.cpp index 58150150a..6313827fa 100644 --- a/tests/auto/api/tst_api.cpp +++ b/tests/auto/api/tst_api.cpp @@ -66,11 +66,11 @@ class LogSink: public qbs::ILogSink public: QString output; - void doPrintWarning(const qbs::ErrorInfo &error) { + void doPrintWarning(const qbs::ErrorInfo &error) override { qDebug("%s", qPrintable(error.toString())); warnings.push_back(error); } - void doPrintMessage(qbs::LoggerLevel, const QString &message, const QString &) { + void doPrintMessage(qbs::LoggerLevel, const QString &message, const QString &) override { output += message; } @@ -2268,8 +2268,12 @@ void TestApi::processResult() QCOMPARE(expectedExitCode == 0, result.success()); QCOMPARE(result.error(), QProcess::UnknownError); struct CheckParams { - CheckParams(bool r, const QString &f, const QByteArray &c, const QStringList &co) - : redirect(r), fileName(f), expectedContent(c), consoleOutput(co) {} + CheckParams(bool r, QString f, QByteArray c, QStringList co) + : redirect(r) + , fileName(std::move(f)) + , expectedContent(std::move(c)) + , consoleOutput(std::move(co)) + {} bool redirect; QString fileName; QByteArray expectedContent; @@ -2847,7 +2851,8 @@ void TestApi::toolInModule() const QList<qbs::ProductData> products = projectData.products(); QCOMPARE(products.size(), 1); const qbs::ProductData product = products.front(); - for (const qbs::GroupData &group : product.groups()) + const auto groups = product.groups(); + for (const qbs::GroupData &group : groups) QVERIFY(group.name() != "thetool binary"); const std::unique_ptr<qbs::BuildJob> buildJob(setupJob->project() .buildAllProducts(qbs::BuildOptions())); diff --git a/tests/auto/api/tst_api.h b/tests/auto/api/tst_api.h index ff32c8634..c04e9feb0 100644 --- a/tests/auto/api/tst_api.h +++ b/tests/auto/api/tst_api.h @@ -50,7 +50,7 @@ class TestApi : public QObject public: TestApi(); - ~TestApi(); + ~TestApi() override; private slots: void initTestCase(); diff --git a/tests/auto/blackbox/testdata-android/no-native/no-native.qbs b/tests/auto/blackbox/testdata-android/no-native/no-native.qbs index 74514f604..7aab4e9fd 100644 --- a/tests/auto/blackbox/testdata-android/no-native/no-native.qbs +++ b/tests/auto/blackbox/testdata-android/no-native/no-native.qbs @@ -4,4 +4,6 @@ Application { Android.sdk.sourceSetDir: Android.sdk.sdkDir + "/samples/android-BasicMediaDecoder/Application/src/main" + Android.sdk.versionCode: 5 + Android.sdk.versionName: "5.0" } diff --git a/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs b/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs index 6beaabfa3..322ded85c 100644 --- a/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs +++ b/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs @@ -13,7 +13,10 @@ CppApplication { var isEvenNewerMsvc; var isOlderMsvc; var isGcc; - if (toolchain.contains("msvc")) { + if (toolchain.contains("clang-cl")) { + isEvenNewerMsvc = true; + isNewerMsvc = true; + } else if (toolchain.contains("msvc")) { if (compilerVersion >= "19.12.25831") isEvenNewerMsvc = true; if (compilerVersion >= "18.00.30723") diff --git a/tests/auto/blackbox/testdata/enableRtti/main.cpp b/tests/auto/blackbox/testdata/enableRtti/main.cpp index 4dcd5d2e8..4011cf823 100644 --- a/tests/auto/blackbox/testdata/enableRtti/main.cpp +++ b/tests/auto/blackbox/testdata/enableRtti/main.cpp @@ -32,6 +32,10 @@ #error RTTI is disabled! #endif +#if defined(_MSC_VER) && !defined (_CPPRTTI) +#error RTTI is disabled! +#endif + class I { public: virtual ~I() { } diff --git a/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs b/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs index 9dd7bf5b2..0b4de0ab9 100644 --- a/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs +++ b/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs @@ -44,7 +44,7 @@ DynamicLibrary { cmd.sourceCode = function() { var file = new TextFile(buildPath + "/linkerscript_with_includes", TextFile.WriteOnly); - file.write("SEARCH_DIR(" + sourcePath + "/scripts)\n" + + file.write("SEARCH_DIR(\"" + sourcePath + "/scripts\")\n" + "INCLUDE linkerscript_to_include\n" + "INCLUDE linkerscript_in_directory\n"); file.close(); diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/main.cpp b/tests/auto/blackbox/testdata/minimumSystemVersion/main.cpp index 4cc99756b..47c9ed007 100644 --- a/tests/auto/blackbox/testdata/minimumSystemVersion/main.cpp +++ b/tests/auto/blackbox/testdata/minimumSystemVersion/main.cpp @@ -42,6 +42,10 @@ int main(int argc, char *argv[]) return 1; #ifdef _WIN32 +#if defined(__clang__) + std::cout << "Unsupported compiler" << std::endl; + return 0; +#endif #if defined(WINVER) && defined(QBS_WINVER) std::cout << "WINVER=" << WINVER << std::endl; std::string command = TOOLCHAIN_INSTALL_PATH; diff --git a/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs b/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs index 4bda00caf..346a94e21 100644 --- a/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs +++ b/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs @@ -12,7 +12,7 @@ Project { id: toolchainProbe property stringList toolchain: qbs.toolchain configure: { - if (toolchain.contains("msvc")) + if (toolchain.contains("msvc") && !toolchain.contains("clang-cl")) console.info("compiler is MSVC") else console.info("compiler is not MSVC") diff --git a/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/file.cpp b/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/file.cpp new file mode 100644 index 000000000..1d9f38c57 --- /dev/null +++ b/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/file.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/main.cpp b/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/main.cpp new file mode 100644 index 000000000..e20edd490 --- /dev/null +++ b/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/main.cpp @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pch.h" + +int main() +{ +} diff --git a/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/pch.h b/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/pch.h new file mode 100644 index 000000000..59d72018e --- /dev/null +++ b/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/pch.h @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <algorithm> +#include <memory> diff --git a/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/precompiled-headers-and-redefine.qbs b/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/precompiled-headers-and-redefine.qbs new file mode 100644 index 000000000..55b53a7af --- /dev/null +++ b/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/precompiled-headers-and-redefine.qbs @@ -0,0 +1,16 @@ +CppApplication { + name: "MyApp" + consoleApplication: true + Group { + files: ["pch.h"] + fileTags: ["cpp_pch_src"] + } + Group { + files: ["file.cpp"] + cpp.defines: ["MYDEF=1"] + cpp.cxxFlags: base.concat(qbs.toolchain.contains("clang-cl") ? ["-Wno-clang-cl-pch"] : []) + } + cpp.treatWarningsAsErrors: true + + files: ["main.cpp"] +} diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index dba77ff60..84322a7c7 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -882,8 +882,8 @@ void TestBlackbox::dependenciesProperty() QJsonArray cpp_dependencies = product2_cpp.value("dependencies").toArray(); QVERIFY(!cpp_dependencies.isEmpty()); int qbsCount = 0; - for (int i = 0; i < cpp_dependencies.size(); ++i) { - if (cpp_dependencies.at(i).toObject().value("name").toString() == "qbs") + for (const auto &dep : cpp_dependencies) { + if (dep.toObject().value("name").toString() == "qbs") ++qbsCount; } QCOMPARE(qbsCount, 1); @@ -2557,6 +2557,9 @@ void TestBlackbox::smartRelinking_data() static QString soName(const QString &readElfPath, const QString &libFilePath) { QProcess readElf; + auto env = QProcessEnvironment::systemEnvironment(); + env.insert(QStringLiteral("LC_ALL"), QStringLiteral("C")); // force readelf to use US encoding + readElf.setProcessEnvironment(env); readElf.start(readElfPath, QStringList() << "-a" << libFilePath); if (!readElf.waitForStarted() || !readElf.waitForFinished() || readElf.exitCode() != 0) { qDebug() << readElf.errorString() << readElf.readAllStandardError(); @@ -2862,6 +2865,12 @@ void TestBlackbox::precompiledAndPrefixHeaders() QCOMPARE(runQbs(), 0); } +void TestBlackbox::precompiledHeaderAndRedefine() +{ + QDir::setCurrent(testDataDir + "/precompiled-headers-and-redefine"); + QCOMPARE(runQbs(), 0); +} + void TestBlackbox::preventFloatingPointValues() { QDir::setCurrent(testDataDir + "/prevent-floating-point-values"); @@ -2956,7 +2965,7 @@ void TestBlackbox::probeChangeTracking() void TestBlackbox::probeProperties() { QDir::setCurrent(testDataDir + "/probeProperties"); - const QByteArray dir = QDir::cleanPath(testDataDir).toLatin1() + "/probeProperties"; + const QByteArray dir = QDir::cleanPath(testDataDir).toLocal8Bit() + "/probeProperties"; QCOMPARE(runQbs(), 0); QVERIFY2(m_qbsStdout.contains("probe1.fileName=bin/tool"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("probe1.path=" + dir), m_qbsStdout.constData()); @@ -6121,14 +6130,14 @@ static bool haveInnoSetup(const Profile &profile) QStringList paths = QProcessEnvironment::systemEnvironment().value("PATH") .split(HostOsInfo::pathListSeparator(), QString::SkipEmptyParts); - for (const QString &key : regKeys) { + for (const QString &key : qAsConst(regKeys)) { QSettings settings(key, QSettings::NativeFormat); QString str = settings.value(QStringLiteral("InstallLocation")).toString(); if (!str.isEmpty()) paths.prepend(str); } - for (const QString &path : paths) { + for (const QString &path : qAsConst(paths)) { if (regularFileExists(QDir::fromNativeSeparators(path) + HostOsInfo::appendExecutableSuffix(QStringLiteral("/ISCC")))) return true; @@ -6442,6 +6451,8 @@ void TestBlackbox::minimumSystemVersion() QbsRunParameters params({ "-f", file + ".qbs" }); params.command = "run"; QCOMPARE(runQbs(params), 0); + if (m_qbsStdout.contains("Unsupported compiler")) + QSKIP("Unsupported compiler"); if (!m_qbsStdout.contains(output.toUtf8())) { qDebug() << "expected output:" << qPrintable(output); qDebug() << "actual output:" << m_qbsStdout.constData(); diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index f7f1c9a29..5b3adcbe2 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -212,6 +212,7 @@ private slots: void pkgConfigProbeSysroot(); void pluginDependency(); void precompiledAndPrefixHeaders(); + void precompiledHeaderAndRedefine(); void preventFloatingPointValues(); void probeChangeTracking(); void probeProperties(); diff --git a/tests/auto/blackbox/tst_blackboxapple.cpp b/tests/auto/blackbox/tst_blackboxapple.cpp index 7cbc07b95..d9cabe270 100644 --- a/tests/auto/blackbox/tst_blackboxapple.cpp +++ b/tests/auto/blackbox/tst_blackboxapple.cpp @@ -749,7 +749,8 @@ void TestBlackboxApple::xcode() QVERIFY2(xcodebuildShowSdks.waitForStarted(), qPrintable(xcodebuildShowSdks.errorString())); QVERIFY2(xcodebuildShowSdks.waitForFinished(), qPrintable(xcodebuildShowSdks.errorString())); QVERIFY2(xcodebuildShowSdks.exitCode() == 0, qPrintable(xcodebuildShowSdks.readAllStandardError().constData())); - for (const QString &line : QString::fromLocal8Bit(xcodebuildShowSdks.readAllStandardOutput().trimmed()).split('\n', QString::SkipEmptyParts)) { + const auto lines = QString::fromLocal8Bit(xcodebuildShowSdks.readAllStandardOutput().trimmed()).split('\n', QString::SkipEmptyParts); + for (const QString &line : lines) { static const std::regex regexp("^.+\\s+\\-sdk\\s+([a-z]+)([0-9]+\\.[0-9]+)$"); const auto ln = line.toStdString(); std::smatch match; diff --git a/tests/auto/blackbox/tst_blackboxbase.h b/tests/auto/blackbox/tst_blackboxbase.h index e7df96f00..251f3752d 100644 --- a/tests/auto/blackbox/tst_blackboxbase.h +++ b/tests/auto/blackbox/tst_blackboxbase.h @@ -70,8 +70,8 @@ public: QString profile; QString settingsDir; QString workingDir; - bool expectFailure; - bool expectCrash; + bool expectFailure = false; + bool expectCrash = false; }; class TestBlackboxBase : public QObject diff --git a/tests/auto/blackbox/tst_clangdb.cpp b/tests/auto/blackbox/tst_clangdb.cpp index 6a4072dd8..3a6dd2d92 100644 --- a/tests/auto/blackbox/tst_clangdb.cpp +++ b/tests/auto/blackbox/tst_clangdb.cpp @@ -111,7 +111,8 @@ void TestClangDb::ensureBuildTreeCreated() if (m_qbsStdout.contains("is msvc") || m_qbsStdout.contains("is mingw")) { sanitizeOutput(&m_qbsStdout); - for (const auto &line : m_qbsStdout.split('\n')) { + const auto lines = m_qbsStdout.split('\n'); + for (const auto &line : lines) { static const QByteArray includeEnv = "INCLUDE="; static const QByteArray libEnv = "LIB="; static const QByteArray pathEnv = "PATH="; diff --git a/tests/auto/blackbox/tst_clangdb.h b/tests/auto/blackbox/tst_clangdb.h index 6122e636d..1ae6db467 100644 --- a/tests/auto/blackbox/tst_clangdb.h +++ b/tests/auto/blackbox/tst_clangdb.h @@ -41,7 +41,7 @@ public: TestClangDb(); private slots: - void initTestCase(); + void initTestCase() override; void ensureBuildTreeCreated(); void checkCanGenerateDb(); void checkDbIsValidJson(); diff --git a/tests/auto/tools/tst_tools.cpp b/tests/auto/tools/tst_tools.cpp index da40a2dc6..edf5a1308 100644 --- a/tests/auto/tools/tst_tools.cpp +++ b/tests/auto/tools/tst_tools.cpp @@ -679,10 +679,10 @@ void TestTools::set_begin() Set<int> set2 = set1; { - Set<int>::const_iterator i = set1.constBegin(); - Set<int>::const_iterator j = set1.cbegin(); - Set<int>::const_iterator k = set2.constBegin(); - Set<int>::const_iterator ell = set2.cbegin(); + const auto i = set1.constBegin(); + const auto j = set1.cbegin(); + const auto k = set2.constBegin(); + const auto ell = set2.cbegin(); QVERIFY(i == j); QVERIFY(k == ell); @@ -691,10 +691,10 @@ void TestTools::set_begin() set1.insert(44); { - Set<int>::const_iterator i = set1.constBegin(); - Set<int>::const_iterator j = set1.cbegin(); - Set<int>::const_iterator k = set2.constBegin(); - Set<int>::const_iterator ell = set2.cbegin(); + const auto i = set1.constBegin(); + const auto j = set1.cbegin(); + const auto k = set2.constBegin(); + const auto ell = set2.cbegin(); QVERIFY(i == j); QVERIFY(k == ell); @@ -703,10 +703,10 @@ void TestTools::set_begin() set2 = set1; { - Set<int>::const_iterator i = set1.constBegin(); - Set<int>::const_iterator j = set1.cbegin(); - Set<int>::const_iterator k = set2.constBegin(); - Set<int>::const_iterator ell = set2.cbegin(); + const auto i = set1.constBegin(); + const auto j = set1.cbegin(); + const auto k = set2.constBegin(); + const auto ell = set2.cbegin(); QVERIFY(i == j); QVERIFY(k == ell); @@ -719,10 +719,10 @@ void TestTools::set_end() Set<int> set2 = set1; { - Set<int>::const_iterator i = set1.constEnd(); - Set<int>::const_iterator j = set1.cend(); - Set<int>::const_iterator k = set2.constEnd(); - Set<int>::const_iterator ell = set2.cend(); + const auto i = set1.constEnd(); + const auto j = set1.cend(); + const auto k = set2.constEnd(); + const auto ell = set2.cend(); QVERIFY(i == j); QVERIFY(k == ell); @@ -734,10 +734,10 @@ void TestTools::set_end() set1.insert(44); { - Set<int>::const_iterator i = set1.constEnd(); - Set<int>::const_iterator j = set1.cend(); - Set<int>::const_iterator k = set2.constEnd(); - Set<int>::const_iterator ell = set2.cend(); + const auto i = set1.constEnd(); + const auto j = set1.cend(); + const auto k = set2.constEnd(); + const auto ell = set2.cend(); QVERIFY(i == j); QVERIFY(k == ell); @@ -749,10 +749,10 @@ void TestTools::set_end() set2 = set1; { - Set<int>::const_iterator i = set1.constEnd(); - Set<int>::const_iterator j = set1.cend(); - Set<int>::const_iterator k = set2.constEnd(); - Set<int>::const_iterator ell = set2.cend(); + const auto i = set1.constEnd(); + const auto j = set1.cend(); + const auto k = set2.constEnd(); + const auto ell = set2.cend(); QVERIFY(i == j); QVERIFY(k == ell); @@ -847,7 +847,7 @@ void TestTools::set_stlIterator() { int sum = 0; - Set<QString>::const_iterator i = set1.cbegin(); + auto i = set1.cbegin(); while (i != set1.end()) { sum += toNumber(*i); ++i; @@ -857,7 +857,7 @@ void TestTools::set_stlIterator() { int sum = 0; - Set<QString>::const_iterator i = set1.cend(); + auto i = set1.cend(); while (i != set1.begin()) { --i; sum += toNumber(*i); @@ -874,7 +874,7 @@ void TestTools::set_stlMutableIterator() { int sum = 0; - Set<QString>::iterator i = set1.begin(); + auto i = set1.begin(); while (i != set1.end()) { sum += toNumber(*i); ++i; @@ -884,7 +884,7 @@ void TestTools::set_stlMutableIterator() { int sum = 0; - Set<QString>::iterator i = set1.end(); + auto i = set1.end(); while (i != set1.begin()) { --i; sum += toNumber(*i); @@ -896,8 +896,8 @@ void TestTools::set_stlMutableIterator() Set<QString> set2 = set1; Set<QString> set3 = set2; - Set<QString>::iterator i = set2.begin(); - Set<QString>::iterator j = set3.begin(); + auto i = set2.begin(); + auto j = set3.begin(); while (i != set2.end()) { i = set2.erase(i); diff --git a/tests/benchmarker/commandlineparser.h b/tests/benchmarker/commandlineparser.h index 2c87daeef..72a364561 100644 --- a/tests/benchmarker/commandlineparser.h +++ b/tests/benchmarker/commandlineparser.h @@ -58,7 +58,7 @@ private: QString m_newCommit; QString m_testProjectFilePath; QString m_qbsRepoDirPath; - int m_regressionThreshold; + int m_regressionThreshold = 0; }; } // namespace qbsBenchmarker diff --git a/tests/benchmarker/exception.h b/tests/benchmarker/exception.h index 3771dc89d..b4df36974 100644 --- a/tests/benchmarker/exception.h +++ b/tests/benchmarker/exception.h @@ -36,13 +36,13 @@ namespace qbsBenchmarker { class Exception : public QException { public: explicit Exception(const QString &description) : m_description(description) {} - ~Exception() throw() { } + ~Exception() throw() override { } QString description() const { return m_description; } private: - void raise() const { throw *this; } - Exception *clone() const { return new Exception(*this); } + void raise() const override { throw *this; } + Exception *clone() const override { return new Exception(*this); } QString m_description; }; diff --git a/tests/benchmarker/valgrindrunner.cpp b/tests/benchmarker/valgrindrunner.cpp index 0441e1b10..344a23516 100644 --- a/tests/benchmarker/valgrindrunner.cpp +++ b/tests/benchmarker/valgrindrunner.cpp @@ -39,6 +39,7 @@ #include <QtConcurrent/qtconcurrentrun.h> +#include <deque> #include <mutex> namespace qbsBenchmarker { @@ -56,15 +57,17 @@ ValgrindRunner::ValgrindRunner(Activities activities, const QString &testProject void ValgrindRunner::run() { - QList<QFuture<void>> futures; + std::deque<QFuture<void>> futures; if (m_activities & ActivityResolving) futures.push_back(QtConcurrent::run(this, &ValgrindRunner::traceResolving)); if (m_activities & ActivityRuleExecution) futures.push_back(QtConcurrent::run(this, &ValgrindRunner::traceRuleExecution)); if (m_activities & ActivityNullBuild) futures.push_back(QtConcurrent::run(this, &ValgrindRunner::traceNullBuild)); - while (!futures.empty()) - futures.takeFirst().waitForFinished(); + while (!futures.empty()) { + futures.front().waitForFinished(); + futures.pop_front(); + } } void ValgrindRunner::traceResolving() diff --git a/tests/fuzzy-test/commandlineparser.h b/tests/fuzzy-test/commandlineparser.h index fa6098e59..a000a515d 100644 --- a/tests/fuzzy-test/commandlineparser.h +++ b/tests/fuzzy-test/commandlineparser.h @@ -36,12 +36,12 @@ class ParseException : public std::exception { public: ParseException(const QString &error) : errorMessage(error) { } - ~ParseException() throw() {} + ~ParseException() throw() override {} QString errorMessage; private: - const char *what() const throw() { return qPrintable(errorMessage); } + const char *what() const throw() override { return qPrintable(errorMessage); } }; class CommandLineParser @@ -68,9 +68,9 @@ private: QString m_command; QString m_profile; QString m_startCommit; - int m_maxDuration; - int m_jobCount; - bool m_log; + int m_maxDuration = 0; + int m_jobCount = 0; + bool m_log = false; }; #endif // Include guard. diff --git a/tests/fuzzy-test/fuzzytester.h b/tests/fuzzy-test/fuzzytester.h index 846e7d14f..2d75bb1af 100644 --- a/tests/fuzzy-test/fuzzytester.h +++ b/tests/fuzzy-test/fuzzytester.h @@ -71,8 +71,8 @@ private: static QString defaultBuildDir(); QString m_profile; - int m_jobCount; - bool m_log; + int m_jobCount = 0; + bool m_log = false; QString m_headCommit; QString m_currentCommit; QString m_currentActivity; |