diff options
235 files changed, 5347 insertions, 3001 deletions
diff --git a/.github/actions/download-qt/action.yml b/.github/actions/download-qt/action.yml index 7c475b926..e27358125 100644 --- a/.github/actions/download-qt/action.yml +++ b/.github/actions/download-qt/action.yml @@ -4,7 +4,7 @@ inputs: version: description: 'Qt version' required: false - default: '5.15.0' + default: '5.15.2' target: description: 'Qt target (desktop, ios, android)' required: false @@ -17,6 +17,6 @@ runs: steps: - name: Install Qt run: | - QT_DIR=$(./scripts/install-qt.sh -d $HOME/Qt --version ${{ inputs.version }} --target ${{ inputs.target }} --toolchain ${{ inputs.toolchain }} qtbase qtdeclarative qttools qtscript qtscxml) + QT_DIR=$(./scripts/install-qt.sh -d $HOME/Qt --version ${{ inputs.version }} --target ${{ inputs.target }} --toolchain ${{ inputs.toolchain }} qtbase qtdeclarative qttools qtscript qtscxml qt5compat) (cygpath -w ${QTC_DIR} 2>/dev/null || echo ${QT_DIR}) >> ${GITHUB_PATH} shell: bash diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a2714380f..29f737a1e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,7 +6,7 @@ jobs: build-linux: name: ${{ matrix.config.name }} runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 60 strategy: fail-fast: false matrix: @@ -54,7 +54,7 @@ jobs: build-linux-extra: name: ${{ matrix.config.name }} runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 60 strategy: fail-fast: false matrix: @@ -104,7 +104,7 @@ jobs: build-macos: name: Build on macOS runs-on: macos-latest - timeout-minutes: 45 + timeout-minutes: 60 env: BUILD_OPTIONS: | modules.cpp.compilerWrapper:ccache @@ -161,7 +161,7 @@ jobs: build-windows: name: Build on Windows runs-on: windows-latest - timeout-minutes: 45 + timeout-minutes: 60 env: BUILD_OPTIONS: | modules.cpp.compilerWrapper:clcache @@ -221,7 +221,7 @@ jobs: test-linux: name: ${{ matrix.config.name }} runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 60 needs: build-linux strategy: fail-fast: false @@ -240,6 +240,12 @@ jobs: script: './scripts/test-qbs.sh', } - { + name: 'Run Linux tests (gcc, Qt 6.0)', + image: 'focal-qt6', + profile: 'qt-gcc_64', + script: './scripts/test-qt.sh', + } + - { name: 'Run Android tests (Qt 5.13)', image: 'focal-android-513', profile: '', @@ -283,9 +289,9 @@ jobs: run: docker-compose run ${{ matrix.config.image }} ${{ matrix.config.script }} release/install-root/usr/local/bin test-baremetal: - name: Run Baremetal tests + name: Run Baremetal tests (Linux) runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 60 needs: build-linux env: QBS_TEST_SOURCE_ROOT: 'tests' @@ -306,15 +312,154 @@ jobs: run: QBS_AUTOTEST_PROFILE=avr-gcc-5_4 docker-compose run focal-baremetal scripts/test-baremetal.sh release/install-root/usr/local/bin - name: msp430-gcc-4_6 run: QBS_AUTOTEST_PROFILE=msp430-gcc-4_6 docker-compose run focal-baremetal scripts/test-baremetal.sh release/install-root/usr/local/bin + - name: xtensa-lx106-elf-gcc-9_2 + run: QBS_AUTOTEST_PROFILE=xtensa-lx106-elf-gcc-9_2 docker-compose run focal-baremetal scripts/test-baremetal.sh release/install-root/usr/local/bin + - name: riscv64-unknown-elf-gcc-9_3 + run: QBS_AUTOTEST_PROFILE=riscv64-unknown-elf-gcc-9_3 docker-compose run focal-baremetal scripts/test-baremetal.sh release/install-root/usr/local/bin - name: sdcc-3_8_0-mcs51 run: QBS_AUTOTEST_PROFILE=sdcc-3_8_0-mcs51 docker-compose run focal-baremetal scripts/test-baremetal.sh release/install-root/usr/local/bin - name: sdcc-3_8_0-stm8 run: QBS_AUTOTEST_PROFILE=sdcc-3_8_0-stm8 docker-compose run focal-baremetal scripts/test-baremetal.sh release/install-root/usr/local/bin + - name: sdcc-3_8_0-hcs8 + run: QBS_AUTOTEST_PROFILE=sdcc-3_8_0-hcs8 docker-compose run focal-baremetal scripts/test-baremetal.sh release/install-root/usr/local/bin + + test-baremetal-windows: + name: Run Baremetal tests (Windows) + runs-on: [self-hosted, windows, x64] + timeout-minutes: 30 + needs: build-windows + env: + QBS_TEST_SOURCE_ROOT: 'tests' + QT_ASSUME_STDERR_HAS_CONSOLE: 1 + steps: + - uses: actions/checkout@v1 + - name: Download artifact + uses: actions/download-artifact@v1 + with: + name: qbs-windows-${{ github.run_id }}.zip + path: ./ + - name: Unpack artifact + run: mkdir -p release/install-root/ && unzip qbs-windows-${{ github.run_id }}.zip -d release/install-root/ + shell: bash + - name: keil-9_53_0-mcs51 + run: QBS_AUTOTEST_PROFILE=keil-9_53_0-mcs51 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: keil-5_60_0-mcs251 + run: QBS_AUTOTEST_PROFILE=keil-5_60_0-mcs251 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: keil-7_57_0-c166 + run: QBS_AUTOTEST_PROFILE=keil-7_57_0-c166 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: keil-5_30_0-arm + run: QBS_AUTOTEST_PROFILE=keil-5_30_0-arm scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: keil-llvm-5_30_0-arm + run: QBS_AUTOTEST_PROFILE=keil-5_30_0-arm scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-8_50_5-arm + run: QBS_AUTOTEST_PROFILE=iar-8_50_5-arm scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-10_30_1-mcs51 + run: QBS_AUTOTEST_PROFILE=iar-10_30_1-mcs51 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-7_30_1-avr + run: QBS_AUTOTEST_PROFILE=iar-7_30_1-avr scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-4_30_2-avr32 + run: QBS_AUTOTEST_PROFILE=iar-4_30_2-avr32 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-7_20_1-msp430 + run: QBS_AUTOTEST_PROFILE=iar-7_20_1-msp430 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-3_11_2_234-stm8 + run: QBS_AUTOTEST_PROFILE=iar-3_11_2_234-stm8 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-4_20_1-rx + run: QBS_AUTOTEST_PROFILE=iar-4_20_1-rx scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-4_20_1-rl78 + run: QBS_AUTOTEST_PROFILE=iar-4_20_1-rl78 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-5_10_1-v850 + run: QBS_AUTOTEST_PROFILE=iar-5_10_1-v850 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-2_21_1-rh850 + run: QBS_AUTOTEST_PROFILE=iar-2_21_1-rh850 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-2_30_1-sh + run: QBS_AUTOTEST_PROFILE=iar-2_30_1-sh scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-4_81_1-78k + run: QBS_AUTOTEST_PROFILE=iar-4_81_1-78k scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-4_10_1-hcs12 + run: QBS_AUTOTEST_PROFILE=iar-4_10_1-hcs12 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-1_40_2-r32c + run: QBS_AUTOTEST_PROFILE=iar-1_40_2-r32c scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-3_71_1-m16c + run: QBS_AUTOTEST_PROFILE=iar-3_71_1-m16c scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-1_21_1-riscv + run: QBS_AUTOTEST_PROFILE=iar-1_21_1-riscv scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: iar-3_30_1-cr16 + run: QBS_AUTOTEST_PROFILE=iar-3_30_1-cr16 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: sdcc-4_0_0-mcs51 + run: QBS_AUTOTEST_PROFILE=sdcc-4_0_0-mcs51 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: sdcc-4_0_0-stm8 + run: QBS_AUTOTEST_PROFILE=sdcc-4_0_0-stm8 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: sdcc-4_0_0-hcs8 + run: QBS_AUTOTEST_PROFILE=sdcc-4_0_0-hcs8 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: avr-gcc-4_6_2 + run: QBS_AUTOTEST_PROFILE=avr-gcc-4_6_2 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: avr32-gcc-4_4_3 + run: QBS_AUTOTEST_PROFILE=avr32-gcc-4_4_3 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: m32c-elf-gcc-4_7_3 + run: QBS_AUTOTEST_PROFILE=m32c-elf-gcc-4_7_3 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: m32r-elf-gcc-4_8_0 + run: QBS_AUTOTEST_PROFILE=m32r-elf-gcc-4_8_0 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: m68k-elf-gcc-4_8_0 + run: QBS_AUTOTEST_PROFILE=m68k-elf-gcc-4_8_0 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: msp430-elf-gcc-8_3_1 + run: QBS_AUTOTEST_PROFILE=msp430-elf-gcc-8_3_1 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: riscv64-unknown-elf-gcc-10_1_0 + run: QBS_AUTOTEST_PROFILE=riscv64-unknown-elf-gcc-10_1_0 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: v850-elf-gcc-4_7_2 + run: QBS_AUTOTEST_PROFILE=v850-elf-gcc-4_7_2 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: arm-none-eabi-gcc-9_3_1 + run: QBS_AUTOTEST_PROFILE=arm-none-eabi-gcc-9_3_1 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: xtensa-lx106-elf-gcc-5_2_0 + run: QBS_AUTOTEST_PROFILE=xtensa-lx106-elf-gcc-5_2_0 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: xtensa-esp32-elf-gcc-8_4_0 + run: QBS_AUTOTEST_PROFILE=xtensa-esp32-elf-gcc-8_4_0 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: rl78-elf-gcc-4_9_2_202002-GNURL78 + run: QBS_AUTOTEST_PROFILE=rl78-elf-gcc-4_9_2_202002-GNURL78 scripts/test-baremetal.sh release/install-root/bin + shell: bash + - name: rx-elf-gcc-8_3_0_202004-GNURX + run: QBS_AUTOTEST_PROFILE=rx-elf-gcc-8_3_0_202004-GNURX scripts/test-baremetal.sh release/install-root/bin + shell: bash test-macos: name: ${{ matrix.config.name }} runs-on: macos-latest - timeout-minutes: 45 + timeout-minutes: 60 needs: build-macos env: QTEST_FUNCTION_TIMEOUT: 9000000 @@ -325,37 +470,57 @@ jobs: matrix: config: - { - name: 'Run macOS tests (Xcode 12.0)', + name: 'Run macOS tests (Xcode 12.4)', target: 'desktop', toolchain: 'clang_64', - testProfile: 'xcode_12-macosx-x86_64', + testProfile: 'xcode_12_4-macosx-x86_64', + qtVersion: '5.15.2', + script: './scripts/test-qbs.sh', + } + - { + name: 'Run macOS tests (Xcode 12.4, Qt 6.0)', + target: 'desktop', + toolchain: 'clang_64', + testProfile: 'xcode_12_4-macosx-x86_64', + qtVersion: '6.0.2', + script: './scripts/test-qt.sh', } - { name: 'Run macOS tests (Xcode 11.6)', target: 'desktop', toolchain: 'clang_64', testProfile: 'xcode_11_6-macosx-x86_64', + qtVersion: '5.15.2', + script: './scripts/test-qbs.sh', } - { name: 'Run macOS tests (Xcode 10.3)', target: 'desktop', toolchain: 'clang_64', testProfile: 'xcode_10_3-macosx-x86_64', + qtVersion: '5.15.2', + script: './scripts/test-qbs.sh', } - { name: 'Run iOS tests (Xcode 12.0)', target: 'ios', toolchain: 'ios', testProfile: 'xcode_12-iphoneos-arm64', + qtVersion: '5.15.2', + script: './scripts/test-qbs.sh', } - { name: 'Run iOS-sim tests (Xcode 12.0)', target: 'ios', toolchain: 'ios', testProfile: 'xcode_12-iphonesimulator-x86_64', + qtVersion: '5.15.2', + script: './scripts/test-qbs.sh', } steps: - uses: actions/checkout@v1 + with: + submodules: true - name: Download artifact uses: actions/download-artifact@v1 with: @@ -372,20 +537,30 @@ jobs: with: target: ${{ matrix.config.target }} toolchain: ${{ matrix.config.toolchain }} + version: ${{ matrix.config.qtVersion }} - name: Setup Qbs run: | qbs setup-toolchains --detect - qbs setup-qt --detect + qbs setup-qt $(which qmake) qt qbs config profiles.qt.baseProfile ${{ matrix.config.testProfile }} qbs config defaultProfile qt qbs config --list - name: Run Tests - run: ./scripts/test-qbs.sh ./release/install-root/usr/local/bin + run: | + sudo chmod g+w /cores + ulimit -c unlimited + ${{ matrix.config.script }} ./release/install-root/usr/local/bin + - name: Coredump on failure + if: ${{ failure() }} + run: | + for f in $(find /cores -maxdepth 1 -name 'core.*' -print); do + lldb --core $f --batch --one-line "bt" + done; test-windows: name: ${{ matrix.config.name }} runs-on: windows-latest - timeout-minutes: 45 + timeout-minutes: 60 needs: build-windows strategy: fail-fast: false @@ -396,12 +571,24 @@ jobs: target: 'desktop', toolchain: 'win64_msvc2019_64', testProfile: 'MSVC2019-x64', + qtVersion: '5.15.2', + script: './scripts/test-qbs.sh', + } + - { + name: 'Run Windows tests (MSVC 2019, Qt 6.0.2)', + target: 'desktop', + toolchain: 'win64_msvc2019_64', + testProfile: 'MSVC2019-x64', + qtVersion: '6.0.2', + script: './scripts/test-qt.sh', } - { name: 'Run Windows tests (clang-cl)', target: 'desktop', toolchain: 'win64_msvc2019_64', testProfile: 'clang-cl-x86_64', + qtVersion: '5.15.2', + script: './scripts/test-qbs.sh', } env: QTEST_FUNCTION_TIMEOUT: 9000000 @@ -429,6 +616,7 @@ jobs: uses: ./.github/actions/download-qt with: toolchain: ${{ matrix.config.toolchain }} + version: ${{ matrix.config.qtVersion }} - name: Setup Qbs run: | qbs setup-toolchains --detect @@ -438,5 +626,5 @@ jobs: qbs config --list shell: bash - name: Run Tests - run: ./scripts/test-qbs.sh ./release/install-root/bin + run: ${{ matrix.config.script }} ./release/install-root/bin shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5fe4c33de..f807e9117 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: build-linux: name: ${{ matrix.config.name }} runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 60 strategy: fail-fast: false matrix: @@ -66,7 +66,7 @@ jobs: build-macos: name: Build on macOS runs-on: macos-latest - timeout-minutes: 45 + timeout-minutes: 60 env: BUILD_OPTIONS: | qbs.installPrefix:"" @@ -127,7 +127,7 @@ jobs: build-windows-with-docker: name: Build on Windows (Docker) runs-on: windows-latest - timeout-minutes: 45 + timeout-minutes: 60 env: WITH_TESTS: 0 QT_ASSUME_STDERR_HAS_CONSOLE: 1 diff --git a/CMakeLists.txt b/CMakeLists.txt index f6a87d10d..8b95f959d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.10) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(FeatureSummary) -include(QbsAPI) +include(QbsBuildConfig) file(STRINGS VERSION QBS_VERSION) project(Qbs VERSION ${QBS_VERSION}) @@ -22,13 +22,6 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) -option(WITH_TESTS "Build Tests" ON) -option(WITH_UNIT_TESTS "Build Unit Tests" OFF) -option(WITH_PROJECT_FILE_UPDATES "Enable project file updates support" ON) -option(INSTALL_PUBLIC_HEADERS "Whether to install public headers" ON) -option(QBS_INSTALL_HTML_DOCS "Whether to install HTML Documentation" OFF) -option(QBS_INSTALL_QCH_DOCS "Whether to install QCH Documentation" OFF) - if(WITH_TESTS) enable_testing() set(QT_TEST_COMPONENT Test) @@ -1 +1 @@ -1.18.2 +1.19.0 diff --git a/cmake/QbsAPI.cmake b/cmake/QbsBuildConfig.cmake index 2856b2d0f..b6614ce3f 100644 --- a/cmake/QbsAPI.cmake +++ b/cmake/QbsBuildConfig.cmake @@ -1,3 +1,11 @@ +option(WITH_TESTS "Build Tests" ON) +option(WITH_UNIT_TESTS "Build Unit Tests" OFF) +option(WITH_PROJECT_FILE_UPDATES "Enable project file updates support" ON) +option(INSTALL_PUBLIC_HEADERS "Whether to install public headers" ON) +option(QBS_ENABLE_RPATH "Whether to enable RPATH" ON) +option(QBS_INSTALL_HTML_DOCS "Whether to install HTML Documentation" OFF) +option(QBS_INSTALL_QCH_DOCS "Whether to install QCH Documentation" OFF) + set(QBS_APP_INSTALL_DIR "bin" CACHE STRING "Relative install location for Qbs binaries.") # default paths set(QBS_LIBDIR_NAME "lib") @@ -26,16 +34,17 @@ set(QBS_RESOURCES_INSTALL_DIR "${QBS_RESOURCES_INSTALL_BASE}/share") file(RELATIVE_PATH QBS_RELATIVE_LIBEXEC_RPATH "/${QBS_LIBEXEC_INSTALL_DIR}" "/${QBS_LIB_INSTALL_DIR}") file(RELATIVE_PATH QBS_RELATIVE_APP_RPATH "/${QBS_APP_INSTALL_DIR}" "/${QBS_LIB_INSTALL_DIR}") file(RELATIVE_PATH QBS_RELATIVE_PLUGINS_RPATH "/${QBS_PLUGINS_INSTALL_DIR}" "/${QBS_LIB_INSTALL_DIR}") -if(APPLE) + +if(WIN32 OR NOT QBS_ENABLE_RPATH) + set(QBS_LIB_RPATH "") + set(QBS_LIBEXEC_RPATH "") + set(QBS_APP_RPATH "") + set(QBS_PLUGINS_RPATH "") +elseif(APPLE) set(QBS_LIB_RPATH "@loader_path") set(QBS_LIBEXEC_RPATH "@loader_path/${QBS_RELATIVE_LIBEXEC_RPATH}") set(QBS_APP_RPATH "@loader_path/${QBS_RELATIVE_APP_RPATH}") set(QBS_PLUGINS_RPATH "@loader_path/${QBS_RELATIVE_PLUGINS_RPATH}") -elseif(WIN32) - set(QBS_LIB_RPATH "") - set(QBS_LIBEXEC_RPATH "") - set(QBS_APP_RPATH "") - set(QBS_PLUGINS_RPATH "") else() set(QBS_LIB_RPATH "\$ORIGIN") set(QBS_LIBEXEC_RPATH "\$ORIGIN/${QBS_RELATIVE_LIBEXEC_RPATH}") @@ -51,7 +60,8 @@ function(get_update_path_command var) endif() get_filename_component(_QT_LIBRARY_PATH "${_QTCORE_LIBRARY}" DIRECTORY) get_target_property(_QBS_LIBRARY_PATH qbscore LIBRARY_OUTPUT_DIRECTORY) - set(${var} "PATH=${_QT_LIBRARY_PATH}\;${_QBS_LIBRARY_PATH}\;%PATH%" PARENT_SCOPE) + file(TO_NATIVE_PATH "${_QT_LIBRARY_PATH}\;${_QBS_LIBRARY_PATH}\;$ENV{PATH}" _NEW_PATH) + set(${var} "PATH=${_NEW_PATH}" PARENT_SCOPE) else() set(${var} "") endif() diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 74d71f4dc..0b5922a1a 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -46,8 +46,7 @@ if (QBS_INSTALL_HTML_DOCS OR QBS_INSTALL_QCH_DOCS) get_update_path_command(UPDATE_PATH_COMMAND) add_custom_target( BuildQbsDocumentation ALL - COMMAND ${UPDATE_PATH_COMMAND} - COMMAND ${_QBS_OUTPUT_DIR}/qbs + COMMAND ${CMAKE_COMMAND} -E env "${UPDATE_PATH_COMMAND}" ${_QBS_OUTPUT_DIR}/qbs resolve --settings-dir ${PROJECT_BINARY_DIR}/settings -f ${PROJECT_SOURCE_DIR}/qbs.qbs @@ -62,7 +61,7 @@ if (QBS_INSTALL_HTML_DOCS OR QBS_INSTALL_QCH_DOCS) modules.qbsbuildconfig.installHtml:${_INSTALL_HTML_DOCS} modules.qbsbuildconfig.installQch:${_INSTALL_QCH_DOCS} moduleProviders.Qt.qmakeFilePaths:${_QT_QMAKE_EXECUTABLE} - COMMAND ${_QBS_OUTPUT_DIR}/qbs + COMMAND ${CMAKE_COMMAND} -E env "${UPDATE_PATH_COMMAND}" ${_QBS_OUTPUT_DIR}/qbs build --settings-dir ${PROJECT_BINARY_DIR}/settings -f ${PROJECT_SOURCE_DIR}/qbs.qbs diff --git a/doc/config/macros.qdocconf b/doc/config/macros.qdocconf index a8abe25e5..6811215c0 100644 --- a/doc/config/macros.qdocconf +++ b/doc/config/macros.qdocconf @@ -4,6 +4,7 @@ macro.qbsversion = $QBS_VERSION macro.defaultvalue = "Default:" macro.nodefaultvalue = "Default: Undefined" macro.appleproperty = "This property is specific to Apple platforms." +macro.androidproperty = "This property is specific to Android platforms." macro.unixproperty = "This property is specific to Unix platforms." macro.windowsproperty = "This property is specific to Windows." macro.baremetalproperty = "This property is specific to bare-metal platforms." diff --git a/doc/howtos.qdoc b/doc/howtos.qdoc index 72cac2357..47c1cafe8 100644 --- a/doc/howtos.qdoc +++ b/doc/howtos.qdoc @@ -54,6 +54,7 @@ \li \l{How do I define a reusable Group of files that can be included in other \QBS files?} \li \l{How do I print the value of a property?} \li \l{How do I debug \QBS scripts?} + \li \l{How do I sign an application for an Apple platform?} \endlist \section1 How do I build a Qt-based project? @@ -776,4 +777,46 @@ \code qbs status config:release \endcode + + \section1 How do I sign an application for an Apple platform? + + To sign an application for an Apple platform, you need to use the \l{codesign} module. + + \code + Depends { name: "codesign" } + \endcode + + Several properties should be set to do signing as shown below. + + Make sure that bundle and team indentifiers match the one used for signing: + + \code + bundle.identifierPrefix: "com.johndoe" + codesign.teamIdentifier: "John Doe" + \endcode + + It is also possible to use an ID of the team identifier instead of a name: + \code + codesign.teamIdentifier: "1234ABCDEF" + \endcode + + \QBS will then try to find the matching signing identity and provisioning profile based on + \l{codesign::signingType}{codesign.signingType}. + + It is also possible to specify \l{codesign::signingIdentity}{codesign.signingIdentity} + manually: + + \code + codesign.signingIdentity: "Apple Development: johndoe@apple.com (ABCDEF1234)" + \endcode + + It is also possible to use an ID of the signing identity instead of a name: + \code + codesign.signingIdentity: "ABCDEF1234567890ABCDEF1234567890ABCDEF12" + \endcode + + If \QBS cannot find the suitable provisioning profile, you can specify it manually as well: + \code + codesign.provisioningProfile: "abcdef12-1234-5678-1111-abcdef123456" + \endcode */ diff --git a/doc/reference/items/probe/iar-probe.qdoc b/doc/reference/items/probe/iar-probe.qdoc index 948db9432..387e70b89 100644 --- a/doc/reference/items/probe/iar-probe.qdoc +++ b/doc/reference/items/probe/iar-probe.qdoc @@ -52,7 +52,10 @@ Detected architecture of the target platform's processor. - The possible values are \c "arm", \c "mcs51" and \c "avr". + The possible values are \c "arm", \c "mcs51", \c "avr", \c "avr32", + \c "stm8", \c "riscv", \c "rl78", \c "rx", \c "rh850", \c "v850", + \c "78k", \c "sh", \c "r32c", \c "m32c", \c "m16c", \c "msp430", + \c "hcs12", \c "hcs8", \c "m68k", and \c "cr16". \nodefaultvalue */ diff --git a/doc/reference/items/probe/keil-probe.qdoc b/doc/reference/items/probe/keil-probe.qdoc index 1f5fb5043..b4b56e0aa 100644 --- a/doc/reference/items/probe/keil-probe.qdoc +++ b/doc/reference/items/probe/keil-probe.qdoc @@ -52,7 +52,7 @@ Detected architecture of the target platform's processor. - The possible values are \c "arm" and \c "mcs51". + The possible values are \c "arm", \c "mcs51", \c "mcs251" and \c "c166". \nodefaultvalue */ diff --git a/doc/reference/items/probe/sdcc-probe.qdoc b/doc/reference/items/probe/sdcc-probe.qdoc index 259a7d143..06cb06891 100644 --- a/doc/reference/items/probe/sdcc-probe.qdoc +++ b/doc/reference/items/probe/sdcc-probe.qdoc @@ -52,7 +52,7 @@ Detected architecture of the target platform's processor. - The possible values are \c "mcs51". + The possible values are \c "mcs51", \c "stm8", and \c "hcs8". \nodefaultvalue */ diff --git a/doc/reference/jsextensions/jsextension-file.qdoc b/doc/reference/jsextensions/jsextension-file.qdoc index 614cc2976..f04055593 100644 --- a/doc/reference/jsextensions/jsextension-file.qdoc +++ b/doc/reference/jsextensions/jsextension-file.qdoc @@ -47,6 +47,9 @@ \note \c targetFilePath must be the counterpart of \c sourceFilePath at the new location, \b{not} the new parent directory. This allows the copy to have a different name and is true even if \c sourceFilePath is a directory. + \note The file is not copied if the source file timestamp is older than the destination file + timestamp. If you want to replace the newer file, you need to remove it first via + File.remove(). \section2 exists \code diff --git a/doc/reference/modules/codesign-module.qdoc b/doc/reference/modules/codesign-module.qdoc new file mode 100644 index 000000000..70a37477b --- /dev/null +++ b/doc/reference/modules/codesign-module.qdoc @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2021 Ivan Komissarov (abbapoh@gmail.com) +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \qmltype codesign + \inqmlmodule QbsModules + \since Qbs 1.19 + + \brief Provides code signing support. + + The \c codesign module contains properties and rules for code signing on Apple and Android + platforms. + + \section2 Relevant File Tags + + \table + \header + \li Tag + \li Auto-tagged File Names + \li Since + \li Description + \row + \li \c{"codesign.entitlements"} + \li \c{*.entitlements} + \li 1.19.0 + \li \l{https://developer.apple.com/documentation/bundleresources/entitlements}{Xcode entitlements} + \row + \li \c{"codesign.provisioningprofile"} + \li \c{*.mobileprovision, *.provisionprofile} + \li 1.19.0 + \li Xcode provisioning profiles + \row + \li \c{"codesign.signed_artifact"} + \li n/a + \li 1.19.0 + \li This tag is attached to all signed artifacts such as applications or libraries + \endtable +*/ + +/*! + \qmlproperty string codesign::codesignFlags + + Additional flags passed to the \c{codesign} tool. + + \since Qbs 1.19 + + \defaultvalue \c{undefined} + + \appleproperty +*/ + +/*! + \qmlproperty string codesign::codesignName + + The name of the \c{codesign} binary. + + \since Qbs 1.19 + + \defaultvalue \c{"codesign"} + + \appleproperty +*/ + +/*! + \qmlproperty string codesign::codesignPath + + Path to the \c{codesign} tool. + + \since Qbs 1.19 + + \defaultvalue Determined automatically + + \appleproperty +*/ + +/*! + \qmlproperty bool codesign::enableCodeSigning + + Whether to actually perform code signing. + + \since Qbs 1.19 + \defaultvalue \c false +*/ + +/*! + \qmlproperty string codesign::provisioningProfile + + Name or UUID of the provisioning profile to embed in the product. + Typically this should be left blank to allow \QBS to use automatic provisioning. + + \since Qbs 1.19 + + \defaultvalue \c undefined + + \appleproperty +*/ + +/*! + \qmlproperty path codesign::provisioningProfilesPath + + Path to directory containing provisioning profiles installed on the system. + This should not normally need to be changed. + + \since Qbs 1.19 + + \defaultvalue \c{"~/Library/MobileDevice/Provisioning Profiles"} + + \appleproperty +*/ + +/*! + \qmlproperty string codesign::signingIdentity + + Search string used to find the certificate to sign the product. This does not have to be + a full certificate name like "Mac Developer: John Doe (XXXXXXXXXX)", and can instead be + a partial string like "Mac Developer" or the certificate's SHA1 fingerprint. + The search string should generally be one of the following: + \list + \li 3rd Party Mac Developer Application + \li 3rd Party Mac Developer Installer + \li Developer ID Application + \li Developer ID Installer + \li iPhone Developer + \li iPhone Distribution + \li Mac Developer + \endlist + + It is also possible to use the special \c "-" value to use the ad-hoc signing. + + See \l{https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html#//apple_ref/doc/uid/TP40012582-CH31-SW41}{Maintaining Your Signing Identities and Certificates} + for complete documentation on the existing certificate types. + In general you should use \l{codesign::signingType}{signingType} instead. + + \since Qbs 1.19 + + \defaultvalue Determined by \l{codesign::signingType}{signingType} + + \appleproperty +*/ + +/*! + \qmlproperty string codesign::signingTimestamp + + URL of the timestamp authority server to be contacted to authenticate code signing. + \c{undefined} indicates that a system-specific default should be used, and the empty + string indicates the default server provided by Apple. \c{"none"} explicitly disables + the use of timestamp services and this should not usually need to be changed. + + \since Qbs 1.19 + + \defaultvalue \c{"none"} + + \appleproperty +*/ + +/*! + \qmlproperty string codesign::signingType + + Type of code signing to use. This should generally be used in preference to an explicit + signing identity like "Mac Developer: John Doe (XXXXXXXXXX)" since it is not user + specific and can be set in a project file. + Possible values include: \c{"app-store"}, \c{"apple-id"}, \c{"ad-hoc"}, which sign for + the App Store or Mac App Store, Developer ID, and Ad-hoc code signing, respectively. + + \section1 Relation between the signingType and signingIdentity + + The following table shows how the signingIdentity's default value is calculated. + + \table + \header + \li \c qbs.targetOS + \li \c codesign.signingType + \li \c qbs.buildVariant + \li \c codesign.signingIdentity + \row + \li {1, 4} \c "macos" + \li \c "ad-hoc" + \li any + \li \c "-" + \row + \li {1, 2} \c "app-store" + \li \c "debug", \c "profiling" + \li \c "Mac Developer" + \row + \li \c "release" + \li \c "3rd Party Mac Developer Application" + \row + \li \c "apple-id" + \li any + \li \c "Developer ID Application" + \row + \li {1, 2} \c "ios", \c "tvos", \c "watchos" + \li {1, 2} \c "app-store" + \li \c "debug", \c "profiling" + \li \c "iPhone Developer" + \row + \li \c "release" + \li \c "iPhone Distribution" + \endtable + + \since Qbs 1.19 + + \defaultvalue Determined automatically + + \appleproperty +*/ + +/*! + \qmlproperty string codesign::teamIdentifier + + Human readable name or 10-digit identifier of the Apple development team that the + signing identity belongs to. This is used to disambiguate between multiple certificates + of the same type in different teams. Typically this can be left blank if the development + machine is only signed in to a single development team, and should be set in a profile + otherwise. + + \since Qbs 1.19 + + \defaultvalue \c undefined + + \appleproperty +*/ + +/*! + \qmlproperty bool codesign::useApksigner + + If \c true, the package is signed using apksignerFilePath binary. + Set this property to \c false to use the jarsignerFilePath one. + Set by the Android.sdk module. + + \since Qbs 1.19 + + \defaultvalue \c true + + \androidproperty +*/ + +/*! + \qmlproperty string codesign::keystorePath + + The absolute path to the keystore file. + + \since Qbs 1.19 + + \defaultvalue \c "${HOME}/.android/debug.keystore" + + \androidproperty +*/ + +/*! + \qmlproperty string codesign::keystorePassword + + The keystore password. + + \since Qbs 1.19 + + \defaultvalue \c "android" + + \androidproperty +*/ + +/*! + \qmlproperty string codesign::keyPassword + + The key password. + + \since Qbs 1.19 + + \defaultvalue \c "android" + + \androidproperty +*/ + +/*! + \qmlproperty string codesign::keyAlias + + The key alias. + + \since Qbs 1.19 + + \defaultvalue \c "androiddebugkey" + + \androidproperty +*/ diff --git a/doc/reference/modules/cpp-module.qdoc b/doc/reference/modules/cpp-module.qdoc index 9925c1a57..1628bc80e 100644 --- a/doc/reference/modules/cpp-module.qdoc +++ b/doc/reference/modules/cpp-module.qdoc @@ -618,6 +618,38 @@ */ /*! + \qmlproperty string cpp::objectSuffix + + A string to append to the generated object files. + + \defaultvalue \l{qbs::toolchain}{toolchain}-dependent, typical values are \c ".o" or \c ".obj" +*/ + +/*! + \qmlproperty string cpp::linkerMapSuffix + + A string to append to the generated linker memory map files. + + \defaultvalue \l{qbs::toolchain}{toolchain}-dependent, typical value is \c ".map" +*/ + +/*! + \qmlproperty string cpp::compilerListingSuffix + + A string to append to the generated compiler listing files. + + \defaultvalue \l{qbs::toolchain}{toolchain}-dependent, typical value is \c ".lst" +*/ + +/*! + \qmlproperty string cpp::assemblerListingSuffix + + A string to append to the generated assembler listing files. + + \defaultvalue \l{qbs::toolchain}{toolchain}-dependent, typical value is \c ".lst" +*/ + +/*! \qmlproperty pathList cpp::prefixHeaders \since Qbs 1.0.1 @@ -1367,11 +1399,24 @@ Set this property to force the use of a specific linker. A non-empty value will result in the \c {-fuse-ld} option being emitted when linking with \c gcc, - \c clang or \c clang-cl. + \c clang or \c clang-cl. Other toolchains do not support this property. The possible values for \c clang and \c gcc are \c "bfd", \c "gold" and \c "lld", the possible values for \c clang-cl are \c "link" and \c "lld". + The following example demonstrates how to change the linker for different toolchains: + + \code + Properties { + condition: qbs.toolchain.contains("gcc") + cpp.linkerVariant: "gold" + } + Properties { + condition: qbs.toolchain.contains("clang-cl") + cpp.linkerVariant: "lld" + } + \endcode + \nodefaultvalue */ @@ -1869,3 +1914,14 @@ \defaultvalue \c{true} */ + +/*! + \qmlproperty string cpp::windowsSdkVersion + \since Qbs 1.19 + + Which Windows SDK version should be used with MSVC toolchain. By default, + the latest SDK is used. + + \windowsproperty + \nodefaultvalue +*/ diff --git a/doc/reference/modules/qbs-module.qdoc b/doc/reference/modules/qbs-module.qdoc index 6c4fbec0d..f8d48ddb4 100644 --- a/doc/reference/modules/qbs-module.qdoc +++ b/doc/reference/modules/qbs-module.qdoc @@ -331,10 +331,19 @@ \li \c{"avr32"} \li 32-bit RISC architecture microcontroller family developed by Atmel \row + \li \c{"c166"} + \li 16-bit architecture microcontroller family developed by Infineon + \row \li \c{"cr16"} \li 16-bit compact RISC architecture microcontroller family developed by National Semiconductor \row + \li \c{"hcs8"} + \li 8-bit HC08 and S08 microcontroller family from Freescale Semiconductor + \row + \li \c{"hcs12"} + \li 16-bit HC12 and S12 microcontroller family from Freescale Semiconductor + \row \li \c{"ia64"} \li 64-bit ISA architecture of the Itanium family processors developed by Intel @@ -357,6 +366,10 @@ Semiconductor Products Sector, and further improved as ColdFire architecture developed by NXP \row + \li \c{"mcs251"} + \li 8-, 16-, and 32-bit microcontroller family which is a next binary + compatible generation for the \c "mcs51" family + \row \li \c{"mcs51"} \li 8-bit Harvard architecture microcontroller family developed by Intel \row diff --git a/docker-compose.yml b/docker-compose.yml index 4a2851e8e..2df603fc5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,13 +21,24 @@ services: focal: << : *linux hostname: focal - image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-5.15.0_1.15.1-0 + image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-5.15.2_1.17.1-1 build: dockerfile: docker/focal/Dockerfile context: . args: - QT_VERSION: 5.15.0 - QTCREATOR_VERSION: 4.11.2 + QT_VERSION: 5.15.2 + QTCREATOR_VERSION: 4.13.3 + + focal-qt6: + << : *linux + hostname: focal-qt6 + image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-qt6-6.0.2_1.18.1-0 + build: + dockerfile: docker/focal/Dockerfile + context: . + args: + QT_VERSION: 6.0.2 + QTCREATOR_VERSION: 4.14.1 focal-android-513: << : *linux @@ -72,7 +83,7 @@ services: focal-baremetal: << : *linux hostname: focal-baremetal - image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-baremetal-2 + image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-baremetal-4 build: dockerfile: docker/focal/test-baremetal.Dockerfile context: . diff --git a/docker/focal/Dockerfile b/docker/focal/Dockerfile index e4e239529..22c5c3373 100644 --- a/docker/focal/Dockerfile +++ b/docker/focal/Dockerfile @@ -57,6 +57,7 @@ RUN apt-get update -qq && \ libnanopb-dev \ libprotobuf-dev \ libgrpc++-dev \ + libxkbcommon-x11-0 \ nanopb \ ninja-build \ nsis \ @@ -85,7 +86,7 @@ ENV LLVM_INSTALL_DIR=/usr/lib/llvm-8 # COPY scripts/install-qt.sh install-qt.sh -RUN ./install-qt.sh --version ${QT_VERSION} qtbase qtdeclarative qtscript qttools qtx11extras qtscxml icu && \ +RUN ./install-qt.sh --version ${QT_VERSION} qtbase qtdeclarative qtscript qttools qtx11extras qtscxml qt5compat icu && \ ./install-qt.sh --version ${QTCREATOR_VERSION} qtcreator && \ echo "export PATH=/opt/Qt/${QT_VERSION}/gcc_64/bin:/opt/Qt/Tools/QtCreator/bin:\${PATH}" > /etc/profile.d/qt.sh diff --git a/docker/focal/test-baremetal.Dockerfile b/docker/focal/test-baremetal.Dockerfile index 0265ff135..5bef208ca 100644 --- a/docker/focal/test-baremetal.Dockerfile +++ b/docker/focal/test-baremetal.Dockerfile @@ -41,7 +41,10 @@ RUN apt-get update -qq && \ gcc-avr \ avr-libc \ gcc-msp430 \ - sdcc + sdcc \ + binutils-xtensa-lx106 \ + gcc-xtensa-lx106 \ + gcc-riscv64-unknown-elf # Work-around for QTBUG-79020. RUN echo "export QT_NO_GLIB=1" >> /etc/profile.d/qt.sh diff --git a/examples/cocoa-application/app.qbs b/examples/cocoa-application/app.qbs index f51f94e8b..67558e8a5 100644 --- a/examples/cocoa-application/app.qbs +++ b/examples/cocoa-application/app.qbs @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import qbs +import qbs.Utilities CppApplication { Depends { condition: product.condition; name: "ib" } @@ -100,4 +100,11 @@ CppApplication { } ib.appIconName: "AppIcon" + + Properties { + // codesign module only present starting from 1.19 + condition: Utilities.versionCompare(qbs.version, "1.19") >= 0 + codesign.enableCodeSigning: true + codesign.signingType: "ad-hoc" + } } diff --git a/examples/cocoa-touch-application/CocoaTouchApplication.xcodeproj/project.pbxproj b/examples/cocoa-touch-application/CocoaTouchApplication.xcodeproj/project.pbxproj index 07f3a1a46..62d4425c9 100644 --- a/examples/cocoa-touch-application/CocoaTouchApplication.xcodeproj/project.pbxproj +++ b/examples/cocoa-touch-application/CocoaTouchApplication.xcodeproj/project.pbxproj @@ -13,15 +13,13 @@ 14E3FEB4175FB2E800C857C6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 14E3FEB2175FB2E800C857C6 /* InfoPlist.strings */; }; 14E3FEB6175FB2E800C857C6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 14E3FEB5175FB2E800C857C6 /* main.m */; }; 14E3FEBA175FB2E800C857C6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 14E3FEB9175FB2E800C857C6 /* AppDelegate.m */; }; - 14E3FEBC175FB2E800C857C6 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 14E3FEBB175FB2E800C857C6 /* Default.png */; }; - 14E3FEBE175FB2E800C857C6 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 14E3FEBD175FB2E800C857C6 /* Default@2x.png */; }; - 14E3FEC0175FB2E800C857C6 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 14E3FEBF175FB2E800C857C6 /* Default-568h@2x.png */; }; 14E3FEC3175FB2E800C857C6 /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 14E3FEC2175FB2E800C857C6 /* MasterViewController.m */; }; 14E3FEC6175FB2E900C857C6 /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 14E3FEC5175FB2E900C857C6 /* DetailViewController.m */; }; 14E3FEC9175FB2E900C857C6 /* MasterViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 14E3FEC7175FB2E900C857C6 /* MasterViewController_iPhone.xib */; }; 14E3FECC175FB2E900C857C6 /* MasterViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 14E3FECA175FB2E900C857C6 /* MasterViewController_iPad.xib */; }; 14E3FECF175FB2E900C857C6 /* DetailViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 14E3FECD175FB2E900C857C6 /* DetailViewController_iPhone.xib */; }; 14E3FED2175FB2E900C857C6 /* DetailViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 14E3FED0175FB2E900C857C6 /* DetailViewController_iPad.xib */; }; + AC83486F258674C900A9CBBB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AC83486E258674C900A9CBBB /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -35,9 +33,6 @@ 14E3FEB7175FB2E800C857C6 /* CocoaTouchApplication-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CocoaTouchApplication-Prefix.pch"; sourceTree = "<group>"; }; 14E3FEB8175FB2E800C857C6 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 14E3FEB9175FB2E800C857C6 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; - 14E3FEBB175FB2E800C857C6 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; }; - 14E3FEBD175FB2E800C857C6 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = "<group>"; }; - 14E3FEBF175FB2E800C857C6 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; }; 14E3FEC1175FB2E800C857C6 /* MasterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = "<group>"; }; 14E3FEC2175FB2E800C857C6 /* MasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = "<group>"; }; 14E3FEC4175FB2E800C857C6 /* DetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = "<group>"; }; @@ -46,6 +41,7 @@ 14E3FECB175FB2E900C857C6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MasterViewController_iPad.xib; sourceTree = "<group>"; }; 14E3FECE175FB2E900C857C6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DetailViewController_iPhone.xib; sourceTree = "<group>"; }; 14E3FED1175FB2E900C857C6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DetailViewController_iPad.xib; sourceTree = "<group>"; }; + AC83486E258674C900A9CBBB /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -103,6 +99,7 @@ 14E3FECD175FB2E900C857C6 /* DetailViewController_iPhone.xib */, 14E3FED0175FB2E900C857C6 /* DetailViewController_iPad.xib */, 14E3FEB0175FB2E800C857C6 /* Supporting Files */, + AC83486E258674C900A9CBBB /* LaunchScreen.storyboard */, ); path = CocoaTouchApplication; sourceTree = "<group>"; @@ -114,9 +111,6 @@ 14E3FEB2175FB2E800C857C6 /* InfoPlist.strings */, 14E3FEB5175FB2E800C857C6 /* main.m */, 14E3FEB7175FB2E800C857C6 /* CocoaTouchApplication-Prefix.pch */, - 14E3FEBB175FB2E800C857C6 /* Default.png */, - 14E3FEBD175FB2E800C857C6 /* Default@2x.png */, - 14E3FEBF175FB2E800C857C6 /* Default-568h@2x.png */, ); name = "Supporting Files"; sourceTree = "<group>"; @@ -147,14 +141,15 @@ 14E3FE9E175FB2E800C857C6 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; - ORGANIZATIONNAME = "Petroules Corporation"; + LastUpgradeCheck = 1220; + ORGANIZATIONNAME = io.qbs; }; buildConfigurationList = 14E3FEA1175FB2E800C857C6 /* Build configuration list for PBXProject "CocoaTouchApplication" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 14E3FE9D175FB2E800C857C6; @@ -172,10 +167,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + AC83486F258674C900A9CBBB /* LaunchScreen.storyboard in Resources */, 14E3FEB4175FB2E800C857C6 /* InfoPlist.strings in Resources */, - 14E3FEBC175FB2E800C857C6 /* Default.png in Resources */, - 14E3FEBE175FB2E800C857C6 /* Default@2x.png in Resources */, - 14E3FEC0175FB2E800C857C6 /* Default-568h@2x.png in Resources */, 14E3FEC9175FB2E900C857C6 /* MasterViewController_iPhone.xib in Resources */, 14E3FECC175FB2E900C857C6 /* MasterViewController_iPad.xib in Resources */, 14E3FECF175FB2E900C857C6 /* DetailViewController_iPhone.xib in Resources */, @@ -247,27 +240,48 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -278,20 +292,40 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -305,6 +339,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "CocoaTouchApplication/CocoaTouchApplication-Prefix.pch"; INFOPLIST_FILE = "CocoaTouchApplication/CocoaTouchApplication-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "io.qbs.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -316,6 +351,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "CocoaTouchApplication/CocoaTouchApplication-Prefix.pch"; INFOPLIST_FILE = "CocoaTouchApplication/CocoaTouchApplication-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "io.qbs.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/examples/cocoa-touch-application/CocoaTouchApplication/AppDelegate.m b/examples/cocoa-touch-application/CocoaTouchApplication/AppDelegate.m index ed4d9f310..b93bcf2c7 100644 --- a/examples/cocoa-touch-application/CocoaTouchApplication/AppDelegate.m +++ b/examples/cocoa-touch-application/CocoaTouchApplication/AppDelegate.m @@ -40,32 +40,24 @@ @synthesize navigationController = _navigationController; @synthesize splitViewController = _splitViewController; -- (void)dealloc -{ - [_window release]; - [_navigationController release]; - [_splitViewController release]; - [super dealloc]; -} - - (BOOL)application:(UIApplication *) __unused application didFinishLaunchingWithOptions:(NSDictionary *) __unused launchOptions { - self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { - MasterViewController *masterViewController = [[[MasterViewController alloc] initWithNibName:@"MasterViewController_iPhone" bundle:nil] autorelease]; - self.navigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease]; + MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController_iPhone" bundle:nil]; + self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController]; self.window.rootViewController = self.navigationController; } else { - MasterViewController *masterViewController = [[[MasterViewController alloc] initWithNibName:@"MasterViewController_iPad" bundle:nil] autorelease]; - UINavigationController *masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease]; + MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController_iPad" bundle:nil]; + UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController]; - DetailViewController *detailViewController = [[[DetailViewController alloc] initWithNibName:@"DetailViewController_iPad" bundle:nil] autorelease]; - UINavigationController *detailNavigationController = [[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease]; + DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController_iPad" bundle:nil]; + UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController]; masterViewController.detailViewController = detailViewController; - self.splitViewController = [[[UISplitViewController alloc] init] autorelease]; + self.splitViewController = [[UISplitViewController alloc] init]; self.splitViewController.delegate = detailViewController; self.splitViewController.viewControllers = [NSArray arrayWithObjects:masterNavigationController, detailNavigationController, nil]; diff --git a/examples/cocoa-touch-application/CocoaTouchApplication/CocoaTouchApplication-Info.plist b/examples/cocoa-touch-application/CocoaTouchApplication/CocoaTouchApplication-Info.plist index f95cb4555..8075a9d96 100644 --- a/examples/cocoa-touch-application/CocoaTouchApplication/CocoaTouchApplication-Info.plist +++ b/examples/cocoa-touch-application/CocoaTouchApplication/CocoaTouchApplication-Info.plist @@ -9,7 +9,7 @@ <key>CFBundleExecutable</key> <string>${EXECUTABLE_NAME}</string> <key>CFBundleIdentifier</key> - <string>org.example.${PRODUCT_NAME:rfc1034identifier}</string> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> @@ -24,6 +24,8 @@ <string>1.0</string> <key>LSRequiresIPhoneOS</key> <true/> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> <key>UIRequiredDeviceCapabilities</key> <array> <string>armv7</string> diff --git a/examples/cocoa-touch-application/CocoaTouchApplication/Default-568h@2x.png b/examples/cocoa-touch-application/CocoaTouchApplication/Default-568h@2x.png Binary files differdeleted file mode 100644 index 0891b7aab..000000000 --- a/examples/cocoa-touch-application/CocoaTouchApplication/Default-568h@2x.png +++ /dev/null diff --git a/examples/cocoa-touch-application/CocoaTouchApplication/Default.png b/examples/cocoa-touch-application/CocoaTouchApplication/Default.png Binary files differdeleted file mode 100644 index 4c8ca6f69..000000000 --- a/examples/cocoa-touch-application/CocoaTouchApplication/Default.png +++ /dev/null diff --git a/examples/cocoa-touch-application/CocoaTouchApplication/Default@2x.png b/examples/cocoa-touch-application/CocoaTouchApplication/Default@2x.png Binary files differdeleted file mode 100644 index 35b84cffe..000000000 --- a/examples/cocoa-touch-application/CocoaTouchApplication/Default@2x.png +++ /dev/null diff --git a/examples/cocoa-touch-application/CocoaTouchApplication/DetailViewController.m b/examples/cocoa-touch-application/CocoaTouchApplication/DetailViewController.m index 85a5d6ddb..dbe821650 100644 --- a/examples/cocoa-touch-application/CocoaTouchApplication/DetailViewController.m +++ b/examples/cocoa-touch-application/CocoaTouchApplication/DetailViewController.m @@ -41,21 +41,12 @@ @synthesize detailDescriptionLabel = _detailDescriptionLabel; @synthesize masterPopoverController = _masterPopoverController; -- (void)dealloc -{ - [_detailItem release]; - [_detailDescriptionLabel release]; - [_masterPopoverController release]; - [super dealloc]; -} - #pragma mark - Managing the detail item - (void)setDetailItem:(id)newDetailItem { if (_detailItem != newDetailItem) { - [_detailItem release]; - _detailItem = [newDetailItem retain]; + _detailItem = newDetailItem; // Update the view. [self configureView]; diff --git a/examples/cocoa-touch-application/CocoaTouchApplication/LaunchScreen.storyboard b/examples/cocoa-touch-application/CocoaTouchApplication/LaunchScreen.storyboard new file mode 100644 index 000000000..344bbca5c --- /dev/null +++ b/examples/cocoa-touch-application/CocoaTouchApplication/LaunchScreen.storyboard @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> + <device id="retina3_5" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17505"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <scenes> + <!--View Controller--> + <scene sceneID="EHf-IW-A2E"> + <objects> + <viewController id="01J-lp-oVM" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> + <rect key="frame" x="0.0" y="0.0" width="320" height="480"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Copyright © 2020 io.qbs. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="obG-Y5-kRd"> + <rect key="frame" x="0.0" y="439.5" width="320" height="20.5"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <nil key="highlightedColor"/> + </label> + <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Cocoa Touch Application" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb"> + <rect key="frame" x="0.0" y="139.5" width="320" height="43"/> + <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/> + <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/> + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <constraints> + <constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="obG-Y5-kRd" secondAttribute="centerX" id="5cz-MP-9tL"/> + <constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="GJd-Yh-RWb" secondAttribute="centerX" id="Q3B-4B-g5h"/> + <constraint firstItem="obG-Y5-kRd" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" constant="20" symbolic="YES" id="SfN-ll-jLj"/> + <constraint firstAttribute="bottom" secondItem="obG-Y5-kRd" secondAttribute="bottom" constant="20" id="Y44-ml-fuU"/> + <constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/> + <constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" symbolic="YES" id="x7j-FC-K8j"/> + </constraints> + </view> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="53" y="375"/> + </scene> + </scenes> +</document> diff --git a/examples/cocoa-touch-application/CocoaTouchApplication/MasterViewController.m b/examples/cocoa-touch-application/CocoaTouchApplication/MasterViewController.m index ebac52dcd..fe8afba09 100644 --- a/examples/cocoa-touch-application/CocoaTouchApplication/MasterViewController.m +++ b/examples/cocoa-touch-application/CocoaTouchApplication/MasterViewController.m @@ -49,20 +49,13 @@ return self; } -- (void)dealloc -{ - [_detailViewController release]; - [_objects release]; - [super dealloc]; -} - - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.navigationItem.leftBarButtonItem = self.editButtonItem; - UIBarButtonItem *addButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)] autorelease]; + UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)]; self.navigationItem.rightBarButtonItem = addButton; } @@ -101,7 +94,7 @@ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { - cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } @@ -150,7 +143,7 @@ NSDate *object = [_objects objectAtIndex:indexPath.row]; if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { if (!self.detailViewController) { - self.detailViewController = [[[DetailViewController alloc] initWithNibName:@"DetailViewController_iPhone" bundle:nil] autorelease]; + self.detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController_iPhone" bundle:nil]; } self.detailViewController.detailItem = object; [self.navigationController pushViewController:self.detailViewController animated:YES]; diff --git a/examples/cocoa-touch-application/CocoaTouchApplication/main.m b/examples/cocoa-touch-application/CocoaTouchApplication/main.m index 7665efcf1..0d92018b6 100644 --- a/examples/cocoa-touch-application/CocoaTouchApplication/main.m +++ b/examples/cocoa-touch-application/CocoaTouchApplication/main.m @@ -33,8 +33,8 @@ int main(int argc, char *argv[]) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - int retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - [pool release]; - return retVal; + @autoreleasepool + { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } } diff --git a/examples/cocoa-touch-application/cocoa-touch-application.qbs b/examples/cocoa-touch-application/cocoa-touch-application.qbs index ec1772f1f..bf2fb4080 100644 --- a/examples/cocoa-touch-application/cocoa-touch-application.qbs +++ b/examples/cocoa-touch-application/cocoa-touch-application.qbs @@ -56,9 +56,14 @@ CppApplication { Depends { condition: product.condition; name: "ib" } condition: qbs.hostOS.contains("macos") && xcode.present && qbs.targetPlatform.contains("ios") name: "Cocoa Touch Application" + install: true + + bundle.identifierPrefix: "io.qbs" + bundle.infoPlist: ({"UILaunchStoryboardName": "LaunchScreen"}) cpp.useObjcPrecompiledHeader: true - cpp.minimumIosVersion: "8.0" + cpp.minimumIosVersion: "9.0" + cpp.automaticReferenceCounting: true cpp.frameworks: [ "UIKit", "Foundation", "CoreGraphics" ] Group { @@ -67,9 +72,6 @@ CppApplication { "AppDelegate.h", "AppDelegate.m", "CocoaTouchApplication-Info.plist", - "Default-568h@2x.png", - "Default.png", - "Default@2x.png", "DetailViewController.h", "DetailViewController.m", "MasterViewController.h", @@ -84,13 +86,22 @@ CppApplication { files: [ "DetailViewController_iPad.xib", "DetailViewController_iPhone.xib", - "InfoPlist.strings", "MasterViewController_iPad.xib", "MasterViewController_iPhone.xib" ] } Group { + id: bundle_resources + files: [ + "CocoaTouchApplication/LaunchScreen.storyboard", + "CocoaTouchApplication/en.lproj/InfoPlist.strings" + ] + } + + bundle.resources: bundle_resources.files + + Group { name: "Xcode Project" files: [ "CocoaTouchApplication.xcodeproj/project.pbxproj" diff --git a/examples/protobuf/addressbook_objc/addressbook_objc.qbs b/examples/protobuf/addressbook_objc/addressbook_objc.qbs index 35409c4db..fe819d77a 100644 --- a/examples/protobuf/addressbook_objc/addressbook_objc.qbs +++ b/examples/protobuf/addressbook_objc/addressbook_objc.qbs @@ -7,8 +7,9 @@ CppApplication { Depends { name: "cpp" } Depends { name: "protobuf.objc"; required: false } - files: [ - "../shared/addressbook.proto", - "main.m", - ] + Group { + cpp.automaticReferenceCounting: true + files: "main.m" + } + files: "../shared/addressbook.proto" } diff --git a/examples/protobuf/addressbook_objc/main.m b/examples/protobuf/addressbook_objc/main.m index 0c330a6c5..5e21fa060 100644 --- a/examples/protobuf/addressbook_objc/main.m +++ b/examples/protobuf/addressbook_objc/main.m @@ -55,8 +55,7 @@ int printUsage(char *argv0) { NSString *programName = [[NSString alloc] initWithUTF8String:argv0]; - NSLog(@"%@", [[NSString alloc] initWithFormat:@"Usage: %@ add|list ADDRESS_BOOK_FILE", programName]); - [programName release]; + NSLog(@"Usage: %@ add|list ADDRESS_BOOK_FILE", programName); return -1; } @@ -65,9 +64,9 @@ NSString *readString(NSString *promt) NSLog(@"%@", promt); NSFileHandle *inputFile = [NSFileHandle fileHandleWithStandardInput]; NSData *inputData = [inputFile availableData]; - NSString *result = [[[NSString alloc]initWithData:inputData encoding:NSUTF8StringEncoding] autorelease]; - result = [[result stringByTrimmingCharactersInSet: - [NSCharacterSet whitespaceAndNewlineCharacterSet]] autorelease]; + NSString *result = [[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding]; + result = [result stringByTrimmingCharactersInSet: + [NSCharacterSet whitespaceAndNewlineCharacterSet]]; return result; } @@ -98,7 +97,7 @@ void promptForAddress(Person* person) else if ([type compare:@"work"] == NSOrderedSame) phoneNumber.type = Person_PhoneType_Work; else - NSLog(@"%@", @"Unknown phone type. Using default."); + NSLog(@"Unknown phone type. Using default."); [person.phonesArray addObject:phoneNumber]; } @@ -107,20 +106,15 @@ void promptForAddress(Person* person) // Iterates though all people in the AddressBook and prints info about them. void listPeople(AddressBook *addressBook) { - NSArray *people = addressBook.peopleArray; - for (unsigned i = 0; i < [people count]; i++) { - Person *person = [people objectAtIndex:i]; - - NSLog(@"%@", [[[NSString alloc] initWithFormat:@"Person ID: %d", person.id_p] autorelease]); - NSLog(@"%@", [[[NSString alloc] initWithFormat:@"Person name: %@", person.name] autorelease]); + for (Person *person in addressBook.peopleArray) { + NSLog(@"Person ID: %d", person.id_p); + NSLog(@"Person name: %@", person.name); if ([person.email length] != 0) { - NSLog(@"%@", [[[NSString alloc] initWithFormat:@"E-mail address: %@", person.email] autorelease]); + NSLog(@"E-mail address: %@", person.email); } - NSArray *phones = person.phonesArray; - for (unsigned j = 0; j < [phones count]; j++) { - Person_PhoneNumber *phoneNumber = [phones objectAtIndex:j]; + for (Person_PhoneNumber *phoneNumber in person.phonesArray) { NSString *phonePrefix; switch (phoneNumber.type) { @@ -138,7 +132,7 @@ void listPeople(AddressBook *addressBook) break; } - NSLog(@"%@", [[[NSString alloc] initWithFormat:@" %@ #: %@", phonePrefix, phoneNumber.number] autorelease]); + NSLog(@" %@ #: %@", phonePrefix, phoneNumber.number); } printf("\n"); } @@ -149,43 +143,41 @@ int main(int argc, char *argv[]) if (argc != 3) return printUsage(argv[0]); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - AddressBook *addressBook;// = [AddressBook alloc]; - NSString *filePath = [[[NSString alloc] initWithUTF8String:argv[2]] autorelease]; - - // Read the existing address book. - NSData *data = [NSData dataWithContentsOfFile:filePath]; - if (!data) { - NSLog(@"%@", [[NSString alloc] initWithFormat:@"%@ : File not found.", filePath]); - addressBook = [[[AddressBook alloc] init] autorelease]; - } else { - NSError *error; - addressBook = [AddressBook parseFromData:data error:&error]; - if (!addressBook) { - NSLog(@"%@", @"Failed to parse address book."); - [pool drain]; - return -1; + @autoreleasepool + { + AddressBook *addressBook; + NSString *filePath = [[NSString alloc] initWithUTF8String:argv[2]]; + + // Read the existing address book. + NSData *data = [NSData dataWithContentsOfFile:filePath]; + if (!data) { + NSLog(@"%@ : File not found.", filePath); + addressBook = [[AddressBook alloc] init]; + } else { + NSError *error; + addressBook = [AddressBook parseFromData:data error:&error]; + if (!addressBook) { + NSLog(@"Failed to parse address book."); + return -1; + } } - } - if (strcmp(argv[1], "add") == 0) { - // Add an address. - Person *person = [[Person alloc] init]; - promptForAddress(person); - [addressBook.peopleArray addObject:person]; + if (strcmp(argv[1], "add") == 0) { + // Add an address. + Person *person = [[Person alloc] init]; + promptForAddress(person); + [addressBook.peopleArray addObject:person]; - if (!data) { - NSLog(@"%@", @"Creating a new file."); + if (!data) { + NSLog(@"Creating a new file."); + } + [[addressBook data] writeToFile:filePath atomically:YES]; + } else if (strcmp(argv[1], "list") == 0) { + listPeople(addressBook); + } else { + return printUsage(argv[0]); } - [[addressBook data] writeToFile:filePath atomically:YES]; - } else if (strcmp(argv[1], "list") == 0) { - listPeople(addressBook); - } else { - [pool drain]; - return printUsage(argv[0]); - } - [pool drain]; - return 0; + return 0; + } } diff --git a/qbs-resources/imports/QbsUnittest.qbs b/qbs-resources/imports/QbsUnittest.qbs new file mode 100644 index 000000000..30e93e65c --- /dev/null +++ b/qbs-resources/imports/QbsUnittest.qbs @@ -0,0 +1,22 @@ +import qbs +import qbs.FileInfo +import qbs.Utilities + +QbsAutotest { + Depends { + name: "Qt.core5compat"; + condition: Utilities.versionCompare(Qt.core.version, "6.0.0") >= 0 + } + Depends { + name: "Qt.script" + condition: !qbsbuildconfig.useBundledQtScript + required: false + } + Depends { + name: "qbsscriptengine" + condition: qbsbuildconfig.useBundledQtScript || !Qt.script.present + } + property stringList bundledQtScriptIncludes: qbsbuildconfig.useBundledQtScript + || !Qt.script.present ? qbsscriptengine.includePaths : [] + cpp.includePaths: base.concat(bundledQtScriptIncludes) +} diff --git a/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs b/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs index ffa61ec03..374fdfacc 100644 --- a/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs +++ b/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs @@ -11,7 +11,7 @@ Module { property bool enableUbSanitizer: false property bool enableThreadSanitizer: false property bool enableUnitTests: false - property bool enableProjectFileUpdates: false + property bool enableProjectFileUpdates: true property bool enableRPath: true property bool installApiHeaders: true property bool enableBundledQt: false diff --git a/scripts/install-qt.sh b/scripts/install-qt.sh index f85ea157a..9a3595062 100755 --- a/scripts/install-qt.sh +++ b/scripts/install-qt.sh @@ -222,6 +222,22 @@ if ${INSTALLATION_IS_VALID}; then exit 0 fi +MIRRORS="\ + http://download.qt.io \ + http://ftp.acc.umu.se/mirror/qt.io/qtproject \ + http://qt.mirrors.tds.net/qt \ + http://ftp.fau.de/qtproject \ +" + +for MIRROR in ${MIRRORS}; do + if curl "${MIRROR}/online" -s -f -o /dev/null; then + break; + else + echo "Server ${MIRROR} not availabe. Trying next alternative..." >&2 + MIRROR="" + fi +done + DOWNLOAD_DIR=`mktemp -d 2>/dev/null || mktemp -d -t 'install-qt'` # @@ -230,13 +246,13 @@ DOWNLOAD_DIR=`mktemp -d 2>/dev/null || mktemp -d -t 'install-qt'` function compute_url(){ local COMPONENT=$1 local CURL="curl -s -L" - local BASE_URL="http://download.qt.io/online/qtsdkrepository/${HOST_OS}/${TARGET_PLATFORM}" + local BASE_URL="${MIRROR}/online/qtsdkrepository/${HOST_OS}/${TARGET_PLATFORM}" local ANDROID_ARCH=$(echo ${TOOLCHAIN##android_}) if [[ "${COMPONENT}" =~ "qtcreator" ]]; then SHORT_VERSION=${VERSION%??} - BASE_URL="http://download.qt.io/official_releases/qtcreator" + BASE_URL="${MIRROR}/official_releases/qtcreator" REMOTE_PATH="${SHORT_VERSION}/${VERSION}/installer_source/${HOST_OS}/qtcreator.7z" echo "${BASE_URL}/${REMOTE_PATH}" return 0 @@ -245,6 +261,7 @@ function compute_url(){ REMOTE_BASES=( # New repository format (>=6.0.0) "qt6_${VERSION//./}/qt.qt6.${VERSION//./}.${TOOLCHAIN}" + "qt6_${VERSION//./}/qt.qt6.${VERSION//./}.${COMPONENT}.${TOOLCHAIN}" "qt6_${VERSION//./}_${ANDROID_ARCH}/qt.qt6.${VERSION//./}.${TOOLCHAIN}" "qt6_${VERSION//./}_${ANDROID_ARCH}/qt.qt6.${VERSION//./}.${COMPONENT}.${TOOLCHAIN}" # New repository format (>=5.9.6) @@ -271,16 +288,39 @@ function compute_url(){ exit 1 } +function version { + echo "$@" | awk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'; +} + mkdir -p ${INSTALL_DIR} rm -f "${HASH_FILEPATH}" for COMPONENT in ${COMPONENTS}; do + if [[ "${COMPONENT}" =~ "qtcreator" ]] && [[ "${HOST_OS}" != "mac_x64" ]]; then + UNPACK_DIR="${INSTALL_DIR}/Tools/QtCreator" + mkdir -p ${UNPACK_DIR} + else + UNPACK_DIR="${INSTALL_DIR}" + fi + + if [ "$(version "${VERSION}")" -ge "$(version "6.0.0")" ]; then + if [[ "${COMPONENT}" =~ "qtscript" ]] || [[ "${COMPONENT}" =~ "qtscxml" ]] || [[ "${COMPONENT}" =~ "qtx11extras" ]]; then + echo "Component ${COMPONENT} was removed in Qt6, skipping" >&2 + continue + fi + else + if [[ "${COMPONENT}" =~ "qt5compat" ]]; then + echo "Component ${COMPONENT} is not present in Qt ${VERSION}, skipping" >&2 + continue + fi + fi + URL="$(compute_url ${COMPONENT})" echo "Downloading ${COMPONENT} ${URL}..." >&2 curl --progress-bar -L -o ${DOWNLOAD_DIR}/package.7z ${URL} >&2 - 7z x -y -o${INSTALL_DIR} ${DOWNLOAD_DIR}/package.7z >/dev/null 2>&1 - 7z l -ba -slt -y ${DOWNLOAD_DIR}/package.7z | tr '\\' '/' | sed -n -e "s|^Path\ =\ |${INSTALL_DIR}/|p" >> "${HASH_FILEPATH}" 2>/dev/null + 7z x -y -o${UNPACK_DIR} ${DOWNLOAD_DIR}/package.7z >/dev/null 2>&1 + 7z l -ba -slt -y ${DOWNLOAD_DIR}/package.7z | tr '\\' '/' | sed -n -e "s|^Path\ =\ |${UNPACK_DIR}/|p" >> "${HASH_FILEPATH}" 2>/dev/null rm -f ${DOWNLOAD_DIR}/package.7z # @@ -302,21 +342,21 @@ for COMPONENT in ${COMPONENTS}; do fi if [ "${TARGET_PLATFORM}" == "android" ] && [ ! "${QT_VERSION}" \< "6.0.0" ]; then - CONF_FILE="${INSTALL_DIR}/${VERSION}/${SUBDIR}/bin/target_qt.conf" + CONF_FILE="${UNPACK_DIR}/${VERSION}/${SUBDIR}/bin/target_qt.conf" sed -i "s|target|../$TOOLCHAIN|g" "${CONF_FILE}" sed -i "/HostPrefix/ s|$|gcc_64|g" "${CONF_FILE}" - ANDROID_QMAKE_FILE="${INSTALL_DIR}/${VERSION}/${SUBDIR}/bin/qmake" - QMAKE_FILE="${INSTALL_DIR}/${VERSION}/gcc_64/bin/qmake" + ANDROID_QMAKE_FILE="${UNPACK_DIR}/${VERSION}/${SUBDIR}/bin/qmake" + QMAKE_FILE="${UNPACK_DIR}/${VERSION}/gcc_64/bin/qmake" sed -i "s|\/home\/qt\/work\/install\/bin\/qmake|$QMAKE_FILE|g" "${ANDROID_QMAKE_FILE}" else - CONF_FILE="${INSTALL_DIR}/${VERSION}/${SUBDIR}/bin/qt.conf" + CONF_FILE="${UNPACK_DIR}/${VERSION}/${SUBDIR}/bin/qt.conf" echo "[Paths]" > ${CONF_FILE} echo "Prefix = .." >> ${CONF_FILE} fi # Adjust the license to be able to run qmake # sed with -i requires intermediate file on Mac OS - PRI_FILE="${INSTALL_DIR}/${VERSION}/${SUBDIR}/mkspecs/qconfig.pri" + PRI_FILE="${UNPACK_DIR}/${VERSION}/${SUBDIR}/mkspecs/qconfig.pri" sed -i.bak 's/Enterprise/OpenSource/g' "${PRI_FILE}" sed -i.bak 's/licheck.*//g' "${PRI_FILE}" rm "${PRI_FILE}.bak" @@ -326,9 +366,9 @@ for COMPONENT in ${COMPONENTS}; do echo $(dirname "${CONF_FILE}") elif [[ "${COMPONENT}" =~ "qtcreator" ]]; then if [ "${HOST_OS}" == "mac_x64" ]; then - echo "${INSTALL_DIR}/Qt Creator.app/Contents/MacOS" + echo "${UNPACK_DIR}/Qt Creator.app/Contents/MacOS" else - echo "${INSTALL_DIR}/bin" + echo "${UNPACK_DIR}/bin" fi fi diff --git a/scripts/test-qbs.sh b/scripts/test-qbs.sh index 07271c45d..55dc6524e 100755 --- a/scripts/test-qbs.sh +++ b/scripts/test-qbs.sh @@ -52,4 +52,8 @@ CPUS=$("$(dirname "$0")"/cpu-count.sh) export QBS_AUTOTEST_PROFILE=${QBS_AUTOTEST_PROFILE:-qt} echo "Running Qbs tests (${CPUS} jobs in parallel)." -find $1 -name "tst_*" | xargs -I{} -n1 -P${CPUS} bash -c 'export LOG=$(mktemp) ; $({} > ${LOG} 2>&1) ; export RESULT=$? ; cat ${LOG} ; exit ${RESULT}' +find $1 -name "tst_*" \ + | grep -v tst_blackbox-joblimits \ + | xargs -I{} -n1 -P${CPUS} bash -c \ + 'export LOG=$(mktemp) ; $({} > ${LOG} 2>&1) ; export RESULT=$? ; cat ${LOG} ; exit ${RESULT}' +tst_blackbox-joblimits diff --git a/scripts/test-qt-for-android.sh b/scripts/test-qt-for-android.sh index 793ba248d..55ef991d4 100755 --- a/scripts/test-qt-for-android.sh +++ b/scripts/test-qt-for-android.sh @@ -62,16 +62,12 @@ qbs setup-android --ndk-dir ${ANDROID_HOME}/ndk-bundle --sdk-dir ${ANDROID_HOME} export QBS_AUTOTEST_PROFILE=qbs_autotests-android export QBS_AUTOTEST_ALWAYS_LOG_STDERR=true +export QTEST_FUNCTION_TIMEOUT=9000000 if [ ! "${QT_VERSION}" \< "5.14.0" ] && [ "${QT_VERSION}" \< "6.0.0" ]; then echo "Using multi-arch data sets for qml tests (only for qt version >= 5.14 and < 6.0.0) with all architectures" qbs config --list tst_blackbox-android - - echo "Using multi-arch data sets for qml tests (only for qt version >= 5.14) with only armv7a and x86_64" - qbs config profiles.qbs_autotests-android-qt.qbs.architectures '["armv7a","x86_64"]' - qbs config --list - tst_blackbox-android fi; echo "Using single-arch (armv7a) data sets for qml tests" diff --git a/scripts/test-qt.sh b/scripts/test-qt.sh new file mode 100755 index 000000000..944d8941d --- /dev/null +++ b/scripts/test-qt.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +############################################################################# +## +## Copyright (C) 2021 Ivan Komissarov <abbapoh@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$ +## +############################################################################# + +set -eu + +# +# 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" + +export PATH="$1:$PATH" + +export QBS_AUTOTEST_PROFILE=${QBS_AUTOTEST_PROFILE:-qt} + +tst_blackbox-qt diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index f607e0a85..bde65d450 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -36,8 +36,7 @@ get_update_path_command(UPDATE_PATH_COMMAND) get_target_property(_QBS_OUTPUT_DIR qbs RUNTIME_OUTPUT_DIRECTORY) add_custom_target( BuildQbsResources ALL - COMMAND ${UPDATE_PATH_COMMAND} - COMMAND ${_QBS_OUTPUT_DIR}/qbs + COMMAND ${CMAKE_COMMAND} -E env "${UPDATE_PATH_COMMAND}" ${_QBS_OUTPUT_DIR}/qbs resolve --settings-dir ${PROJECT_BINARY_DIR}/settings -f ${PROJECT_SOURCE_DIR}/qbs.qbs @@ -47,7 +46,7 @@ add_custom_target( project.withCode:false project.withDocumentation:false profile:none - COMMAND ${_QBS_OUTPUT_DIR}/qbs + COMMAND ${CMAKE_COMMAND} -E env "${UPDATE_PATH_COMMAND}" ${_QBS_OUTPUT_DIR}/qbs build --settings-dir ${PROJECT_BINARY_DIR}/settings -f ${PROJECT_SOURCE_DIR}/qbs.qbs diff --git a/share/qbs/imports/qbs/DarwinTools/darwin-tools.js b/share/qbs/imports/qbs/DarwinTools/darwin-tools.js index 9b81310f0..0a944802d 100644 --- a/share/qbs/imports/qbs/DarwinTools/darwin-tools.js +++ b/share/qbs/imports/qbs/DarwinTools/darwin-tools.js @@ -260,19 +260,3 @@ function cleanPropertyList(plist) { cleanPropertyList(plist[key]); } } - -function _codeSignTimestampFlags(product) { - // If signingTimestamp is undefined, do not specify the flag at all - - // this uses the system-specific default behavior - var signingTimestamp = product.moduleProperty("xcode", "signingTimestamp"); - if (signingTimestamp !== undefined) { - // If signingTimestamp is an empty string, specify the flag but do - // not specify a value - this uses a default Apple-provided server - var flag = "--timestamp"; - if (signingTimestamp) - flag += "=" + signingTimestamp; - return [flag]; - } - - return []; -} diff --git a/share/qbs/imports/qbs/ModUtils/utils.js b/share/qbs/imports/qbs/ModUtils/utils.js index 586564d73..0433fa46e 100644 --- a/share/qbs/imports/qbs/ModUtils/utils.js +++ b/share/qbs/imports/qbs/ModUtils/utils.js @@ -48,7 +48,7 @@ function mergeCFiles(inputs, outputFilePath) } function sanitizedList(list, product, fullPropertyName) { - if (!Array.isArray(list)) + if (!(list instanceof Array)) return list; var filterFunc = function(elem) { if (typeof elem === "string" && elem.length === 0) { @@ -588,6 +588,8 @@ function guessArchitecture(m) { architecture = "sh"; } else if (hasAnyOf(m, ["__CR16__"])) { architecture = "cr16"; + } else if (hasAnyOf(m, ["__mc68hc1x__", "__mc68hc1x"])) { + architecture = "hcs12"; } } diff --git a/share/qbs/imports/qbs/Probes/ClangClProbe.qbs b/share/qbs/imports/qbs/Probes/ClangClProbe.qbs index 8205e92fa..658da8a9f 100644 --- a/share/qbs/imports/qbs/Probes/ClangClProbe.qbs +++ b/share/qbs/imports/qbs/Probes/ClangClProbe.qbs @@ -42,6 +42,7 @@ PathProbe { property string preferredArchitecture property string _nullDevice: qbs.nullDevice property string _pathListSeparator: qbs.pathListSeparator + property string winSdkVersion // Outputs property int versionMajor @@ -58,9 +59,21 @@ PathProbe { languages = ["c"]; var info = languages.contains("c") - ? Utilities.clangClCompilerInfo(compilerFilePath, preferredArchitecture, vcvarsallFilePath, "c") : {}; + ? Utilities.clangClCompilerInfo( + compilerFilePath, + preferredArchitecture, + vcvarsallFilePath, + "c", + winSdkVersion) + : {}; var infoCpp = languages.contains("cpp") - ? Utilities.clangClCompilerInfo(compilerFilePath, preferredArchitecture, vcvarsallFilePath, "cpp") : {}; + ? Utilities.clangClCompilerInfo( + compilerFilePath, + preferredArchitecture, + vcvarsallFilePath, + "cpp", + winSdkVersion) + : {}; found = (!languages.contains("c") || (!!info && !!info.macros && !!info.buildEnvironment)) && (!languages.contains("cpp") || diff --git a/share/qbs/imports/qbs/Probes/MsvcProbe.qbs b/share/qbs/imports/qbs/Probes/MsvcProbe.qbs index 2d5faecdd..d3624e010 100644 --- a/share/qbs/imports/qbs/Probes/MsvcProbe.qbs +++ b/share/qbs/imports/qbs/Probes/MsvcProbe.qbs @@ -38,6 +38,7 @@ PathProbe { property string compilerFilePath property stringList enableDefinesByLanguage property string preferredArchitecture + property string winSdkVersion // Outputs property string architecture @@ -54,9 +55,9 @@ PathProbe { languages = ["c"]; var info = languages.contains("c") - ? Utilities.msvcCompilerInfo(compilerFilePath, "c") : {}; + ? Utilities.msvcCompilerInfo(compilerFilePath, "c", winSdkVersion) : {}; var infoCpp = languages.contains("cpp") - ? Utilities.msvcCompilerInfo(compilerFilePath, "cpp") : {}; + ? Utilities.msvcCompilerInfo(compilerFilePath, "cpp", winSdkVersion) : {}; found = (!languages.contains("c") || (!!info && !!info.macros && !!info.buildEnvironment)) && (!languages.contains("cpp") || diff --git a/share/qbs/imports/qbs/Probes/XcodeProbe.qbs b/share/qbs/imports/qbs/Probes/XcodeProbe.qbs index e0ed99346..edd67433b 100644 --- a/share/qbs/imports/qbs/Probes/XcodeProbe.qbs +++ b/share/qbs/imports/qbs/Probes/XcodeProbe.qbs @@ -48,6 +48,7 @@ Probe { // Outputs property var architectureSettings property var availableSdks + property var platformSettings property string xcodeVersion configure: { @@ -97,6 +98,8 @@ Probe { }); availableSdks = Xcode.sdkInfoList(sdksPath); + var platformInfoPlist = FileInfo.joinPaths(platformPath, "Info.plist"); + platformSettings = Xcode.platformInfo(platformInfoPlist); found = !!xcodeVersion; } } diff --git a/share/qbs/imports/qbs/Probes/path-probe.js b/share/qbs/imports/qbs/Probes/path-probe.js index b1bdf9930..1f55dcf32 100644 --- a/share/qbs/imports/qbs/Probes/path-probe.js +++ b/share/qbs/imports/qbs/Probes/path-probe.js @@ -36,7 +36,7 @@ var ModUtils = require("qbs.ModUtils"); function asStringList(key, value) { if (typeof(value) === "string") return [value]; - if (Array.isArray(value)) + if (value instanceof Array) return value; throw key + " must be a string or a stringList"; } @@ -45,7 +45,7 @@ function canonicalSelectors(selectors, nameSuffixes) { var mapper = function(selector) { if (typeof(selector) === "string") return {names : [selector]}; - if (Array.isArray(selector)) + if (selector instanceof Array) return {names : selector}; // dict if (!selector.names) diff --git a/share/qbs/imports/qbs/base/Application.qbs b/share/qbs/imports/qbs/base/Application.qbs index 80ee7b51e..76536c68e 100644 --- a/share/qbs/imports/qbs/base/Application.qbs +++ b/share/qbs/imports/qbs/base/Application.qbs @@ -60,7 +60,7 @@ NativeBinary { installDir: isBundle ? "Applications" : "bin" Group { - condition: install + condition: install && _installable fileTagsFilter: isBundle ? "bundle.content" : "application" qbs.install: true qbs.installDir: installDir @@ -68,7 +68,7 @@ NativeBinary { } Group { - condition: installDebugInformation + condition: installDebugInformation && _installable fileTagsFilter: ["debuginfo_app"] qbs.install: true qbs.installDir: debugInformationInstallDir diff --git a/share/qbs/imports/qbs/base/Library.qbs b/share/qbs/imports/qbs/base/Library.qbs index c8a114624..914d79bcb 100644 --- a/share/qbs/imports/qbs/base/Library.qbs +++ b/share/qbs/imports/qbs/base/Library.qbs @@ -52,7 +52,7 @@ NativeBinary { property string importLibInstallDir: "lib" Group { - condition: install + condition: install && _installable fileTagsFilter: { if (isBundle) return ["bundle.content"]; @@ -70,14 +70,16 @@ NativeBinary { } Group { - condition: installImportLib && type.contains("dynamiclibrary") + condition: installImportLib + && type.contains("dynamiclibrary") + && _installable fileTagsFilter: "dynamiclibrary_import" qbs.install: true qbs.installDir: importLibInstallDir } Group { - condition: installDebugInformation + condition: installDebugInformation && _installable fileTagsFilter: { if (isDynamicLibrary) return ["debuginfo_dll"]; diff --git a/share/qbs/imports/qbs/base/NativeBinary.qbs b/share/qbs/imports/qbs/base/NativeBinary.qbs index 0928e96bb..c51f132ee 100644 --- a/share/qbs/imports/qbs/base/NativeBinary.qbs +++ b/share/qbs/imports/qbs/base/NativeBinary.qbs @@ -35,6 +35,9 @@ Product { property bool install: false property string installDir + // Product artifacts should be installed if it's not multiplexed or aggregated, + // or if it is multiplexed and it's the aggregate product + readonly property bool _installable: !multiplexed || !aggregate || !multiplexConfigurationId property bool installDebugInformation: false property string debugInformationInstallDir: installDir diff --git a/share/qbs/module-providers/Qt/setup-qt.js b/share/qbs/module-providers/Qt/setup-qt.js index 70acc753c..5cf1bcb44 100644 --- a/share/qbs/module-providers/Qt/setup-qt.js +++ b/share/qbs/module-providers/Qt/setup-qt.js @@ -267,6 +267,10 @@ function getQtProperties(qmakeFilePath, qbs) { qtProps.mkspecBasePath = FileInfo.joinPaths (pathQueryValue(queryResult, "QT_INSTALL_DATA"), "mkspecs"); } + + if (Utilities.versionCompare(qtProps.qtVersion, "6") >= 0) + qtProps.libExecPath = pathQueryValue(queryResult, "QT_INSTALL_LIBEXECS"); + if (!File.exists(qtProps.mkspecBasePath)) throw "Cannot extract the mkspecs directory."; @@ -514,8 +518,13 @@ function isFramework(modInfo, qtProps) { if (!qtProps.frameworkBuild || modInfo.isStaticLibrary) return false; var modulesNeverBuiltAsFrameworks = [ - "bootstrap", "openglextensions", "platformsupport", "qmldevtools", "uitools", "harfbuzzng" + "bootstrap", "openglextensions", "platformsupport", "qmldevtools", "harfbuzzng" ]; + + if (qtProps.qtMajorVersion <= 5) { + modulesNeverBuiltAsFrameworks.push("uitools"); // is framework since qt6 + } + return !modulesNeverBuiltAsFrameworks.contains(modInfo.qbsName); } @@ -1334,6 +1343,7 @@ function replaceSpecialValues(content, module, qtProps, abi) { binPath: ModUtils.toJSLiteral(qtProps.binaryPath), installPath: ModUtils.toJSLiteral(qtProps.installPath), libPath: ModUtils.toJSLiteral(qtProps.libraryPath), + libExecPath: ModUtils.toJSLiteral(qtProps.libExecPath), pluginPath: ModUtils.toJSLiteral(qtProps.pluginPath), incPath: ModUtils.toJSLiteral(qtProps.includePath), docPath: ModUtils.toJSLiteral(qtProps.documentationPath), @@ -1536,6 +1546,8 @@ function setupOneQt(qmakeFilePath, outputBaseDir, uniquify, location, qbs) { allFiles); copyTemplateFile("qdoc.js", qbsQtModuleDir, qtProps, androidAbis[a], location, allFiles); + copyTemplateFile("rcc.js", qbsQtModuleDir, qtProps, androidAbis[a], location, + allFiles); } else if (module.qbsName === "gui") { moduleTemplateFileName = "gui.qbs"; } else if (module.qbsName === "scxml") { @@ -1559,6 +1571,8 @@ function setupOneQt(qmakeFilePath, outputBaseDir, uniquify, location, qbs) { moduleTemplateFileName = "quick.qbs"; copyTemplateFile("quick.js", qbsQtModuleDir, qtProps, androidAbis[a], location, allFiles); + copyTemplateFile("rcc.js", qbsQtModuleDir, qtProps, androidAbis[a], location, + allFiles); } else if (module.isPlugin) { moduleTemplateFileName = "plugin.qbs"; } else { diff --git a/share/qbs/module-providers/Qt/templates/android_support.qbs b/share/qbs/module-providers/Qt/templates/android_support.qbs index 3790037f3..68a29bb95 100644 --- a/share/qbs/module-providers/Qt/templates/android_support.qbs +++ b/share/qbs/module-providers/Qt/templates/android_support.qbs @@ -4,6 +4,7 @@ import qbs.ModUtils import qbs.TextFile import qbs.Utilities import qbs.Process +import qbs.Xml Module { version: @version@ @@ -35,10 +36,14 @@ Module { property bool _multiAbi: Utilities.versionCompare(version, "5.14") >= 0 + // QTBUG-87288: correct QtNetwork jar dependencies for 5.15.0 < Qt < 5.15.3 + property bool _correctQtNetworkDependencies: Utilities.versionCompare(version, "5.15.0") > 0 && + Utilities.versionCompare(version, "5.15.3") < 0 + Depends { name: "Android.sdk"; condition: _enableSdkSupport } Depends { name: "Android.ndk"; condition: _enableNdkSupport } Depends { name: "java"; condition: _enableSdkSupport } - Depends { name: "cpp" } + Depends { name: "cpp"; condition: _enableNdkSupport } Properties { condition: _enableNdkSupport && qbs.toolchain.contains("clang") @@ -62,8 +67,10 @@ Module { condition: _enableSdkSupport && Utilities.versionCompare(version, "6.0") >= 0 java.additionalClassPaths: [FileInfo.joinPaths(_qtInstallDir, "jar", "Qt6Android.jar")] } + // "ANDROID_HAS_WSTRING" was removed from qtcore qstring.h in Qt 5.14.0 Properties { - condition: _enableNdkSupport && (Android.ndk.abi === "armeabi-v7a" || Android.ndk.abi === "x86") + condition: _enableNdkSupport && Utilities.versionCompare(version, "5.14.0") < 0 && + (Android.ndk.abi === "armeabi-v7a" || Android.ndk.abi === "x86") cpp.defines: "ANDROID_HAS_WSTRING" } Properties { @@ -78,7 +85,11 @@ Module { condition: _enableSdkSupport && Utilities.versionCompare(version, "6.0") >= 0 Android.sdk.minimumVersion: "23" } - cpp.archSuffix: _multiAbi ? "_" + Android.ndk.abi : "" + + Properties { + condition: _enableNdkSupport + cpp.archSuffix: _multiAbi ? "_" + Android.ndk.abi : "" + } Rule { condition: _enableSdkSupport @@ -191,7 +202,7 @@ Module { var prefixDirs = product.Qt.android_support.extraPrefixDirs; if (prefixDirs && prefixDirs.length > 0) f.writeLine('"extraPrefixDirs": ' + JSON.stringify(prefixDirs) + ','); - if (Array.isArray(product.qmlImportPaths) && product.qmlImportPaths.length > 0) + if ((product.qmlImportPaths instanceof Array) && product.qmlImportPaths.length > 0) f.writeLine('"qml-import-paths": "' + product.qmlImportPaths.join(',') + '",'); if (Utilities.versionCompare(product.Qt.android_support.version, "6.0") >= 0) { @@ -349,8 +360,6 @@ Module { var moveCmd = new JavaScriptCommand(); moveCmd.description = "processing androiddeployqt outout"; moveCmd.sourceCode = function() { - File.move(product.Qt.android_support._deployQtOutDir + "/AndroidManifest.xml", - outputs["android.manifest_final"][0].filePath); var libsDir = product.Qt.android_support._deployQtOutDir + "/libs"; var libDir = product.Android.sdk.packageContentsDir + "/lib"; var listFilePath = outputs["android.deployqt_list"][0].filePath; @@ -394,7 +403,78 @@ Module { File.remove(oldLibs[i]); } }; - return [copyCmd, androidDeployQtCmd, moveCmd]; + + var correctingCmd = new JavaScriptCommand(); + if (product.Qt.android_support._correctQtNetworkDependencies) { + correctingCmd.description = "correcting network jar dependency"; + correctingCmd.sourceCode = function() { + var findNetworkLib = function() { + var libsDir = product.Android.sdk.packageContentsDir + "/lib"; + var dirList = File.directoryEntries(libsDir, File.Dirs | + File.NoDotAndDotDot); + for (var i = 0; i < dirList.length; ++i) { + var archDir = FileInfo.joinPaths(libsDir, dirList[i]); + var fileList = File.directoryEntries(archDir, File.Files); + if (fileList) { + for (var j = 0; j < fileList.length; ++j) { + if (fileList[j].contains("libQt5Network")) { + return true; + } + } + } + } + return false; + } + + if (findNetworkLib()) { + var manifestData = new Xml.DomDocument(); + var manifestFilePath = product.Qt.android_support._deployQtOutDir + + "/AndroidManifest.xml" + manifestData.load(manifestFilePath); + + var rootElem = manifestData.documentElement(); + if (!rootElem || !rootElem.isElement() || rootElem.tagName() != "manifest") + throw "No manifest tag found in '" + manifestFilePath + "'."; + var appElem = rootElem.firstChild("application"); + if (!appElem || !appElem.isElement() || appElem.tagName() != "application") + throw "No application tag found in '" + manifestFilePath + "'."; + var activityElem = appElem.firstChild("activity"); + if (!activityElem || !activityElem.isElement() || + activityElem.tagName() != "activity") + throw "No activity tag found in '" + manifestFilePath + "'."; + var metaDataElem = activityElem.firstChild("meta-data"); + while (metaDataElem && metaDataElem.isElement()) { + if (metaDataElem.attribute("android:name") == + "android.app.load_local_jars" ) { + var value = metaDataElem.attribute("android:value"); + var fileName = "QtAndroidNetwork.jar"; + metaDataElem.setAttribute("android:value", value + ":jar/" + + fileName); + var jarFilePath = FileInfo.joinPaths( + product.Qt.android_support._qtInstallDir, "jar", + fileName); + var targetFilePath = FileInfo.joinPaths(product.java.classFilesDir, + fileName); + File.copy(jarFilePath, targetFilePath); + break; + } + metaDataElem = metaDataElem.nextSibling("meta-data"); + } + manifestData.save(outputs["android.manifest_final"][0].filePath, 4); + } else { + File.move(product.Qt.android_support._deployQtOutDir + "/AndroidManifest.xml", + outputs["android.manifest_final"][0].filePath); + } + }; + } else { + correctingCmd.description = "copying manifest"; + correctingCmd.sourceCode = function() { + File.move(product.Qt.android_support._deployQtOutDir + "/AndroidManifest.xml", + outputs["android.manifest_final"][0].filePath); + } + } + + return [copyCmd, androidDeployQtCmd, moveCmd, correctingCmd]; } } diff --git a/share/qbs/module-providers/Qt/templates/core.qbs b/share/qbs/module-providers/Qt/templates/core.qbs index 8f0b0e2df..2e810eeed 100644 --- a/share/qbs/module-providers/Qt/templates/core.qbs +++ b/share/qbs/module-providers/Qt/templates/core.qbs @@ -5,6 +5,7 @@ import qbs.Utilities import qbs.Xml import "moc.js" as Moc import "qdoc.js" as Qdoc +import "rcc.js" as Rcc Module { condition: (qbs.targetPlatform === targetPlatform || isCombinedUIKitBuild) @@ -41,12 +42,14 @@ Module { property path installPath: @installPath@ property path incPath: @incPath@ property path libPath: @libPath@ + property path libExecPath: @libExecPath@ property path pluginPath: @pluginPath@ property string mkspecName: @mkspecName@ property path mkspecPath: @mkspecPath@ property string mocName: "moc" property stringList mocFlags: [] property string lreleaseName: "lrelease" + property string rccName: "rcc" property string qdocName: versionMajor >= 5 ? "qdoc" : "qdoc3" property stringList qdocEnvironment property path docPath: @docPath@ @@ -433,7 +436,7 @@ Module { "-o", output.filePath]; if (input.Qt.core.enableBigResources) args.push("-pass", "1"); - var cmd = new Command(product.Qt.core.binPath + '/rcc', args); + var cmd = new Command(Rcc.fullPath(product), args); cmd.description = "rcc " + (input.Qt.core.enableBigResources ? "(pass 1) " : "") + input.fileName; @@ -445,7 +448,7 @@ Module { Rule { inputs: ["intermediate_obj"] Artifact { - filePath: input.completeBaseName + ".2.o" + filePath: input.completeBaseName + ".2" + input.cpp.objectSuffix fileTags: ["obj"] } prepare: { @@ -464,7 +467,7 @@ Module { } var qrcArtifact = findChild(input, function(c) { return c.fileTags.contains("qrc"); }); var cppArtifact = findChild(input, function(c) { return c.fileTags.contains("cpp"); }); - var cmd = new Command(product.Qt.core.binPath + '/rcc', + var cmd = new Command(Rcc.fullPath(product), [qrcArtifact.filePath, "-temp", input.filePath, "-name", FileInfo.completeBaseName(input.filePath), diff --git a/share/qbs/module-providers/Qt/templates/dbus.js b/share/qbs/module-providers/Qt/templates/dbus.js index 0674bf684..3cdd6fb90 100644 --- a/share/qbs/module-providers/Qt/templates/dbus.js +++ b/share/qbs/module-providers/Qt/templates/dbus.js @@ -29,6 +29,7 @@ ****************************************************************************/ var FileInfo = require("qbs.FileInfo"); +var ModUtils = require("qbs.ModUtils"); function outputFileName(input, suffix) { diff --git a/share/qbs/module-providers/Qt/templates/gui.qbs b/share/qbs/module-providers/Qt/templates/gui.qbs index a3c427175..1d45c6f1e 100644 --- a/share/qbs/module-providers/Qt/templates/gui.qbs +++ b/share/qbs/module-providers/Qt/templates/gui.qbs @@ -23,9 +23,11 @@ QtModule { } prepare: { - var cmd = new Command(ModUtils.moduleProperty(product, "binPath") + '/' - + ModUtils.moduleProperty(product, "uicName"), - [input.filePath, '-o', output.filePath]) + var uicPath = Utilities.versionCompare(product.Qt.gui.version, "6.1") < 0 + ? product.Qt.core.binPath + '/' + product.Qt.gui.uicName + : product.Qt.core.libExecPath + '/' + product.Qt.gui.uicName; + + var cmd = new Command(uicPath, [input.filePath, '-o', output.filePath]); cmd.description = 'uic ' + input.fileName; cmd.highlight = 'codegen'; return cmd; diff --git a/share/qbs/module-providers/Qt/templates/moc.js b/share/qbs/module-providers/Qt/templates/moc.js index 92983e4f7..7d230267c 100644 --- a/share/qbs/module-providers/Qt/templates/moc.js +++ b/share/qbs/module-providers/Qt/templates/moc.js @@ -29,6 +29,7 @@ ****************************************************************************/ var ModUtils = require("qbs.ModUtils"); +var Utilities = require("qbs.Utilities"); function args(product, input, outputs) { @@ -78,7 +79,9 @@ function args(product, input, outputs) function fullPath(product) { - return product.Qt.core.binPath + '/' + product.Qt.core.mocName; + if (Utilities.versionCompare(product.Qt.core.version, "6.1") < 0) + return product.Qt.core.binPath + '/' + product.Qt.core.mocName; + return product.Qt.core.libExecPath + '/' + product.Qt.core.mocName; } function outputArtifacts(project, product, inputs, input) diff --git a/share/qbs/module-providers/Qt/templates/plugin_support.qbs b/share/qbs/module-providers/Qt/templates/plugin_support.qbs index 1de923f17..19a739589 100644 --- a/share/qbs/module-providers/Qt/templates/plugin_support.qbs +++ b/share/qbs/module-providers/Qt/templates/plugin_support.qbs @@ -32,7 +32,7 @@ Module { newValue = []; else if (typeof newValue == "string") newValue = [newValue]; - if (!Array.isArray(newValue)) + if (!newValue instanceof Array) throw "Invalid value '" + newValue + "' in Qt.plugin_support.pluginsByType"; eppt[pluginType] = (eppt[pluginType] || []).uniqueConcat(newValue); } diff --git a/share/qbs/module-providers/Qt/templates/qml.js b/share/qbs/module-providers/Qt/templates/qml.js index df69034fe..e48c9230e 100644 --- a/share/qbs/module-providers/Qt/templates/qml.js +++ b/share/qbs/module-providers/Qt/templates/qml.js @@ -3,14 +3,31 @@ var FileInfo = require("qbs.FileInfo"); var Process = require("qbs.Process"); var TextFile = require("qbs.TextFile"); -function scannerData(scannerFilePath, qmlFiles, qmlPath) +function scannerData(scannerFilePath, qmlFiles, qmlPath, targetOS) { var p; try { p = new Process(); - p.exec(scannerFilePath, ["-qmlFiles"].concat(qmlFiles).concat(["-importPath", qmlPath]), - true); - return JSON.parse(p.readStdOut()); + if (!targetOS.contains("windows")) { + p.exec(scannerFilePath, ["-qmlFiles"].concat(qmlFiles).concat(["-importPath", qmlPath]), + true); + return JSON.parse(p.readStdOut()); + } + var data = []; + var nextFileIndex = 0; + while (nextFileIndex < qmlFiles.length) { + var currentFileList = []; + var currentFileListStringLength = 0; + while (nextFileIndex < qmlFiles.length && currentFileListStringLength < 30000) { + var currentFile = qmlFiles[nextFileIndex++]; + currentFileList.push(currentFile); + currentFileListStringLength += currentFile.length; + } + p.exec(scannerFilePath, ["-qmlFiles"].concat(currentFileList) + .concat(["-importPath", qmlPath]), true); + data = data.concat(JSON.parse(p.readStdOut())); + } + return data; } finally { if (p) p.close(); diff --git a/share/qbs/module-providers/Qt/templates/qml.qbs b/share/qbs/module-providers/Qt/templates/qml.qbs index f608ba4dd..af7b0fb5f 100644 --- a/share/qbs/module-providers/Qt/templates/qml.qbs +++ b/share/qbs/module-providers/Qt/templates/qml.qbs @@ -144,7 +144,7 @@ QtModule { qmlInputs = []; var scannerData = Qml.scannerData(product.Qt.qml.qmlImportScannerFilePath, qmlInputs.map(function(inp) { return inp.filePath; }), - product.Qt.qml.qmlPath); + product.Qt.qml.qmlPath, product.qbs.targetOS); var cppFile; var listFile; try { diff --git a/share/qbs/module-providers/Qt/templates/quick.js b/share/qbs/module-providers/Qt/templates/quick.js index 4f3da2fb0..ad433736c 100644 --- a/share/qbs/module-providers/Qt/templates/quick.js +++ b/share/qbs/module-providers/Qt/templates/quick.js @@ -30,13 +30,14 @@ var FileInfo = require("qbs.FileInfo"); var Process = require("qbs.Process"); +var Rcc = require("rcc.js"); -function scanQrc(qrcFilePath) { +function scanQrc(product, qrcFilePath) { var absInputDir = FileInfo.path(qrcFilePath); var result = []; var process = new Process(); try { - var rcc = FileInfo.joinPaths(product.Qt.core.binPath, 'rcc' + product.cpp.executableSuffix); + var rcc = FileInfo.joinPaths(Rcc.fullPath(product) + product.cpp.executableSuffix); var exitCode = process.exec(rcc, ["--list", qrcFilePath], true); for (;;) { var line = process.readLine(); @@ -65,8 +66,8 @@ function qtQuickResourceFileOutputName(fileName) { return fileName.replace(/\.qrc$/, "_qtquickcompiler.qrc"); } -function contentFromQrc(qrcFilePath) { - var filesInQrc = scanQrc(qrcFilePath); +function contentFromQrc(product, qrcFilePath) { + var filesInQrc = scanQrc(product, qrcFilePath); var qmlJsFiles = filesInQrc.filter(function (filePath) { return (/\.(js|qml)$/).test(filePath); } ); diff --git a/share/qbs/module-providers/Qt/templates/quick.qbs b/share/qbs/module-providers/Qt/templates/quick.qbs index bf04fe869..ac3ab5b26 100644 --- a/share/qbs/module-providers/Qt/templates/quick.qbs +++ b/share/qbs/module-providers/Qt/templates/quick.qbs @@ -79,7 +79,7 @@ QtModule { condition: useCompiler inputs: 'qt.quick.qrc' searchPaths: [FileInfo.path(input.filePath)] - scan: QC.scanQrc(input.filePath) + scan: QC.scanQrc(product, input.filePath) } FileTagger { @@ -100,7 +100,7 @@ QtModule { var cmd = new JavaScriptCommand(); cmd.silent = true; cmd.sourceCode = function() { - var content = QC.contentFromQrc(input.filePath); + var content = QC.contentFromQrc(product, input.filePath); content.qrcFilePath = input.filePath; var tf = new TextFile(output.filePath, TextFile.WriteOnly); diff --git a/share/qbs/module-providers/Qt/templates/rcc.js b/share/qbs/module-providers/Qt/templates/rcc.js new file mode 100644 index 000000000..89c57d99b --- /dev/null +++ b/share/qbs/module-providers/Qt/templates/rcc.js @@ -0,0 +1,8 @@ +var Utilities = require("qbs.Utilities"); + +function fullPath(product) +{ + if (Utilities.versionCompare(product.Qt.core.version, "6.1") < 0) + return product.Qt.core.binPath + '/' + product.Qt.core.rccName; + return product.Qt.core.libExecPath + '/' + product.Qt.core.rccName; +} diff --git a/share/qbs/modules/Android/ndk/utils.js b/share/qbs/modules/Android/ndk/utils.js index 3605df314..e763ed9b6 100644 --- a/share/qbs/modules/Android/ndk/utils.js +++ b/share/qbs/modules/Android/ndk/utils.js @@ -100,6 +100,6 @@ function commonLinkerFlags(abi) { return ["-z", "noexecstack", "-z", "relro", "-z", "now", "--build-id=sha1", "--gc-sections" ]; } -function stlFilePath(path, ndk, suffix) { - return path + ndk.appStl.slice(0, ndk.appStl.indexOf('_')) + suffix + "." + ndk.platformVersion; +function stlFileName(prefix, ndk, suffix) { + return prefix + ndk.appStl.slice(0, ndk.appStl.indexOf('_')) + suffix; } diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs index f0e727caf..cae5fc2e5 100644 --- a/share/qbs/modules/Android/sdk/sdk.qbs +++ b/share/qbs/modules/Android/sdk/sdk.qbs @@ -178,20 +178,18 @@ Module { property path compiledResourcesDir: FileInfo.joinPaths(product.buildDirectory, "compiled_resources") property string packageContentsDir: FileInfo.joinPaths(product.buildDirectory, packageType) - property string debugKeyStorePath: FileInfo.joinPaths( - Environment.getEnv(qbs.hostOS.contains("windows") - ? "USERPROFILE" : "HOME"), - ".android", "debug.keystore") - property bool useApksigner: buildToolsVersion && Utilities.versionCompare( - buildToolsVersion, "24.0.3") >= 0 property stringList aidlSearchPaths Depends { name: "java"; condition: _enableRules } + Depends { name: "codesign"; condition: _enableRules } Properties { condition: _enableRules java.languageVersion: platformJavaVersion java.runtimeVersion: platformJavaVersion java.bootClassPaths: androidJarFilePath + codesign.apksignerFilePath: Android.sdk.apksignerFilePath + codesign._packageName: Android.sdk.apkBaseName + (_generateAab ? ".aab" : ".apk") + codesign.useApksigner: !_generateAab } validate: { @@ -211,6 +209,11 @@ Module { + "Android bundletool can be downloaded from " + "https://github.com/google/bundletool"); } + if (Utilities.versionCompare(buildToolsVersion, "24.0.3") < 0) { + throw ModUtils.ModuleError("Version of Android SDK build tools too old. This version " + + "is " + buildToolsVersion + " and minimum version is " + + "24.0.3. Please update the Android SDK.") + } } FileTagger { @@ -223,36 +226,6 @@ Module { fileTags: ["android.aidl"] } - FileTagger { - patterns: ["*.keystore"] - fileTags: ["android.keystore"] - } - - // Typically there is a debug keystore in ~/.android/debug.keystore which gets created - // by the native build tools the first time a build is done. However, we don't want to create it - // ourselves, because writing to a location outside the qbs build directory is both polluting - // and has the potential for race conditions. So we'll instruct the user what to do. - Group { - name: "Android debug keystore" - files: { - if (!File.exists(Android.sdk.debugKeyStorePath)) { - throw ModUtils.ModuleError("Could not find an Android debug keystore at " + - Android.sdk.debugKeyStorePath + ". " + - "If you are developing for Android on this machine for the first time and " + - "have never built an application using the native Gradle / Android Studio " + - "tooling, this is normal. You must create the debug keystore now using the " + - "following command, in order to continue:\n\n" + - SdkUtils.createDebugKeyStoreCommandString(java.keytoolFilePath, - Android.sdk.debugKeyStorePath) + - "\n\n" + - "See the following URL for more information: " + - "https://developer.android.com/studio/publish/app-signing.html#debug-mode"); - } - return [Android.sdk.debugKeyStorePath]; - } - fileTags: ["android.keystore"] - } - Parameter { property bool embedJar: true } @@ -273,7 +246,7 @@ Module { for (var i = 0; i < (aidlSearchPaths ? aidlSearchPaths.length : 0); ++i) args.push("-I" + aidlSearchPaths[i]); args.push(input.filePath, output.filePath); - cmd = new Command(aidl, args); + var cmd = new Command(aidl, args); cmd.description = "Processing " + input.fileName; return [cmd]; } @@ -498,7 +471,7 @@ Module { outputArtifacts: { var deploymentData = SdkUtils.stlDeploymentData(product, inputs, "stl"); var outputs = []; - for (i = 0; i < deploymentData.outputFilePaths.length; ++i) { + for (var i = 0; i < deploymentData.outputFilePaths.length; ++i) { outputs.push({filePath: deploymentData.outputFilePaths[i], fileTags: "android.stl_deployed"}); } @@ -525,11 +498,11 @@ Module { inputs: [ "android.resources", "android.assets", "android.manifest_final", "android.dex", "android.stl_deployed", - "android.nativelibrary_deployed", "android.keystore" + "android.nativelibrary_deployed" ] Artifact { - filePath: product.Android.sdk.apkBaseName + ".apk" - fileTags: "android.package" + filePath: product.Android.sdk.apkBaseName + ".apk_unsigned" + fileTags: "android.package_unsigned" } prepare: SdkUtils.prepareAaptPackage.apply(SdkUtils, arguments) } @@ -540,11 +513,11 @@ Module { inputs: [ "android.apk_resources", "android.manifest_final", "android.dex", "android.stl_deployed", - "android.nativelibrary_deployed", "android.keystore" + "android.nativelibrary_deployed" ] Artifact { - filePath: product.Android.sdk.apkBaseName + ".apk" - fileTags: "android.package" + filePath: product.Android.sdk.apkBaseName + ".apk_unsigned" + fileTags: "android.package_unsigned" } prepare: SdkUtils.prepareApkPackage.apply(SdkUtils, arguments) } @@ -558,8 +531,8 @@ Module { "android.nativelibrary_deployed" ] Artifact { - filePath: product.Android.sdk.apkBaseName + ".aab" - fileTags: "android.package" + filePath: product.Android.sdk.apkBaseName + ".aab_unsigned" + fileTags: "android.package_unsigned" } prepare: SdkUtils.prepareBundletoolPackage.apply(SdkUtils, arguments) } diff --git a/share/qbs/modules/Android/sdk/utils.js b/share/qbs/modules/Android/sdk/utils.js index 63bf1f5c4..264ad2da7 100644 --- a/share/qbs/modules/Android/sdk/utils.js +++ b/share/qbs/modules/Android/sdk/utils.js @@ -30,9 +30,11 @@ var File = require("qbs.File"); var FileInfo = require("qbs.FileInfo"); +var ModUtils = require("qbs.ModUtils"); var Process = require("qbs.Process"); var TextFile = require("qbs.TextFile"); var Utilities = require("qbs.Utilities"); +var Xml = require("qbs.Xml"); function availableBuildToolsVersions(sdkDir) { var re = /^([0-9]+)\.([0-9]+)\.([0-9]+)$/; @@ -172,7 +174,8 @@ function prepareAapt2CompileResource(project, product, inputs, outputs, input, o throw "Cannot create directory '" + FileInfo.toNativeSeparators(compilesResourcesDir) + "'."; } - var args = ["compile", input.filePath, "-o", compilesResourcesDir]; + var args = ["compile", FileInfo.toNativeSeparators(input.filePath), + "-o", FileInfo.toNativeSeparators(compilesResourcesDir)]; var cmd = new Command(product.Android.sdk.aaptFilePath, args); var outputFileName = generateAapt2ResourceFileName(input.filePath); cmd.description = "compiling resource " + input.fileName + " into " + outputFileName; @@ -240,7 +243,7 @@ function prepareAaptGenerate(project, product, inputs, outputs, input, output, function prepareAaptPackage(project, product, inputs, outputs, input, output, explicitlyDependsOn) { var cmds = []; - var apkOutput = outputs["android.package"][0]; + var apkOutput = outputs["android.package_unsigned"][0]; var args = commonAaptPackageArgs.apply(this, arguments); args.push("-F", apkOutput.filePath + ".unaligned"); args.push(product.Android.sdk.packageContentsDir); @@ -248,17 +251,6 @@ function prepareAaptPackage(project, product, inputs, outputs, input, output, ex cmd.description = "generating " + apkOutput.fileName; cmds.push(cmd); - if (!product.Android.sdk.useApksigner) { - args = ["-sigalg", "SHA1withRSA", "-digestalg", "SHA1", - "-keystore", inputs["android.keystore"][0].filePath, - "-storepass", "android", - apkOutput.filePath + ".unaligned", - "androiddebugkey"]; - cmd = new Command(product.java.jarsignerFilePath, args); - cmd.description = "signing " + apkOutput.fileName; - cmds.push(cmd); - } - cmd = new Command(product.Android.sdk.zipalignFilePath, ["-f", "4", apkOutput.filePath + ".unaligned", apkOutput.filePath]); cmd.silent = true; @@ -269,26 +261,14 @@ function prepareAaptPackage(project, product, inputs, outputs, input, output, ex cmd.unalignedApk = apkOutput.filePath + ".unaligned"; cmd.sourceCode = function() { File.remove(unalignedApk); }; cmds.push(cmd); - - if (product.Android.sdk.useApksigner) { - // TODO: Implement full signing support, not just using the debug keystore - args = ["sign", - "--ks", inputs["android.keystore"][0].filePath, - "--ks-pass", "pass:android", - apkOutput.filePath]; - cmd = new Command(product.Android.sdk.apksignerFilePath, args); - cmd.description = "signing " + apkOutput.fileName; - cmds.push(cmd); - } - return cmds; } function prepareApkPackage(project, product, inputs, outputs, input, output, explicitlyDependsOn) { var cmds = []; var apkInputFilePath = inputs["android.apk_resources"][0].filePath; - var apkOutput = outputs["android.package"][0]; - var apkOutputFilePathUnaligned = outputs["android.package"][0].filePath + ".unaligned"; + var apkOutput = outputs["android.package_unsigned"][0]; + var apkOutputFilePathUnaligned = apkOutput.filePath + ".unaligned"; var dexFilePath = inputs["android.dex"][0].filePath; var copyCmd = new JavaScriptCommand(); @@ -307,17 +287,6 @@ function prepareApkPackage(project, product, inputs, outputs, input, output, exp jarCmd.workingDirectory = libPath; cmds.push(jarCmd); - if (!product.Android.sdk.useApksigner) { - args = ["-sigalg", "SHA1withRSA", "-digestalg", "SHA1", - "-keystore", inputs["android.keystore"][0].filePath, - "-storepass", "android", - apkOutputFilePathUnaligned, - "androiddebugkey"]; - cmd = new Command(product.java.jarsignerFilePath, args); - cmd.description = "signing " + apkOutput.fileName; - cmds.push(cmd); - } - cmd = new Command(product.Android.sdk.zipalignFilePath, ["-f", "4", apkOutputFilePathUnaligned, apkOutput.filePath]); cmd.silent = true; @@ -328,18 +297,6 @@ function prepareApkPackage(project, product, inputs, outputs, input, output, exp cmd.unalignedApk = apkOutputFilePathUnaligned; cmd.sourceCode = function() { File.remove(unalignedApk); }; cmds.push(cmd); - - if (product.Android.sdk.useApksigner) { - // TODO: Implement full signing support, not just using the debug keystore - args = ["sign", - "--ks", inputs["android.keystore"][0].filePath, - "--ks-pass", "pass:android", - apkOutput.filePath]; - cmd = new Command(product.Android.sdk.apksignerFilePath, args); - cmd.description = "signing " + apkOutput.fileName; - cmds.push(cmd); - } - return cmds; } @@ -375,7 +332,7 @@ function prepareBundletoolPackage(project, product, inputs, outputs, input, outp jarBaseCmd.workingDirectory = baseModuleDir; cmds.push(jarBaseCmd); - var aabFilePath = outputs["android.package"][0].filePath; + var aabFilePath = outputs["android.package_unsigned"][0].filePath; var removeCmd = new JavaScriptCommand(); removeCmd.description = "removing previous aab"; removeCmd.filePath = aabFilePath; @@ -389,20 +346,12 @@ function prepareBundletoolPackage(project, product, inputs, outputs, input, outp args.push("--modules=" + baseFilePath); args.push("--output=" + aabFilePath); var cmd = new Command(product.java.interpreterFilePath, args); - cmd.description = "generating " + outputs["android.package"][0].fileName; + cmd.description = "generating " + aabFilePath.fileName; cmds.push(cmd); return cmds; } -function createDebugKeyStoreCommandString(keytoolFilePath, keystoreFilePath) { - var args = ["-genkey", "-keystore", keystoreFilePath, "-alias", "androiddebugkey", - "-storepass", "android", "-keypass", "android", "-keyalg", "RSA", - "-keysize", "2048", "-validity", "10000", "-dname", - "CN=Android Debug,O=Android,C=US"]; - return Process.shellQuote(keytoolFilePath, args); -} - function stlDeploymentData(product, inputs, type) { var data = { uniqueInputs: [], outputFilePaths: []}; diff --git a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js index a3109d61d..52b4dffe3 100644 --- a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js +++ b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js @@ -44,9 +44,9 @@ function writeEntry(product, file, key, propertyName, required, additionalValues var value = product.Exporter.pkgconfig[propertyName]; if (additionalValues && additionalValues.length > 0) value = (value || []).concat(additionalValues); - var valueIsNotEmpty = value && (!Array.isArray(value) || value.length > 0); + var valueIsNotEmpty = value && (!(value instanceof Array) || value.length > 0); if (valueIsNotEmpty) { - if (Array.isArray(value)) + if (value instanceof Array) value = value.join(' '); file.writeLine(key + ": " + value); } else if (required) { @@ -83,7 +83,7 @@ function collectAutodetectedData(topLevelProduct) || (value.length > installPrefix.length && value[installPrefix.length] !== '/')) { return quotedValue; } - return quotedValue.replace(product.qbs.installPrefix, "${prefix}"); + return quotedValue.replace(topLevelProduct.qbs.installPrefix, "${prefix}"); } function transformedValue(product, moduleName, propertyName) @@ -92,7 +92,7 @@ function collectAutodetectedData(topLevelProduct) var value = transformFunc ? eval("(" + transformFunc + ")(product, moduleName, propertyName, originalValue)") : originalValue; - if (Array.isArray(value)) + if (value instanceof Array) value.forEach(function(v, i, a) { a[i] = quoteAndPrefixify(v); }); else if (value) value = quoteAndPrefixify(value); diff --git a/share/qbs/modules/Exporter/qbs/qbsexporter.js b/share/qbs/modules/Exporter/qbs/qbsexporter.js index 015ed4418..be46372c3 100644 --- a/share/qbs/modules/Exporter/qbs/qbsexporter.js +++ b/share/qbs/modules/Exporter/qbs/qbsexporter.js @@ -113,7 +113,7 @@ function checkValuePrefix(name, value, forbiddenPrefix, prefixDescription) function stringifyValue(project, product, moduleInstallDir, prop, value) { - if (Array.isArray(value)) { + if (value instanceof Array) { var repr = "["; for (var i = 0; i < value.length; ++i) { repr += stringifyValue(project, product, moduleInstallDir, prop, value[i]) + ", "; @@ -267,6 +267,6 @@ function writeImportStatements(product, moduleFile) if (!imports.contains("import qbs.FileInfo")) imports.push("import qbs.FileInfo"); - for (var i = 0; i < product.exports.imports.length; ++i) - moduleFile.writeLine(product.exports.imports[i]); + for (var i = 0; i < imports.length; ++i) + moduleFile.writeLine(imports[i]); } diff --git a/share/qbs/modules/bundle/BundleModule.qbs b/share/qbs/modules/bundle/BundleModule.qbs index 05e77c81b..63f12db07 100644 --- a/share/qbs/modules/bundle/BundleModule.qbs +++ b/share/qbs/modules/bundle/BundleModule.qbs @@ -38,9 +38,11 @@ import qbs.PropertyList import qbs.TextFile import qbs.Utilities import "bundle.js" as Bundle +import "../codesign/codesign.js" as Codesign Module { Depends { name: "xcode"; required: false; } + Depends { name: "codesign"; required: false; } Probe { id: bundleSettingsProbe @@ -510,9 +512,9 @@ Module { multiplex: true inputs: ["bundle.input", "aggregate_infoplist", "pkginfo", "hpp", - "icns", "xcent", + "icns", "codesign.xcent", "compiled_ibdoc", "compiled_assetcatalog", - "xcode.provisioningprofile.main"] + "codesign.embedded_provisioningprofile"] // Make sure the inputs of this rule are only those rules which produce outputs compatible // with the type of the bundle being produced. @@ -540,13 +542,13 @@ Module { }); } - for (i in inputs["xcode.provisioningprofile.main"]) { - var ext = inputs["xcode.provisioningprofile.main"][i].fileName.split('.')[1]; + var provprofiles = inputs["codesign.embedded_provisioningprofile"]; + for (i in provprofiles) { artifacts.push({ filePath: FileInfo.joinPaths(product.destinationDirectory, ModUtils.moduleProperty(product, "contentsFolderPath"), - "embedded." + ext), + provprofiles[i].fileName), fileTags: ["bundle.provisioningprofile", "bundle.content"] }); } @@ -613,8 +615,8 @@ Module { for (var i = 0; i < artifacts.length; ++i) artifacts[i].bundle = { wrapperPath: wrapperPath }; - if (product.qbs.hostOS.contains("darwin") && product.xcode - && product.xcode.signingIdentity) { + if (product.qbs.hostOS.contains("darwin") && product.codesign + && product.codesign.enableCodeSigning) { artifacts.push({ filePath: FileInfo.joinPaths(product.bundle.contentsFolderPath, "_CodeSignature/CodeResources"), fileTags: ["bundle.code-signature", "bundle.content"] @@ -706,18 +708,21 @@ Module { commands.push(cmd); } - var provisioningProfiles = outputs["bundle.provisioningprofile"]; - for (i in provisioningProfiles) { - cmd = new JavaScriptCommand(); - cmd.description = "copying provisioning profile"; - cmd.highlight = "filegen"; - cmd.source = inputs["xcode.provisioningprofile.main"][i].filePath; - cmd.destination = provisioningProfiles[i].filePath; - cmd.sourceCode = function() { - File.copy(source, destination); - }; + cmd = new JavaScriptCommand(); + cmd.description = "copying provisioning profile"; + cmd.highlight = "filegen"; + cmd.sources = (inputs["codesign.embedded_provisioningprofile"] || []) + .map(function(artifact) { return artifact.filePath; }); + cmd.destination = (outputs["bundle.provisioningprofile"] || []) + .map(function(artifact) { return artifact.filePath; }); + cmd.sourceCode = function() { + var i; + for (var i in sources) { + File.copy(sources[i], destination[i]); + } + }; + if (cmd.sources && cmd.sources.length) commands.push(cmd); - } cmd = new JavaScriptCommand(); cmd.description = "copying public headers"; @@ -762,34 +767,8 @@ Module { commands.push(cmd); if (product.moduleProperty("qbs", "hostOS").contains("darwin")) { - var actualSigningIdentity = product.moduleProperty("xcode", "actualSigningIdentity"); - var codesignDisplayName = product.moduleProperty("xcode", "actualSigningIdentityDisplayName"); - if (actualSigningIdentity) { - var args = product.moduleProperty("xcode", "codesignFlags") || []; - args.push("--force"); - args.push("--sign", actualSigningIdentity); - args = args.concat(DarwinTools._codeSignTimestampFlags(product)); - - for (var j in inputs.xcent) { - args.push("--entitlements", inputs.xcent[j].filePath); - break; // there should only be one - } - - // If this is a framework, we need to sign its versioned directory - if (bundleType === "framework") { - args.push(product.bundle.contentsFolderPath); - } else { - args.push(product.bundle.bundleName); - } - - cmd = new Command(product.moduleProperty("xcode", "codesignPath"), args); - cmd.workingDirectory = product.destinationDirectory; - cmd.description = "codesign " - + ModUtils.moduleProperty(product, "bundleName") - + " using " + codesignDisplayName - + " (" + actualSigningIdentity + ")"; - commands.push(cmd); - } + Array.prototype.push.apply(commands, Codesign.prepareSign( + project, product, inputs, outputs, input, output)); if (bundleType === "application" && product.moduleProperty("qbs", "targetOS").contains("macos")) { diff --git a/share/qbs/modules/bundle/bundle.js b/share/qbs/modules/bundle/bundle.js index 6d9305702..6bb43ecdc 100644 --- a/share/qbs/modules/bundle/bundle.js +++ b/share/qbs/modules/bundle/bundle.js @@ -89,7 +89,7 @@ function productTypeIdentifier(productType) { } function excludedAuxiliaryInputs(project, product) { - var chain = product.moduleProperty("bundle", "_productTypeIdentifierChain"); + var chain = product.bundle._productTypeIdentifierChain; var bestPossibleType; for (var i = chain.length - 1; i >= 0; --i) { switch (chain[i]) { diff --git a/share/qbs/modules/codesign/CodeSignModule.qbs b/share/qbs/modules/codesign/CodeSignModule.qbs new file mode 100644 index 000000000..1951ec374 --- /dev/null +++ b/share/qbs/modules/codesign/CodeSignModule.qbs @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2021 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.File +import qbs.FileInfo +import "codesign.js" as CodeSign + +Module { + condition: false + + property bool enableCodeSigning: false + + property string codesignName + property string codesignPath: codesignName + property stringList codesignFlags + + property bool _canSignArtifacts: false // whether can sign individual actifacts +} diff --git a/share/qbs/modules/codesign/android.qbs b/share/qbs/modules/codesign/android.qbs new file mode 100644 index 000000000..be96d42de --- /dev/null +++ b/share/qbs/modules/codesign/android.qbs @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2021 Raphaël Cotty <raphael.cotty@gmail.com> +** Contact: http://www.qt.io/licensing +** +** This file is part of the 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.Environment +import qbs.File +import qbs.FileInfo +import qbs.ModUtils +import qbs.Probes +import "codesign.js" as CodeSign + +CodeSignModule { + condition: qbs.targetOS.contains("android") + priority: 1 + enableCodeSigning: true + + property bool useApksigner: true + property path apksignerFilePath + + Probes.JdkProbe { + id: jdk + environmentPaths: (jdkPath ? [jdkPath] : []).concat(base) + } + property string jdkPath: jdk.path + property string jarsignerFilePath: FileInfo.joinPaths(jdkPath, "bin", jarsignerName) + property string jarsignerName: "jarsigner" + property string keytoolFilePath: FileInfo.joinPaths(jdkPath, "bin", keytoolName) + property string keytoolName: "keytool" + + property string debugKeystorePath: FileInfo.joinPaths( + Environment.getEnv(qbs.hostOS.contains("windows") + ? "USERPROFILE" : "HOME"), + ".android", "debug.keystore") + readonly property string debugKeystorePassword: "android" + readonly property string debugPassword: "android" + readonly property string debugKeyAlias: "androiddebugkey" + + property string keystorePath: debugKeystorePath + property string keystorePassword: debugKeystorePassword + property string keyPassword: debugPassword + property string keyAlias: debugKeyAlias + + // Private property set by the Android.sdk module + property string _packageName + + Rule { + condition: useApksigner + inputs: ["android.package_unsigned"] + Artifact { + filePath: product.codesign._packageName + fileTags: "android.package" + } + prepare: CodeSign.signApkPackage.apply(this, arguments) + } + + Rule { + condition: !useApksigner + inputs: ["android.package_unsigned"] + Artifact { + filePath: product.codesign._packageName + fileTags: "android.package" + } + prepare: CodeSign.signAabPackage.apply(this, arguments) + } + + validate: { + // Typically there is a debug keystore in ~/.android/debug.keystore which gets created + // by the native build tools the first time a build is done. However, we don't want to + // create it ourselves, because writing to a location outside the qbs build directory is + // both polluting and has the potential for race conditions. So we'll instruct the user what + // to do. + if (keystorePath === debugKeystorePath && !File.exists(debugKeystorePath)) { + throw ModUtils.ModuleError("Could not find an Android debug keystore at " + + codesign.debugKeystorePath + ". " + + "If you are developing for Android on this machine for the first time and " + + "have never built an application using the native Gradle / Android Studio " + + "tooling, this is normal. You must create the debug keystore now using the " + + "following command, in order to continue:\n\n" + + CodeSign.createDebugKeyStoreCommandString(codesign.keytoolFilePath, + codesign.debugKeystorePath, + codesign.debugKeystorePassword, + codesign.debugPassword, + codesign.debugKeyAlias) + + "\n\n" + + "See the following URL for more information: " + + "https://developer.android.com/studio/publish/app-signing.html#debug-mode"); + } + } +} diff --git a/share/qbs/modules/codesign/apple.qbs b/share/qbs/modules/codesign/apple.qbs new file mode 100644 index 000000000..31e2c366d --- /dev/null +++ b/share/qbs/modules/codesign/apple.qbs @@ -0,0 +1,387 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2021 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.BundleTools +import qbs.DarwinTools +import qbs.Environment +import qbs.File +import qbs.FileInfo +import qbs.ModUtils +import qbs.PropertyList +import qbs.Probes +import qbs.Utilities +import "codesign.js" as CodeSign +import "../xcode/xcode.js" as XcodeUtils + +CodeSignModule { + Depends { name: "xcode"; required: qbs.toolchain && qbs.toolchain.contains("xcode") } + + Probes.BinaryProbe { + id: codesignProbe + names: [codesignName] + } + + condition: qbs.hostOS.contains("macos") && qbs.targetOS.contains("darwin") + priority: 0 + + enableCodeSigning: _codeSigningRequired + + codesignName: "codesign" + codesignPath: codesignProbe.filePath + + _canSignArtifacts: true + + property string signingType: { + if (_adHocCodeSigningAllowed) + return "ad-hoc"; + if (_codeSigningAllowed) + return "app-store"; + } + + PropertyOptions { + name: "signingType" + allowedValues: ["app-store", "apple-id", "ad-hoc"] + } + + property string signingIdentity: { + if (signingType === "ad-hoc") // only useful on macOS + return "-"; + + var isDebug = qbs.buildVariant !== "release"; + + if (qbs.targetOS.contains("ios") || qbs.targetOS.contains("tvos") + || qbs.targetOS.contains("watchos")) { + switch (signingType) { + case "app-store": + return isDebug ? "iPhone Developer" : "iPhone Distribution"; + } + } + + if (qbs.targetOS.contains("macos")) { + switch (signingType) { + case "app-store": + return isDebug ? "Mac Developer" : "3rd Party Mac Developer Application"; + case "apple-id": + return "Developer ID Application"; + } + } + } + + property string signingTimestamp: "none" + + property string provisioningProfile + PropertyOptions { + name: "provisioningProfile" + description: "Name or UUID of the provisioning profile to embed in the application; " + + "typically left blank to allow automatic provisioning" + } + + property string teamIdentifier + PropertyOptions { + name: "teamIdentifier" + description: "Name or identifier of the development team whose identities will be used; " + + "typically left blank unless signed into multiple development teams" + } + + property path provisioningProfilesPath: "~/Library/MobileDevice/Provisioning Profiles" + + readonly property var _actualSigningIdentity: { + if (signingIdentity === "-") { + return { + SHA1: signingIdentity, + subjectInfo: { CN: "ad hoc" } + } + } + + var identities = CodeSign.findSigningIdentities(signingIdentity, teamIdentifier); + if (identities && Object.keys(identities).length > 1) { + throw "Multiple codesigning identities (i.e. certificate and private key pairs) " + + "matching '" + signingIdentity + "' were found." + + CodeSign.humanReadableIdentitySummary(identities); + } + + for (var i in identities) + return identities[i]; + } + + // Allowed for macOS + readonly property bool _adHocCodeSigningAllowed: + XcodeUtils.boolFromSdkOrPlatform("AD_HOC_CODE_SIGNING_ALLOWED", + xcode._sdkProps, xcode._platformProps, true) + + // Allowed for all device platforms (not simulators) + readonly property bool _codeSigningAllowed: + XcodeUtils.boolFromSdkOrPlatform("CODE_SIGNING_ALLOWED", + xcode._sdkProps, xcode._platformProps, true) + + // Required for tvOS, iOS, and watchOS (not simulators) + property bool _codeSigningRequired: { + // allow to override value from Xcode so tests do not require signing + var envRequired = Environment.getEnv("QBS_AUTOTEST_CODE_SIGNING_REQUIRED"); + if (envRequired) + return envRequired === "1"; + return XcodeUtils.boolFromSdkOrPlatform("CODE_SIGNING_REQUIRED", + xcode._sdkProps, xcode._platformProps, false) + } + + // Required for tvOS, iOS, and watchOS (not simulators) + readonly property bool _entitlementsRequired: + XcodeUtils.boolFromSdkOrPlatform("ENTITLEMENTS_REQUIRED", + xcode._sdkProps, xcode._platformProps, false) + + readonly property bool _provisioningProfileAllowed: + product.bundle + && product.bundle.isBundle + && product.type.contains("application") + && xcode.platformType !== "simulator" + + // Required for tvOS, iOS, and watchOS (not simulators) + // PROVISIONING_PROFILE_REQUIRED is specified only in Embedded-Device.xcspec in the + // IDEiOSSupportCore IDE plugin, so we'll just write out the logic here manually + readonly property bool _provisioningProfileRequired: + _provisioningProfileAllowed && !qbs.targetOS.contains("macos") + + // Not used on simulator platforms either but provisioning profiles aren't used there anyways + readonly property string _provisioningProfilePlatform: { + if (qbs.targetOS.contains("macos")) + return "OSX"; + if (qbs.targetOS.contains("ios") || qbs.targetOS.contains("watchos")) + return "iOS"; + if (qbs.targetOS.contains("tvos")) + return "tvOS"; + } + + readonly property string _embeddedProfileName: + (xcode._platformProps || {})["EMBEDDED_PROFILE_NAME"] + + setupBuildEnvironment: { + var prefixes = product.xcode ? [ + product.xcode.platformPath + "/Developer", + product.xcode.toolchainPath, + product.xcode.developerPath + ] : []; + for (var i = 0; i < prefixes.length; ++i) { + var codesign_allocate = prefixes[i] + "/usr/bin/codesign_allocate"; + if (File.exists(codesign_allocate)) { + var v = new ModUtils.EnvironmentVariable("CODESIGN_ALLOCATE"); + v.value = codesign_allocate; + v.set(); + break; + } + } + } + + Group { + name: "Provisioning Profiles" + prefix: codesign.provisioningProfilesPath + "/" + files: ["*.mobileprovision", "*.provisionprofile"] + } + + FileTagger { + fileTags: ["codesign.entitlements"] + patterns: ["*.entitlements"] + } + + FileTagger { + fileTags: ["codesign.provisioningprofile"] + patterns: ["*.mobileprovision", "*.provisionprofile"] + } + + Rule { + multiplex: true + condition: product.codesign.enableCodeSigning && + product.codesign._provisioningProfileAllowed + inputs: ["codesign.provisioningprofile"] + + outputFileTags: ["codesign.embedded_provisioningprofile"] + outputArtifacts: { + var artifacts = []; + var provisioningProfiles = (inputs["codesign.provisioningprofile"] || []) + .map(function (a) { return a.filePath; }); + var bestProfile = CodeSign.findBestProvisioningProfile(product, provisioningProfiles); + var uuid = product.provisioningProfile; + if (bestProfile) { + artifacts.push({ + filePath: FileInfo.joinPaths(product.destinationDirectory, + product.codesign._embeddedProfileName), + fileTags: ["codesign.embedded_provisioningprofile"], + codesign: { + _provisioningProfileFilePath: bestProfile.filePath, + _provisioningProfileData: JSON.stringify(bestProfile.data), + } + }); + } else if (uuid) { + throw "Your build settings specify a provisioning profile with the UUID '" + + uuid + "', however, no such provisioning profile was found."; + } else if (product._provisioningProfileRequired) { + var hasProfiles = !!((inputs["codesign.provisioningprofile"] || []).length); + var teamIdentifier = product.teamIdentifier; + var codeSignIdentity = product.signingIdentity; + if (hasProfiles) { + if (codeSignIdentity) { + console.warn("No provisioning profiles matching the bundle identifier '" + + product.bundle.identifier + + "' were found."); + } else { + console.warn("No provisioning profiles matching an applicable signing " + + "identity were found."); + } + } else { + if (codeSignIdentity) { + if (teamIdentifier) { + console.warn("No provisioning profiles with a valid signing identity " + + "(i.e. certificate and private key pair) matching the " + + "team ID '" + teamIdentifier + "' were found.") + } else { + console.warn("No provisioning profiles with a valid signing identity " + + "(i.e. certificate and private key pair) were found."); + } + } else { + console.warn("No non-expired provisioning profiles were found."); + } + } + } + return artifacts; + } + + prepare: { + var cmd = new JavaScriptCommand(); + var data = JSON.parse(output.codesign._provisioningProfileData); + cmd.source = output.codesign._provisioningProfileFilePath; + cmd.destination = output.filePath; + cmd.description = "using provisioning profile " + data.Name + " (" + data.UUID + ")"; + cmd.highlight = "filegen"; + cmd.sourceCode = function() { + File.copy(source, destination); + }; + return [cmd]; + } + } + + Rule { + multiplex: true + condition: product.codesign.enableCodeSigning + inputs: ["codesign.entitlements", "codesign.embedded_provisioningprofile"] + + Artifact { + filePath: FileInfo.joinPaths(product.destinationDirectory, + product.targetName + ".xcent") + fileTags: ["codesign.xcent"] + } + + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating entitlements"; + cmd.highlight = "codegen"; + cmd.bundleIdentifier = product.bundle.identifier; + cmd.signingEntitlements = (inputs["codesign.entitlements"] || []) + .map(function (a) { return a.filePath; }); + cmd.provisioningProfiles = (inputs["codesign.embedded_provisioningprofile"] || []) + .map(function (a) { return a.filePath; }); + cmd.platformPath = product.xcode ? product.xcode.platformPath : undefined; + cmd.sdkPath = product.xcode ? product.xcode.sdkPath : undefined; + cmd.sourceCode = function() { + var i; + var provData = {}; + var provisionProfiles = inputs["codesign.embedded_provisioningprofile"]; + for (i in provisionProfiles) { + var plist = new PropertyList(); + try { + plist.readFromData(Utilities.smimeMessageContent( + provisionProfiles[i].filePath)); + provData = plist.toObject(); + } finally { + plist.clear(); + } + } + + var aggregateEntitlements = {}; + + // Start building up an aggregate entitlements plist from the files in the SDKs, + // which contain placeholders in the same manner as Info.plist + function entitlementsFileContents(path) { + return File.exists(path) ? BundleTools.infoPlistContents(path) : undefined; + } + var entitlementsSources = []; + if (platformPath) { + entitlementsSources.push( + entitlementsFileContents( + FileInfo.joinPaths(platformPath, "Entitlements.plist"))); + } + if (sdkPath) { + entitlementsSources.push( + entitlementsFileContents( + FileInfo.joinPaths(sdkPath, "Entitlements.plist"))); + } + + for (i = 0; i < signingEntitlements.length; ++i) { + entitlementsSources.push(entitlementsFileContents(signingEntitlements[i])); + } + + for (i = 0; i < entitlementsSources.length; ++i) { + var contents = entitlementsSources[i]; + for (var key in contents) { + if (contents.hasOwnProperty(key)) + aggregateEntitlements[key] = contents[key]; + } + } + + contents = provData["Entitlements"]; + for (key in contents) { + if (contents.hasOwnProperty(key) && !aggregateEntitlements.hasOwnProperty(key)) + aggregateEntitlements[key] = contents[key]; + } + + // Expand entitlements variables with data from the provisioning profile + var env = { + "AppIdentifierPrefix": (provData["ApplicationIdentifierPrefix"] || "") + ".", + "CFBundleIdentifier": bundleIdentifier + }; + DarwinTools.expandPlistEnvironmentVariables(aggregateEntitlements, env, true); + + // Anything with an undefined or otherwise empty value should be removed + // Only JSON-formatted plists can have null values, other formats error out + // This also follows Xcode behavior + DarwinTools.cleanPropertyList(aggregateEntitlements); + + var plist = new PropertyList(); + try { + plist.readFromObject(aggregateEntitlements); + plist.writeToFile(outputs["codesign.xcent"][0].filePath, "xml1"); + } finally { + plist.clear(); + } + }; + return [cmd]; + } + } +} diff --git a/share/qbs/modules/codesign/codesign.js b/share/qbs/modules/codesign/codesign.js new file mode 100644 index 000000000..bf7e95224 --- /dev/null +++ b/share/qbs/modules/codesign/codesign.js @@ -0,0 +1,351 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2021 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. +** +****************************************************************************/ + +var File = require("qbs.File"); +var FileInfo = require("qbs.FileInfo"); +var PathTools = require("qbs.PathTools"); +var Process = require("qbs.Process"); +var PropertyList = require("qbs.PropertyList"); +var Utilities = require("qbs.Utilities"); + +function findSigningIdentities(searchString, team) { + if (!searchString) + return {}; + var identities = Utilities.signingIdentities(); + var matchedIdentities = {}; + for (var key in identities) { + var identity = identities[key]; + if (team && ![identity.subjectInfo.O, identity.subjectInfo.OU].contains(team)) + continue; + if (searchString === key || identity.subjectInfo.CN.startsWith(searchString)) + matchedIdentities[key] = identity; + } + return matchedIdentities; +} + +function humanReadableIdentitySummary(identities) { + return "\n\t" + Object.keys(identities).map(function (key) { + return identities[key].subjectInfo.CN + + " in team " + + identities[key].subjectInfo.O + + " (" + identities[key].subjectInfo.OU + ")"; + }).join("\n\t"); +} + +/** + * Returns the best provisioning profile for code signing a binary with the given parameters. + * Ideally, this should behave identically as Xcode but the algorithm is not documented + * \l{https://developer.apple.com/library/ios/qa/qa1814/_index.html}{Automatic Provisioning} + */ +function findBestProvisioningProfile(product, files) { + var actualSigningIdentity = product.codesign._actualSigningIdentity || {}; + var teamIdentifier = product.codesign.teamIdentifier; + var bundleIdentifier = product.bundle.identifier; + var targetOS = product.qbs.targetOS; + var buildVariant = product.qbs.buildVariant; + var query = product.codesign.provisioningProfile; + var profilePlatform = product.codesign._provisioningProfilePlatform; + + // Read all provisioning profiles on disk into plist objects in memory + var profiles = files.map(function(filePath) { + var plist = new PropertyList(); + try { + plist.readFromData(Utilities.smimeMessageContent(filePath)); + return { + data: plist.toObject(), + filePath: filePath + }; + } finally { + plist.clear(); + } + }); + + // Do a simple search by matching UUID or Name + if (query) { + for (var i = 0; i < profiles.length; ++i) { + var obj = profiles[i]; + if (obj.data && (obj.data.UUID === query || obj.data.Name === query)) + return obj; + } + + // If we asked for a specific provisioning profile, don't select one automatically + return undefined; + } + + // Provisioning profiles are not normally used with ad-hoc code signing or non-apps + // We do these checks down here only for the automatic selection but not above because + // if the user explicitly selects a provisioning profile it should be used no matter what + if (actualSigningIdentity.SHA1 === "-" || !product.type.contains("application")) + return undefined; + + // Filter out any provisioning profiles we know to be unsuitable from the start + profiles = profiles.filter(function (profile) { + var data = profile.data; + + if (actualSigningIdentity.subjectInfo) { + var certCommonNames = (data["DeveloperCertificates"] || []).map(function (cert) { + return Utilities.certificateInfo(cert).subjectInfo.CN; + }); + if (!certCommonNames.contains(actualSigningIdentity.subjectInfo.CN)) { + console.log("Skipping provisioning profile with no matching certificate names for '" + + actualSigningIdentity.subjectInfo.CN + + "' (found " + certCommonNames.join(", ") + "): " + + profile.filePath); + return false; + } + } + + var platforms = data["Platform"] || []; + if (platforms.length > 0 && profilePlatform && !platforms.contains(profilePlatform)) { + console.log("Skipping provisioning profile for platform " + platforms.join(", ") + + " (current platform " + profilePlatform + ")" + + ": " + profile.filePath); + return false; + } + + if (teamIdentifier + && !data["TeamIdentifier"].contains(teamIdentifier) + && data["TeamName"] !== teamIdentifier) { + console.log("Skipping provisioning profile for team " + data["TeamIdentifier"] + + " (" + data["TeamName"] + ") (current team " + teamIdentifier + ")" + + ": " + profile.filePath); + return false; + } + + if (Date.parse(data["ExpirationDate"]) <= Date.now()) { + console.log("Skipping expired provisioning profile: " + profile.filePath); + return false; + } + + // Filter development vs distribution profiles; + // though the certificate common names check should have been sufficient + var isDebug = buildVariant === "debug"; + if (data["Entitlements"]["get-task-allow"] !== isDebug) { + console.log("Skipping provisioning profile for wrong debug mode: " + profile.filePath); + return false; + } + + var prefix = data["ApplicationIdentifierPrefix"]; + var fullAppId = data["Entitlements"]["application-identifier"]; + if ([prefix, bundleIdentifier].join(".") !== fullAppId + && [prefix, "*"].join(".") !== fullAppId) { + console.log("Skipping provisioning profile not matching full (" + + [prefix, bundleIdentifier].join(".") + ") or wildcard (" + + [prefix, "*"].join(".") + ") app ID (found " + fullAppId + "): " + + profile.filePath); + return false; + } + + return true; + }); + + // Sort by expiration date - sooner expiration dates come last + profiles.sort(function(profileA, profileB) { + var expA = Date.parse(profileA.data["ExpirationDate"]); + var expB = Date.parse(profileB.data["ExpirationDate"]); + if (expA < expB) + return -1; + if (expA > expB) + return 1; + return 0; + }); + + // Sort by application identifier - wildcard profiles come last + profiles.sort(function(profileA, profileB) { + var idA = profileA.data["Entitlements"]["application-identifier"]; + var idB = profileB.data["Entitlements"]["application-identifier"]; + if (!idA.endsWith(".*") && idB.endsWith(".*")) + return -1; + if (idA.endsWith(".*") && !idB.endsWith(".*")) + return 1; + return 0; + }); + + if (profiles.length) { + console.log("Automatic provisioning using profile " + + profiles[0].data.UUID + + " (" + + profiles[0].data.TeamName + + " - " + + profiles[0].data.Name + + ") in product " + + product.name); + return profiles[0]; + } +} + +function prepareSign(project, product, inputs, outputs, input, output) { + var cmd, cmds = []; + + if (!product.codesign.enableCodeSigning) + return cmds; + + var isBundle = "bundle.content" in outputs; + var outputFilePath = isBundle + ? FileInfo.joinPaths(product.destinationDirectory, product.bundle.bundleName) + : outputs["codesign.signed_artifact"][0].filePath; + var outputFileName = isBundle + ? product.bundle.bundleName + : outputs["codesign.signed_artifact"][0].fileName; + var isProductBundle = product.bundle && product.bundle.isBundle; + + // If the product is a bundle, just sign the bundle + // instead of signing the bundle and executable separately + var shouldSignArtifact = !isProductBundle || isBundle; + + var enableCodeSigning = product.codesign.enableCodeSigning; + if (enableCodeSigning && shouldSignArtifact) { + var actualSigningIdentity = product.codesign._actualSigningIdentity; + if (!actualSigningIdentity) { + throw "No codesigning identities (i.e. certificate and private key pairs) matching “" + + product.codesign.signingIdentity + "” were found."; + } + + // If this is a framework, we need to sign its versioned directory + var subpath = ""; + if (isBundle) { + var frameworkVersion = product.bundle.frameworkVersion; + if (frameworkVersion) { + subpath = product.bundle.contentsFolderPath; + subpath = subpath.substring(product.bundle.bundleName.length); + } + } + + var args = product.codesign.codesignFlags || []; + args.push("--force"); + args.push("--sign", actualSigningIdentity.SHA1); + + // If signingTimestamp is undefined, do not specify the flag at all - + // this uses the system-specific default behavior + var signingTimestamp = product.codesign.signingTimestamp; + if (signingTimestamp !== undefined) { + // If signingTimestamp is an empty string, specify the flag but do + // not specify a value - this uses a default Apple-provided server + var flag = "--timestamp"; + if (signingTimestamp) + flag += "=" + signingTimestamp; + args.push(flag); + } + + for (var j in inputs["codesign.xcent"]) { + args.push("--entitlements", inputs["codesign.xcent"][j].filePath); + break; // there should only be one + } + args.push(outputFilePath + subpath); + cmd = new Command(product.codesign.codesignPath, args); + cmd.description = "codesign " + outputFileName + + " (" + actualSigningIdentity.subjectInfo.CN + ")"; + cmd.outputFilePath = outputFilePath; + cmd.stderrFilterFunction = function(stderr) { + return stderr.replace(outputFilePath + ": replacing existing signature\n", ""); + }; + cmds.push(cmd); + } + + if (isBundle) { + cmd = new Command("touch", ["-c", outputFilePath]); + cmd.silent = true; + cmds.push(cmd); + } + + return cmds; +} + +function signApkPackage(project, product, inputs, outputs, input, output, explicitlyDependsOn) { + var apkInput = inputs["android.package_unsigned"][0]; + var apkOutput = outputs["android.package"][0]; + var cmd; + if (product.codesign.enableCodeSigning) { + var args = ["sign", + "--ks", product.codesign.keystorePath, + "--ks-pass", "pass:" + product.codesign.keystorePassword, + "--ks-key-alias", product.codesign.keyAlias, + "--key-pass", "pass:" + product.codesign.keyPassword, + "--out", apkOutput.filePath, + apkInput.filePath]; + cmd = new Command(product.codesign.apksignerFilePath, args); + cmd.description = "signing " + apkOutput.fileName; + } else { + cmd = new JavaScriptCommand(); + cmd.description = "copying without signing " + apkOutput.fileName; + cmd.source = apkInput.filePath; + cmd.target = apkOutput.filePath; + cmd.silent = true; + cmd.sourceCode = function() { + // If enableCodeSigning is changed to false without any change to unsigned package then + // the copy won't happen because of timestamps. So the target file needs file needs to + // be removed to avoid it. + File.remove(target); + File.copy(source, target); + } + } + return cmd; +} + +function signAabPackage(project, product, inputs, outputs, input, output, explicitlyDependsOn) { + var aabInput = inputs["android.package_unsigned"][0]; + var aabOutput = outputs["android.package"][0]; + var cmd; + if (product.codesign.enableCodeSigning) { + args = ["-sigalg", "SHA1withRSA", "-digestalg", "SHA1", + "-keystore", product.codesign.keystorePath, + "-storepass", product.codesign.keystorePassword, + "-keypass", product.codesign.keyPassword, + "-signedjar", aabOutput.filePath, + aabInput.filePath, + product.codesign.keyAlias]; + cmd = new Command(product.codesign.jarsignerFilePath, args); + cmd.description = "signing " + aabOutput.fileName; + } else { + cmd = new JavaScriptCommand(); + cmd.description = "copying without signing " + aabOutput.fileName; + cmd.source = aabInput.filePath; + cmd.target = aabOutput.filePath; + cmd.silent = true; + cmd.sourceCode = function() { + // If enableCodeSigning is changed to false without any change to unsigned package then + // the copy won't happen because of timestamps. So the target file needs file needs to + // be removed to avoid it. + File.remove(target); + File.copy(source, target); + } + } + return cmd; +} + +function createDebugKeyStoreCommandString(keytoolFilePath, keystoreFilePath, keystorePassword, + keyPassword, keyAlias) { + var args = ["-genkey", "-keystore", keystoreFilePath, "-alias", keyAlias, + "-storepass", keystorePassword, "-keypass", keyPassword, "-keyalg", "RSA", + "-keysize", "2048", "-validity", "10000", "-dname", + "CN=Android Debug,O=Android,C=US"]; + return Process.shellQuote(keytoolFilePath, args); +} diff --git a/share/qbs/modules/codesign/noop.qbs b/share/qbs/modules/codesign/noop.qbs new file mode 100644 index 000000000..3234d7476 --- /dev/null +++ b/share/qbs/modules/codesign/noop.qbs @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2021 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 + +CodeSignModule { + condition: true + priority: -100 +} diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs index 9f4e6be99..39077bec8 100644 --- a/share/qbs/modules/cpp/CppModule.qbs +++ b/share/qbs/modules/cpp/CppModule.qbs @@ -145,6 +145,12 @@ Module { be set." } + property string toolchainInstallPath + PropertyOptions { + name: "toolchainInstallPath" + description: "a path to the directory where the toolchain executable files are located." + } + property pathList includePaths property pathList systemIncludePaths property pathList distributionIncludePaths @@ -180,6 +186,10 @@ Module { property string debugInfoBundleSuffix: "" property string variantSuffix: "" property string dynamicLibraryImportSuffix: ".lib" + property string objectSuffix: ".o" + property string linkerMapSuffix: ".map" + property string compilerListingSuffix: ".lst" + property string assemblerListingSuffix: ".lst" property bool createSymlinks: true property stringList dynamicLibraries // list of names, will be linked with -lname property stringList staticLibraries // list of static library files diff --git a/share/qbs/modules/cpp/DarwinGCC.qbs b/share/qbs/modules/cpp/DarwinGCC.qbs index 9332603ec..158c3c061 100644 --- a/share/qbs/modules/cpp/DarwinGCC.qbs +++ b/share/qbs/modules/cpp/DarwinGCC.qbs @@ -98,7 +98,7 @@ UnixGCC { setupBuildEnvironment: { for (var key in product.cpp.buildEnv) { - v = new ModUtils.EnvironmentVariable(key); + var v = new ModUtils.EnvironmentVariable(key); v.value = product.cpp.buildEnv[key]; v.set(); } @@ -216,7 +216,8 @@ UnixGCC { multiplex: true outputFileTags: ["bundle.input", "application", "primary", "debuginfo_app", - "debuginfo_bundle", "bundle.variant_symlink", "debuginfo_plist"] + "debuginfo_bundle", "bundle.variant_symlink", "debuginfo_plist", + "codesign.signed_artifact"] outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "application", "app") prepare: Darwin.prepareLipo.apply(Darwin, arguments) @@ -227,7 +228,8 @@ UnixGCC { inputsFromDependencies: ["loadablemodule"] multiplex: true - outputFileTags: ["bundle.input", "loadablemodule", "primary", "debuginfo_loadablemodule"] + outputFileTags: ["bundle.input", "loadablemodule", "primary", "debuginfo_loadablemodule", + "debuginfo_bundle", "debuginfo_plist", "codesign.signed_artifact"] outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "loadablemodule", "loadablemodule") @@ -241,7 +243,7 @@ UnixGCC { outputFileTags: ["bundle.input", "dynamiclibrary", "dynamiclibrary_symbols", "primary", "debuginfo_dll","debuginfo_bundle","bundle.variant_symlink", - "debuginfo_plist"] + "debuginfo_plist", "codesign.signed_artifact"] outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "dynamiclibrary", "dll") prepare: Darwin.prepareLipo.apply(Darwin, arguments) @@ -252,7 +254,7 @@ UnixGCC { inputsFromDependencies: ["staticlibrary"] multiplex: true - outputFileTags: ["bundle.input", "staticlibrary", "primary"] + outputFileTags: ["bundle.input", "staticlibrary", "primary", "codesign.signed_artifact"] outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "staticlibrary") prepare: Darwin.prepareLipo.apply(Darwin, arguments) diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs index b69f26739..934636849 100644 --- a/share/qbs/modules/cpp/GenericGCC.qbs +++ b/share/qbs/modules/cpp/GenericGCC.qbs @@ -44,6 +44,8 @@ CppModule { condition: qbs.toolchain && qbs.toolchain.contains("gcc") priority: -100 + Depends { name: "codesign" } + Probes.GccBinaryProbe { id: compilerPathProbe condition: !toolchainInstallPath && !_skipAllChecks @@ -134,8 +136,7 @@ CppModule { property string toolchainPrefix: compilerPathProbe.found ? compilerPathProbe.tcPrefix : undefined - property string toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path - : undefined + toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined property string binutilsPath: binutilsProbe.found ? binutilsProbe.path : toolchainInstallPath assemblerName: 'as' + compilerExtension @@ -211,6 +212,11 @@ CppModule { return createSymlinks && internalVersion && ["macho", "elf"].contains(cpp.imageFormat); } + readonly property bool shouldSignArtifacts: codesign._canSignArtifacts + && codesign.enableCodeSigning + // codesigning is done during the lipo step + && !product.multiplexed + property string internalVersion: { if (product.version === undefined) return undefined; @@ -401,12 +407,15 @@ CppModule { "bundle.input", "dynamiclibrary", "dynamiclibrary_symlink", "dynamiclibrary_symbols", "debuginfo_dll", "debuginfo_bundle","dynamiclibrary_import", "debuginfo_plist", + "codesign.signed_artifact", ] outputArtifacts: { var artifacts = [{ filePath: product.destinationDirectory + "/" + PathTools.dynamicLibraryFilePath(product), - fileTags: ["bundle.input", "dynamiclibrary"], + fileTags: ["bundle.input", "dynamiclibrary"] + .concat(product.cpp.shouldSignArtifacts + ? ["codesign.signed_artifact"] : []), bundle: { _bundleFilePath: product.destinationDirectory + "/" + PathTools.bundleExecutableFilePath(product) @@ -511,12 +520,14 @@ CppModule { inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"] outputFileTags: ["bundle.input", "loadablemodule", "debuginfo_loadablemodule", - "debuginfo_bundle","debuginfo_plist"] + "debuginfo_bundle", "debuginfo_plist", "codesign.signed_artifact"] outputArtifacts: { var app = { filePath: FileInfo.joinPaths(product.destinationDirectory, PathTools.loadableModuleFilePath(product)), - fileTags: ["bundle.input", "loadablemodule"], + fileTags: ["bundle.input", "loadablemodule"] + .concat(product.cpp.shouldSignArtifacts + ? ["codesign.signed_artifact"] : []), bundle: { _bundleFilePath: FileInfo.joinPaths(product.destinationDirectory, PathTools.bundleExecutableFilePath(product)) @@ -548,13 +559,14 @@ CppModule { } inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"] - outputFileTags: ["bundle.input", "application", "debuginfo_app","debuginfo_bundle", - "debuginfo_plist", "mem_map"] + outputFileTags: ["bundle.input", "application", "debuginfo_app", "debuginfo_bundle", + "debuginfo_plist", "mem_map", "codesign.signed_artifact"] outputArtifacts: { var app = { filePath: FileInfo.joinPaths(product.destinationDirectory, PathTools.applicationFilePath(product)), - fileTags: ["bundle.input", "application"], + fileTags: ["bundle.input", "application"].concat( + product.cpp.shouldSignArtifacts ? ["codesign.signed_artifact"] : []), bundle: { _bundleFilePath: FileInfo.joinPaths(product.destinationDirectory, PathTools.bundleExecutableFilePath(product)) @@ -566,7 +578,7 @@ CppModule { if (product.cpp.generateLinkerMapFile) { artifacts.push({ filePath: FileInfo.joinPaths(product.destinationDirectory, - product.targetName + ".map"), + product.targetName + product.cpp.linkerMapSuffix), fileTags: ["mem_map"] }); } @@ -598,7 +610,7 @@ CppModule { return [{ fileTags: tags, filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir), - input.fileName + ".o") + input.fileName + input.cpp.objectSuffix) }]; } @@ -613,7 +625,7 @@ CppModule { Artifact { fileTags: ["obj"] - filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir), input.fileName + ".o") + filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir), input.fileName + input.cpp.objectSuffix) } prepare: { diff --git a/share/qbs/modules/cpp/android-gcc.qbs b/share/qbs/modules/cpp/android-gcc.qbs index 5759606aa..e42601a23 100644 --- a/share/qbs/modules/cpp/android-gcc.qbs +++ b/share/qbs/modules/cpp/android-gcc.qbs @@ -43,21 +43,32 @@ LinuxGCC { priority: 2 rpaths: [] + // toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android cxxLanguageVersion: "c++14" - property string cxxStlBaseDir: FileInfo.joinPaths(Android.ndk.ndkDir, "sources", "cxx-stl") - property string stlBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "llvm-libc++") - property string stlLibsDir: { - if (stlBaseDir) - return FileInfo.joinPaths(stlBaseDir, "libs", Android.ndk.abi); - return undefined; + property string archLibsDir: { + switch (qbs.architecture) { + case "arm64": + return "aarch64"; + case "armv7a": + return "arm"; + case "x86_64": + return qbs.architecture; + case "x86": + return "i686"; + } } + property string targetDir: "android" + (["armeabi", "armeabi-v7a"].contains(Android.ndk.abi) ? "eabi" : "") + property string triple: [archLibsDir, targetSystem, targetDir].join("-") + property string libsDir: FileInfo.joinPaths(sysroot, "usr", "lib", triple); - property string sharedStlFilePath: (stlLibsDir && Android.ndk.appStl.endsWith("_shared")) - ? FileInfo.joinPaths(stlLibsDir, dynamicLibraryPrefix + Android.ndk.appStl + dynamicLibrarySuffix) + property string sharedStlFilePath: (libsDir && Android.ndk.appStl.endsWith("_shared")) + ? FileInfo.joinPaths(libsDir, dynamicLibraryPrefix + Android.ndk.appStl + dynamicLibrarySuffix) : undefined - property string staticStlFilePath: (stlLibsDir && Android.ndk.appStl.endsWith("_static")) - ? FileInfo.joinPaths(stlLibsDir, NdkUtils.stlFilePath(staticLibraryPrefix, Android.ndk, staticLibrarySuffix)) + property string staticStlFilePath: (libsDir && Android.ndk.appStl.endsWith("_static")) + ? FileInfo.joinPaths(libsDir, Android.ndk.platformVersion, + NdkUtils.stlFileName(staticLibraryPrefix, Android.ndk, + staticLibrarySuffix)) : undefined Group { @@ -91,52 +102,35 @@ LinuxGCC { linkerFlags: NdkUtils.commonLinkerFlags(Android.ndk.abi); driverLinkerFlags: { - var flags = ["-fuse-ld=lld", "-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libatomic.a", "-nostdlib++"]; - if (Android.ndk.appStl.startsWith("c++") && Android.ndk.abi === "armeabi-v7a") - flags = flags.concat(["-Wl,--exclude-libs,libunwind.a"]); + var flags = ["-fuse-ld=lld", "-Wl,--exclude-libs,libgcc.a", "-nostdlib++"]; + // See https://android.googlesource.com/platform/ndk/+/ndk-release-r21/docs/BuildSystemMaintainers.md#Unwinding + if (Android.ndk.abi === "armeabi-v7a") { + flags = flags.concat(["-Wl,--exclude-libs,libgcc_real.a"]); + if (Android.ndk.appStl.startsWith("c++")) + flags = flags.concat(["-Wl,--exclude-libs,libunwind.a"]); + } return flags; } 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 === "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(FileInfo.joinPaths(stlLibsDir, NdkUtils.stlFilePath(dynamicLibraryPrefix, Android.ndk, dynamicLibrarySuffix))); + libs.push(FileInfo.joinPaths(libsDir, Android.ndk.platformVersion, + NdkUtils.stlFileName(dynamicLibraryPrefix, Android.ndk, + dynamicLibrarySuffix))); return libs; } - staticLibraries: staticStlFilePath - systemIncludePaths: { - 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: ["ANDROID", "__ANDROID__"] binutilsPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", "llvm", "prebuilt", Android.ndk.hostArch, "bin"); binutilsPathPrefix: FileInfo.joinPaths(binutilsPath, "llvm-") - syslibroot: FileInfo.joinPaths(Android.ndk.ndkDir, "platforms", - Android.ndk.platform, "arch-" - + NdkUtils.abiNameToDirName(Android.ndk.abi)) - sysroot: FileInfo.joinPaths(Android.ndk.ndkDir, "sysroot") + sysroot: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", "llvm", "prebuilt", + Android.ndk.hostArch, "sysroot") targetArch: { switch (qbs.architecture) { diff --git a/share/qbs/modules/cpp/darwin.js b/share/qbs/modules/cpp/darwin.js index 6373b57c4..7f7e9a05d 100644 --- a/share/qbs/modules/cpp/darwin.js +++ b/share/qbs/modules/cpp/darwin.js @@ -28,6 +28,7 @@ ** ****************************************************************************/ +var Codesign = require("../codesign/codesign.js"); var File = require("qbs.File"); var FileInfo = require("qbs.FileInfo"); var Gcc = require("./gcc.js"); @@ -99,6 +100,9 @@ function lipoOutputArtifacts(product, inputs, fileTag, debugSuffix) { else tags.push(fileTag, "primary"); + if (product.codesign.enableCodeSigning) + tags.push("codesign.signed_artifact"); + return { filePath: FileInfo.joinPaths(product.destinationDirectory, PathTools.linkerOutputFilePath(fileTag, product, @@ -188,6 +192,12 @@ function prepareLipo(project, product, inputs, outputs, input, output) { commands.push(cmd); if (outputs.dynamiclibrary_symbols) Array.prototype.push.apply(commands, Gcc.createSymbolCheckingCommands(product, outputs)); + + if (product.codesign.enableCodeSigning) { + Array.prototype.push.apply( + commands, Codesign.prepareSign(project, product, inputs, outputs, input, output)); + } + return commands; } diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js index 9b6a074d2..775c06a31 100644 --- a/share/qbs/modules/cpp/gcc.js +++ b/share/qbs/modules/cpp/gcc.js @@ -28,6 +28,7 @@ ** ****************************************************************************/ +var Codesign = require("../codesign/codesign.js"); var Cpp = require("cpp.js"); var File = require("qbs.File"); var FileInfo = require("qbs.FileInfo"); @@ -132,7 +133,7 @@ function collectLibraryDependencies(product, isDarwin) { if (!obj.cpp) return; function ensureArray(a) { - return Array.isArray(a) ? a : []; + return (a instanceof Array) ? a : []; } function sanitizedModuleListProperty(obj, moduleName, propertyName) { return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName)); @@ -355,11 +356,12 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat return rpath; } + function isNotSystemRunPath(p) { + return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p) + && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p))); + }; + if (!product.qbs.targetOS.contains("windows")) { - function isNotSystemRunPath(p) { - return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p) - && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p))); - }; for (i in rpaths) { if (isNotSystemRunPath(rpaths[i])) escapableLinkerFlags.push("-rpath", fixupRPath(rpaths[i])); @@ -1383,27 +1385,9 @@ function prepareLinker(project, product, inputs, outputs, input, output) { } } - if (product.xcode && product.bundle) { - var actualSigningIdentity = product.xcode.actualSigningIdentity; - var codesignDisplayName = product.xcode.actualSigningIdentityDisplayName; - if (actualSigningIdentity && !product.bundle.isBundle) { - args = product.xcode.codesignFlags || []; - args.push("--force"); - args.push("--sign", actualSigningIdentity); - args = args.concat(DarwinTools._codeSignTimestampFlags(product)); - - for (var j in inputs.xcent) { - args.push("--entitlements", inputs.xcent[j].filePath); - break; // there should only be one - } - args.push(primaryOutput.filePath); - cmd = new Command(product.xcode.codesignPath, args); - cmd.description = "codesign " - + primaryOutput.fileName - + " using " + codesignDisplayName - + " (" + actualSigningIdentity + ")"; - commands.push(cmd); - } + if (product.cpp.shouldSignArtifacts) { + Array.prototype.push.apply( + commands, Codesign.prepareSign(project, product, inputs, outputs, input, output)); } return commands; diff --git a/share/qbs/modules/cpp/iar.js b/share/qbs/modules/cpp/iar.js index f1c41fe64..416de7ee2 100644 --- a/share/qbs/modules/cpp/iar.js +++ b/share/qbs/modules/cpp/iar.js @@ -38,35 +38,138 @@ var TemporaryDir = require("qbs.TemporaryDir"); var TextFile = require("qbs.TextFile"); function supportXLinker(architecture) { - return architecture === "78k" || architecture === "avr" - || architecture === "avr32" || architecture === "mcs51" - || architecture === "msp430" || architecture === "v850" - || architecture === "m68k" || architecture === "m32c" - || architecture === "r32c" || architecture === "m16c" - || architecture === "cr16"; + return architecture === "78k" + || architecture === "avr" + || architecture === "avr32" + || architecture === "cr16" + || architecture === "hcs12" + || architecture === "hcs8" + || architecture === "m16c" + || architecture === "m32c" + || architecture === "m68k" + || architecture === "mcs51" + || architecture === "msp430" + || architecture === "r32c" + || architecture === "v850"; } function supportILinker(architecture) { return architecture.startsWith("arm") - || architecture === "rh850" || architecture === "rl78" - || architecture === "rx" || architecture === "stm8" - || architecture === "sh" || architecture === "riscv"; + || architecture === "rh850" + || architecture === "riscv" + || architecture === "rl78" + || architecture === "rx" + || architecture === "sh" + || architecture === "stm8"; } function supportXArchiver(architecture) { - return architecture === "mcs51" || architecture === "avr" - || architecture === "msp430" || architecture === "v850" - || architecture === "78k" || architecture === "avr32" - || architecture === "m68k" || architecture === "m32c" - || architecture === "r32c" || architecture === "m16c" - || architecture === "cr16"; + return architecture === "78k" + || architecture === "avr" + || architecture === "avr32" + || architecture === "cr16" + || architecture === "hcs12" + || architecture === "hcs8" + || architecture === "m16c" + || architecture === "m32c" + || architecture === "m68k" + || architecture === "mcs51" + || architecture === "msp430" + || architecture === "r32c" + || architecture === "v850"; } function supportIArchiver(architecture) { return architecture.startsWith("arm") - || architecture === "stm8" || architecture === "rl78" - || architecture === "rx" || architecture === "rh850" - || architecture === "sh" || architecture === "riscv"; + || architecture === "rh850" + || architecture === "riscv" + || architecture === "rl78" + || architecture === "rx" + || architecture === "sh" + || architecture === "stm8"; +} + +function supportXAssembler(architecture) { + return architecture.startsWith("arm") + || architecture === "78k" + || architecture === "avr" + || architecture === "hcs12" + || architecture === "m16c" + || architecture === "mcs51" + || architecture === "msp430" + || architecture === "m32c" + || architecture === "v850"; +} + +function supportIAssembler(architecture) { + return architecture === "avr32" + || architecture === "cr16" + || architecture === "hcs8" + || architecture === "r32c" + || architecture === "rh850" + || architecture === "riscv" + || architecture === "rl78" + || architecture === "rx" + || architecture === "sh" + || architecture === "stm8" + || architecture === "m68k"; +} + +function supportEndianness(architecture) { + return architecture.startsWith("arm") + || architecture === "rx"; +} + +function supportCppExceptions(architecture) { + return architecture.startsWith("arm") + || architecture === "rh850" + || architecture === "riscv" + || architecture === "rl78" + || architecture === "rx"; +} + +function supportCppRtti(architecture) { + return architecture.startsWith("arm") + || architecture === "rh850" + || architecture === "riscv" + || architecture === "rl78" + || architecture === "rx"; +} + +function supportCppWarningAboutCStyleCast(architecture) { + return architecture.startsWith("arm") + || architecture === "avr" + || architecture === "avr32" + || architecture === "cr16" + || architecture === "mcs51" + || architecture === "msp430" + || architecture === "rh850" + || architecture === "rl78" + || architecture === "rx" + || architecture === "stm8" + || architecture === "v850"; +} + +function supportDeprecatedFeatureWarnings(architecture) { + return architecture.startsWith("arm") + || architecture === "avr" + || architecture === "cr16" + || architecture === "mcs51" + || architecture === "msp430" + || architecture === "rh850" + || architecture === "rl78" + || architecture === "rx" + || architecture === "stm8" + || architecture === "v850"; +} + +function supportCLanguageVersion(architecture) { + return architecture !== "78k"; +} + +function supportCppLanguage(compilerFilePath) { + var baseName = FileInfo.baseName(compilerFilePath); + return baseName !== "iccs08"; } // It is a 'magic' IAR-specific target architecture code. @@ -94,7 +197,11 @@ function architectureCode(architecture) { return "34"; case "cr16": return "45"; - case "rh850": case "rl78": case "rx": case "stm8": case "sh": case "riscv": + case "hcs12": + return "12"; + case "hcs8": + return "78"; + case "rh850": case "riscv": case "rl78": case "rx": case "sh": case "stm8": return ""; default: if (architecture.startsWith("arm")) @@ -107,40 +214,44 @@ function compilerName(qbs) { var architecture = qbs.architecture; if (architecture.startsWith("arm")) return "iccarm"; - else if (architecture === "mcs51") - return "icc8051"; + else if (architecture === "78k") + return "icc78k"; else if (architecture === "avr") return "iccavr"; - else if (architecture === "stm8") - return "iccstm8"; + else if (architecture === "avr32") + return "iccavr32"; + else if (architecture === "cr16") + return "icccr16c"; + else if (architecture === "hcs12") + return "icchcs12"; + else if (architecture === "hcs8") + return "iccs08"; + else if (architecture === "m16c") + return "iccm16c"; + else if (architecture === "m32c") + return "iccm32c"; + else if (architecture === "m68k") + return "icccf"; + else if (architecture === "mcs51") + return "icc8051"; else if (architecture === "msp430") return "icc430"; - else if (architecture === "v850") - return "iccv850"; - else if (architecture === "78k") - return "icc78k"; + else if (architecture === "r32c") + return "iccr32c"; + else if (architecture === "rh850") + return "iccrh850"; + else if (architecture === "riscv") + return "iccriscv"; else if (architecture === "rl78") return "iccrl78"; else if (architecture === "rx") return "iccrx"; - else if (architecture === "rh850") - return "iccrh850"; - else if (architecture === "avr32") - return "iccavr32"; else if (architecture === "sh") return "iccsh"; - else if (architecture === "riscv") - return "iccriscv"; - else if (architecture === "m68k") - return "icccf"; - else if (architecture === "m32c") - return "iccm32c"; - else if (architecture === "r32c") - return "iccr32c"; - else if (architecture === "m16c") - return "iccm16c"; - else if (architecture === "cr16") - return "icccr16c"; + else if (architecture === "stm8") + return "iccstm8"; + else if (architecture === "v850") + return "iccv850"; throw "Unable to deduce compiler name for unsupported architecture: '" + architecture + "'"; } @@ -149,40 +260,44 @@ function assemblerName(qbs) { var architecture = qbs.architecture; if (architecture.startsWith("arm")) return "iasmarm"; - else if (architecture === "rl78") - return "iasmrl78"; - else if (architecture === "rx") - return "iasmrx"; - else if (architecture === "rh850") - return "iasmrh850"; - else if (architecture === "mcs51") - return "a8051"; - else if (architecture === "avr") - return "aavr"; - else if (architecture === "stm8") - return "iasmstm8"; - else if (architecture === "msp430") - return "a430"; - else if (architecture === "v850") - return "av850"; else if (architecture === "78k") return "a78k"; + else if (architecture === "avr") + return "aavr"; else if (architecture === "avr32") return "aavr32"; - else if (architecture === "sh") - return "iasmsh"; - else if (architecture === "riscv") - return "iasmriscv"; - else if (architecture === "m68k") - return "acf"; + else if (architecture === "cr16") + return "acr16c"; + else if (architecture === "hcs12") + return "ahcs12"; + else if (architecture === "hcs8") + return "as08"; + else if (architecture === "m16c") + return "am16c"; else if (architecture === "m32c") return "am32c"; + else if (architecture === "m68k") + return "acf"; + else if (architecture === "mcs51") + return "a8051"; + else if (architecture === "msp430") + return "a430"; else if (architecture === "r32c") return "ar32c"; - else if (architecture === "m16c") - return "am16c"; - else if (architecture === "cr16") - return "acr16c"; + else if (architecture === "rh850") + return "iasmrh850"; + else if (architecture === "riscv") + return "iasmriscv"; + else if (architecture === "rl78") + return "iasmrl78"; + else if (architecture === "rx") + return "iasmrx"; + else if (architecture === "sh") + return "iasmsh"; + else if (architecture === "stm8") + return "iasmstm8"; + else if (architecture === "v850") + return "av850"; throw "Unable to deduce assembler name for unsupported architecture: '" + architecture + "'"; } @@ -253,16 +368,16 @@ function guessArmArchitecture(core) { arch += "v4m"; else if (core === "__ARM4TM__") arch += "v4tm"; - else if (core === "__ARM5__") - arch += "v5"; else if (core === "__ARM5E__") arch += "v5e"; - else if (core === "__ARM6__") - arch += "v6"; + else if (core === "__ARM5__") + arch += "v5"; else if (core === "__ARM6M__") arch += "v6m"; else if (core === "__ARM6SM__") arch += "v6sm"; + else if (core === "__ARM6__") + arch += "v6"; else if (core === "__ARM7M__") arch += "v7m"; else if (core === "__ARM7R__") @@ -271,42 +386,46 @@ function guessArmArchitecture(core) { } function guessArchitecture(macros) { - if (macros["__ICCARM__"] === "1") - return guessArmArchitecture(macros["__CORE__"]); - else if (macros["__ICC8051__"] === "1") - return "mcs51"; - else if (macros["__ICCAVR__"] === "1") - return "avr"; - else if (macros["__ICCSTM8__"] === "1") - return "stm8"; - else if (macros["__ICC430__"] === "1") + if (macros["__ICC430__"] === "1") return "msp430"; - else if (macros["__ICCRL78__"] === "1") - return "rl78"; - else if (macros["__ICCRX__"] === "1") - return "rx"; - else if (macros["__ICCRH850__"] === "1") - return "rh850"; - else if (macros["__ICCV850__"] === "1") - return "v850"; else if (macros["__ICC78K__"] === "1") return "78k"; + else if (macros["__ICC8051__"] === "1") + return "mcs51"; + else if (macros["__ICCARM__"] === "1") + return guessArmArchitecture(macros["__CORE__"]); else if (macros["__ICCAVR32__"] === "1") return "avr32"; - else if (macros["__ICCSH__"] === "1") - return "sh"; - else if (macros["__ICCRISCV__"] === "1") - return "riscv"; + else if (macros["__ICCAVR__"] === "1") + return "avr"; else if (macros["__ICCCF__"] === "1") return "m68k"; + else if (macros["__ICCCR16C__"] === "1") + return "cr16"; + else if (macros["__ICCHCS12__"] === "1") + return "hcs12"; + else if (macros["__ICCM16C__"] === "1") + return "m16c"; else if (macros["__ICCM32C__"] === "1") return "m32c"; else if (macros["__ICCR32C__"] === "1") return "r32c"; - else if (macros["__ICCM16C__"] === "1") - return "m16c"; - else if (macros["__ICCCR16C__"] === "1") - return "cr16"; + else if (macros["__ICCRH850__"] === "1") + return "rh850"; + else if (macros["__ICCRISCV__"] === "1") + return "riscv"; + else if (macros["__ICCRL78__"] === "1") + return "rl78"; + else if (macros["__ICCRX__"] === "1") + return "rx"; + else if (macros["__ICCS08__"] === "1") + return "hcs8"; + else if (macros["__ICCSH__"] === "1") + return "sh"; + else if (macros["__ICCSTM8__"] === "1") + return "stm8"; + else if (macros["__ICCV850__"] === "1") + return "v850"; } function guessEndianness(macros) { @@ -315,19 +434,31 @@ function guessEndianness(macros) { return "big" } -function guessVersion(macros, architecture) -{ +function guessVersion(macros, architecture) { var version = parseInt(macros["__VER__"], 10); if (architecture.startsWith("arm")) { return { major: parseInt(version / 1000000), minor: parseInt(version / 1000) % 1000, patch: parseInt(version) % 1000 } - } else if (architecture === "mcs51" || architecture === "avr" || architecture === "stm8" - || architecture === "msp430" || architecture === "rl78" || architecture === "rx" - || architecture === "rh850" || architecture === "v850" || architecture === "78k" - || architecture === "avr32" || architecture === "sh" || architecture === "riscv" - || architecture === "m68k" || architecture === "m32c" || architecture === "r32c" - || architecture === "m16c" || architecture === "cr16") { + } else if (architecture === "78k" + || architecture === "avr" + || architecture === "avr32" + || architecture === "cr16" + || architecture === "hcs12" + || architecture === "hcs8" + || architecture === "m16c" + || architecture === "m32c" + || architecture === "m68k" + || architecture === "mcs51" + || architecture === "msp430" + || architecture === "r32c" + || architecture === "rh850" + || architecture === "riscv" + || architecture === "rl78" + || architecture === "rx" + || architecture === "sh" + || architecture === "stm8" + || architecture === "v850") { return { major: parseInt(version / 100), minor: parseInt(version % 100), patch: 0 } @@ -338,24 +469,25 @@ function cppLanguageOption(compilerFilePath) { var baseName = FileInfo.baseName(compilerFilePath); switch (baseName) { case "iccarm": - case "iccrl78": - case "iccrx": case "iccrh850": case "iccriscv": + case "iccrl78": + case "iccrx": return "--c++"; - case "icc8051": - case "iccavr": - case "iccstm8": case "icc430": - case "iccv850": case "icc78k": + case "icc8051": + case "iccavr": case "iccavr32": - case "iccsh": case "icccf": + case "icccr16c": + case "icchcs12": + case "iccm16c": case "iccm32c": case "iccr32c": - case "iccm16c": - case "icccr16c": + case "iccsh": + case "iccstm8": + case "iccv850": return "--ec++"; } throw "Unable to deduce C++ language option for unsupported compiler: '" @@ -369,7 +501,7 @@ function dumpMacros(compilerFilePath, tag) { var outFilePath = FileInfo.fromNativeSeparators(tempDir.path() + "/iar-macros.predef"); var args = [ inFilePath, "--predef_macros", outFilePath ]; - if (tag && tag === "cpp") + if (tag === "cpp" && supportCppLanguage(compilerFilePath)) args.push(cppLanguageOption(compilerFilePath)); var p = new Process(); @@ -378,45 +510,48 @@ function dumpMacros(compilerFilePath, tag) { return ModUtils.extractMacros(outFile.readAll()); } -function dumpDefaultPaths(compilerFilePath, tag) { +function dumpCompilerIncludePaths(compilerFilePath, tag) { + // We can dump the compiler include paths using the undocumented `--IDE3` flag, + // e.g. which also is used in the IAR extension for the VSCode. In this case the + // compiler procuces the console output in the following format: + // `$$TOOL_BEGIN $$VERSION "3" $$INC_BEGIN $$FILEPATH "<path\\to\\directory>" $$TOOL_END` + 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") + var args = ["--IDE3", inFilePath]; + if (tag === "cpp" && supportCppLanguage(compilerFilePath)) args.push(cppLanguageOption(compilerFilePath)); + var includePaths = []; var p = new Process(); - // This process should return an error, don't throw - // an error in this case. + // It is possible that the process can return an error code in case the + // compiler does not support the `--IDE3` flag. So, 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; + p.readStdOut().trim().split(/\r?\n/g).map(function(line) { + var m = line.match(/\$\$INC_BEGIN\s\$\$FILEPATH\s\"([^"]*)/); + if (m) { + var includePath = m[1].replace(/\\\\/g, '/'); + if (includePath && File.exists(includePath)) + includePaths.push(includePath); + } + }); - var path = output.substring(startQuoteIndex + 1, endQuoteIndex) - .replace(/[\s]{2,}/g, ' '); - includePaths.push(path); + if (includePaths.length === 0) { + // This can happen if the compiler does not support the `--IDE3` flag, + // e.g. IAR for S08 architecture. In this case we use fallback to the + // detection of the `inc` directory. + var includePath = FileInfo.joinPaths(FileInfo.path(compilerFilePath), "../inc/"); + if (File.exists(includePath)) + includePaths.push(includePath); } + return includePaths; +} + +function dumpDefaultPaths(compilerFilePath, tag) { + var includePaths = dumpCompilerIncludePaths(compilerFilePath, tag); return { "includePaths": includePaths }; @@ -441,7 +576,7 @@ function collectLibraryDependencies(product) { if (!obj.cpp) return; function ensureArray(a) { - return Array.isArray(a) ? a : []; + return (a instanceof Array) ? a : []; } function sanitizedModuleListProperty(obj, moduleName, propertyName) { return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName)); @@ -477,18 +612,24 @@ function collectLibraryDependencies(product) { return result; } -function compilerOutputArtifacts(input, useListing) { +function compilerOutputArtifacts(input, isCompilerArtifacts) { var artifacts = []; artifacts.push({ fileTags: ["obj"], filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + input.cpp.objectSuffix }); - if (useListing) { + if (isCompilerArtifacts && input.cpp.generateCompilerListingFiles) { + artifacts.push({ + fileTags: ["lst"], + filePath: Utilities.getHash(input.baseDir) + "/" + + input.fileName + input.cpp.compilerListingSuffix + }); + } else if (!isCompilerArtifacts && input.cpp.generateAssemblerListingFiles) { artifacts.push({ fileTags: ["lst"], filePath: Utilities.getHash(input.baseDir) + "/" - + input.fileName + ".lst" + + input.fileName + input.cpp.assemblerListingSuffix }); } return artifacts; @@ -505,7 +646,7 @@ function applicationLinkerOutputArtifacts(product) { fileTags: ["mem_map"], filePath: FileInfo.joinPaths( product.destinationDirectory, - product.targetName + ".map") + product.targetName + product.cpp.linkerMapSuffix) }; return [app, mem_map] } @@ -521,9 +662,6 @@ function staticLibraryLinkerOutputArtifacts(product) { } function compilerFlags(project, product, input, outputs, explicitlyDependsOn) { - // Determine which C-language we're compiling. - var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags)); - var args = []; // Input. @@ -580,6 +718,7 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) { } var architecture = input.qbs.architecture; + var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags)); // Warning level flags. switch (input.cpp.warningLevel) { @@ -587,24 +726,21 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) { args.push("--no_warnings"); break; case "all": - if (architecture !== "78k") { - if (architecture !== "avr32" && architecture !== "r32c" - && architecture !== "sh" && architecture !== "m16c") { + if (supportDeprecatedFeatureWarnings(architecture)) { args.push("--deprecated_feature_warnings=" +"+attribute_syntax," +"+preprocessor_extensions," +"+segment_pragmas"); } - if (tag === "cpp") + if (tag === "cpp" && supportCppWarningAboutCStyleCast(architecture)) args.push("--warn_about_c_style_casts"); - } break; } if (input.cpp.treatWarningsAsErrors) args.push("--warnings_are_errors"); // C language version flags. - if (tag === "c" && (architecture !== "78k")) { + if (tag === "c" && supportCLanguageVersion(architecture)) { var knownValues = ["c89"]; var cLanguageVersion = Cpp.languageVersion( input.cpp.cLanguageVersion, knownValues, "C"); @@ -620,35 +756,27 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) { } // C++ language version flags. - if (tag === "cpp") { - if (architecture.startsWith("arm") - || architecture === "rl78" || architecture === "rx" - || architecture === "rh850" || architecture === "riscv") { - // Enable C++ language flags. - args.push("--c++"); - // Exceptions flags. - if (!input.cpp.enableExceptions) - args.push("--no_exceptions"); - // RTTI flags. - if (!input.cpp.enableRtti) - args.push("--no_rtti"); - } else if (architecture === "stm8" || architecture === "mcs51" - || architecture === "avr" || architecture === "msp430" - || architecture === "v850" || architecture === "78k" - || architecture === "avr32" || architecture === "sh" - || architecture === "m68k" || architecture === "m32c" - || architecture === "r32c" || architecture === "m16c" - || architecture === "cr16") { - args.push("--ec++"); - } + var compilerFilePath = input.cpp.compilerPath; + if (tag === "cpp" && supportCppLanguage(compilerFilePath)) { + // C++ language flag. + var cppOption = cppLanguageOption(compilerFilePath); + args.push(cppOption); + + // Exceptions flag. + var enableExceptions = input.cpp.enableExceptions; + if (!enableExceptions && supportCppExceptions(architecture)) + args.push("--no_exceptions"); + + // RTTI flag. + var enableRtti = input.cpp.enableRtti; + if (!enableRtti && supportCppRtti(architecture)) + args.push("--no_rtti"); } // Byte order flags. - if (architecture.startsWith("arm") || architecture === "rx") { - var endianness = input.cpp.endianness; - if (endianness) - args.push("--endian=" + endianness); - } + var endianness = input.cpp.endianness; + if (endianness && supportEndianness(architecture)) + args.push("--endian=" + endianness); // Listing files generation flag. if (input.cpp.generateCompilerListingFiles) @@ -675,6 +803,16 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) { // Output. args.push("-o", outputs.obj[0].filePath); + var architecture = input.qbs.architecture; + + // The `--preinclude` flag is only supported for a certain + // set of assemblers, not for all. + if (supportIAssembler(architecture)) { + var prefixHeaders = input.cpp.prefixHeaders; + for (var i in prefixHeaders) + args.push("--preinclude", prefixHeaders[i]); + } + // Includes. var allIncludePaths = []; var systemIncludePaths = input.cpp.systemIncludePaths; @@ -690,12 +828,7 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) { args.push("-r"); // Architecture specific flags. - var architecture = input.qbs.architecture; - if (architecture === "stm8" || architecture === "rl78" - || architecture === "rx" || architecture === "rh850" - || architecture === "avr32" || architecture === "sh" - || architecture === "riscv" || architecture === "m68k" - || architecture === "r32c" || architecture === "cr16") { + if (supportIAssembler(architecture)) { // Silent output generation flag. args.push("--silent"); // Warning level flags. @@ -703,13 +836,18 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) { args.push("--no_warnings"); if (input.cpp.treatWarningsAsErrors) args.push("--warnings_are_errors"); - } else { + } else if (supportXAssembler(architecture)){ // Silent output generation flag. args.push("-S"); // Warning level flags. args.push("-w" + (input.cpp.warningLevel === "none" ? "-" : "+")); } + // Byte order flags. + var endianness = input.cpp.endianness; + if (endianness && supportEndianness(architecture)) + args.push("--endian", endianness); + // Listing files generation flag. if (input.cpp.generateAssemblerListingFiles) args.push("-l", outputs.lst[0].filePath); diff --git a/share/qbs/modules/cpp/iar.qbs b/share/qbs/modules/cpp/iar.qbs index 519d30f2a..9709695c1 100644 --- a/share/qbs/modules/cpp/iar.qbs +++ b/share/qbs/modules/cpp/iar.qbs @@ -64,8 +64,7 @@ CppModule { compilerDefinesByLanguage: iarProbe.compilerDefinesByLanguage compilerIncludePaths: iarProbe.includePaths - property string toolchainInstallPath: compilerPathProbe.found - ? compilerPathProbe.path : undefined + toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : "" @@ -89,8 +88,7 @@ CppModule { staticLibrarySuffix: IAR.staticLibrarySuffix(qbs) executableSuffix: IAR.executableSuffix(qbs) - - property string objectSuffix: IAR.objectSuffix(qbs) + objectSuffix: IAR.objectSuffix(qbs) imageFormat: IAR.imageFormat(qbs) @@ -101,8 +99,7 @@ CppModule { id: assembler inputs: ["asm"] outputFileTags: ["obj", "lst"] - outputArtifacts: IAR.compilerOutputArtifacts( - input, input.cpp.generateAssemblerListingFiles) + outputArtifacts: IAR.compilerOutputArtifacts(input, false) prepare: IAR.prepareAssembler.apply(IAR, arguments) } @@ -116,8 +113,7 @@ CppModule { inputs: ["cpp", "c"] auxiliaryInputs: ["hpp"] outputFileTags: ["obj", "lst"] - outputArtifacts: IAR.compilerOutputArtifacts( - input, input.cpp.generateCompilerListingFiles) + outputArtifacts: IAR.compilerOutputArtifacts(input, true) prepare: IAR.prepareCompiler.apply(IAR, arguments) } diff --git a/share/qbs/modules/cpp/keil.js b/share/qbs/modules/cpp/keil.js index 1e8169853..27e4e12d7 100644 --- a/share/qbs/modules/cpp/keil.js +++ b/share/qbs/modules/cpp/keil.js @@ -168,7 +168,7 @@ function objectSuffix(qbs) { + architecture + "'"; } -function mapFileSuffix(qbs) { +function linkerMapSuffix(qbs) { var architecture = qbs.architecture; if (isMcs51Architecture(architecture)) return ".m51"; @@ -507,14 +507,6 @@ function dumpDefaultPaths(compilerFilePath, nullDevice) { return { "includePaths": includePaths }; } -function adjustPathsToWindowsSeparators(sourcePaths) { - var resulingPaths = []; - sourcePaths.forEach(function(path) { - resulingPaths.push(FileInfo.toWindowsSeparators(path)); - }); - return resulingPaths; -} - function collectLibraryDependencies(product) { var seen = {}; var result = []; @@ -534,7 +526,7 @@ function collectLibraryDependencies(product) { if (!obj.cpp) return; function ensureArray(a) { - return Array.isArray(a) ? a : []; + return (a instanceof Array) ? a : []; } function sanitizedModuleListProperty(obj, moduleName, propertyName) { return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName)); @@ -590,19 +582,24 @@ function filterC166Output(output) { return filteredLines.join('\n'); }; -function compilerOutputArtifacts(input, useListing) { +function compilerOutputArtifacts(input, isCompilerArtifacts) { var artifacts = []; artifacts.push({ fileTags: ["obj"], filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + input.cpp.objectSuffix }); - if (useListing) { + if (isCompilerArtifacts && input.cpp.generateCompilerListingFiles) { artifacts.push({ fileTags: ["lst"], filePath: Utilities.getHash(input.baseDir) + "/" - + (isArmCCCompiler(input.cpp.compilerPath) ? input.baseName : input.fileName) - + ".lst" + + input.fileName + input.cpp.compilerListingSuffix + }); + } else if (!isCompilerArtifacts && input.cpp.generateAssemblerListingFiles) { + artifacts.push({ + fileTags: ["lst"], + filePath: Utilities.getHash(input.baseDir) + "/" + + input.fileName + input.cpp.assemblerListingSuffix }); } return artifacts; @@ -619,7 +616,7 @@ function applicationLinkerOutputArtifacts(product) { fileTags: ["mem_map"], filePath: FileInfo.joinPaths( product.destinationDirectory, - product.targetName + product.cpp.mapFileSuffix) + product.targetName + product.cpp.linkerMapSuffix) }; return [app, mem_map]; } @@ -661,20 +658,18 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) { var architecture = input.qbs.architecture; if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) { // Input. - args.push(FileInfo.toWindowsSeparators(input.filePath)); + args.push(input.filePath); // Output. - args.push("OBJECT (" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath) + ")"); + args.push("OBJECT (" + outputs.obj[0].filePath + ")"); // Defines. if (allDefines.length > 0) args = args.concat("DEFINE (" + allDefines.join(",") + ")"); // Includes. - if (allIncludePaths.length > 0) { - var adjusted = adjustPathsToWindowsSeparators(allIncludePaths); - args = args.concat("INCDIR (" + adjusted.join(";") + ")"); - } + if (allIncludePaths.length > 0) + args = args.concat("INCDIR (" + allIncludePaths.join(";") + ")"); // Debug information flags. if (input.cpp.debugInformation) @@ -709,7 +704,7 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) { if (!input.cpp.generateCompilerListingFiles) args.push("NOPRINT"); else - args.push("PRINT(" + FileInfo.toWindowsSeparators(outputs.lst[0].filePath) + ")"); + args.push("PRINT(" + outputs.lst[0].filePath + ")"); } else if (isArmArchitecture(architecture)) { // Input. args.push("-c", input.filePath); @@ -897,20 +892,18 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) { var architecture = input.qbs.architecture; if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) { // Input. - args.push(FileInfo.toWindowsSeparators(input.filePath)); + args.push(input.filePath); // Output. - args.push("OBJECT (" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath) + ")"); + args.push("OBJECT (" + outputs.obj[0].filePath + ")"); // Defines. if (allDefines.length > 0) args = args.concat("DEFINE (" + allDefines.join(",") + ")"); // Includes. - if (allIncludePaths.length > 0) { - var adjusted = adjustPathsToWindowsSeparators(allIncludePaths); + if (allIncludePaths.length > 0) args = args.concat("INCDIR (" + adjusted.join(";") + ")"); - } // Debug information flags. if (input.cpp.debugInformation) @@ -923,7 +916,7 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) { if (!input.cpp.generateAssemblerListingFiles) args.push("NOPRINT"); else - args.push("PRINT(" + FileInfo.toWindowsSeparators(outputs.lst[0].filePath) + ")"); + args.push("PRINT(" + outputs.lst[0].filePath + ")"); } else if (isArmArchitecture(architecture)) { // Input. args.push(input.filePath); @@ -982,39 +975,50 @@ function disassemblerFlags(project, product, input, outputs, explicitlyDependsOn function linkerFlags(project, product, inputs, outputs) { var args = []; + // Library paths. + var libraryPaths = product.cpp.libraryPaths; + var architecture = product.qbs.architecture; if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) { - // Note: The C51/256/166 linker does not distinguish an object files and + // Note: The C51, C251, or C166 linker does not distinguish an object files and // a libraries, it interpret all this stuff as an input objects, // so, we need to pass it together in one string. - var allObjectPaths = []; - function addObjectPath(obj) { - allObjectPaths.push(obj.filePath); - } // Inputs. if (inputs.obj) - inputs.obj.map(function(obj) { addObjectPath(obj) }); + inputs.obj.map(function(obj) { allObjectPaths.push(obj.filePath) }); // Library dependencies. var libraryObjects = collectLibraryDependencies(product); - libraryObjects.forEach(function(dep) { addObjectPath(dep); }) + allObjectPaths = allObjectPaths.concat(libraryObjects.map(function(lib) { + // Semi-intelligent handling the library paths. + // We need to add the full path prefix to the library file if this + // file is not absolute or not relative. Reason is that the C51, C251, + // and C166 linkers does not support the library paths. + var filePath = lib.filePath; + if (FileInfo.isAbsolutePath(filePath)) + return filePath; + for (var i = 0; i < libraryPaths.length; ++i) { + var fullPath = FileInfo.joinPaths(libraryPaths[i], filePath); + if (File.exists(fullPath)) + return fullPath; + } + return filePath; + })); // Add all input objects as arguments (application and library object files). - var adjusted = adjustPathsToWindowsSeparators(allObjectPaths); - args = args.concat(adjusted.join(",")); + if (allObjectPaths.length > 0) + args = args.concat(allObjectPaths.join(",")); // Output. - // Note: We need to wrap an output file name with quotes. Otherwise - // the linker will ignore a specified file name. - args.push("TO", '"' + FileInfo.toWindowsSeparators(outputs.application[0].filePath) + '"'); + args.push("TO", outputs.application[0].filePath); // Map file generation flag. if (!product.cpp.generateLinkerMapFile) args.push("NOPRINT"); else - args.push("PRINT(" + FileInfo.toWindowsSeparators(outputs.mem_map[0].filePath) + ")"); + args.push("PRINT(" + outputs.mem_map[0].filePath + ")"); } else if (isArmArchitecture(architecture)) { // Inputs. if (inputs.obj) @@ -1023,8 +1027,6 @@ function linkerFlags(project, product, inputs, outputs) { // Output. args.push("--output", outputs.application[0].filePath); - // Library paths. - var libraryPaths = product.cpp.libraryPaths; if (libraryPaths) args.push("--userlibpath=" + libraryPaths.join(",")); @@ -1074,13 +1076,11 @@ function archiverFlags(project, product, inputs, outputs) { inputs.obj.map(function(obj) { addObjectPath(obj) }); // Add all input objects as arguments. - var adjusted = adjustPathsToWindowsSeparators(allObjectPaths); - args = args.concat(adjusted.join(",")); + if (allObjectPaths.length > 0) + args = args.concat(allObjectPaths.join(",")); // Output. - // Note: We need to wrap a output file name with quotes. Otherwise - // the linker will ignore a specified file name. - args.push("TO", '"' + FileInfo.toWindowsSeparators(outputs.staticlibrary[0].filePath) + '"'); + args.push("TO", outputs.staticlibrary[0].filePath); } else if (isArmArchitecture(architecture)) { // Note: The ARM archiver command line expect the output file // first, and then a set of input objects. @@ -1100,6 +1100,38 @@ function archiverFlags(project, product, inputs, outputs) { return args; } +// The ARMCLANG compiler does not support generation +// for the listing files: +// * https://www.keil.com/support/docs/4152.htm +// So, we generate the listing files from the object files +// using the disassembler. +function generateClangCompilerListing(project, product, inputs, outputs, input, output) { + if (isArmClangCompiler(input.cpp.compilerPath) && input.cpp.generateCompilerListingFiles) { + var args = disassemblerFlags(project, product, input, outputs, explicitlyDependsOn); + var disassemblerPath = input.cpp.disassemblerPath; + var cmd = new Command(disassemblerPath, args); + cmd.silent = true; + return cmd; + } +} + +// The ARMCC compiler generates the listing files only in a short form, +// e.g. to 'module.lst' instead of 'module.{c|cpp}.lst', that complicates +// the auto-tests. Therefore we need to rename generated listing files +// with correct unified names. +function generateArmccCompilerListing(project, product, inputs, outputs, input, output) { + if (isArmCCCompiler(input.cpp.compilerPath) && input.cpp.generateCompilerListingFiles) { + var listingPath = FileInfo.path(outputs.lst[0].filePath); + var cmd = new JavaScriptCommand(); + cmd.oldListing = FileInfo.joinPaths(listingPath, input.baseName + ".lst"); + cmd.newListing = FileInfo.joinPaths( + listingPath, input.fileName + input.cpp.compilerListingSuffix); + cmd.silent = true; + cmd.sourceCode = function() { File.move(oldListing, newListing); }; + return cmd; + } +} + function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) { var cmds = []; var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn); @@ -1117,18 +1149,14 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli } cmds.push(cmd); - // The ARMCLANG compiler does not support generation - // for the listing files: - // * https://www.keil.com/support/docs/4152.htm - // So, we generate the listing files from the object files - // using the disassembler. - if (isArmClangCompiler(compilerPath) && input.cpp.generateCompilerListingFiles) { - args = disassemblerFlags(project, product, input, outputs, explicitlyDependsOn); - var disassemblerPath = input.cpp.disassemblerPath; - cmd = new Command(disassemblerPath, args); - cmd.silent = true; + cmd = generateClangCompilerListing(project, product, inputs, outputs, input, output); + if (cmd) cmds.push(cmd); - } + + cmd = generateArmccCompilerListing(project, product, inputs, outputs, input, output); + if (cmd) + cmds.push(cmd); + return cmds; } diff --git a/share/qbs/modules/cpp/keil.qbs b/share/qbs/modules/cpp/keil.qbs index eba52adff..ea99b589c 100644 --- a/share/qbs/modules/cpp/keil.qbs +++ b/share/qbs/modules/cpp/keil.qbs @@ -62,8 +62,7 @@ CppModule { compilerDefinesByLanguage: keilProbe.compilerDefinesByLanguage compilerIncludePaths: keilProbe.includePaths - property string toolchainInstallPath: compilerPathProbe.found - ? compilerPathProbe.path : undefined + toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : "" @@ -90,9 +89,8 @@ CppModule { staticLibrarySuffix: KEIL.staticLibrarySuffix(qbs) executableSuffix: KEIL.executableSuffix(qbs) - - property string objectSuffix: KEIL.objectSuffix(qbs) - property string mapFileSuffix: KEIL.mapFileSuffix(qbs) + objectSuffix: KEIL.objectSuffix(qbs) + linkerMapSuffix: KEIL.linkerMapSuffix(qbs) imageFormat: KEIL.imageFormat(qbs) @@ -105,8 +103,7 @@ CppModule { id: assembler inputs: ["asm"] outputFileTags: ["obj", "lst"] - outputArtifacts: KEIL.compilerOutputArtifacts( - input, input.cpp.generateAssemblerListingFiles) + outputArtifacts: KEIL.compilerOutputArtifacts(input, false) prepare: KEIL.prepareAssembler.apply(KEIL, arguments) } @@ -120,8 +117,7 @@ CppModule { inputs: ["cpp", "c"] auxiliaryInputs: ["hpp"] outputFileTags: ["obj", "lst"] - outputArtifacts: KEIL.compilerOutputArtifacts( - input, input.cpp.generateCompilerListingFiles) + outputArtifacts: KEIL.compilerOutputArtifacts(input, true) prepare: KEIL.prepareCompiler.apply(KEIL, arguments) } diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js index df1f5eb5b..566059610 100644 --- a/share/qbs/modules/cpp/msvc.js +++ b/share/qbs/modules/cpp/msvc.js @@ -354,7 +354,7 @@ function collectLibraryDependencies(product) { if (!obj.cpp) return; function ensureArray(a) { - return Array.isArray(a) ? a : []; + return (a instanceof Array) ? a : []; } function sanitizedModuleListProperty(obj, moduleName, propertyName) { return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName)); diff --git a/share/qbs/modules/cpp/sdcc.js b/share/qbs/modules/cpp/sdcc.js index 36454031e..1904f59fc 100644 --- a/share/qbs/modules/cpp/sdcc.js +++ b/share/qbs/modules/cpp/sdcc.js @@ -28,6 +28,7 @@ ** ****************************************************************************/ +var BinaryFile = require("qbs.BinaryFile"); var Cpp = require("cpp.js"); var Environment = require("qbs.Environment"); var File = require("qbs.File"); @@ -50,6 +51,8 @@ function assemblerName(qbs) { return "sdas8051"; case "stm8": return "sdasstm8"; + case "hcs8": + return "sdas6808"; } throw "Unable to deduce assembler name for unsupported architecture: '" + qbs.architecture + "'"; @@ -61,6 +64,8 @@ function linkerName(qbs) { return "sdld"; case "stm8": return "sdldstm8"; + case "hcs8": + return "sdld6808"; } throw "Unable to deduce linker name for unsupported architecture: '" + qbs.architecture + "'"; @@ -75,6 +80,8 @@ function targetArchitectureFlag(architecture) { return "-mmcs51"; if (architecture === "stm8") return "-mstm8"; + if (architecture === "hcs8") + return "-mhc08"; } function guessArchitecture(macros) { @@ -82,6 +89,8 @@ function guessArchitecture(macros) { return "mcs51"; if (macros["__SDCC_stm8"] === "1") return "stm8"; + if (macros["__SDCC_hc08"] === "1") + return "hcs8"; } function guessEndianness(macros) { @@ -142,7 +151,8 @@ function dumpDefaultPaths(compilerFilePath, architecture) { || line.startsWith("libpath:")) { addIncludePaths = false; } else if (addIncludePaths) { - includePaths.push(line); + if (File.exists(line)) + includePaths.push(line); } } @@ -193,7 +203,7 @@ function collectLibraryDependencies(product) { if (!obj.cpp) return; function ensureArray(a) { - return Array.isArray(a) ? a : []; + return (a instanceof Array) ? a : []; } function sanitizedModuleListProperty(obj, moduleName, propertyName) { return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName)); @@ -229,7 +239,7 @@ function collectLibraryDependencies(product) { return result; } -function compilerOutputArtifacts(input, useListing) { +function compilerOutputArtifacts(input, isCompilerArtifacts) { var obj = { fileTags: ["obj"], filePath: Utilities.getHash(input.baseDir) + "/" @@ -260,11 +270,17 @@ function compilerOutputArtifacts(input, useListing) { + input.fileName + ".rst" }; var artifacts = [obj, asm_adb, asm_src, asm_sym, rst_data]; - if (useListing) { + if (isCompilerArtifacts && input.cpp.generateCompilerListingFiles) { artifacts.push({ fileTags: ["lst"], filePath: Utilities.getHash(input.baseDir) + "/" - + input.fileName + ".lst" + + input.fileName + input.cpp.compilerListingSuffix + }); + } else if (!isCompilerArtifacts && input.cpp.generateAssemblerListingFiles) { + artifacts.push({ + fileTags: ["lst"], + filePath: Utilities.getHash(input.baseDir) + "/" + + input.fileName + input.cpp.assemblerListingSuffix }); } return artifacts; @@ -293,7 +309,7 @@ function applicationLinkerOutputArtifacts(product) { fileTags: ["mem_map"], filePath: FileInfo.joinPaths( product.destinationDirectory, - product.targetName + ".map") + product.targetName + product.cpp.linkerMapSuffix) }; return [app, lk_cmd, mem_summary, mem_map] } @@ -537,6 +553,119 @@ function archiverFlags(project, product, inputs, outputs) { return args; } +function buildLinkerMapFilePath(target, suffix) { + return FileInfo.joinPaths(FileInfo.path(target.filePath), + FileInfo.completeBaseName(target.fileName) + suffix); +} + +// This is the workaround for the SDCC bug on a Windows host: +// * https://sourceforge.net/p/sdcc/bugs/2970/ +// We need to replace the '\r\n\' line endings with the'\n' line +// endings for each generated object file. +function patchObjectFile(project, product, inputs, outputs, input, output) { + var isWindows = input.qbs.hostOS.contains("windows"); + if (isWindows && input.cpp.debugInformation) { + var cmd = new JavaScriptCommand(); + cmd.objectPath = outputs.obj[0].filePath; + cmd.silent = true; + cmd.sourceCode = function() { + var file = new BinaryFile(objectPath, BinaryFile.ReadWrite); + var data = file.read(file.size()); + file.resize(0); + for (var pos = 0; pos < data.length; ++pos) { + // Find the next index of CR (\r) symbol. + var index = data.indexOf(0x0d, pos); + if (index < 0) + index = data.length; + // Write next data chunk between the previous position and the CR + // symbol, exclude the CR symbol. + file.write(data.slice(pos, index)); + pos = index; + } + }; + return cmd; + } +} + +// It is a workaround which removes the generated linker map file +// if it is disabled by cpp.generateLinkerMapFile property. +// Reason is that the SDCC compiler always generates this file, +// and does not have an option to disable generation for a linker +// map file. So, we can to remove a listing files only after the +// linking completes. +function removeLinkerMapFile(project, product, inputs, outputs, input, output) { + if (!product.cpp.generateLinkerMapFile) { + var target = outputs.application[0]; + var cmd = new JavaScriptCommand(); + cmd.mapFilePath = buildLinkerMapFilePath(target, product.cpp.linkerMapSuffix) + cmd.silent = true; + cmd.sourceCode = function() { File.remove(mapFilePath); }; + return cmd; + } +} + +// It is a workaround to rename the extension of the output linker +// map file to the specified one, since the linker generates only +// files with the '.map' extension. +function renameLinkerMapFile(project, product, inputs, outputs, input, output) { + if (product.cpp.generateLinkerMapFile && (product.cpp.linkerMapSuffix !== ".map")) { + var target = outputs.application[0]; + var cmd = new JavaScriptCommand(); + cmd.newMapFilePath = buildLinkerMapFilePath(target, product.cpp.linkerMapSuffix); + cmd.oldMapFilePath = buildLinkerMapFilePath(target, ".map"); + cmd.silent = true; + cmd.sourceCode = function() { File.move(oldMapFilePath, newMapFilePath); }; + return cmd; + } +} + +// It is a workaround which removes the generated listing files +// if it is disabled by cpp.generateCompilerListingFiles property +// or when the cpp.compilerListingSuffix differs with '.lst'. +// Reason is that the SDCC compiler does not have an option to +// disable generation for a listing files. Besides, the SDCC +// compiler use this files and for the linking. So, we can to +// remove a listing files only after the linking completes. +function removeCompilerListingFiles(project, product, inputs, outputs, input, output) { + var cmd = new JavaScriptCommand(); + cmd.objects = inputs.obj.map(function(a) { return a; }); + cmd.silent = true; + cmd.sourceCode = function() { + objects.forEach(function(object) { + if (!object.filePath.endsWith(".c" + object.cpp.objectSuffix)) + return; // Skip the assembler generated objects. + if (!object.cpp.generateCompilerListingFiles + || (object.cpp.compilerListingSuffix !== ".lst")) { + var listingPath = FileInfo.joinPaths(FileInfo.path(object.filePath), + object.completeBaseName + ".lst"); + File.remove(listingPath); + } + }) + }; + return cmd; +} + +// It is a workaround that duplicates the generated listing files +// but with desired names. The problem is that the SDCC compiler does +// not support an options to specify names for the generated listing +// files. At the same time, the compiler always generates the listing +// files in the form of 'module.c.lst', which makes it impossible to +// change the file suffix to a user-specified one. In addition, these +// files are also somehow used for linking. Thus, we can not rename them +// on the compiling stage. +function duplicateCompilerListingFile(project, product, inputs, outputs, input, output) { + if (input.cpp.generateCompilerListingFiles + && (input.cpp.compilerListingSuffix !== ".lst")) { + var cmd = new JavaScriptCommand(); + cmd.newListing = outputs.lst[0].filePath; + cmd.oldListing = FileInfo.joinPaths(FileInfo.path(outputs.lst[0].filePath), + outputs.lst[0].completeBaseName + ".lst"); + cmd.silent = true; + cmd.sourceCode = function() { File.copy(oldListing, newListing); }; + return cmd; + } +} + function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) { var cmds = []; var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn); @@ -546,87 +675,53 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli cmd.highlight = "compiler"; cmds.push(cmd); - // This is the workaround for the SDCC bug on a Windows host: - // * https://sourceforge.net/p/sdcc/bugs/2970/ - // We need to replace the '\r\n\' line endings with the'\n' line - // endings for each generated object file. - var isWindows = input.qbs.hostOS.contains("windows"); - if (isWindows) { - cmd = new JavaScriptCommand(); - cmd.objectPath = outputs.obj[0].filePath; - cmd.silent = true; - cmd.sourceCode = function() { - var lines = []; - var file = new TextFile(objectPath, TextFile.ReadWrite); - while (!file.atEof()) - lines.push(file.readLine() + "\n"); - file.truncate(); - for (var l in lines) - file.write(lines[l]); - }; + cmd = patchObjectFile(project, product, inputs, outputs, input, output); + if (cmd) + cmds.push(cmd); + + cmd = duplicateCompilerListingFile(project, product, inputs, outputs, input, output); + if (cmd) cmds.push(cmd); - } return cmds; } function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) { + var cmds = []; var args = assemblerFlags(project, product, input, outputs, explicitlyDependsOn); var assemblerPath = input.cpp.assemblerPath; var cmd = new Command(assemblerPath, args); cmd.description = "assembling " + input.fileName; cmd.highlight = "compiler"; - return [cmd]; + cmds.push(cmd); + + cmd = patchObjectFile(project, product, inputs, outputs, input, output); + if (cmd) + cmds.push(cmd); + + return cmds; } function prepareLinker(project, product, inputs, outputs, input, output) { var cmds = []; - var target = outputs.application[0]; var args = linkerFlags(project, product, inputs, outputs); var linkerPath = effectiveLinkerPath(product); var cmd = new Command(linkerPath, args); - cmd.description = "linking " + target.fileName; + cmd.description = "linking " + outputs.application[0].fileName; cmd.highlight = "linker"; cmds.push(cmd); - // It is a workaround which removes the generated listing files - // if it is disabled by cpp.generateCompilerListingFiles property. - // Reason is that the SDCC compiler does not have an option to - // disable generation for a listing files. Besides, the SDCC - // compiler use this files and for the linking. So, we can to - // remove a listing files only after the linking completes. - if (!product.cpp.generateCompilerListingFiles) { - cmd = new JavaScriptCommand(); - cmd.objectPaths = inputs.obj.map(function(a) { return a.filePath; }); - cmd.objectSuffix = product.cpp.objectSuffix; - cmd.silent = true; - cmd.sourceCode = function() { - objectPaths.forEach(function(objectPath) { - if (!objectPath.endsWith(".c" + objectSuffix)) - return; // Skip the assembler objects. - var listingPath = FileInfo.joinPaths( - FileInfo.path(objectPath), - FileInfo.completeBaseName(objectPath) + ".lst"); - File.remove(listingPath); - }); - }; + cmd = removeCompilerListingFiles(project, product, inputs, outputs, input, output); + if (cmd) cmds.push(cmd); - } - // It is a workaround which removes the generated linker map file - // if it is disabled by cpp.generateLinkerMapFile property. - // Reason is that the SDCC compiler always generates this file, - // and does not have an option to disable generation for a linker - // map file. So, we can to remove a listing files only after the - // linking completes. - if (!product.cpp.generateLinkerMapFile) { - cmd = new JavaScriptCommand(); - cmd.mapFilePath = FileInfo.joinPaths( - FileInfo.path(target.filePath), - FileInfo.completeBaseName(target.fileName) + ".map"); - cmd.silent = true; - cmd.sourceCode = function() { File.remove(mapFilePath); }; + + cmd = renameLinkerMapFile(project, product, inputs, outputs, input, output); + if (cmd) + cmds.push(cmd); + + cmd = removeLinkerMapFile(project, product, inputs, outputs, input, output); + if (cmd) cmds.push(cmd); - } return cmds; } diff --git a/share/qbs/modules/cpp/sdcc.qbs b/share/qbs/modules/cpp/sdcc.qbs index da1b89402..c5a0893d4 100644 --- a/share/qbs/modules/cpp/sdcc.qbs +++ b/share/qbs/modules/cpp/sdcc.qbs @@ -63,8 +63,7 @@ CppModule { compilerDefinesByLanguage: sdccProbe.compilerDefinesByLanguage compilerIncludePaths: sdccProbe.includePaths - property string toolchainInstallPath: compilerPathProbe.found - ? compilerPathProbe.path : undefined + toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : "" @@ -90,8 +89,7 @@ CppModule { staticLibrarySuffix: ".lib" executableSuffix: ".ihx" - - property string objectSuffix: ".rel" + objectSuffix: ".rel" imageFormat: "ihx" @@ -102,7 +100,7 @@ CppModule { id: assembler inputs: ["asm"] outputFileTags: ["obj", "asm_adb", "lst", "asm_src", "asm_sym", "rst_data"] - outputArtifacts: SDCC.compilerOutputArtifacts(input, true) + outputArtifacts: SDCC.compilerOutputArtifacts(input, false) prepare: SDCC.prepareAssembler.apply(SDCC, arguments) } @@ -116,8 +114,7 @@ CppModule { inputs: ["cpp", "c"] auxiliaryInputs: ["hpp"] outputFileTags: ["obj", "asm_adb", "lst", "asm_src", "asm_sym", "rst_data"] - outputArtifacts: SDCC.compilerOutputArtifacts( - input, input.cpp.generateCompilerListingFiles) + outputArtifacts: SDCC.compilerOutputArtifacts(input, true) prepare: SDCC.prepareCompiler.apply(SDCC, arguments) } diff --git a/share/qbs/modules/cpp/windows-clang-cl.qbs b/share/qbs/modules/cpp/windows-clang-cl.qbs index a34a67ad2..556efb042 100644 --- a/share/qbs/modules/cpp/windows-clang-cl.qbs +++ b/share/qbs/modules/cpp/windows-clang-cl.qbs @@ -53,6 +53,7 @@ MsvcBaseModule { vcvarsallFilePath: vcvarsallPath enableDefinesByLanguage: enableCompilerDefinesByLanguage preferredArchitecture: qbs.architecture + winSdkVersion: windowsSdkVersion } qbs.architecture: clangClProbe.found ? clangClProbe.architecture : original diff --git a/share/qbs/modules/cpp/windows-mingw.qbs b/share/qbs/modules/cpp/windows-mingw.qbs index ffed76cdd..ef2ef4946 100644 --- a/share/qbs/modules/cpp/windows-mingw.qbs +++ b/share/qbs/modules/cpp/windows-mingw.qbs @@ -68,7 +68,7 @@ MingwBaseModule { auxiliaryInputs: ["hpp"] Artifact { - filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + "_res.o" + filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + "_res" + input.cpp.objectSuffix fileTags: ["obj"] } diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs index e88c3f15f..81fe48385 100644 --- a/share/qbs/modules/cpp/windows-msvc-base.qbs +++ b/share/qbs/modules/cpp/windows-msvc-base.qbs @@ -81,7 +81,6 @@ CppModule { separateDebugInformation: true property bool generateManifestFile: true - property string toolchainInstallPath architecture: qbs.architecture endianness: "little" @@ -89,6 +88,7 @@ CppModule { dynamicLibrarySuffix: ".dll" executableSuffix: ".exe" debugInfoSuffix: ".pdb" + objectSuffix: ".obj" imageFormat: "pe" Properties { condition: product.multiplexByQbsProperties.contains("buildVariants") @@ -108,13 +108,15 @@ CppModule { } } + property string windowsSdkVersion + Rule { condition: useCPrecompiledHeader inputs: ["c_pch_src"] auxiliaryInputs: ["hpp"] Artifact { fileTags: ['obj'] - filePath: Utilities.getHash(input.completeBaseName) + '_c.obj' + filePath: Utilities.getHash(input.completeBaseName) + '_c' + input.cpp.objectSuffix } Artifact { fileTags: ['c_pch'] @@ -132,7 +134,7 @@ CppModule { auxiliaryInputs: ["hpp"] Artifact { fileTags: ['obj'] - filePath: Utilities.getHash(input.completeBaseName) + '_cpp.obj' + filePath: Utilities.getHash(input.completeBaseName) + '_cpp' + input.cpp.objectSuffix } Artifact { fileTags: ['cpp_pch'] @@ -157,12 +159,13 @@ CppModule { var artifacts = []; artifacts.push({ fileTags: tags, - filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + ".obj" + filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + input.cpp.objectSuffix }); if (input.cpp.generateCompilerListingFiles) { artifacts.push({ fileTags: ["lst"], - filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + ".lst" + filePath: Utilities.getHash(input.baseDir) + + "/" + input.fileName + input.cpp.compilerListingSuffix }); } return artifacts; @@ -210,7 +213,7 @@ CppModule { fileTags: ["mem_map"], filePath: FileInfo.joinPaths( product.destinationDirectory, - product.targetName + ".map") + product.targetName + product.cpp.linkerMapSuffix) }); } return artifacts; @@ -327,7 +330,7 @@ CppModule { Rule { inputs: ["asm"] Artifact { - filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".obj" + filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + input.cpp.objectSuffix fileTags: ["obj"] } prepare: { diff --git a/share/qbs/modules/cpp/windows-msvc.qbs b/share/qbs/modules/cpp/windows-msvc.qbs index d5b5baf92..33c5e74c8 100644 --- a/share/qbs/modules/cpp/windows-msvc.qbs +++ b/share/qbs/modules/cpp/windows-msvc.qbs @@ -51,6 +51,7 @@ MsvcBaseModule { compilerFilePath: compilerPath enableDefinesByLanguage: enableCompilerDefinesByLanguage preferredArchitecture: qbs.architecture + winSdkVersion: windowsSdkVersion } qbs.architecture: msvcProbe.found ? msvcProbe.architecture : original diff --git a/share/qbs/modules/ico/ico.js b/share/qbs/modules/ico/ico.js index 997a6dc23..a61d585ab 100644 --- a/share/qbs/modules/ico/ico.js +++ b/share/qbs/modules/ico/ico.js @@ -29,6 +29,7 @@ ****************************************************************************/ var File = require("qbs.File"); +var FileInfo = require("qbs.FileInfo"); var Process = require("qbs.Process"); function prepareIconset(project, product, inputs, outputs, input, output) { diff --git a/share/qbs/modules/java/JavaModule.qbs b/share/qbs/modules/java/JavaModule.qbs index ad055fe34..ceb29f36f 100644 --- a/share/qbs/modules/java/JavaModule.qbs +++ b/share/qbs/modules/java/JavaModule.qbs @@ -240,7 +240,7 @@ Module { if (!product.java._tagJniHeaders) { for (var i = 0; i < artifacts.length; ++i) { var a = artifacts[i]; - if (Array.isArray(a.fileTags)) + if (a.fileTags instanceof Array) a.fileTags = a.fileTags.map(function(tag) { if (tag === "hpp") return "java.jni-hpp"; diff --git a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs index b443b4dbf..36b92dd30 100644 --- a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs +++ b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs @@ -12,6 +12,8 @@ ProtobufBase { property bool useGrpc: false + property bool _linkLibraries: true + property string grpcIncludePath: grpcIncludeProbe.found ? grpcIncludeProbe.path : undefined property string grpcLibraryPath: grpcLibraryProbe.found ? grpcLibraryProbe.path : undefined @@ -36,6 +38,9 @@ ProtobufBase { } cpp.libraryPaths: { + if (!_linkLibraries) + return []; + var result = []; if (libraryProbe.found) result.push(libraryProbe.path); @@ -44,6 +49,9 @@ ProtobufBase { return result; } cpp.dynamicLibraries: { + if (!_linkLibraries) + return []; + var result = []; if (_libraryName) result.push(_libraryName) @@ -54,6 +62,9 @@ ProtobufBase { return result; } cpp.includePaths: { + if (!_linkLibraries) + return [outputDir]; + var result = [outputDir]; if (includeProbe.found) result.push(includePath); @@ -129,17 +140,17 @@ ProtobufBase { validate: { HelperFunctions.validateCompiler(compilerName, compilerPath); - if (!includeProbe.found) + if (_linkLibraries && !includeProbe.found) throw "Can't find cpp protobuf include files. Please set the includePath property."; - if (!libraryProbe.found) + if (_linkLibraries && !libraryProbe.found) throw "Can't find cpp protobuf library. Please set the libraryPath property."; if (useGrpc) { if (!File.exists(grpcPluginPath)) throw "Can't find grpc_cpp_plugin plugin. Please set the grpcPluginPath property."; - if (!grpcIncludeProbe.found) + if (_linkLibraries && !grpcIncludeProbe.found) throw "Can't find grpc++ include files. Please set the grpcIncludePath property."; - if (!grpcLibraryProbe.found) + if (_linkLibraries && !grpcLibraryProbe.found) throw "Can't find grpc++ library. Please set the grpcLibraryPath property."; } } diff --git a/share/qbs/modules/xcode/xcode.js b/share/qbs/modules/xcode/xcode.js index 9c87e09dc..1060894d4 100644 --- a/share/qbs/modules/xcode/xcode.js +++ b/share/qbs/modules/xcode/xcode.js @@ -93,6 +93,16 @@ var XcodeArchSpecsReader = (function () { return XcodeArchSpecsReader; }()); +function platformInfo(platformInfoPlist) { + var propertyList = new PropertyList(); + try { + propertyList.readFromFile(platformInfoPlist); + return propertyList.toObject(); + } finally { + propertyList.clear(); + } +} + function sdkInfoList(sdksPath) { var sdkInfo = []; var sdks = File.directoryEntries(sdksPath, File.Dirs | File.NoDotAndDotDot); @@ -181,6 +191,17 @@ function provisioningProfilePlistContents(filePath) { } } +function boolFromSdkOrPlatform(varName, sdkProps, platformProps, defaultValue) { + var values = [(sdkProps || {})[varName], (platformProps || {})[varName]]; + for (var i = 0; i < values.length; ++i) { + if (values[i] === "YES") + return true; + if (values[i] === "NO") + return false; + } + return defaultValue; +} + function archsSpecsPath(version, targetOS, platformType, platformPath, devicePlatformPath) { var _specsPluginBaseName; if (Utilities.versionCompare(version, "12") >= 0) { diff --git a/share/qbs/modules/xcode/xcode.qbs b/share/qbs/modules/xcode/xcode.qbs index aeb0760ac..6c0584c81 100644 --- a/share/qbs/modules/xcode/xcode.qbs +++ b/share/qbs/modules/xcode/xcode.qbs @@ -7,7 +7,6 @@ import qbs.ModUtils import qbs.Probes import qbs.PropertyList import qbs.Utilities -import 'xcode.js' as Xcode Module { id: xcodeModule @@ -87,31 +86,6 @@ Module { } } - property string signingIdentity - readonly property string actualSigningIdentity: { - if (_actualSigningIdentity && _actualSigningIdentity.length === 2) - return _actualSigningIdentity[0]; - } - - readonly property string actualSigningIdentityDisplayName: { - if (_actualSigningIdentity && _actualSigningIdentity.length === 2) - return _actualSigningIdentity[1]; - } - - property string signingTimestamp: "none" - - property string provisioningProfile - - property string xcodebuildName: "xcodebuild" - property string xcodebuildPath: FileInfo.joinPaths(developerPath, "usr", "bin", xcodebuildName) - - property string securityName: "security" - property string securityPath: securityName - - property string codesignName: "codesign" - property string codesignPath: codesignName - property stringList codesignFlags - readonly property path toolchainPath: FileInfo.joinPaths(toolchainsPath, "XcodeDefault" + ".xctoolchain") readonly property path platformPath: FileInfo.joinPaths(platformsPath, @@ -143,35 +117,11 @@ Module { readonly property path toolchainInfoPlist: FileInfo.joinPaths(toolchainPath, "ToolchainInfo.plist") - readonly property stringList _actualSigningIdentity: { - if (/^[A-Fa-f0-9]{40}$/.test(signingIdentity)) { - return [signingIdentity, signingIdentity]; - } - - var result = []; + readonly property var _platformSettings: xcodeProbe.platformSettings - if (signingIdentity) { - var identities = Utilities.signingIdentities(); - for (var key in identities) { - if (identities[key].subjectInfo.CN === signingIdentity) { - result.push([key, signingIdentity]); - } - } - - if (result.length == 0) { - throw "Unable to find signingIdentity '" + signingIdentity + "'"; - } - - if (result.length > 1) { - throw "Signing identity '" + signingIdentity + "' is ambiguous"; - } - } - - return result[0]; - } - - property path provisioningProfilesPath: { - return FileInfo.joinPaths(Environment.getEnv("HOME"), "Library/MobileDevice/Provisioning Profiles"); + readonly property var _platformProps: { + if (_platformSettings) + return _platformSettings["DefaultProperties"]; } readonly property stringList standardArchitectures: _architectureSettings["ARCHS_STANDARD"] @@ -197,6 +147,12 @@ Module { } } + readonly property var _sdkProps: { + if (_sdkSettings) { + return _sdkSettings["DefaultProperties"]; + } + } + qbs.sysroot: sdkPath validate: { @@ -231,23 +187,10 @@ Module { validator.validate(); } - property var buildEnv: { - var env = { - "DEVELOPER_DIR": developerPath, - "SDKROOT": sdkPath - }; - - var prefixes = [platformPath + "/Developer", toolchainPath, developerPath]; - for (var i = 0; i < prefixes.length; ++i) { - var codesign_allocate = prefixes[i] + "/usr/bin/codesign_allocate"; - if (File.exists(codesign_allocate)) { - env["CODESIGN_ALLOCATE"] = codesign_allocate; - break; - } - } - - return env; - } + property var buildEnv: ({ + "DEVELOPER_DIR": developerPath, + "SDKROOT": sdkPath + }) setupBuildEnvironment: { var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, false); @@ -261,191 +204,4 @@ Module { v.set(); } } - - Group { - name: "Provisioning Profiles" - prefix: xcode.provisioningProfilesPath + "/" - files: ["*.mobileprovision", "*.provisionprofile"] - fileTags: ["xcode.provisioningprofile"] - } - - FileTagger { - fileTags: ["xcode.entitlements"] - patterns: ["*.entitlements"] - } - - FileTagger { - fileTags: ["xcode.provisioningprofile"] - patterns: ["*.mobileprovision", "*.provisionprofile"] - } - - Rule { - inputs: ["xcode.provisioningprofile"] - - Artifact { - filePath: FileInfo.joinPaths("provisioning-profiles", input.fileName + ".xml") - fileTags: ["xcode.provisioningprofile.data"] - } - - prepare: { - var cmds = []; - - var cmd = new Command("openssl", ["smime", "-verify", "-noverify", "-inform", "DER", - "-in", input.filePath, "-out", output.filePath]); - cmd.silent = true; - cmd.stderrFilterFunction = function (output) { - return output.replace("Verification successful\n", ""); - }; - cmds.push(cmd); - - cmd = new JavaScriptCommand(); - cmd.silent = true; - cmd.inputFilePath = input.filePath; - cmd.outputFilePath = output.filePath; - cmd.sourceCode = function() { - var propertyList = new PropertyList(); - try { - propertyList.readFromFile(outputFilePath); - propertyList.readFromObject({ - data: propertyList.toObject(), - fileName: FileInfo.fileName(inputFilePath), - filePath: inputFilePath - }); - propertyList.writeToFile(outputFilePath, "xml1"); - } finally { - propertyList.clear(); - } - }; - cmds.push(cmd); - - return cmds; - } - } - - Rule { - multiplex: true - inputs: ["xcode.provisioningprofile.data"] - outputFileTags: ["xcode.provisioningprofile.main", "xcode.provisioningprofile.data.main"] - - outputArtifacts: { - var artifacts = []; - for (var i = 0; i < inputs["xcode.provisioningprofile.data"].length; ++i) { - var dataFile = inputs["xcode.provisioningprofile.data"][i].filePath; - var query = product.moduleProperty("xcode", "provisioningProfile"); - var obj = Xcode.provisioningProfilePlistContents(dataFile); - if (obj && obj.data && (obj.data.UUID === query || obj.data.Name === query)) { - console.log("Using provisioning profile: " + obj.filePath); - artifacts.push({ - filePath: obj.fileName, - fileTags: ["xcode.provisioningprofile.main"], - qbs: { _inputFilePath: obj.filePath } - }); - - artifacts.push({ - filePath: obj.fileName + ".xml", - fileTags: ["xcode.provisioningprofile.data.main"], - qbs: { _inputFilePath: dataFile } - }); - } - } - return artifacts; - } - - prepare: { - var cmds = []; - for (var tag in outputs) { - for (var i = 0; i < outputs[tag].length; ++i) { - var output = outputs[tag][i]; - var cmd = new JavaScriptCommand(); - cmd.silent = true; - cmd.inputFilePath = output.qbs._inputFilePath; // there's no such prop in qbs, see QBS-754 - cmd.outputFilePath = output.filePath; - cmd.sourceCode = function() { - File.copy(inputFilePath, outputFilePath); - }; - cmds.push(cmd); - } - } - return cmds; - } - } - - Rule { - inputs: ["xcode.entitlements", "xcode.provisioningprofile.data.main"] - - Artifact { - filePath: FileInfo.joinPaths(product.destinationDirectory, - product.targetName + ".xcent") - fileTags: ["xcent"] - } - - prepare: { - var cmd = new JavaScriptCommand(); - cmd.description = "generating entitlements"; - cmd.highlight = "codegen"; - cmd.bundleIdentifier = product.moduleProperty("bundle", "identifier"); - cmd.signingEntitlements = inputs["xcode.entitlements"] - ? inputs["xcode.entitlements"].map(function (a) { return a.filePath; }) - : []; - cmd.platformPath = ModUtils.moduleProperty(product, "platformPath"); - cmd.sdkPath = ModUtils.moduleProperty(product, "sdkPath"); - cmd.sourceCode = function() { - var i; - var provData = Xcode.provisioningProfilePlistContents(input.filePath); - if (provData) - provData = provData.data; - - var aggregateEntitlements = {}; - - // Start building up an aggregate entitlements plist from the files in the SDKs, - // which contain placeholders in the same manner as Info.plist - function entitlementsFileContents(path) { - return File.exists(path) ? BundleTools.infoPlistContents(path) : undefined; - } - var entitlementsSources = [ - entitlementsFileContents(FileInfo.joinPaths(platformPath, "Entitlements.plist")), - entitlementsFileContents(FileInfo.joinPaths(sdkPath, "Entitlements.plist")) - ]; - - for (i = 0; i < signingEntitlements.length; ++i) { - entitlementsSources.push(entitlementsFileContents(signingEntitlements[i])); - } - - for (i = 0; i < entitlementsSources.length; ++i) { - var contents = entitlementsSources[i]; - for (var key in contents) { - if (contents.hasOwnProperty(key)) - aggregateEntitlements[key] = contents[key]; - } - } - - contents = provData["Entitlements"]; - for (key in contents) { - if (contents.hasOwnProperty(key) && !aggregateEntitlements.hasOwnProperty(key)) - aggregateEntitlements[key] = contents[key]; - } - - // Expand entitlements variables with data from the provisioning profile - var env = { - "AppIdentifierPrefix": provData["ApplicationIdentifierPrefix"] + ".", - "CFBundleIdentifier": bundleIdentifier - }; - DarwinTools.expandPlistEnvironmentVariables(aggregateEntitlements, env, true); - - // Anything with an undefined or otherwise empty value should be removed - // Only JSON-formatted plists can have null values, other formats error out - // This also follows Xcode behavior - DarwinTools.cleanPropertyList(aggregateEntitlements); - - var plist = new PropertyList(); - try { - plist.readFromObject(aggregateEntitlements); - plist.writeToFile(outputs.xcent[0].filePath, "xml1"); - } finally { - plist.clear(); - } - }; - return [cmd]; - } - } } diff --git a/src/3rdparty/python/lib/python2.7/site-packages/dmgbuild/core.py b/src/3rdparty/python/lib/python2.7/site-packages/dmgbuild/core.py index efccd0028..d94a06c1f 100644 --- a/src/3rdparty/python/lib/python2.7/site-packages/dmgbuild/core.py +++ b/src/3rdparty/python/lib/python2.7/site-packages/dmgbuild/core.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import os import pkg_resources +import platform import re import shutil import stat @@ -25,7 +26,19 @@ try: except NameError: unicode = str -import biplist +if sys.version_info < (3, 4): + import biplist + def plist_from_bytes(data): + return biplist.readPlistFromString(data) + def plist_bytes(data): + return biplist.Data(data) +else: + import plistlib + def plist_from_bytes(data): + return plistlib.loads(data) + def plist_bytes(data): + return data + from mac_alias import * from ds_store import * @@ -39,6 +52,10 @@ except ImportError: _hexcolor_re = re.compile(r'#[0-9a-f]{3}(?:[0-9a-f]{3})?') +# The first element in the platform.mac_ver() tuple is a string containing the +# macOS version (e.g., '10.15.6'). Parse into an integer tuple. +MACOS_VERSION = tuple(int(v) for v in platform.mac_ver()[0].split('.')) + class DMGError(Exception): pass @@ -51,7 +68,7 @@ def hdiutil(cmd, *args, **kwargs): p = subprocess.Popen(all_args, stdout=subprocess.PIPE, close_fds=True) output, errors = p.communicate() if plist: - results = biplist.readPlistFromString(output) + results = plist_from_bytes(output) else: results = output retcode = p.wait() @@ -103,6 +120,8 @@ def load_json(filename, settings): settings['compression_level'] = json_data.get('compression-level', None) settings['license'] = json_data.get('license', None) files = [] + hide = [] + hide_extensions = [] symlinks = {} icon_locations = {} for fileinfo in json_data.get('contents', []): @@ -123,8 +142,16 @@ def load_json(filename, settings): elif kind == 'position': pass icon_locations[name] = (fileinfo['x'], fileinfo['y']) + hide_ext = fileinfo.get('hide_extension', False) + if hide_ext: + hide_extensions.append(name) + hidden = fileinfo.get('hidden', False) + if hidden: + hide.append(name) settings['files'] = files + settings['hide_extensions'] = hide_extensions + settings['hide'] = hide settings['symlinks'] = symlinks settings['icon_locations'] = icon_locations @@ -139,6 +166,8 @@ def build_dmg(filename, volume_name, settings_file=None, settings={}, 'size': None, 'files': [], 'symlinks': {}, + 'hide': [], + 'hide_extensions': [], 'icon': None, 'badge_icon': None, 'background': None, @@ -258,7 +287,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={}, } background = options['background'] - + columns = { 'name': 'name', 'date-modified': 'dateModified', @@ -297,7 +326,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={}, 'version': 'ascending', 'comments': 'ascending', } - + lsvp = { 'viewOptionsVersion': 1, 'sortColumn': columns.get(options['list_sort_by'], 'name'), @@ -319,7 +348,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={}, default_widths[column]) asc = 'ascending' == options['list_column_sort_directions'].get(column, default_sort_directions[column]) - + lsvp['columns'][columns[column]] = { 'index': n, 'width': width, @@ -334,7 +363,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={}, cndx[k] = n width = default_widths[k] asc = 'ascending' == default_sort_directions[k] - + lsvp['columns'][columns[column]] = { 'index': n, 'width': width, @@ -344,7 +373,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={}, } n += 1 - + default_view = options['default_view'] views = { 'icon-view': b'icnv', @@ -411,11 +440,19 @@ def build_dmg(filename, volume_name, settings_file=None, settings={}, if ret: raise DMGError('Unable to create disk image') - ret, output = hdiutil('attach', - '-nobrowse', - '-owners', 'off', - '-noidme', - writableFile.name) + # IDME was deprecated in macOS 10.15/Catalina; as a result, use of -noidme + # started raising a warning. + if MACOS_VERSION >= (10, 15): + ret, output = hdiutil('attach', + '-nobrowse', + '-owners', 'off', + writableFile.name) + else: + ret, output = hdiutil('attach', + '-nobrowse', + '-owners', 'off', + '-noidme', + writableFile.name) if ret: raise DMGError('Unable to attach disk image') @@ -506,7 +543,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={}, background_bmk = Bookmark.for_file(path_in_image) icvp['backgroundType'] = 2 - icvp['backgroundImageAlias'] = biplist.Data(alias.to_bytes()) + icvp['backgroundImageAlias'] = plist_bytes(alias.to_bytes()) for f in options['files']: if isinstance(f, tuple): @@ -523,6 +560,22 @@ def build_dmg(filename, volume_name, settings_file=None, settings={}, name_in_image = os.path.join(mount_point, name) os.symlink(target, name_in_image) + to_hide = [] + for name in options['hide_extensions']: + name_in_image = os.path.join(mount_point, name) + to_hide.append(name_in_image) + + if to_hide: + subprocess.call(['/usr/bin/SetFile', '-a', 'E'] + to_hide) + + to_hide = [] + for name in options['hide']: + name_in_image = os.path.join(mount_point, name) + to_hide.append(name_in_image) + + if to_hide: + subprocess.call(['/usr/bin/SetFile', '-a', 'V'] + to_hide) + userfn = options.get('create_hook', None) if callable(userfn): userfn(mount_point, options) diff --git a/src/app/config/configcommandexecutor.cpp b/src/app/config/configcommandexecutor.cpp index f2d9fc59e..0a6883aa7 100644 --- a/src/app/config/configcommandexecutor.cpp +++ b/src/app/config/configcommandexecutor.cpp @@ -128,7 +128,7 @@ void ConfigCommandExecutor::exportSettings(const QString &filename) .arg(QDir::toNativeSeparators(filename), file.errorString())); } QTextStream stream(&file); - stream.setCodec("UTF-8"); + setupDefaultCodec(stream); const auto keys = m_settings->allKeys(m_scope); for (const QString &key : keys) stream << key << ": " << qbs::settingsValueToRepresentation(m_settings->value(key, m_scope)) @@ -148,7 +148,7 @@ void ConfigCommandExecutor::importSettings(const QString &filename) m_settings->remove(key); QTextStream stream(&file); - stream.setCodec("UTF-8"); + setupDefaultCodec(stream); while (!stream.atEnd()) { QString line = stream.readLine(); int colon = line.indexOf(QLatin1Char(':')); diff --git a/src/app/qbs-create-project/createproject.cpp b/src/app/qbs-create-project/createproject.cpp index 20338be98..cb6229ce3 100644 --- a/src/app/qbs-create-project/createproject.cpp +++ b/src/app/qbs-create-project/createproject.cpp @@ -103,7 +103,7 @@ void ProjectCreator::serializeProject(const ProjectCreator::Project &project) .arg(projectFile.fileName(), projectFile.errorString())); } QTextStream fileContents(&projectFile); - fileContents.setCodec("UTF-8"); + qbs::setupDefaultCodec(fileContents); fileContents << "import qbs\n\n"; if (!project.fileNames.empty() || m_projectStructure == ProjectStructure::Flat) { fileContents << "Product {\n"; diff --git a/src/app/qbs-setup-toolchains/gccprobe.cpp b/src/app/qbs-setup-toolchains/gccprobe.cpp index c521a3fed..85aba8a68 100644 --- a/src/app/qbs-setup-toolchains/gccprobe.cpp +++ b/src/app/qbs-setup-toolchains/gccprobe.cpp @@ -282,30 +282,28 @@ static QStringList gnuRegistrySearchPaths() if (!HostOsInfo::isWindowsHost()) return {}; - QStringList searchPaths; +#ifdef Q_OS_WIN64 + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\ARM"; +#else + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\ARM"; +#endif - QSettings registry(QLatin1String(kUninstallRegistryKey), QSettings::NativeFormat); - const auto productGroups = registry.childGroups(); - for (const QString &productKey : productGroups) { - // Registry token for the "GNU Tools for ARM Embedded Processors". - if (!productKey.startsWith( - QLatin1String("GNU Tools for ARM Embedded Processors"))) { - continue; + QStringList searchPaths; + QSettings registry(QLatin1String(kRegistryNode), QSettings::NativeFormat); + const auto groupKeys = registry.childGroups(); + for (const QString &groupKey : groupKeys) { + registry.beginGroup(groupKey); + const QString rootPath = registry.value(QStringLiteral("InstallFolder")).toString(); + if (!rootPath.isEmpty()) { + const QFileInfo toolchainPath(rootPath + QLatin1String("/bin")); + if (toolchainPath.exists()) { + const auto filePath = toolchainPath.absoluteFilePath(); + if (!searchPaths.contains(filePath)) + searchPaths.push_back(filePath); + } } - registry.beginGroup(productKey); - QString uninstallFilePath = registry.value( - QLatin1String("UninstallString")).toString(); - if (uninstallFilePath.startsWith(QLatin1Char('"'))) - uninstallFilePath.remove(0, 1); - if (uninstallFilePath.endsWith(QLatin1Char('"'))) - uninstallFilePath.remove(uninstallFilePath.size() - 1, 1); registry.endGroup(); - - const QString toolkitRootPath = QFileInfo(uninstallFilePath).path(); - const QString toolchainPath = toolkitRootPath + QLatin1String("/bin"); - searchPaths.push_back(toolchainPath); } - return searchPaths; } @@ -410,8 +408,8 @@ static QStringList renesasRl78RegistrySearchPaths() if (installLocation.isEmpty()) continue; - const QFileInfo toolchainPath = QDir(installLocation).absolutePath() - + QLatin1String("/rl78-elf/rl78-elf/bin"); + const QFileInfo toolchainPath(QDir(installLocation).absolutePath() + + QLatin1String("/rl78-elf/rl78-elf/bin")); if (!toolchainPath.exists()) continue; searchPaths.push_back(toolchainPath.absoluteFilePath()); @@ -442,8 +440,8 @@ static QStringList mplabX32RegistrySearchPaths() if (installLocation.isEmpty()) continue; - const QFileInfo toolchainPath = QDir(installLocation).absolutePath() - + QLatin1String("/bin"); + const QFileInfo toolchainPath(QDir(installLocation).absolutePath() + + QLatin1String("/bin")); if (!toolchainPath.exists()) continue; searchPaths.push_back(toolchainPath.absoluteFilePath()); @@ -543,7 +541,7 @@ void gccProbe(Settings *settings, std::vector<Profile> &profiles, const QString || fileName.startsWith(QLatin1String("c99-gcc"))) { continue; } - const QFileInfo candidate = dir.filePath(fileName); + const QFileInfo candidate(dir.filePath(fileName)); // Filter duplicates. const auto existingEnd = candidates.end(); const auto existingIt = std::find_if( diff --git a/src/app/qbs-setup-toolchains/iarewprobe.cpp b/src/app/qbs-setup-toolchains/iarewprobe.cpp index 4f87590a6..6c1506778 100644 --- a/src/app/qbs-setup-toolchains/iarewprobe.cpp +++ b/src/app/qbs-setup-toolchains/iarewprobe.cpp @@ -65,7 +65,8 @@ static QStringList knownIarCompilerNames() QStringLiteral("iccavr32"), QStringLiteral("iccsh"), QStringLiteral("iccriscv"), QStringLiteral("icccf"), QStringLiteral("iccm32c"), QStringLiteral("iccr32c"), - QStringLiteral("iccm16c"), QStringLiteral("icccr16c")}; + QStringLiteral("iccm16c"), QStringLiteral("icccr16c"), + QStringLiteral("icchcs12"), QStringLiteral("iccs08")}; } static QString guessIarArchitecture(const QFileInfo &compiler) @@ -107,6 +108,10 @@ static QString guessIarArchitecture(const QFileInfo &compiler) return QStringLiteral("m16c"); if (baseName == QLatin1String("icccr16c")) return QStringLiteral("cr16"); + if (baseName == QLatin1String("icchcs12")) + return QStringLiteral("hcs12"); + if (baseName == QLatin1String("iccs08")) + return QStringLiteral("hcs8"); return {}; } @@ -190,7 +195,9 @@ static Version dumpIarCompilerVersion(const QFileInfo &compiler) || arch == QLatin1String("m32c") || arch == QLatin1String("r32c") || arch == QLatin1String("m16c") - || arch == QLatin1String("rc16")) { + || arch == QLatin1String("rc16") + || arch == QLatin1String("hcs12") + || arch == QLatin1String("hcs8")) { return Version{verCode / 100, verCode % 100}; } @@ -249,6 +256,8 @@ static std::vector<ToolchainInstallInfo> installedIarsFromRegistry() {QStringLiteral("EWR32C"), QStringLiteral("/r32c/bin/iccr32c.exe")}, {QStringLiteral("EWM16C"), QStringLiteral("/m16c/bin/iccm16c.exe")}, {QStringLiteral("EWCR16C"), QStringLiteral("/cr16c/bin/icccr16c.exe")}, + {QStringLiteral("EWHCS12"), QStringLiteral("/hcs12/bin/icchcs12.exe")}, + {QStringLiteral("EWS08"), QStringLiteral("/s08/bin/iccs08.exe")}, }; QSettings registry(QLatin1String(kRegistryNode), QSettings::NativeFormat); @@ -269,7 +278,7 @@ static std::vector<ToolchainInstallInfo> installedIarsFromRegistry() const QFileInfo iarPath(rootPath + entry.subExePath); if (iarPath.exists()) { // Note: threeLevelKey is a guessed toolchain version. - infos.push_back({iarPath, Version::fromString(threeLevelKey)}); + infos.push_back({iarPath, Version::fromString(threeLevelKey, true)}); } } registry.endGroup(); diff --git a/src/app/qbs-setup-toolchains/keilprobe.cpp b/src/app/qbs-setup-toolchains/keilprobe.cpp index ee0144c77..0f3bcca04 100644 --- a/src/app/qbs-setup-toolchains/keilprobe.cpp +++ b/src/app/qbs-setup-toolchains/keilprobe.cpp @@ -337,51 +337,6 @@ static std::vector<ToolchainInstallInfo> installedKeilsFromPath() return infos; } -// Parse the 'tools.ini' file to fetch a toolchain version. -// Note: We can't use QSettings here! -static QString extractVersion(const QString &toolsIniFile, const QString §ion) -{ - QFile f(toolsIniFile); - if (!f.open(QIODevice::ReadOnly)) - return {}; - QTextStream in(&f); - enum State { Enter, Lookup, Exit } state = Enter; - while (!in.atEnd()) { - const QString line = in.readLine().trimmed(); - // Search for section. - const int firstBracket = line.indexOf(QLatin1Char('[')); - const int lastBracket = line.lastIndexOf(QLatin1Char(']')); - const bool hasSection = (firstBracket == 0 && lastBracket != -1 - && (lastBracket + 1) == line.size()); - switch (state) { - case Enter: { - if (hasSection) { - const auto content = line.midRef(firstBracket + 1, - lastBracket - firstBracket - 1); - if (content == section) - state = Lookup; - } - } - break; - case Lookup: { - if (hasSection) - return {}; // Next section found. - const int versionIndex = line.indexOf(QLatin1String("VERSION=")); - if (versionIndex < 0) - continue; - QString version = line.mid(8); - if (version.startsWith(QLatin1Char('V'))) - version.remove(0, 1); - return version; - } - break; - default: - return {}; - } - } - return {}; -} - static std::vector<ToolchainInstallInfo> installedKeilsFromRegistry() { std::vector<ToolchainInstallInfo> infos; @@ -389,52 +344,43 @@ static std::vector<ToolchainInstallInfo> installedKeilsFromRegistry() if (HostOsInfo::isWindowsHost()) { #ifdef Q_OS_WIN64 - static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\" \ - "Windows\\CurrentVersion\\Uninstall\\Keil \u00B5Vision4"; + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Keil\\Products"; #else - static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" \ - "Windows\\CurrentVersion\\Uninstall\\Keil \u00B5Vision4"; + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Keil\\Products"; #endif QSettings registry(QLatin1String(kRegistryNode), QSettings::NativeFormat); const auto productGroups = registry.childGroups(); for (const QString &productKey : productGroups) { - if (!productKey.startsWith(QStringLiteral("App"))) - continue; registry.beginGroup(productKey); - const QString productPath = registry.value(QStringLiteral("ProductDir")) - .toString(); - // Fetch the toolchain executable path. - QVector<QFileInfo> keilPaths; - if (productPath.endsWith(QStringLiteral("ARM"))) { - keilPaths << QFileInfo(productPath + QStringLiteral("/ARMCC/bin/armcc.exe")); - keilPaths << QFileInfo(productPath + QStringLiteral("/ARMCLANG/bin/armclang.exe")); - } else if (productPath.endsWith(QStringLiteral("C51"))) { - keilPaths << QFileInfo(productPath + QStringLiteral("/BIN/c51.exe")); - } else if (productPath.endsWith(QStringLiteral("C251"))) { - keilPaths << QFileInfo(productPath + QStringLiteral("/BIN/c251.exe")); - } else if (productPath.endsWith(QStringLiteral("C166"))) { - keilPaths << QFileInfo(productPath + QStringLiteral("/BIN/c166.exe")); + const QString productPath = registry.value(QStringLiteral("Path")) + .toString(); + QString productVersion = registry.value(QStringLiteral("Version")) + .toString(); + if (productVersion.startsWith(QLatin1Char('V'))) + productVersion.remove(0, 1); + + if (productKey == QLatin1String("MDK")) { + const QFileInfo ccPath(productPath + QStringLiteral("/ARMCC/bin/armcc.exe")); + if (ccPath.exists()) + infos.push_back({ccPath, Version::fromString(productVersion)}); + const QFileInfo clangPath(productPath + QStringLiteral("/ARMCLANG/bin/armclang.exe")); + if (clangPath.exists()) + infos.push_back({clangPath, Version::fromString(productVersion)}); + } if (productKey == QLatin1String("C51")) { + const QFileInfo cPath(productPath + QStringLiteral("/BIN/c51.exe")); + if (cPath.exists()) + infos.push_back({cPath, Version::fromString(productVersion)}); + } if (productKey == QLatin1String("C251")) { + const QFileInfo cPath(productPath + QStringLiteral("/BIN/c251.exe")); + if (cPath.exists()) + infos.push_back({cPath, Version::fromString(productVersion)}); + } if (productKey == QLatin1String("C166")) { + const QFileInfo cPath(productPath + QStringLiteral("/BIN/c166.exe")); + if (cPath.exists()) + infos.push_back({cPath, Version::fromString(productVersion)}); } - // Fetch the toolchain version. - const QDir rootPath(registry.value(QStringLiteral("Directory")).toString()); - const QString toolsIniFilePath = rootPath.absoluteFilePath( - QStringLiteral("tools.ini")); - - for (const QFileInfo &keilPath : qAsConst(keilPaths)) { - if (keilPath.exists()) { - for (auto index = 1; index <= 2; ++index) { - const QString section = registry.value( - QStringLiteral("Section %1").arg(index)).toString(); - const QString version = extractVersion(toolsIniFilePath, section); - if (!version.isEmpty()) { - infos.push_back({keilPath, Version::fromString(version)}); - break; - } - } - } - } registry.endGroup(); } } diff --git a/src/app/qbs-setup-toolchains/msvcprobe.cpp b/src/app/qbs-setup-toolchains/msvcprobe.cpp index bb54add9f..19da1e25a 100644 --- a/src/app/qbs-setup-toolchains/msvcprobe.cpp +++ b/src/app/qbs-setup-toolchains/msvcprobe.cpp @@ -58,6 +58,7 @@ #include <QtCore/qstringlist.h> #include <algorithm> +#include <unordered_set> #include <vector> using namespace qbs; @@ -182,9 +183,14 @@ void msvcProbe(Settings *settings, std::vector<Profile> &profiles) } } + std::unordered_set<QString> seenNames; for (MSVC &msvc : msvcs) { const QString name = QLatin1String("MSVC") + msvc.version + QLatin1Char('-') + msvc.architecture; + // TODO: Qbs currently does not support multiple versions of installed MSVCs + // so we stop at the first (the newest) one + if (!seenNames.insert(name).second) + continue; try { msvc.init(); addMSVCPlatform(settings, profiles, name, &msvc); diff --git a/src/app/qbs-setup-toolchains/probe.h b/src/app/qbs-setup-toolchains/probe.h index bce150bd7..63b4c6555 100644 --- a/src/app/qbs-setup-toolchains/probe.h +++ b/src/app/qbs-setup-toolchains/probe.h @@ -43,14 +43,11 @@ #include <tools/version.h> #include <QtCore/qfileinfo.h> +#include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> #include <tuple> // for std::tie -QT_BEGIN_NAMESPACE -class QString; -class QStringList; -QT_END_NAMESPACE - namespace qbs { class Settings; } QStringList systemSearchPaths(); diff --git a/src/app/qbs-setup-toolchains/sdccprobe.cpp b/src/app/qbs-setup-toolchains/sdccprobe.cpp index 977d834c4..a8a27fb96 100644 --- a/src/app/qbs-setup-toolchains/sdccprobe.cpp +++ b/src/app/qbs-setup-toolchains/sdccprobe.cpp @@ -89,13 +89,12 @@ static QByteArray dumpSdccMacros(const QFileInfo &compiler, return p.readAllStandardOutput(); } -static QString dumpSdccArchitecture(const QFileInfo &compiler, - const QString &arch) +static bool supportsSdccArchitecture(const QFileInfo &compiler, QStringView flag) { - const auto targetFlag = QStringLiteral("-m%1").arg(arch); - const auto token = QStringLiteral("__SDCC_%1").arg(arch); + const auto targetFlag = QStringLiteral("-m%1").arg(flag); const auto macros = dumpSdccMacros(compiler, targetFlag); - return macros.contains(token.toLatin1()) ? arch : QString(); + const auto token = QStringLiteral("__SDCC_%1").arg(flag); + return macros.contains(token.toLatin1()); } static std::vector<Profile> createSdccProfileHelper( @@ -107,13 +106,15 @@ static std::vector<Profile> createSdccProfileHelper( std::vector<Profile> profiles; - const char *knownArchs[] = {"mcs51", "stm8"}; + static constexpr struct KnownArch { + QStringView architecture; + QStringView flag; + } knownArchs[] = {{u"mcs51", u"mcs51"}, {u"stm8", u"stm8"}, {u"hcs8", u"hc08"}}; + for (const auto &knownArch : knownArchs) { - const auto actualArch = dumpSdccArchitecture( - compiler, QString::fromLatin1(knownArch)); // Don't create a profile in case the compiler does // not support the proposed architecture. - if (actualArch != QString::fromLatin1(knownArch)) + if (!supportsSdccArchitecture(compiler, knownArch.flag)) continue; QString fullProfileName; @@ -122,18 +123,18 @@ static std::vector<Profile> createSdccProfileHelper( // in auto-detecting mode. if (!info.compilerVersion.isValid()) { fullProfileName = QStringLiteral("sdcc-unknown-%1") - .arg(actualArch); + .arg(knownArch.architecture); } else { const QString version = info.compilerVersion.toString( QLatin1Char('_'), QLatin1Char('_')); fullProfileName = QStringLiteral("sdcc-%1-%2").arg( - version, actualArch); + version, knownArch.architecture); } } else { // Append the detected actual architecture name // to the proposed profile name. fullProfileName = QStringLiteral("%1-%2").arg( - profileName, actualArch); + profileName, knownArch.architecture); } Profile profile(fullProfileName, settings); @@ -141,8 +142,8 @@ static std::vector<Profile> createSdccProfileHelper( compiler.absolutePath()); profile.setValue(QStringLiteral("qbs.toolchainType"), QStringLiteral("sdcc")); - if (!actualArch.isEmpty()) - profile.setValue(QStringLiteral("qbs.architecture"), actualArch); + profile.setValue(QStringLiteral("qbs.architecture"), + knownArch.architecture.toString()); qbsInfo() << Tr::tr("Profile '%1' created for '%2'.").arg( profile.name(), compiler.absoluteFilePath()); @@ -253,8 +254,10 @@ static std::vector<ToolchainInstallInfo> installedSdccsFromRegistry() return candidate == SdccInstallInfo{ info.compilerPath.filePath(), info.compilerVersion.toString()}; }); - if (infosIt == infosEnd) - infos.push_back({candidate.compilerPath, Version::fromString(candidate.version)}); + if (infosIt == infosEnd) { + infos.push_back({QFileInfo(candidate.compilerPath), + Version::fromString(candidate.version)}); + } } } diff --git a/src/lib/corelib/CMakeLists.txt b/src/lib/corelib/CMakeLists.txt index a687eb0ad..224754a30 100644 --- a/src/lib/corelib/CMakeLists.txt +++ b/src/lib/corelib/CMakeLists.txt @@ -422,7 +422,7 @@ add_qbs_library(qbscore PUBLIC_DEFINES ${QBS_PROJECT_FILE_UPDATES_DEFINES} DEPENDS - Qt5::CorePrivate Qt5::Gui Qt5::Network Qt5::Script Qt5::Xml ${EXTERNAL_DEPENDS} + Qt5::CorePrivate Qt5::Network Qt5::Script Qt5::Xml ${EXTERNAL_DEPENDS} PUBLIC_DEPENDS Qt5::Core INCLUDES diff --git a/src/lib/corelib/api/changeset.cpp b/src/lib/corelib/api/changeset.cpp index 773af328d..b5419fd80 100644 --- a/src/lib/corelib/api/changeset.cpp +++ b/src/lib/corelib/api/changeset.cpp @@ -44,12 +44,12 @@ namespace QbsQmlJS { ChangeSet::ChangeSet() - : m_string(nullptr), m_cursor(nullptr), m_error(false) + : m_string(nullptr), m_error(false) { } ChangeSet::ChangeSet(QList<EditOp> operations) - : m_string(nullptr), m_cursor(nullptr), m_operationList(std::move(operations)), m_error(false) + : m_string(nullptr), m_operationList(std::move(operations)), m_error(false) { } @@ -131,7 +131,6 @@ QList<ChangeSet::EditOp> ChangeSet::operationList() const void ChangeSet::clear() { m_string = nullptr; - m_cursor = nullptr; m_operationList.clear(); m_error = false; } @@ -274,10 +273,6 @@ void ChangeSet::doReplace(const EditOp &replace_helper, QList<EditOp> *replaceLi if (m_string) { m_string->replace(replace_helper.pos1, replace_helper.length1, replace_helper.text); - } else if (m_cursor) { - m_cursor->setPosition(replace_helper.pos1); - m_cursor->setPosition(replace_helper.pos1 + replace_helper.length1, QTextCursor::KeepAnchor); - m_cursor->insertText(replace_helper.text); } } @@ -348,21 +343,10 @@ void ChangeSet::apply(QString *s) m_string = nullptr; } -void ChangeSet::apply(QTextCursor *textCursor) -{ - m_cursor = textCursor; - apply_helper(); - m_cursor = nullptr; -} - QString ChangeSet::textAt(int pos, int length) { if (m_string) { return m_string->mid(pos, length); - } else if (m_cursor) { - m_cursor->setPosition(pos); - m_cursor->setPosition(pos + length, QTextCursor::KeepAnchor); - return m_cursor->selectedText(); } return {}; } @@ -380,17 +364,11 @@ void ChangeSet::apply_helper() } // execute replaces - if (m_cursor) - m_cursor->beginEditBlock(); - while (!replaceList.empty()) { const EditOp cmd(replaceList.front()); replaceList.removeFirst(); doReplace(cmd, &replaceList); } - - if (m_cursor) - m_cursor->endEditBlock(); } } // namespace QbsQmlJS diff --git a/src/lib/corelib/api/changeset.h b/src/lib/corelib/api/changeset.h index 23248c48e..9182cb8e4 100644 --- a/src/lib/corelib/api/changeset.h +++ b/src/lib/corelib/api/changeset.h @@ -43,8 +43,6 @@ #include <QtCore/qstring.h> #include <QtCore/qlist.h> -QT_FORWARD_DECLARE_CLASS(QTextCursor) - namespace QbsQmlJS { class ChangeSet @@ -109,7 +107,6 @@ public: bool hadErrors(); void apply(QString *s); - void apply(QTextCursor *textCursor); private: // length-based API. @@ -129,7 +126,6 @@ private: private: QString *m_string; - QTextCursor *m_cursor; QList<EditOp> m_operationList; bool m_error; diff --git a/src/lib/corelib/api/projectdata.cpp b/src/lib/corelib/api/projectdata.cpp index c378fbea4..289c14781 100644 --- a/src/lib/corelib/api/projectdata.cpp +++ b/src/lib/corelib/api/projectdata.cpp @@ -994,7 +994,7 @@ static QString mapToString(const QVariantMap &map, const QString &prefix) QString stringRep; for (const QString &key : qAsConst(keys)) { const QVariant &val = map.value(key); - if (val.type() == QVariant::Map) { + if (val.userType() == QMetaType::QVariantMap) { stringRep += mapToString(val.value<QVariantMap>(), prefix + key + QLatin1Char('.')); } else { stringRep += QStringLiteral("%1%2: %3\n") diff --git a/src/lib/corelib/api/qmljsrewriter.cpp b/src/lib/corelib/api/qmljsrewriter.cpp index 5551e5650..b7e573e07 100644 --- a/src/lib/corelib/api/qmljsrewriter.cpp +++ b/src/lib/corelib/api/qmljsrewriter.cpp @@ -41,10 +41,6 @@ #include <parser/qmljsast_p.h> -#include <QtGui/qtextobject.h> -#include <QtGui/qtextcursor.h> -#include <QtGui/qtextdocument.h> - namespace QbsQmlJS { using namespace AST; @@ -500,28 +496,19 @@ bool Rewriter::includeSurroundingWhitespace(const QString &source, int &start, i return paragraphFound; } -void Rewriter::includeLeadingEmptyLine(const QString &source, int &start) +void Rewriter::includeLeadingEmptyLine(QStringView source, int &start) { - QTextDocument doc(source); - if (start == 0) return; - if (doc.characterAt(start - 1) != QChar::ParagraphSeparator) - return; - - QTextCursor tc(&doc); - tc.setPosition(start); - const int blockNr = tc.blockNumber(); - if (blockNr == 0) + const qsizetype lineEnd = source.lastIndexOf(QChar::LineFeed, start); + if (lineEnd <= 0) return; - - const QTextBlock prevBlock = tc.block().previous(); - const QString trimmedPrevBlockText = prevBlock.text().trimmed(); - if (!trimmedPrevBlockText.isEmpty()) + const qsizetype lineStart = source.lastIndexOf(QChar::LineFeed, lineEnd - 1) + 1; + const auto line = source.mid(lineStart, lineEnd - lineStart); + if (!line.trimmed().isEmpty()) return; - - start = prevBlock.position(); + start = lineStart; } void Rewriter::includeEmptyGroupedProperty(UiObjectDefinition *groupedProperty, UiObjectMember *memberToBeRemoved, int &start, int &end) diff --git a/src/lib/corelib/api/qmljsrewriter.h b/src/lib/corelib/api/qmljsrewriter.h index 3788035f2..7cba699e2 100644 --- a/src/lib/corelib/api/qmljsrewriter.h +++ b/src/lib/corelib/api/qmljsrewriter.h @@ -97,7 +97,7 @@ public: static AST::UiObjectMemberList *searchMemberToInsertAfter(AST::UiObjectMemberList *members, const QString &propertyName, const QStringList &propertyOrder); static bool includeSurroundingWhitespace(const QString &source, int &start, int &end); - static void includeLeadingEmptyLine(const QString &source, int &start); + static void includeLeadingEmptyLine(QStringView source, int &start); static void includeEmptyGroupedProperty(AST::UiObjectDefinition *groupedProperty, AST::UiObjectMember *memberToBeRemoved, int &start, int &end); private: diff --git a/src/lib/corelib/api/rulecommand.h b/src/lib/corelib/api/rulecommand.h index 438849604..cebcfa949 100644 --- a/src/lib/corelib/api/rulecommand.h +++ b/src/lib/corelib/api/rulecommand.h @@ -44,11 +44,10 @@ #include <QtCore/qlist.h> #include <QtCore/qshareddata.h> +#include <QtCore/qstringlist.h> QT_BEGIN_NAMESPACE class QProcessEnvironment; -class QString; -class QStringList; QT_END_NAMESPACE namespace qbs { diff --git a/src/lib/corelib/api/runenvironment.h b/src/lib/corelib/api/runenvironment.h index c5123ca9c..b95bfbf85 100644 --- a/src/lib/corelib/api/runenvironment.h +++ b/src/lib/corelib/api/runenvironment.h @@ -44,12 +44,11 @@ #include <tools/qbs_export.h> #include <QtCore/qglobal.h> +#include <QtCore/qstringlist.h> QT_BEGIN_NAMESPACE class QProcess; class QProcessEnvironment; -class QString; -class QStringList; QT_END_NAMESPACE class TestApi; diff --git a/src/lib/corelib/buildgraph/dependencyparametersscriptvalue.cpp b/src/lib/corelib/buildgraph/dependencyparametersscriptvalue.cpp index f1bf8db13..ac6b1dc42 100644 --- a/src/lib/corelib/buildgraph/dependencyparametersscriptvalue.cpp +++ b/src/lib/corelib/buildgraph/dependencyparametersscriptvalue.cpp @@ -53,7 +53,7 @@ static QScriptValue toScriptValue(ScriptEngine *engine, const QString &productNa QScriptValue obj = engine->newObject(); bool objIdAddedToObserver = false; for (auto it = v.begin(); it != v.end(); ++it) { - if (it.value().type() == QVariant::Map) { + if (it.value().userType() == QMetaType::QVariantMap) { obj.setProperty(it.key(), toScriptValue(engine, productName, it.value().toMap(), depName, QualifiedId(moduleName) << it.key())); } else { diff --git a/src/lib/corelib/buildgraph/filedependency.h b/src/lib/corelib/buildgraph/filedependency.h index 802654e9f..93bfc5d05 100644 --- a/src/lib/corelib/buildgraph/filedependency.h +++ b/src/lib/corelib/buildgraph/filedependency.h @@ -77,8 +77,8 @@ private: FileTime m_timestamp; QString m_filePath; - QStringRef m_dirPath; - QStringRef m_fileName; + QStringView m_dirPath; + QStringView m_fileName; }; class FileDependency : public FileResourceBase diff --git a/src/lib/corelib/buildgraph/jscommandexecutor.cpp b/src/lib/corelib/buildgraph/jscommandexecutor.cpp index b7270c9a5..c933a6a35 100644 --- a/src/lib/corelib/buildgraph/jscommandexecutor.cpp +++ b/src/lib/corelib/buildgraph/jscommandexecutor.cpp @@ -202,6 +202,9 @@ JsCommandExecutor::JsCommandExecutor(const Logger &logger, QObject *parent) , m_objectInThread(new JsCommandExecutorThreadObject(logger)) , m_running(false) { + qRegisterMetaType<Transformer *>("Transformer *"); + qRegisterMetaType<const JavaScriptCommand *>("const JavaScriptCommand *"); + m_objectInThread->moveToThread(m_thread); connect(m_objectInThread, &JsCommandExecutorThreadObject::finished, this, &JsCommandExecutor::onJavaScriptCommandFinished); diff --git a/src/lib/corelib/buildgraph/rulecommands.cpp b/src/lib/corelib/buildgraph/rulecommands.cpp index 8fa3255f1..9eed7c715 100644 --- a/src/lib/corelib/buildgraph/rulecommands.cpp +++ b/src/lib/corelib/buildgraph/rulecommands.cpp @@ -156,7 +156,7 @@ void AbstractCommand::applyCommandProperties(const QScriptValue *scriptValue) if (m_predefinedProperties.contains(it.name())) continue; const QVariant value = it.value().toVariant(); - if (QMetaType::Type(value.type()) == QMetaType::QObjectStar + if (QMetaType::Type(value.userType()) == QMetaType::QObjectStar || it.value().scriptClass() || it.value().data().isValid()) { throw ErrorInfo(Tr::tr("Property '%1' has a type unsuitable for storing in a command " @@ -468,7 +468,7 @@ void CommandList::load(PersistentPool &pool) void CommandList::store(PersistentPool &pool) const { - pool.store(m_commands.size()); + pool.store(int(m_commands.size())); for (const AbstractCommandPtr &cmd : m_commands) { pool.store(static_cast<quint8>(cmd->type())); pool.store(cmd); diff --git a/src/lib/corelib/corelib.pro b/src/lib/corelib/corelib.pro index 002e36683..799aebda1 100644 --- a/src/lib/corelib/corelib.pro +++ b/src/lib/corelib/corelib.pro @@ -15,7 +15,6 @@ isEmpty(QBS_RELATIVE_LIBEXEC_PATH) { DEFINES += QBS_RELATIVE_LIBEXEC_PATH=\\\"$${QBS_RELATIVE_LIBEXEC_PATH}\\\" QT += core-private network -qbs_enable_project_file_updates: QT += gui INCLUDEPATH += $$PWD diff --git a/src/lib/corelib/corelib.qbs b/src/lib/corelib/corelib.qbs index 9f95f417f..6a5b33f98 100644 --- a/src/lib/corelib/corelib.qbs +++ b/src/lib/corelib/corelib.qbs @@ -5,6 +5,10 @@ QbsLibrary { Depends { name: "cpp" } Depends { name: "Qt"; submodules: ["core-private", "network", "xml"] } Depends { + name: "Qt.core5compat"; + condition: Utilities.versionCompare(Qt.core.version, "6.0.0") >= 0 + } + Depends { name: "Qt.script" condition: !qbsbuildconfig.useBundledQtScript required: false @@ -13,7 +17,6 @@ QbsLibrary { name: "qbsscriptengine" condition: qbsbuildconfig.useBundledQtScript || !Qt.script.present } - Depends { condition: qbsbuildconfig.enableProjectFileUpdates; name: "Qt.gui" } name: "qbscore" property stringList bundledQtScriptIncludes: qbsbuildconfig.useBundledQtScript || !Qt.script.present ? qbsscriptengine.includePaths : [] @@ -372,6 +375,7 @@ QbsLibrary { files: [ "qmlerror.cpp", "qmlerror.h", + "qmljs.g", "qmljsast.cpp", "qmljsast_p.h", "qmljsastfwd_p.h", diff --git a/src/lib/corelib/generators/generatordata.cpp b/src/lib/corelib/generators/generatordata.cpp index 7c6573484..25afae23d 100644 --- a/src/lib/corelib/generators/generatordata.cpp +++ b/src/lib/corelib/generators/generatordata.cpp @@ -133,7 +133,7 @@ QFileInfo GeneratableProject::filePath() const filePath.insert(it.value().location().filePath()); } Q_ASSERT(filePath.size() == 1); - return *filePath.begin(); + return QFileInfo(*filePath.begin()); } bool GeneratableProject::hasMultipleConfigurations() const diff --git a/src/lib/corelib/jsextensions/process.cpp b/src/lib/corelib/jsextensions/process.cpp index a91084b4a..8ddb48acd 100644 --- a/src/lib/corelib/jsextensions/process.cpp +++ b/src/lib/corelib/jsextensions/process.cpp @@ -46,10 +46,13 @@ #include <QtCore/qobject.h> #include <QtCore/qprocess.h> -#include <QtCore/qtextcodec.h> #include <QtCore/qtextstream.h> #include <QtCore/qvariant.h> - +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#include <QtCore5Compat/qtextcodec.h> +#else +#include <QtCore/qtextcodec.h> +#endif #include <QtScript/qscriptable.h> #include <QtScript/qscriptengine.h> #include <QtScript/qscriptvalue.h> @@ -100,10 +103,10 @@ private: // ResourceAcquiringScriptObject implementation void releaseResources() override; - QProcess *m_qProcess; + QProcess *m_qProcess = nullptr; QProcessEnvironment m_environment; QString m_workingDirectory; - QTextStream *m_textStream; + QTextCodec *m_codec = nullptr; }; QScriptValue Process::ctor(QScriptContext *context, QScriptEngine *engine) @@ -143,7 +146,6 @@ QScriptValue Process::ctor(QScriptContext *context, QScriptEngine *engine) Process::~Process() { - delete m_textStream; delete m_qProcess; } @@ -153,7 +155,7 @@ Process::Process(QScriptContext *context) Q_ASSERT(thisObject().engine() == engine()); m_qProcess = new QProcess; - m_textStream = new QTextStream(m_qProcess); + m_codec = QTextCodec::codecForName("UTF-8"); } QString Process::getEnv(const QString &name) @@ -188,7 +190,7 @@ bool Process::start(const QString &program, const QStringList &arguments) m_qProcess->setWorkingDirectory(m_workingDirectory); m_qProcess->setProcessEnvironment(m_environment); - m_qProcess->start(findExecutable(program), arguments); + m_qProcess->start(findExecutable(program), arguments, QIODevice::ReadWrite | QIODevice::Text); return m_qProcess->waitForStarted(); } @@ -234,8 +236,6 @@ void Process::close() if (!m_qProcess) return; Q_ASSERT(thisObject().engine() == engine()); - delete m_textStream; - m_textStream = nullptr; delete m_qProcess; m_qProcess = nullptr; } @@ -262,32 +262,36 @@ void Process::kill() void Process::setCodec(const QString &codec) { Q_ASSERT(thisObject().engine() == engine()); - m_textStream->setCodec(qPrintable(codec)); + const auto newCodec = QTextCodec::codecForName(qPrintable(codec)); + if (newCodec) + m_codec = newCodec; } QString Process::readLine() { - return m_textStream->readLine(); + auto result = m_codec->toUnicode(m_qProcess->readLine()); + if (!result.isEmpty() && result.back() == QLatin1Char('\n')) + result.chop(1); + return result; } bool Process::atEnd() const { - return m_textStream->atEnd(); + return m_qProcess->atEnd(); } QString Process::readStdOut() { - return m_textStream->readAll(); + return m_codec->toUnicode(m_qProcess->readAllStandardOutput()); } QString Process::readStdErr() { - return m_textStream->codec()->toUnicode(m_qProcess->readAllStandardError()); + return m_codec->toUnicode(m_qProcess->readAllStandardError()); } void Process::closeWriteChannel() { - m_textStream->flush(); m_qProcess->closeWriteChannel(); } @@ -310,15 +314,13 @@ void Process::releaseResources() void Process::write(const QString &str) { - (*m_textStream) << str; + m_qProcess->write(m_codec->fromUnicode(str)); } void Process::writeLine(const QString &str) { - (*m_textStream) << str; - if (HostOsInfo::isWindowsHost()) - (*m_textStream) << '\r'; - (*m_textStream) << '\n'; + m_qProcess->write(m_codec->fromUnicode(str)); + m_qProcess->putChar('\n'); } QScriptValue Process::js_shellQuote(QScriptContext *context, QScriptEngine *engine) diff --git a/src/lib/corelib/jsextensions/propertylistutils.mm b/src/lib/corelib/jsextensions/propertylistutils.mm index b8ae1b8e0..704b1a8ce 100644 --- a/src/lib/corelib/jsextensions/propertylistutils.mm +++ b/src/lib/corelib/jsextensions/propertylistutils.mm @@ -127,33 +127,33 @@ static NSArray *toArray(const QVariantList &list); static id toObject(const QVariant &variant) { - if (variant.type() == QVariant::Hash) { + if (variant.userType() == QMetaType::QVariantHash) { return toDictionary(qHashToMap(variant.toHash())); - } else if (variant.type() == QVariant::Map) { + } else if (variant.userType() == QMetaType::QVariantMap) { return toDictionary(variant.toMap()); - } else if (variant.type() == QVariant::List) { + } else if (variant.userType() == QMetaType::QVariantList) { return toArray(variant.toList()); - } else if (variant.type() == QVariant::String) { + } else if (variant.userType() == QMetaType::QString) { return variant.toString().toNSString(); - } else if (variant.type() == QVariant::ByteArray) { + } else if (variant.userType() == QMetaType::QByteArray) { return variant.toByteArray().toNSData(); - } else if (variant.type() == QVariant::Date || - variant.type() == QVariant::DateTime) { + } else if (variant.userType() == QMetaType::QDate || + variant.userType() == QMetaType::QDateTime) { return variant.toDateTime().toNSDate(); - } else if (variant.type() == QVariant::Bool) { + } else if (variant.userType() == QMetaType::Bool) { return variant.toBool() ? [NSNumber numberWithBool:YES] : [NSNumber numberWithBool:NO]; - } else if (variant.type() == QVariant::Char || - variant.type() == QVariant::Int) { + } else if (variant.userType() == QMetaType::Char || + variant.userType() == QMetaType::Int) { return [NSNumber numberWithInt:variant.toInt()]; - } else if (variant.type() == QVariant::UInt) { + } else if (variant.userType() == QMetaType::UInt) { return [NSNumber numberWithUnsignedInt:variant.toUInt()]; - } else if (variant.type() == QVariant::LongLong) { + } else if (variant.userType() == QMetaType::LongLong) { return [NSNumber numberWithLongLong:variant.toLongLong()]; - } else if (variant.type() == QVariant::ULongLong) { + } else if (variant.userType() == QMetaType::ULongLong) { return [NSNumber numberWithUnsignedLongLong:variant.toULongLong()]; - } else if (variant.type() == QVariant::Double) { + } else if (variant.userType() == QMetaType::Double) { return [NSNumber numberWithDouble:variant.toDouble()]; } else { return [NSNull null]; diff --git a/src/lib/corelib/jsextensions/textfile.cpp b/src/lib/corelib/jsextensions/textfile.cpp index 7c67f9019..3c7f2d316 100644 --- a/src/lib/corelib/jsextensions/textfile.cpp +++ b/src/lib/corelib/jsextensions/textfile.cpp @@ -47,6 +47,12 @@ #include <QtCore/qtextstream.h> #include <QtCore/qvariant.h> +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#include <QtCore5Compat/qtextcodec.h> +#else +#include <QtCore/qtextcodec.h> +#endif + #include <QtScript/qscriptable.h> #include <QtScript/qscriptengine.h> #include <QtScript/qscriptvalue.h> @@ -82,15 +88,15 @@ public: private: TextFile(QScriptContext *context, const QString &filePath, OpenMode mode = ReadOnly, - const QString &codec = QLatin1String("UTF8")); + const QString &codec = QLatin1String("UTF-8")); bool checkForClosed() const; // ResourceAcquiringScriptObject implementation void releaseResources() override; - QFile *m_file; - QTextStream *m_stream; + QFile *m_file = nullptr; + QTextCodec *m_codec = nullptr; }; QScriptValue TextFile::ctor(QScriptContext *context, QScriptEngine *engine) @@ -132,7 +138,6 @@ QScriptValue TextFile::ctor(QScriptContext *context, QScriptEngine *engine) TextFile::~TextFile() { - delete m_stream; delete m_file; } @@ -143,7 +148,8 @@ TextFile::TextFile(QScriptContext *context, const QString &filePath, OpenMode mo Q_ASSERT(thisObject().engine() == engine()); m_file = new QFile(filePath); - m_stream = new QTextStream(m_file); + const auto newCodec = QTextCodec::codecForName(qPrintable(codec)); + m_codec = newCodec ? newCodec : QTextCodec::codecForName("UTF-8"); QIODevice::OpenMode m = QIODevice::NotOpen; if (mode & ReadOnly) m |= QIODevice::ReadOnly; @@ -151,6 +157,7 @@ TextFile::TextFile(QScriptContext *context, const QString &filePath, OpenMode mo m |= QIODevice::WriteOnly; if (mode & Append) m |= QIODevice::Append; + m |= QIODevice::Text; if (Q_UNLIKELY(!m_file->open(m))) { context->throwError(Tr::tr("Unable to open file '%1': %2") .arg(filePath, m_file->errorString())); @@ -163,8 +170,6 @@ void TextFile::close() { if (checkForClosed()) return; - delete m_stream; - m_stream = nullptr; m_file->close(); delete m_file; m_file = nullptr; @@ -181,28 +186,33 @@ void TextFile::setCodec(const QString &codec) { if (checkForClosed()) return; - m_stream->setCodec(qPrintable(codec)); + const auto newCodec = QTextCodec::codecForName(qPrintable(codec)); + if (newCodec) + m_codec = newCodec; } QString TextFile::readLine() { if (checkForClosed()) return {}; - return m_stream->readLine(); + auto result = m_codec->toUnicode(m_file->readLine()); + if (!result.isEmpty() && result.back() == QLatin1Char('\n')) + result.chop(1); + return result; } QString TextFile::readAll() { if (checkForClosed()) return {}; - return m_stream->readAll(); + return m_codec->toUnicode(m_file->readAll()); } bool TextFile::atEof() const { if (checkForClosed()) return true; - return m_stream->atEnd(); + return m_file->atEnd(); } void TextFile::truncate() @@ -210,24 +220,21 @@ void TextFile::truncate() if (checkForClosed()) return; m_file->resize(0); - m_stream->reset(); } void TextFile::write(const QString &str) { if (checkForClosed()) return; - (*m_stream) << str; + m_file->write(m_codec->fromUnicode(str)); } void TextFile::writeLine(const QString &str) { if (checkForClosed()) return; - (*m_stream) << str; - if (HostOsInfo::isWindowsHost()) - (*m_stream) << '\r'; - (*m_stream) << '\n'; + m_file->write(m_codec->fromUnicode(str)); + m_file->putChar('\n'); } bool TextFile::checkForClosed() const diff --git a/src/lib/corelib/jsextensions/utilitiesextension.cpp b/src/lib/corelib/jsextensions/utilitiesextension.cpp index 6c693cb61..282362382 100644 --- a/src/lib/corelib/jsextensions/utilitiesextension.cpp +++ b/src/lib/corelib/jsextensions/utilitiesextension.cpp @@ -468,9 +468,10 @@ static std::pair<QVariantMap /*result*/, QString /*error*/> msvcCompilerInfoHelp const QString &compilerFilePath, MSVC::CompilerLanguage language, const QString &vcvarsallPath, - const QString &arch) + const QString &arch, + const QString &sdkVersion) { - MSVC msvc(compilerFilePath, arch); + MSVC msvc(compilerFilePath, arch, sdkVersion); VsEnvironmentDetector envdetector(vcvarsallPath); if (!envdetector.start(&msvc)) return { {}, QStringLiteral("Detecting the MSVC build environment failed: ") @@ -501,12 +502,16 @@ 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() < 2)) + if (Q_UNLIKELY(context->argumentCount() < 3)) return context->throwError(QScriptContext::SyntaxError, - QStringLiteral("msvcCompilerInfo expects 2 arguments")); + QStringLiteral("msvcCompilerInfo expects 3 arguments")); const QString compilerFilePath = context->argument(0).toString(); const QString compilerLanguage = context->argument(1).toString(); + const QString sdkVersion = + !context->argument(2).isNull() && !context->argument(2).isUndefined() + ? context->argument(2).toString() + : QString(); MSVC::CompilerLanguage language; if (compilerLanguage == QStringLiteral("c")) language = MSVC::CLanguage; @@ -517,7 +522,11 @@ QScriptValue UtilitiesExtension::js_msvcCompilerInfo(QScriptContext *context, QS QStringLiteral("msvcCompilerInfo expects \"c\" or \"cpp\" as its second argument")); const auto result = msvcCompilerInfoHelper( - compilerFilePath, language, {}, MSVC::architectureFromClPath(compilerFilePath)); + compilerFilePath, + language, + {}, + MSVC::architectureFromClPath(compilerFilePath), + sdkVersion); if (result.first.isEmpty()) return context->throwError(QScriptContext::UnknownError, result.second); return engine->toScriptValue(result.first); @@ -531,9 +540,9 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context, return context->throwError(QScriptContext::UnknownError, QStringLiteral("clangClCompilerInfo is not available on this platform")); #else - if (Q_UNLIKELY(context->argumentCount() < 4)) + if (Q_UNLIKELY(context->argumentCount() < 5)) return context->throwError(QScriptContext::SyntaxError, - QStringLiteral("clangClCompilerInfo expects 4 arguments")); + QStringLiteral("clangClCompilerInfo expects 5 arguments")); const QString compilerFilePath = context->argument(0).toString(); // architecture cannot be empty as vcvarsall.bat requires at least 1 arg, so fallback @@ -542,9 +551,14 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context, ? context->argument(1).toString() : QString::fromStdString(HostOsInfo::hostOSArchitecture()); QString vcvarsallPath = context->argument(2).toString(); - const QString compilerLanguage = context->argumentCount() > 3 + const QString compilerLanguage = + !context->argument(3).isNull() && !context->argument(3).isUndefined() ? context->argument(3).toString() : QString(); + const QString sdkVersion = + !context->argument(4).isNull() && !context->argument(4).isUndefined() + ? context->argument(4).toString() + : QString(); MSVC::CompilerLanguage language; if (compilerLanguage == QStringLiteral("c")) language = MSVC::CLanguage; @@ -555,7 +569,7 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context, QStringLiteral("clangClCompilerInfo expects \"c\" or \"cpp\" as its fourth argument")); const auto result = msvcCompilerInfoHelper( - compilerFilePath, language, vcvarsallPath, arch); + compilerFilePath, language, vcvarsallPath, arch, sdkVersion); if (result.first.isEmpty()) return context->throwError(QScriptContext::UnknownError, result.second); return engine->toScriptValue(result.first); diff --git a/src/lib/corelib/language/astpropertiesitemhandler.cpp b/src/lib/corelib/language/astpropertiesitemhandler.cpp index 1ea78bf79..b28fe7d76 100644 --- a/src/lib/corelib/language/astpropertiesitemhandler.cpp +++ b/src/lib/corelib/language/astpropertiesitemhandler.cpp @@ -139,7 +139,7 @@ private: value = JSSourceValue::create(true); value->setFile(conditionalValue->file()); item->setProperty(propertyName, value); - value->setSourceCode(QStringRef(&StringConstants::baseVar())); + value->setSourceCode(StringConstants::baseVar()); value->setSourceUsesBaseFlag(); } m_alternative.value = conditionalValue; diff --git a/src/lib/corelib/language/asttools.cpp b/src/lib/corelib/language/asttools.cpp index 1b6abac7f..0d0c234c4 100644 --- a/src/lib/corelib/language/asttools.cpp +++ b/src/lib/corelib/language/asttools.cpp @@ -64,10 +64,10 @@ QString textOf(const QString &source, QbsQmlJS::AST::Node *node) int(node->lastSourceLocation().end() - node->firstSourceLocation().begin())); } -QStringRef textRefOf(const QString &source, QbsQmlJS::AST::Node *node) +QStringView textViewOf(const QString &source, QbsQmlJS::AST::Node *node) { const quint32 firstBegin = node->firstSourceLocation().begin(); - return source.midRef(firstBegin, int(node->lastSourceLocation().end() - firstBegin)); + return QStringView(source).mid(firstBegin, int(node->lastSourceLocation().end() - firstBegin)); } } // namespace Internal diff --git a/src/lib/corelib/language/asttools.h b/src/lib/corelib/language/asttools.h index b4f5c4d98..086d59290 100644 --- a/src/lib/corelib/language/asttools.h +++ b/src/lib/corelib/language/asttools.h @@ -50,7 +50,7 @@ namespace Internal { QStringList toStringList(QbsQmlJS::AST::UiQualifiedId *qid); CodeLocation toCodeLocation(const QString &filePath, const QbsQmlJS::AST::SourceLocation &location); QString textOf(const QString &source, QbsQmlJS::AST::Node *node); -QStringRef textRefOf(const QString &source, QbsQmlJS::AST::Node *node); +QStringView textViewOf(const QString &source, QbsQmlJS::AST::Node *node); } // namespace Internal } // namespace qbs diff --git a/src/lib/corelib/language/item.cpp b/src/lib/corelib/language/item.cpp index a86cfeac1..fa33a264d 100644 --- a/src/lib/corelib/language/item.cpp +++ b/src/lib/corelib/language/item.cpp @@ -260,8 +260,8 @@ void Item::setupForBuiltinType(Logger &logger) sourceValue->setIsBuiltinDefaultValue(); sourceValue->setFile(file()); sourceValue->setSourceCode(pd.initialValueSource().isEmpty() - ? QStringRef(&StringConstants::undefinedValue()) - : QStringRef(&pd.initialValueSource())); + ? StringConstants::undefinedValue() + : pd.initialValueSource()); m_properties.insert(pd.name(), sourceValue); } else if (pd.isDeprecated()) { const DeprecationInfo &di = pd.deprecationInfo(); diff --git a/src/lib/corelib/language/itemreaderastvisitor.cpp b/src/lib/corelib/language/itemreaderastvisitor.cpp index 901772d16..f22a1c4e8 100644 --- a/src/lib/corelib/language/itemreaderastvisitor.cpp +++ b/src/lib/corelib/language/itemreaderastvisitor.cpp @@ -271,7 +271,7 @@ bool ItemReaderASTVisitor::handleBindingRhs(AST::Statement *statement, value->m_flags |= JSSourceValue::HasFunctionForm; value->setFile(m_file); - value->setSourceCode(textRefOf(m_file->content(), statement)); + value->setSourceCode(textViewOf(m_file->content(), statement)); value->setLocation(statement->firstSourceLocation().startLine, statement->firstSourceLocation().startColumn); diff --git a/src/lib/corelib/language/itemreadervisitorstate.cpp b/src/lib/corelib/language/itemreadervisitorstate.cpp index 1946715b8..a51b7eab4 100644 --- a/src/lib/corelib/language/itemreadervisitorstate.cpp +++ b/src/lib/corelib/language/itemreadervisitorstate.cpp @@ -99,7 +99,7 @@ private: QExplicitlySharedDataPointer<ASTCacheValueData> d; }; -class ItemReaderVisitorState::ASTCache : public QHash<QString, ASTCacheValue> {}; +class ItemReaderVisitorState::ASTCache : public std::unordered_map<QString, ASTCacheValue> {}; ItemReaderVisitorState::ItemReaderVisitorState(Logger &logger) @@ -125,7 +125,7 @@ Item *ItemReaderVisitorState::readFile(const QString &filePath, const QStringLis m_filesRead.insert(filePath); QTextStream stream(&file); - stream.setCodec("UTF-8"); + setupDefaultCodec(stream); const QString &code = stream.readAll(); QbsQmlJS::Lexer lexer(cacheValue.engine()); lexer.setCode(code, 1); diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index 5c4033c3f..f65421a35 100644 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -644,7 +644,7 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult, TopLevelProjectContext *topLevelProjectContext, Item *projectItem, const Set<QString> &referencedFilePaths) { - QScopedPointer<ProjectContext> p(new ProjectContext); + auto p = std::make_unique<ProjectContext>(); auto &projectContext = *p; projectContext.topLevelProject = topLevelProjectContext; projectContext.result = loadResult; @@ -672,8 +672,7 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult, m_disabledProjects.insert(projectContext.name); return; } - p.take(); - topLevelProjectContext->projects.push_back(&projectContext); + topLevelProjectContext->projects.push_back(p.release()); m_reader->pushExtraSearchPaths(readExtraSearchPaths(projectItem) << projectItem->file()->dirPath()); projectContext.searchPathsStack = m_reader->extraSearchPathsStack(); @@ -1339,7 +1338,7 @@ void ModuleLoader::setupProductDependencies(ProductContext *productContext, || !containsKey(m_productsWithDeferredDependsItems, productContext)) { addProductModuleDependencies(productContext); } - productContext->project->result->productInfos.insert(item, productContext->info); + productContext->project->result->productInfos[item] = productContext->info; } // Leaf modules first. @@ -1515,7 +1514,7 @@ void ModuleLoader::handleProduct(ModuleLoader::ProductContext *productContext) handleGroup(productContext, child, reverseModuleDeps); } } - productContext->project->result->productInfos.insert(item, productContext->info); + productContext->project->result->productInfos[item] = productContext->info; } static Item *rootPrototype(Item *item) @@ -1544,7 +1543,7 @@ private: void check(const QVariantMap ¶meters, const QualifiedId &moduleName) const { for (auto it = parameters.begin(); it != parameters.end(); ++it) { - if (it.value().type() == QVariant::Map) { + if (it.value().userType() == QMetaType::QVariantMap) { check(it.value().toMap(), QualifiedId(moduleName) << it.key()); } else { const auto &deps = m_productItem->modules(); @@ -1942,7 +1941,7 @@ void ModuleLoader::printProfilingInfo() static void mergeParameters(QVariantMap &dst, const QVariantMap &src) { for (auto it = src.begin(); it != src.end(); ++it) { - if (it.value().type() == QVariant::Map) { + if (it.value().userType() == QMetaType::QVariantMap) { QVariant &vdst = dst[it.key()]; QVariantMap mdst = vdst.toMap(); mergeParameters(mdst, it.value().toMap()); @@ -2370,7 +2369,7 @@ void ModuleLoader::adjustDefiningItemsInGroupModuleInstances(const Item::Module // c) The defining item is a different instance of the module, i.e. it was instantiated // in some other module. - QHash<Item *, Item *> definingItemReplacements; + std::unordered_map<Item *, Item *> definingItemReplacements; Item *modulePrototype = rootPrototype(module.item->prototype()); QBS_CHECK(modulePrototype->type() == ItemType::Module @@ -3207,30 +3206,30 @@ QStringList &ModuleLoader::getModuleFileNames(const QString &dirPath) return moduleFileNames; } -// returns QVariant::Invalid for types that do not need conversion -static QVariant::Type variantType(PropertyDeclaration::Type t) +// returns QMetaType::UnknownType for types that do not need conversion +static QMetaType::Type variantType(PropertyDeclaration::Type t) { switch (t) { case PropertyDeclaration::UnknownType: break; case PropertyDeclaration::Boolean: - return QVariant::Bool; + return QMetaType::Bool; case PropertyDeclaration::Integer: - return QVariant::Int; + return QMetaType::Int; case PropertyDeclaration::Path: - return QVariant::String; + return QMetaType::QString; case PropertyDeclaration::PathList: - return QVariant::StringList; + return QMetaType::QStringList; case PropertyDeclaration::String: - return QVariant::String; + return QMetaType::QString; case PropertyDeclaration::StringList: - return QVariant::StringList; + return QMetaType::QStringList; case PropertyDeclaration::VariantList: - return QVariant::List; + return QMetaType::QVariantList; case PropertyDeclaration::Variant: break; } - return QVariant::Invalid; + return QMetaType::UnknownType; } static QVariant convertToPropertyType(const QVariant &v, PropertyDeclaration::Type t, @@ -3238,16 +3237,16 @@ static QVariant convertToPropertyType(const QVariant &v, PropertyDeclaration::Ty { if (v.isNull() || !v.isValid()) return v; - const QVariant::Type vt = variantType(t); - if (vt == QVariant::Invalid) + const auto vt = variantType(t); + if (vt == QMetaType::UnknownType) return v; // Handle the foo,bar,bla stringlist syntax. - if (t == PropertyDeclaration::StringList && v.type() == QVariant::String) + if (t == PropertyDeclaration::StringList && v.userType() == QMetaType::QString) return v.toString().split(QLatin1Char(',')); QVariant c = v; - if (!c.convert(vt)) { + if (!qVariantConvert(c, vt)) { QStringList name = namePrefix; name << key; throw ErrorInfo(Tr::tr("Value '%1' of property '%2' has incompatible type.") @@ -3802,13 +3801,14 @@ QStringList ModuleLoader::findExistingModulePaths( QVariantMap ModuleLoader::moduleProviderConfig(ModuleLoader::ProductContext &product) { - if (product.moduleProviderConfigRetrieved) - return product.theModuleProviderConfig; + if (product.theModuleProviderConfig) + return *product.theModuleProviderConfig; + QVariantMap providerConfig; const ItemValueConstPtr configItemValue = product.item->itemProperty(StringConstants::moduleProviders()); if (configItemValue) { const std::function<void(const Item *, QualifiedId)> collectMap - = [this, &product, &collectMap](const Item *item, const QualifiedId &name) { + = [this, &providerConfig, &collectMap](const Item *item, const QualifiedId &name) { const Item::PropertyMap &props = item->properties(); for (auto it = props.begin(); it != props.end(); ++it) { QVariant value; @@ -3826,9 +3826,9 @@ QVariantMap ModuleLoader::moduleProviderConfig(ModuleLoader::ProductContext &pro value = static_cast<VariantValue *>(it.value().get())->value(); break; } - QVariantMap m = product.theModuleProviderConfig.value(name.toString()).toMap(); + QVariantMap m = providerConfig.value(name.toString()).toMap(); m.insert(it.key(), value); - product.theModuleProviderConfig.insert(name.toString(), m); + providerConfig.insert(name.toString(), m); } }; configItemValue->item()->setScope(product.item); @@ -3841,15 +3841,14 @@ QVariantMap ModuleLoader::moduleProviderConfig(ModuleLoader::ProductContext &pro const QVariantMap providerConfigFromBuildConfig = it.value().toMap(); if (providerConfigFromBuildConfig.empty()) continue; - QVariantMap currentMapForProvider = product.theModuleProviderConfig.value(provider).toMap(); + QVariantMap currentMapForProvider = providerConfig.value(provider).toMap(); for (auto propIt = providerConfigFromBuildConfig.begin(); propIt != providerConfigFromBuildConfig.end(); ++propIt) { currentMapForProvider.insert(propIt.key(), propIt.value()); } - product.theModuleProviderConfig.insert(provider, currentMapForProvider); + providerConfig.insert(provider, currentMapForProvider); } - product.moduleProviderConfigRetrieved = true; - return product.theModuleProviderConfig; + return *(product.theModuleProviderConfig = std::move(providerConfig)); } ModuleLoader::ModuleProviderResult ModuleLoader::findModuleProvider(const QualifiedId &name, @@ -3887,7 +3886,7 @@ ModuleLoader::ModuleProviderResult ModuleLoader::findModuleProvider(const Qualif const QVariant moduleConfig = moduleProviderConfig(product).value(name.toString()); QTextStream stream(&dummyItemFile); using Qt::endl; - stream.setCodec("UTF-8"); + setupDefaultCodec(stream); stream << "import qbs.FileInfo" << endl; stream << "import qbs.Utilities" << endl; stream << "import '" << providerFile << "' as Provider" << endl; @@ -4166,8 +4165,7 @@ void ModuleLoader::handleProductError(const ErrorInfo &error, 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); + productContext->project->result->productInfos[productContext->item] = productContext->info; m_disabledItems << productContext->item; m_erroneousProducts.insert(productContext->name); } diff --git a/src/lib/corelib/language/moduleloader.h b/src/lib/corelib/language/moduleloader.h index df853e77f..3dc091003 100644 --- a/src/lib/corelib/language/moduleloader.h +++ b/src/lib/corelib/language/moduleloader.h @@ -106,7 +106,7 @@ struct ModuleLoaderResult std::shared_ptr<ItemPool> itemPool; Item *root; - QHash<Item *, ProductInfo> productInfos; + std::unordered_map<Item *, ProductInfo> productInfos; std::vector<ProbeConstPtr> projectProbes; ModuleProviderInfoList moduleProviderInfo; Set<QString> qbsFiles; @@ -187,8 +187,7 @@ private: std::vector<QStringList> newlyAddedModuleProviderSearchPaths; Set<QualifiedId> knownModuleProviders; - QVariantMap theModuleProviderConfig; - bool moduleProviderConfigRetrieved = false; + std::optional<QVariantMap> theModuleProviderConfig; // The key corresponds to DeferredDependsContext.exportingProductItem, which is the // only value from that data structure that we still need here. diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp index 570b3513f..4ae5f3ca7 100644 --- a/src/lib/corelib/language/projectresolver.cpp +++ b/src/lib/corelib/language/projectresolver.cpp @@ -655,8 +655,8 @@ QVariantMap ProjectResolver::resolveAdditionalModuleProperties(const Item *group const QVariantMap ¤tValues) { // Step 1: Retrieve the properties directly set in the group - const ModulePropertiesPerGroup &mp = m_loadResult.productInfos.value(m_productContext->item) - .modulePropertiesSetInGroups; + const ModulePropertiesPerGroup &mp = mapValue( + m_loadResult.productInfos, m_productContext->item).modulePropertiesSetInGroups; const auto it = mp.find(group); if (it == mp.end()) return {}; @@ -900,7 +900,7 @@ void ProjectResolver::adaptExportedPropertyValues(const Item *shadowProductItem) const std::function<QVariant(const QVariantMap &, const QVariant &)> mapper = [&stringListMapper, &mapper]( const QVariantMap &mappings, const QVariant &value) -> QVariant { - switch (static_cast<QMetaType::Type>(value.type())) { + switch (static_cast<QMetaType::Type>(value.userType())) { case QMetaType::QString: return stringMapper(mappings, value.toString()); case QMetaType::QStringList: @@ -945,7 +945,7 @@ void ProjectResolver::collectExportedProductDependencies() } } const ModuleLoaderResult::ProductInfo &importingProductInfo - = m_loadResult.productInfos.value(importingProductItem); + = mapValue(m_loadResult.productInfos, importingProductItem); const ProductDependencyInfos &depInfos = getProductDependencies(dummyProduct, importingProductInfo); for (const auto &dep : depInfos.dependencies) { @@ -1610,7 +1610,7 @@ void ProjectResolver::resolveProductDependencies(const ProjectContext &projectCo continue; Item *productItem = m_productItemMap.value(rproduct); const ModuleLoaderResult::ProductInfo &productInfo - = m_loadResult.productInfos.value(productItem); + = mapValue(m_loadResult.productInfos, productItem); const ProductDependencyInfos &depInfos = getProductDependencies(rproduct, productInfo); if (depInfos.hasDisabledDependency) disabledDependency = true; diff --git a/src/lib/corelib/language/projectresolver.h b/src/lib/corelib/language/projectresolver.h index 73f3442ac..52d835535 100644 --- a/src/lib/corelib/language/projectresolver.h +++ b/src/lib/corelib/language/projectresolver.h @@ -186,8 +186,8 @@ private: QHash<ResolvedProductPtr, Item *> m_productItemMap; mutable QHash<FileContextConstPtr, ResolvedFileContextPtr> m_fileContextMap; mutable QHash<CodeLocation, ScriptFunctionPtr> m_scriptFunctionMap; - mutable QHash<std::pair<QStringRef, QStringList>, QString> m_scriptFunctions; - mutable QHash<QStringRef, QString> m_sourceCode; + mutable QHash<std::pair<QStringView, QStringList>, QString> m_scriptFunctions; + mutable QHash<QStringView, QString> m_sourceCode; const SetupProjectParameters m_setupParams; ModuleLoaderResult m_loadResult; Set<CodeLocation> m_groupLocationWarnings; diff --git a/src/lib/corelib/language/propertydeclaration.h b/src/lib/corelib/language/propertydeclaration.h index 5ced7eccb..77b6837f5 100644 --- a/src/lib/corelib/language/propertydeclaration.h +++ b/src/lib/corelib/language/propertydeclaration.h @@ -43,10 +43,6 @@ #include <QtCore/qshareddata.h> #include <QtCore/qstring.h> -QT_BEGIN_NAMESPACE -class QStringList; -QT_END_NAMESPACE - namespace qbs { namespace Internal { class DeprecationInfo; diff --git a/src/lib/corelib/language/scriptengine.cpp b/src/lib/corelib/language/scriptengine.cpp index e79ec54d7..8b3d6fa76 100644 --- a/src/lib/corelib/language/scriptengine.cpp +++ b/src/lib/corelib/language/scriptengine.cpp @@ -381,7 +381,7 @@ void ScriptEngine::importFile(const QString &filePath, QScriptValue &targetObjec if (Q_UNLIKELY(!file.open(QFile::ReadOnly))) throw ErrorInfo(tr("Cannot open '%1'.").arg(filePath)); QTextStream stream(&file); - stream.setCodec("UTF-8"); + setupDefaultCodec(stream); const QString sourceCode = stream.readAll(); file.close(); m_currentDirPathStack.push(FileInfo::path(filePath)); diff --git a/src/lib/corelib/language/scriptimporter.cpp b/src/lib/corelib/language/scriptimporter.cpp index 9c6d4d38e..40162eb12 100644 --- a/src/lib/corelib/language/scriptimporter.cpp +++ b/src/lib/corelib/language/scriptimporter.cpp @@ -95,7 +95,7 @@ private: return false; } - void add(const QStringRef &name) + void add(QStringView name) { if (m_first) { m_first = false; @@ -104,9 +104,10 @@ private: m_suffix.reserve(m_suffix.length() + name.length() * 2 + 2); m_suffix += QLatin1Char(','); } - m_suffix += name; - m_suffix += QLatin1Char(':'); - m_suffix += name; + // ugly, but qt5 does not have append overload for QStringView + m_suffix.append(name.data(), name.size()); + m_suffix.append(QLatin1Char(':')); + m_suffix.append(name.data(), name.size()); } bool m_first = false; diff --git a/src/lib/corelib/language/value.cpp b/src/lib/corelib/language/value.cpp index b3e782519..16326f521 100644 --- a/src/lib/corelib/language/value.cpp +++ b/src/lib/corelib/language/value.cpp @@ -189,7 +189,7 @@ VariantValuePtr VariantValue::create(const QVariant &v) { if (!v.isValid()) return invalidValue(); - if (static_cast<QMetaType::Type>(v.type()) == QMetaType::Bool) + if (static_cast<QMetaType::Type>(v.userType()) == QMetaType::Bool) return v.toBool() ? VariantValue::trueValue() : VariantValue::falseValue(); return std::make_shared<VariantValue>(v); } diff --git a/src/lib/corelib/language/value.h b/src/lib/corelib/language/value.h index 287060809..5f6b5ca16 100644 --- a/src/lib/corelib/language/value.h +++ b/src/lib/corelib/language/value.h @@ -121,8 +121,8 @@ public: void apply(ValueHandler *handler) override { handler->handle(this); } ValuePtr clone() const override; - void setSourceCode(const QStringRef &sourceCode) { m_sourceCode = sourceCode; } - const QStringRef &sourceCode() const { return m_sourceCode; } + void setSourceCode(QStringView sourceCode) { m_sourceCode = sourceCode; } + QStringView sourceCode() const { return m_sourceCode; } QString sourceCodeForEvaluation() const; void setLocation(int line, int column); @@ -179,7 +179,7 @@ public: void setDefiningItem(Item *item) override; private: - QStringRef m_sourceCode; + QStringView m_sourceCode; int m_line; int m_column; FileContextPtr m_file; diff --git a/src/lib/corelib/logging/logger.cpp b/src/lib/corelib/logging/logger.cpp index 2ed29c4c2..d4020892f 100644 --- a/src/lib/corelib/logging/logger.cpp +++ b/src/lib/corelib/logging/logger.cpp @@ -163,7 +163,7 @@ LogWriter operator<<(LogWriter w, const Internal::Set<QString> &strSet) LogWriter operator<<(LogWriter w, const QVariant &variant) { QString str = QLatin1String(variant.typeName()) + QLatin1Char('('); - if (variant.type() == QVariant::List) { + if (variant.userType() == QMetaType::QVariantList) { bool firstLoop = true; const auto list = variant.toList(); for (const QVariant &item : list) { diff --git a/src/lib/corelib/parser/qmlerror.cpp b/src/lib/corelib/parser/qmlerror.cpp index d638b7202..8a8118290 100644 --- a/src/lib/corelib/parser/qmlerror.cpp +++ b/src/lib/corelib/parser/qmlerror.cpp @@ -39,6 +39,8 @@ #include "qmlerror.h" +#include <tools/qttools.h> + #include <QtCore/qdebug.h> #include <QtCore/qfile.h> #include <QtCore/qstringlist.h> @@ -259,9 +261,7 @@ QDebug operator<<(QDebug debug, const QmlError &error) if (f.open(QIODevice::ReadOnly)) { QByteArray data = f.readAll(); QTextStream stream(data, QIODevice::ReadOnly); -#ifndef QT_NO_TEXTCODEC - stream.setCodec("UTF-8"); -#endif + qbs::setupDefaultCodec(stream); const QString code = stream.readAll(); const QStringList lines = code.split(QLatin1Char('\n')); diff --git a/src/lib/corelib/parser/qmljs.g b/src/lib/corelib/parser/qmljs.g index 956c65809..b9d533ada 100644 --- a/src/lib/corelib/parser/qmljs.g +++ b/src/lib/corelib/parser/qmljs.g @@ -189,6 +189,23 @@ ** ****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +// +// This file is automatically generated from qmljs.g. +// Changes will be lost. +// + #ifndef QMLJSPARSER_P_H #define QMLJSPARSER_P_H @@ -196,17 +213,16 @@ #include "qmljsgrammar_p.h" #include "qmljsast_p.h" #include "qmljsengine_p.h" +#include <tools/qbs_export.h> #include <QtCore/qlist.h> #include <QtCore/qstring.h> -QT_QML_BEGIN_NAMESPACE - -namespace QmlJS { +namespace QbsQmlJS { class Engine; -class QML_PARSER_EXPORT Parser: protected $table +class QBS_AUTOTEST_EXPORT Parser: protected $table { public: union Value { @@ -270,7 +286,7 @@ public: AST::Statement *statement() const { if (! program) - return 0; + return nullptr; return program->statementCast(); } @@ -278,7 +294,7 @@ public: AST::ExpressionNode *expression() const { if (! program) - return 0; + return nullptr; return program->expressionCast(); } @@ -286,7 +302,7 @@ public: AST::UiObjectMember *uiObjectMember() const { if (! program) - return 0; + return nullptr; return program->uiObjectMemberCast(); } @@ -348,13 +364,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; @@ -366,7 +382,7 @@ protected: QList<DiagnosticMessage> diagnostic_messages; }; -} // end of namespace QmlJS +} // end of namespace QbsQmlJS :/ @@ -458,7 +474,7 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr) return currentId->finish(); } - return 0; + return nullptr; } bool Parser::parse(int startToken) @@ -3003,9 +3019,5 @@ QT_QML_END_NAMESPACE ./ /: -QT_QML_END_NAMESPACE - - - #endif // QMLJSPARSER_P_H :/ diff --git a/src/lib/corelib/parser/qmljsast_p.h b/src/lib/corelib/parser/qmljsast_p.h index dcee233da..e2ba68508 100644 --- a/src/lib/corelib/parser/qmljsast_p.h +++ b/src/lib/corelib/parser/qmljsast_p.h @@ -57,6 +57,10 @@ #include <QtCore/qstring.h> +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#include <QtCore5Compat/qstringref.h> +#endif + namespace QbsQmlJS { #define QMLJS_DECLARE_AST_NODE(name) \ diff --git a/src/lib/corelib/parser/qmljsengine_p.cpp b/src/lib/corelib/parser/qmljsengine_p.cpp index 92ac6452a..11bf8a3f3 100644 --- a/src/lib/corelib/parser/qmljsengine_p.cpp +++ b/src/lib/corelib/parser/qmljsengine_p.cpp @@ -149,7 +149,7 @@ QStringRef Engine::newStringRef(const QString &text) { const int pos = _extraCode.length(); _extraCode += text; - return _extraCode.midRef(pos, text.length()); + return QStringRef(&_extraCode).mid(pos, text.length()); } QStringRef Engine::newStringRef(const QChar *chars, int size) diff --git a/src/lib/corelib/parser/qmljsengine_p.h b/src/lib/corelib/parser/qmljsengine_p.h index c55d525f8..2a616126d 100644 --- a/src/lib/corelib/parser/qmljsengine_p.h +++ b/src/lib/corelib/parser/qmljsengine_p.h @@ -58,6 +58,10 @@ #include <QtCore/qstring.h> +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#include <QtCore5Compat/qstringref.h> +#endif + #include <set> #include <utility> @@ -115,7 +119,10 @@ public: MemoryPool *pool(); - inline QStringRef midRef(int position, int size) { return _code.midRef(position, size); } + inline QStringRef midRef(int position, int size) + { + return QStringRef(&_code).mid(position, size); + } QStringRef newStringRef(const QString &s); QStringRef newStringRef(const QChar *chars, int size); diff --git a/src/lib/corelib/parser/qmljsgrammar.cpp b/src/lib/corelib/parser/qmljsgrammar.cpp index 07a193f6f..75b4a488a 100644 --- a/src/lib/corelib/parser/qmljsgrammar.cpp +++ b/src/lib/corelib/parser/qmljsgrammar.cpp @@ -43,969 +43,975 @@ namespace QbsQmlJS { const char *const QmlJSGrammar::spell [] = { - "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ",", "continue", - "default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===", - "finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier", - "if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=", - "-", "-=", "--", "new", "!", "!=", "!==", "numeric literal", "|", "|=", - "||", "+", "+=", "++", "?", "}", "]", "%", "%=", "return", - ")", ";", 0, "*", "*=", "string literal", "property", "signal", "readonly", "switch", - "this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^", - "^=", "null", "true", "false", "const", "debugger", "reserved word", "multiline string literal", "comment", "public", - "import", "as", "on", 0, 0, 0, 0, 0, 0, 0, - 0, 0}; + "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ",", "continue", + "default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===", + "finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier", + "if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=", + "-", "-=", "--", "new", "!", "!=", "!==", "numeric literal", "|", "|=", + "||", "+", "+=", "++", "?", "}", "]", "%", "%=", "return", + ")", ";", 0, "*", "*=", "string literal", "property", "signal", "readonly", "switch", + "this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^", + "^=", "null", "true", "false", "const", "debugger", "reserved word", "multiline string literal", "comment", "public", + "import", "as", "on", 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; const short QmlJSGrammar::lhs [] = { - 102, 102, 102, 102, 102, 102, 103, 109, 109, 112, - 112, 114, 113, 113, 113, 113, 113, 113, 113, 113, - 116, 111, 110, 119, 119, 120, 120, 121, 121, 118, - 107, 107, 107, 107, 123, 123, 123, 123, 123, 123, - 123, 107, 131, 131, 131, 132, 132, 133, 133, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 117, 117, 117, 117, - 117, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 122, - 138, 138, 138, 138, 137, 137, 140, 140, 142, 142, - 142, 142, 142, 142, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 144, 144, 115, 115, 115, - 115, 115, 147, 147, 148, 148, 148, 148, 146, 146, - 149, 149, 150, 150, 151, 151, 151, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 153, 153, 153, - 153, 154, 154, 154, 155, 155, 155, 155, 156, 156, - 156, 156, 156, 156, 156, 157, 157, 157, 157, 157, - 157, 158, 158, 158, 158, 158, 159, 159, 159, 159, - 159, 160, 160, 161, 161, 162, 162, 163, 163, 164, - 164, 165, 165, 166, 166, 167, 167, 168, 168, 169, - 169, 170, 170, 171, 171, 141, 141, 172, 172, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 105, 105, 174, 174, 175, 175, 176, 176, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 124, 185, 185, 184, 184, 135, - 135, 186, 186, 187, 187, 189, 189, 188, 190, 193, - 191, 191, 194, 192, 192, 125, 126, 126, 127, 127, - 177, 177, 177, 177, 177, 177, 177, 178, 178, 178, - 178, 179, 179, 179, 179, 180, 180, 128, 129, 195, - 195, 198, 198, 196, 196, 199, 197, 181, 181, 181, - 182, 182, 130, 130, 130, 200, 201, 183, 183, 134, - 145, 205, 205, 202, 202, 203, 203, 206, 108, 108, - 207, 207, 106, 106, 204, 204, 139, 139, 208}; + 102, 102, 102, 102, 102, 102, 103, 109, 109, 112, + 112, 114, 113, 113, 113, 113, 113, 113, 113, 113, + 116, 111, 110, 119, 119, 120, 120, 121, 121, 118, + 107, 107, 107, 107, 123, 123, 123, 123, 123, 123, + 123, 107, 131, 131, 131, 132, 132, 133, 133, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 117, 117, 117, 117, + 117, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 122, + 138, 138, 138, 138, 137, 137, 140, 140, 142, 142, + 142, 142, 142, 142, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 144, 144, 115, 115, 115, + 115, 115, 147, 147, 148, 148, 148, 148, 146, 146, + 149, 149, 150, 150, 151, 151, 151, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 153, 153, 153, + 153, 154, 154, 154, 155, 155, 155, 155, 156, 156, + 156, 156, 156, 156, 156, 157, 157, 157, 157, 157, + 157, 158, 158, 158, 158, 158, 159, 159, 159, 159, + 159, 160, 160, 161, 161, 162, 162, 163, 163, 164, + 164, 165, 165, 166, 166, 167, 167, 168, 168, 169, + 169, 170, 170, 171, 171, 141, 141, 172, 172, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 105, 105, 174, 174, 175, 175, 176, 176, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 124, 185, 185, 184, 184, 135, + 135, 186, 186, 187, 187, 189, 189, 188, 190, 193, + 191, 191, 194, 192, 192, 125, 126, 126, 127, 127, + 177, 177, 177, 177, 177, 177, 177, 178, 178, 178, + 178, 179, 179, 179, 179, 180, 180, 128, 129, 195, + 195, 198, 198, 196, 196, 199, 197, 181, 181, 181, + 182, 182, 130, 130, 130, 200, 201, 183, 183, 134, + 145, 205, 205, 202, 202, 203, 203, 206, 108, 108, + 207, 207, 106, 106, 204, 204, 139, 139, 208 +}; const short QmlJSGrammar::rhs [] = { - 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, - 2, 1, 2, 2, 3, 3, 5, 5, 4, 4, - 2, 0, 1, 1, 2, 1, 3, 2, 3, 2, - 1, 5, 4, 4, 1, 1, 1, 1, 1, 1, - 1, 3, 1, 1, 1, 0, 1, 2, 4, 6, - 6, 3, 3, 7, 7, 4, 4, 5, 5, 5, - 6, 6, 10, 6, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 3, 3, 4, 5, 3, 4, 3, 1, - 1, 2, 3, 4, 1, 2, 3, 5, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, - 3, 5, 1, 2, 4, 4, 4, 3, 0, 1, - 1, 3, 1, 1, 1, 2, 2, 1, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 1, 3, 3, - 3, 1, 3, 3, 1, 3, 3, 3, 1, 3, - 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, - 3, 1, 3, 3, 3, 3, 1, 3, 3, 3, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 5, 1, 5, 1, 3, 1, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 0, 1, 1, 3, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 2, 0, 1, 3, - 3, 1, 1, 1, 3, 1, 3, 2, 2, 2, - 0, 1, 2, 0, 1, 1, 2, 2, 7, 5, - 7, 7, 5, 9, 10, 7, 8, 2, 2, 3, - 3, 2, 2, 3, 3, 3, 3, 5, 5, 3, - 5, 1, 2, 0, 1, 4, 3, 3, 3, 3, - 3, 3, 3, 3, 4, 5, 2, 2, 2, 8, - 8, 1, 3, 0, 1, 0, 1, 1, 1, 1, - 1, 2, 1, 1, 0, 1, 0, 1, 2}; + 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, + 2, 1, 2, 2, 3, 3, 5, 5, 4, 4, + 2, 0, 1, 1, 2, 1, 3, 2, 3, 2, + 1, 5, 4, 4, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 1, 1, 0, 1, 2, 4, 6, + 6, 3, 3, 7, 7, 4, 4, 5, 5, 5, + 6, 6, 10, 6, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 3, 3, 4, 5, 3, 4, 3, 1, + 1, 2, 3, 4, 1, 2, 3, 5, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, + 3, 5, 1, 2, 4, 4, 4, 3, 0, 1, + 1, 3, 1, 1, 1, 2, 2, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 1, 3, 3, + 3, 1, 3, 3, 1, 3, 3, 3, 1, 3, + 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, + 3, 1, 3, 3, 3, 3, 1, 3, 3, 3, + 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, + 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, + 3, 1, 5, 1, 5, 1, 3, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 0, 1, 1, 3, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 1, 2, 0, 1, 3, + 3, 1, 1, 1, 3, 1, 3, 2, 2, 2, + 0, 1, 2, 0, 1, 1, 2, 2, 7, 5, + 7, 7, 5, 9, 10, 7, 8, 2, 2, 3, + 3, 2, 2, 3, 3, 3, 3, 5, 5, 3, + 5, 1, 2, 0, 1, 4, 3, 3, 3, 3, + 3, 3, 3, 3, 4, 5, 2, 2, 2, 8, + 8, 1, 3, 0, 1, 0, 1, 1, 1, 1, + 1, 2, 1, 1, 0, 1, 0, 1, 2 +}; const short QmlJSGrammar::action_default [] = { - 0, 0, 22, 0, 0, 0, 22, 0, 175, 242, - 206, 214, 210, 154, 226, 202, 3, 139, 73, 155, - 218, 222, 143, 172, 153, 158, 138, 192, 179, 0, - 80, 81, 76, 345, 67, 347, 0, 0, 0, 0, - 78, 0, 0, 74, 77, 71, 0, 0, 68, 70, - 69, 79, 72, 0, 75, 0, 0, 168, 0, 0, - 155, 174, 157, 156, 0, 0, 0, 170, 171, 169, - 173, 0, 203, 0, 0, 0, 0, 193, 0, 0, - 0, 0, 0, 0, 183, 0, 0, 0, 177, 178, - 176, 181, 185, 184, 182, 180, 195, 194, 196, 0, - 211, 0, 207, 0, 0, 149, 136, 148, 137, 105, - 106, 107, 132, 108, 133, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 134, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 135, - 0, 0, 147, 243, 150, 0, 151, 0, 152, 146, - 0, 239, 232, 230, 237, 238, 236, 235, 241, 234, - 233, 231, 240, 227, 0, 215, 0, 0, 219, 0, - 0, 223, 0, 0, 149, 141, 0, 140, 0, 145, - 159, 0, 346, 334, 335, 0, 332, 0, 333, 0, - 336, 250, 257, 256, 264, 252, 0, 253, 337, 0, - 344, 254, 255, 260, 258, 341, 338, 343, 261, 0, - 272, 0, 0, 0, 0, 345, 67, 0, 347, 68, - 244, 286, 69, 0, 0, 0, 273, 0, 0, 262, - 263, 0, 251, 259, 287, 288, 331, 342, 0, 302, - 303, 304, 305, 0, 298, 299, 300, 301, 328, 329, - 0, 0, 0, 0, 0, 291, 292, 248, 246, 208, - 216, 212, 228, 204, 249, 0, 155, 220, 224, 197, - 186, 0, 0, 205, 0, 0, 0, 0, 198, 0, - 0, 0, 0, 0, 190, 188, 191, 189, 187, 200, - 199, 201, 0, 213, 0, 209, 0, 247, 155, 0, - 229, 244, 245, 0, 244, 0, 0, 294, 0, 0, - 0, 296, 0, 217, 0, 0, 221, 0, 0, 225, - 284, 0, 276, 285, 279, 0, 283, 0, 244, 277, - 0, 244, 0, 0, 295, 0, 0, 0, 297, 346, - 334, 0, 0, 336, 0, 330, 0, 320, 0, 0, - 0, 290, 0, 289, 0, 348, 0, 104, 266, 269, - 0, 105, 272, 108, 133, 110, 111, 76, 115, 116, - 67, 117, 120, 74, 77, 68, 244, 69, 79, 123, - 72, 125, 75, 127, 128, 273, 130, 131, 135, 0, - 97, 0, 0, 99, 103, 101, 88, 100, 102, 0, - 98, 87, 267, 265, 143, 144, 149, 0, 142, 0, - 319, 0, 306, 307, 0, 318, 0, 0, 0, 309, - 314, 312, 315, 0, 0, 313, 314, 0, 310, 0, - 311, 268, 317, 0, 268, 316, 0, 321, 322, 0, - 268, 323, 324, 0, 0, 325, 0, 0, 0, 326, - 327, 161, 160, 0, 0, 0, 293, 0, 0, 0, - 308, 281, 274, 0, 282, 278, 0, 280, 270, 0, - 271, 275, 91, 0, 0, 95, 82, 0, 84, 93, - 0, 85, 94, 96, 86, 92, 83, 0, 89, 165, - 163, 167, 164, 162, 166, 339, 6, 340, 4, 2, - 65, 90, 0, 0, 68, 70, 69, 31, 5, 0, - 66, 0, 45, 44, 43, 0, 0, 58, 0, 59, - 35, 36, 37, 38, 40, 41, 62, 39, 0, 45, - 0, 0, 0, 0, 0, 54, 0, 55, 0, 0, - 26, 0, 0, 63, 27, 0, 30, 28, 24, 0, - 29, 25, 0, 56, 0, 57, 143, 0, 60, 64, - 0, 0, 0, 0, 61, 0, 52, 46, 53, 47, - 0, 0, 0, 0, 49, 0, 50, 51, 48, 0, - 0, 143, 268, 0, 0, 42, 105, 272, 108, 133, - 110, 111, 76, 115, 116, 67, 117, 120, 74, 77, - 68, 244, 69, 79, 123, 72, 125, 75, 127, 128, - 273, 130, 131, 135, 0, 32, 33, 0, 34, 8, - 0, 10, 0, 9, 0, 1, 21, 12, 0, 13, - 0, 14, 0, 19, 20, 0, 15, 16, 0, 17, - 18, 11, 23, 7, 349}; + 0, 0, 22, 0, 0, 0, 22, 0, 175, 242, + 206, 214, 210, 154, 226, 202, 3, 139, 73, 155, + 218, 222, 143, 172, 153, 158, 138, 192, 179, 0, + 80, 81, 76, 345, 67, 347, 0, 0, 0, 0, + 78, 0, 0, 74, 77, 71, 0, 0, 68, 70, + 69, 79, 72, 0, 75, 0, 0, 168, 0, 0, + 155, 174, 157, 156, 0, 0, 0, 170, 171, 169, + 173, 0, 203, 0, 0, 0, 0, 193, 0, 0, + 0, 0, 0, 0, 183, 0, 0, 0, 177, 178, + 176, 181, 185, 184, 182, 180, 195, 194, 196, 0, + 211, 0, 207, 0, 0, 149, 136, 148, 137, 105, + 106, 107, 132, 108, 133, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 134, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 135, + 0, 0, 147, 243, 150, 0, 151, 0, 152, 146, + 0, 239, 232, 230, 237, 238, 236, 235, 241, 234, + 233, 231, 240, 227, 0, 215, 0, 0, 219, 0, + 0, 223, 0, 0, 149, 141, 0, 140, 0, 145, + 159, 0, 346, 334, 335, 0, 332, 0, 333, 0, + 336, 250, 257, 256, 264, 252, 0, 253, 337, 0, + 344, 254, 255, 260, 258, 341, 338, 343, 261, 0, + 272, 0, 0, 0, 0, 345, 67, 0, 347, 68, + 244, 286, 69, 0, 0, 0, 273, 0, 0, 262, + 263, 0, 251, 259, 287, 288, 331, 342, 0, 302, + 303, 304, 305, 0, 298, 299, 300, 301, 328, 329, + 0, 0, 0, 0, 0, 291, 292, 248, 246, 208, + 216, 212, 228, 204, 249, 0, 155, 220, 224, 197, + 186, 0, 0, 205, 0, 0, 0, 0, 198, 0, + 0, 0, 0, 0, 190, 188, 191, 189, 187, 200, + 199, 201, 0, 213, 0, 209, 0, 247, 155, 0, + 229, 244, 245, 0, 244, 0, 0, 294, 0, 0, + 0, 296, 0, 217, 0, 0, 221, 0, 0, 225, + 284, 0, 276, 285, 279, 0, 283, 0, 244, 277, + 0, 244, 0, 0, 295, 0, 0, 0, 297, 346, + 334, 0, 0, 336, 0, 330, 0, 320, 0, 0, + 0, 290, 0, 289, 0, 348, 0, 104, 266, 269, + 0, 105, 272, 108, 133, 110, 111, 76, 115, 116, + 67, 117, 120, 74, 77, 68, 244, 69, 79, 123, + 72, 125, 75, 127, 128, 273, 130, 131, 135, 0, + 97, 0, 0, 99, 103, 101, 88, 100, 102, 0, + 98, 87, 267, 265, 143, 144, 149, 0, 142, 0, + 319, 0, 306, 307, 0, 318, 0, 0, 0, 309, + 314, 312, 315, 0, 0, 313, 314, 0, 310, 0, + 311, 268, 317, 0, 268, 316, 0, 321, 322, 0, + 268, 323, 324, 0, 0, 325, 0, 0, 0, 326, + 327, 161, 160, 0, 0, 0, 293, 0, 0, 0, + 308, 281, 274, 0, 282, 278, 0, 280, 270, 0, + 271, 275, 91, 0, 0, 95, 82, 0, 84, 93, + 0, 85, 94, 96, 86, 92, 83, 0, 89, 165, + 163, 167, 164, 162, 166, 339, 6, 340, 4, 2, + 65, 90, 0, 0, 68, 70, 69, 31, 5, 0, + 66, 0, 45, 44, 43, 0, 0, 58, 0, 59, + 35, 36, 37, 38, 40, 41, 62, 39, 0, 45, + 0, 0, 0, 0, 0, 54, 0, 55, 0, 0, + 26, 0, 0, 63, 27, 0, 30, 28, 24, 0, + 29, 25, 0, 56, 0, 57, 143, 0, 60, 64, + 0, 0, 0, 0, 61, 0, 52, 46, 53, 47, + 0, 0, 0, 0, 49, 0, 50, 51, 48, 0, + 0, 143, 268, 0, 0, 42, 105, 272, 108, 133, + 110, 111, 76, 115, 116, 67, 117, 120, 74, 77, + 68, 244, 69, 79, 123, 72, 125, 75, 127, 128, + 273, 130, 131, 135, 0, 32, 33, 0, 34, 8, + 0, 10, 0, 9, 0, 1, 21, 12, 0, 13, + 0, 14, 0, 19, 20, 0, 15, 16, 0, 17, + 18, 11, 23, 7, 349 +}; const short QmlJSGrammar::goto_default [] = { - 7, 625, 207, 196, 205, 508, 496, 624, 643, 495, - 623, 621, 626, 22, 622, 18, 507, 549, 539, 546, - 541, 526, 191, 195, 197, 201, 233, 208, 230, 530, - 570, 569, 200, 232, 26, 474, 473, 356, 355, 9, - 354, 357, 107, 17, 145, 24, 13, 144, 19, 25, - 57, 23, 8, 28, 27, 269, 15, 263, 10, 259, - 12, 261, 11, 260, 20, 267, 21, 268, 14, 262, - 258, 299, 411, 264, 265, 202, 193, 192, 204, 203, - 229, 194, 360, 359, 231, 463, 462, 321, 322, 465, - 324, 464, 323, 419, 423, 426, 422, 421, 441, 442, - 185, 199, 181, 184, 198, 206, 0}; + 7, 625, 207, 196, 205, 508, 496, 624, 643, 495, + 623, 621, 626, 22, 622, 18, 507, 549, 539, 546, + 541, 526, 191, 195, 197, 201, 233, 208, 230, 530, + 570, 569, 200, 232, 26, 474, 473, 356, 355, 9, + 354, 357, 107, 17, 145, 24, 13, 144, 19, 25, + 57, 23, 8, 28, 27, 269, 15, 263, 10, 259, + 12, 261, 11, 260, 20, 267, 21, 268, 14, 262, + 258, 299, 411, 264, 265, 202, 193, 192, 204, 203, + 229, 194, 360, 359, 231, 463, 462, 321, 322, 465, + 324, 464, 323, 419, 423, 426, 422, 421, 441, 442, + 185, 199, 181, 184, 198, 206, 0 +}; const short QmlJSGrammar::action_index [] = { - 404, 1275, 2411, 2411, 2509, 1000, 68, 92, 90, -102, - 88, 62, 60, 256, -102, 298, 86, -102, -102, 638, - 83, 134, 172, 219, -102, -102, -102, 454, 194, 1275, - -102, -102, -102, 381, -102, 2215, 1555, 1275, 1275, 1275, - -102, 790, 1275, -102, -102, -102, 1275, 1275, -102, -102, - -102, -102, -102, 1275, -102, 1275, 1275, -102, 1275, 1275, - 102, 217, -102, -102, 1275, 1275, 1275, -102, -102, -102, - 204, 1275, 304, 1275, 1275, 1275, 1275, 539, 1275, 1275, - 1275, 1275, 1275, 1275, 308, 1275, 1275, 1275, 103, 131, - 135, 308, 210, 225, 216, 308, 444, 390, 434, 1275, - 82, 1275, 100, 2117, 1275, 1275, -102, -102, -102, -102, - -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, - -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, - -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, - 139, 1275, -102, -102, 91, 10, -102, 1275, -102, -102, - 1275, -102, -102, -102, -102, -102, -102, -102, -102, -102, - -102, -102, -102, -102, 1275, 26, 1275, 1275, 69, 66, - 1275, -102, 2117, 1275, 1275, -102, 97, -102, 44, -102, - -102, 67, -102, 297, 78, 24, -102, 291, -102, 36, - 2411, -102, -102, -102, -102, -102, 234, -102, -102, 12, - -102, -102, -102, -102, -102, -102, 2411, -102, -102, 464, - -102, 461, 115, 2509, 42, 381, 58, 46, 2705, 70, - 1275, -102, 74, 57, 1275, 65, -102, 59, 61, -102, - -102, 367, -102, -102, -102, -102, -102, -102, 106, -102, - -102, -102, -102, 87, -102, -102, -102, -102, -102, -102, - 56, 55, 1275, 99, 84, -102, -102, 1461, -102, 75, - 48, 52, -102, 306, 72, 53, 579, 77, 110, 370, - 230, 381, 1275, 286, 1275, 1275, 1275, 1275, 380, 1275, - 1275, 1275, 1275, 1275, 184, 169, 166, 190, 198, 460, - 363, 353, 1275, 50, 1275, 63, 1275, -102, 638, 1275, - -102, 1275, 64, 39, 1275, 30, 2509, -102, 1275, 173, - 2509, -102, 1275, 79, 1275, 1275, 81, 80, 1275, -102, - 71, 149, 32, -102, -102, 1275, -102, 381, 1275, -102, - 73, 1275, 76, 2509, -102, 1275, 142, 2509, -102, -16, - 381, -42, -12, 2411, -39, -102, 2509, -102, 1275, 154, - 2509, 14, 2509, -102, 20, 16, -32, -102, -102, 2509, - -51, 519, -4, 511, 136, 1275, 2509, -2, -35, 395, - -1, -27, 908, 4, 6, -102, 1370, -102, 0, -36, - 27, 1275, 47, 22, 1275, 45, 1275, 21, 17, 1275, - -102, 2313, 144, -102, -102, -102, -102, -102, -102, 1275, - -102, -102, -102, -102, 274, -102, 1275, -21, -102, 2509, - -102, 138, -102, -102, 2509, -102, 1275, 132, 5, -102, - 40, -102, 41, 101, 1275, -102, 38, 34, -102, -38, - -102, 2509, -102, 105, 2509, -102, 245, -102, -102, 96, - 2509, 11, -102, -7, -11, -102, 352, 8, 18, -102, - -102, -102, -102, 1275, 129, 2509, -102, 1275, 130, 2509, - -102, 49, -102, 226, -102, -102, 1275, -102, -102, 362, - -102, -102, -102, 107, 1837, -102, -102, 1649, -102, -102, - 1743, -102, -102, -102, -102, -102, -102, 114, -102, -102, - -102, -102, -102, -102, -102, -102, -102, 2411, -102, -102, - -102, 94, 9, 818, 189, -10, 31, -102, -102, 223, - -102, 191, -102, -102, -102, 300, 178, -102, 1928, -102, - -102, -102, -102, -102, -102, -102, -102, -102, 257, -25, - 381, 195, -22, 305, 240, -102, -6, -102, 818, 127, - -102, -18, 818, -102, -102, 1184, -102, -102, -102, 1092, - -102, -102, 237, -102, 1928, -102, 294, -8, -102, -102, - 176, 381, 19, 1928, -102, 165, -102, 174, -102, 2, - -52, 381, 183, 381, -102, 117, -102, -102, -102, 2019, - 880, 285, 2607, 1555, 3, -102, 522, 35, 453, 108, - 1275, 2509, 51, 23, 475, 54, -17, 700, 7, 43, - -102, 1370, -102, 28, -3, 33, 1275, 37, 15, 1275, - 25, 1275, 1, 13, 124, -102, -102, 29, -102, -102, - 728, -102, 250, -43, 627, -102, -102, 231, 372, -102, - 222, -102, 111, -102, -102, 381, -102, -102, 104, -102, - -102, -102, -102, -102, -102, + 360, 1257, 2491, 2491, 2393, 982, 78, 84, 145, -102, + 81, 64, 68, 210, -102, 306, 54, -102, -102, 620, + 59, 128, 268, 244, -102, -102, -102, 521, 205, 1257, + -102, -102, -102, 442, -102, 2197, 1819, 1257, 1257, 1257, + -102, 682, 1257, -102, -102, -102, 1257, 1257, -102, -102, + -102, -102, -102, 1257, -102, 1257, 1257, -102, 1257, 1257, + 95, 188, -102, -102, 1257, 1257, 1257, -102, -102, -102, + 191, 1257, 313, 1257, 1257, 1257, 1257, 521, 1257, 1257, + 1257, 1257, 1257, 1257, 196, 1257, 1257, 1257, 151, 146, + 116, 167, 174, 182, 186, 189, 521, 429, 521, 1257, + 45, 1257, 41, 2099, 1257, 1257, -102, -102, -102, -102, + -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, + -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, + -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, + 125, 1257, -102, -102, 58, 46, -102, 1257, -102, -102, + 1257, -102, -102, -102, -102, -102, -102, -102, -102, -102, + -102, -102, -102, -102, 1257, 17, 1257, 1257, 75, 71, + 1257, -102, 2099, 1257, 1257, -102, 154, -102, 51, -102, + -102, 55, -102, 288, 72, 57, -102, 297, -102, 62, + 2491, -102, -102, -102, -102, -102, 232, -102, -102, 60, + -102, -102, -102, -102, -102, -102, 2491, -102, -102, 458, + -102, 470, 89, 2393, 49, 442, 69, 47, 2687, 65, + 1257, -102, 61, 43, 1257, 40, -102, 39, 82, -102, + -102, 442, -102, -102, -102, -102, -102, -102, 102, -102, + -102, -102, -102, 98, -102, -102, -102, -102, -102, -102, + 76, 63, 1257, 92, 93, -102, -102, 1348, -102, 88, + 66, 48, -102, 304, 80, 77, 560, 187, 86, 400, + 271, 442, 1257, 302, 1257, 1257, 1257, 1257, 407, 1257, + 1257, 1257, 1257, 1257, 253, 257, 272, 281, 278, 362, + 358, 337, 1257, 48, 1257, 73, 1257, -102, 620, 1257, + -102, 1257, 56, 44, 1257, 42, 2393, -102, 1257, 117, + 2393, -102, 1257, 38, 1257, 1257, 187, 74, 1257, -102, + 70, 118, 22, -102, -102, 1257, -102, 442, 1257, -102, + 67, 1257, 79, 2393, -102, 1257, 112, 2393, -102, -25, + 442, -48, -20, 2491, -41, -102, 2393, -102, 1257, 113, + 2393, 2, 2393, -102, 3, 11, -34, -102, -102, 2393, + -30, 504, 19, 450, 114, 1257, 2393, 20, -16, 414, + -1, -31, 772, -3, -4, -102, 1443, -102, 87, -35, + -5, 1257, 0, 30, 1257, 33, 1257, 14, 15, 1257, + -102, 2295, 1, -102, -102, -102, -102, -102, -102, 1257, + -102, -102, -102, -102, 226, -102, 1257, -6, -102, 2393, + -102, 96, -102, -102, 2393, -102, 1257, 101, 36, -102, + 53, -102, 29, 91, 1257, -102, 24, 23, -102, -24, + -102, 2393, -102, 100, 2393, -102, 250, -102, -102, 90, + 2393, 16, -102, 10, 12, -102, 442, -12, 4, -102, + -102, -102, -102, 1257, 111, 2393, -102, 1257, 105, 2393, + -102, 6, -102, 214, -102, -102, 1257, -102, -102, 354, + -102, -102, -102, 85, 1537, -102, -102, 1631, -102, -102, + 1725, -102, -102, -102, -102, -102, -102, 135, -102, -102, + -102, -102, -102, -102, -102, -102, -102, 2491, -102, -102, + -102, 159, -10, 890, 202, -11, 18, -102, -102, 222, + -102, 199, -102, -102, -102, 359, 211, -102, 1910, -102, + -102, -102, -102, -102, -102, -102, -102, -102, 183, -13, + 349, 175, -2, 344, 282, -102, -17, -102, 800, 124, + -102, -18, 890, -102, -102, 1074, -102, -102, -102, 1166, + -102, -102, 208, -102, 1910, -102, 369, -18, -102, -102, + 204, 341, 9, 1910, -102, 203, -102, 177, -102, -8, + -51, 309, 206, 442, -102, 83, -102, -102, -102, 2001, + 800, 369, 2589, 1819, 34, -102, 436, 25, 493, 108, + 1257, 2393, 26, 7, 409, 28, 8, 598, 32, 31, + -102, 1443, -102, 87, 5, 21, 1257, 52, 37, 1257, + 50, 1257, 35, 13, 134, -102, -102, 27, -102, -102, + 710, -102, 266, -38, 890, -102, -102, 115, 300, -102, + 176, -102, 122, -102, -102, 442, -102, -102, 126, -102, + -102, -102, -102, -102, -102, - -107, 9, -103, 2, 5, 266, 1, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -39, - -107, -107, -107, -107, -107, -107, -107, -107, -107, 86, - -107, -107, -107, 8, -107, -107, -22, 19, 71, 174, - -107, 186, 171, -107, -107, -107, 184, 178, -107, -107, - -107, -107, -107, 144, -107, 124, 150, -107, 165, 161, - -107, -107, -107, -107, 156, 160, 157, -107, -107, -107, - -107, 147, -107, 142, 135, 179, 166, -107, 177, 170, - 117, 72, 134, 92, -107, 75, 94, 66, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, 181, - -107, 106, -107, 143, 78, 55, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -5, -107, -107, -107, -107, -107, 54, -107, -107, - 51, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, 114, -107, 113, 38, -107, -107, - 41, -107, 231, 63, 112, -107, -107, -107, -107, -107, - -107, -107, -107, 30, -107, -107, -107, 52, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, 36, -107, -107, 45, - -107, 42, -107, 40, -107, 80, -107, -107, 77, -107, - 88, -107, -107, -107, 83, 74, -107, -107, -107, -107, - -107, -10, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, 23, -107, -107, -107, -107, 100, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, 4, 223, -107, 230, 236, 222, 205, -107, 127, - 125, 115, 96, 102, -107, -107, -107, -107, -107, -107, - -107, -107, 234, -107, 215, -107, 199, -107, -107, 197, - -107, 190, -107, -107, 163, -107, 90, -107, 0, -107, - -1, -107, 203, -107, 189, 211, -107, -107, 195, -107, - -107, -107, -107, -107, -107, 191, -107, 98, 119, -107, - -107, 95, -107, 81, -107, 79, -107, 82, -107, -107, - 101, -107, -107, -16, -107, -107, 53, -107, 46, -107, - 57, -107, 59, -107, -107, -107, -107, -107, -107, 35, - -107, 33, -107, 39, -107, 89, 67, -107, -107, 58, - -107, -107, 84, -107, -107, -107, 73, -107, -107, -107, - -107, 65, -107, 43, 93, -107, 109, -107, -107, 49, - -107, 47, -107, -107, -107, -107, -107, -107, -107, 50, - -107, -107, -107, -107, -107, -107, 108, -107, -107, 61, - -107, -107, -107, -107, 62, -107, 68, -107, -107, -107, - -107, -107, -23, -107, 69, -107, -19, -107, -107, -107, - -107, 97, -107, -107, 99, -107, -107, -107, -107, -107, - 60, -61, -107, -107, 34, -107, 37, -107, 29, -107, - -107, -107, -107, 32, -107, 76, -107, 44, -107, 56, - -107, -107, -107, -107, -107, -107, 31, -107, -107, 116, - -107, -107, -107, -107, -6, -107, -107, 70, -107, -107, - 64, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, 193, -107, -107, - -107, -107, -107, 7, -107, -107, -107, -107, -107, -107, - -107, -20, -107, -107, -107, -7, -107, -107, 290, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -2, -25, -107, -15, -107, -107, -107, -107, 172, -107, - -107, -107, 287, -107, -107, 288, -107, -107, -107, 291, - -107, -107, -107, -107, 336, -107, -107, 20, -107, -107, - 15, 3, -107, 304, -107, -107, -107, 24, -107, -107, - -107, 28, 21, 26, -107, -107, -107, -107, -107, 320, - 104, -107, 13, 381, -3, -107, 6, -107, 10, -107, - 167, 22, -107, -107, 12, -107, -107, 87, -107, -107, - -107, 25, -107, -107, -107, -107, 11, -107, 14, 85, - -107, 121, -107, -107, -107, -107, -107, 27, -107, -107, - 17, -107, -107, 18, 91, -107, -107, -107, 16, -107, - -107, -107, -107, -107, -107, -4, -107, -107, -107, -107, - -107, -107, -107, -107, -107}; + -107, -3, -98, 4, 7, 280, 3, -107, -107, -107, + -107, -107, -107, -107, -107, -107, -107, -107, -107, -35, + -107, -107, -107, -107, -107, -107, -107, -107, -107, 78, + -107, -107, -107, 20, -107, -107, -22, 15, 86, 72, + -107, 193, 175, -107, -107, -107, 174, 170, -107, -107, + -107, -107, -107, 118, -107, 144, 145, -107, 127, 156, + -107, -107, -107, -107, 162, 165, 166, -107, -107, -107, + -107, 149, -107, 137, 136, 135, 134, -107, 181, 180, + 179, 173, 53, 117, -107, 81, 95, 90, -107, -107, + -107, -107, -107, -107, -107, -107, -107, -107, -107, 103, + -107, 101, -107, 194, 92, 58, -107, -107, -107, -107, + -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -107, 32, -107, -107, -107, -107, -107, 16, -107, -107, + 49, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -107, -107, -107, -107, 70, -107, 109, 34, -107, -107, + 45, -107, 216, 60, 100, -107, -107, -107, -107, -107, + -107, -107, -107, 44, -107, -107, -107, 47, -107, -107, + -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -107, -107, -107, -107, -107, -107, 48, -107, -107, 35, + -107, 39, -107, 56, -107, 79, -107, -107, 83, -107, + 76, -107, -107, -107, 89, 69, -107, -107, -107, -107, + -107, -2, -107, -107, -107, -107, -107, -107, -107, -107, + -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -107, -107, 19, -107, -107, -107, -107, 105, -107, -107, + -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -107, -13, 195, -107, 218, 212, 215, 228, -107, 114, + 87, 121, 124, 107, -107, -107, -107, -107, -107, -107, + -107, -107, 198, -107, 221, -107, 236, -107, -107, 237, + -107, 128, -107, -107, 184, -107, 36, -107, 24, -107, + 102, -107, 192, -107, 234, 238, -107, -107, 224, -107, + -107, -107, -107, -107, -107, 191, -107, 93, 99, -107, + -107, 108, -107, 88, -107, 84, -107, 91, -107, -107, + 141, -107, -107, -23, -107, -107, 59, -107, 57, -107, + 55, -107, 54, -107, -107, -107, -107, -107, -107, 46, + -107, 31, -107, 30, -107, 169, 37, -107, -107, 68, + -107, -107, 85, -107, -107, -107, 73, -107, -107, -107, + -107, 66, -107, 52, 98, -107, 104, -107, -107, 43, + -107, 40, -107, -107, -107, -107, -107, -107, -107, 42, + -107, -107, -107, -107, -107, -107, 106, -107, -107, 62, + -107, -107, -107, -107, 63, -107, 65, -107, -107, -107, + -107, -107, -30, -107, 67, -107, -19, -107, -107, -107, + -107, 94, -107, -107, 97, -107, -107, -107, -107, -107, + 75, -50, -107, -107, 25, -107, 28, -107, 29, -107, + -107, -107, -107, 41, -107, 64, -107, 38, -107, 51, + -107, -107, -107, -107, -107, -107, 33, -107, -107, 122, + -107, -107, -107, -107, 61, -107, -107, 163, -107, -107, + 50, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -107, -107, -107, -107, -107, -107, -107, 82, -107, -107, + -107, -107, -107, -12, -107, -107, -107, -107, -107, -107, + -107, -15, -107, -107, -107, -5, -107, -107, 297, -107, + -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -9, -26, -107, -11, -107, -107, -107, -107, 183, -107, + -107, -107, 288, -107, -107, 283, -107, -107, -107, 390, + -107, -107, -107, -107, 321, -107, -107, -8, -107, -107, + 11, 18, -107, 305, -107, -107, -107, 1, -107, -107, + -107, 14, -4, 0, -107, -107, -107, -107, -107, 337, + 217, -107, 22, 279, 9, -107, 8, -107, 6, -107, + 153, 17, -107, -107, 5, -107, -107, 96, -107, -107, + -107, 13, -107, -107, -107, -107, 23, -107, 10, 77, + -107, 71, -107, -107, -107, -107, -107, 12, -107, -107, + 21, -107, -107, 26, 148, -107, -107, -107, 27, -107, + -107, -107, -107, -107, -107, -10, -107, -107, -107, -107, + -107, -107, -107, -107, -107 +}; const short QmlJSGrammar::action_info [] = { - 416, 257, 533, -132, 403, -113, 346, -102, 575, 348, - 572, -121, 531, -103, -121, 545, 345, 430, 342, 348, - 340, 343, 440, 401, 391, 545, 563, 389, 538, 446, - 352, 444, -129, 416, -124, -102, 545, 453, 420, 408, - -124, 431, -132, 424, -126, 424, 424, 620, 440, 457, - -103, 440, -129, 457, -126, 440, 560, 453, -113, 257, - 565, 346, 545, 335, 272, 346, 466, 236, 448, 190, - 149, 164, 141, 170, 99, 511, 272, 409, 257, 312, - 296, 414, 348, 312, 189, 164, 187, 318, 325, 71, - 306, 252, 644, 416, 141, 453, 292, 457, 440, 147, - 304, 71, 443, 183, 179, 141, 0, 141, 0, 172, - 99, 427, 434, 141, 301, 477, 444, 0, 0, 0, - 0, 0, 141, 0, 0, 0, 0, 292, 173, 294, - 58, 294, 542, 251, 331, 542, 333, 141, 141, 101, - 141, 59, 0, 58, 62, 256, 255, 141, 247, 246, - 141, 399, 0, 177, 59, 63, 428, 327, 620, 254, - 314, 101, 141, 478, 315, 640, 639, 242, 241, 249, - 248, 58, 634, 633, 488, 58, 249, 248, 577, 576, - 615, 141, 59, 543, 166, 518, 59, 172, 167, 455, - 459, 85, 418, 86, 85, 142, 86, 249, 248, 413, - 412, 567, 337, 512, 87, 512, 173, 87, 174, 85, - 328, 86, 512, 0, 350, 85, 64, 86, 529, 85, - 512, 86, 87, 85, 512, 86, 568, 566, 87, 64, - 579, 64, 87, 310, 469, 85, 87, 86, 0, 519, - 517, 85, 141, 86, 554, 0, 172, 536, 87, 514, - 85, 514, 86, 141, 87, 85, 545, 86, 514, 0, - 513, 65, 513, 87, 514, 173, 514, 66, 87, 513, - 514, 103, 172, 0, 65, 513, 65, 513, 0, 0, - 66, 513, 66, 637, 636, 0, 0, 470, 468, 172, - 104, 173, 105, 406, 0, 235, 234, 630, 555, 553, - 172, 537, 535, 0, 274, 275, 438, 437, 173, 172, - 406, 631, 629, 635, 0, 580, 73, 74, -90, 173, - 34, 174, 73, 74, 274, 275, 34, -90, 173, 34, - 174, 276, 277, 85, 34, 86, 0, 0, 0, 0, - 0, 628, 0, 75, 76, 0, 87, 0, 0, 75, - 76, 276, 277, 0, 0, 0, 0, 48, 50, 49, - 0, 0, 0, 48, 50, 49, 48, 50, 49, 0, - 0, 48, 50, 49, 0, 0, 279, 280, 0, 0, - 0, 34, 0, 45, 0, 281, 279, 280, 282, 45, - 283, 34, 45, 279, 280, 281, 34, 45, 282, 0, - 283, 34, 281, 279, 280, 282, 0, 283, 0, 0, - 34, 0, 281, 78, 79, 282, 0, 283, 48, 50, - 49, 80, 81, 0, 34, 82, 0, 83, 48, 50, - 49, -345, 0, 48, 50, 49, 0, 0, 48, 50, - 49, 0, 0, 0, 45, 0, 0, 48, 50, 49, - 0, 0, 0, 0, 45, 0, 0, 78, 79, 45, - 0, 48, 50, 49, 45, 80, 81, 78, 79, 82, - 0, 83, 0, 45, 0, 80, 81, 78, 79, 82, - 0, 83, 34, 279, 280, 80, 81, 45, 0, 82, - 34, 83, 281, 34, 0, 282, 0, 283, 6, 5, - 4, 1, 3, 2, 34, 0, 0, 0, 0, 0, - 0, -345, 0, 0, 245, 244, 0, 0, 0, 48, - 50, 49, 245, 244, 0, 240, 239, 48, 50, 49, - 48, 50, 49, 0, 0, 0, 0, 0, 0, 0, - 34, 48, 50, 49, 0, 45, 0, 0, 34, 0, - 0, 34, 0, 45, 0, 0, 45, 0, 0, 0, - 0, 0, 78, 79, 0, 0, 0, 45, 0, 0, - 80, 81, 245, 244, 82, 0, 83, 48, 50, 49, - 240, 239, 151, 240, 239, 48, 50, 49, 48, 50, - 49, 0, 152, 0, 0, 0, 153, 0, 0, 0, - 0, 0, 0, 45, 0, 154, 0, 155, 0, 0, - 308, 45, 0, 0, 45, 0, 0, 0, 156, 0, - 157, 62, 0, 0, 0, 0, 0, 0, 158, 0, - 0, 159, 63, 0, 0, 0, 0, 160, 0, 30, - 31, 151, 0, 161, 0, 0, 0, 0, 0, 33, - 0, 152, 0, 0, 0, 153, 34, 0, 0, 162, - 35, 36, 0, 37, 154, 0, 155, 0, 0, 0, - 503, 0, 0, 0, 44, 0, 0, 156, 0, 157, - 62, 0, 0, 0, 0, 0, 0, 158, 0, 0, - 159, 63, 51, 48, 50, 49, 160, 52, 0, 0, - 0, 0, 161, 0, 0, 0, 0, 0, 43, 54, - 32, 0, 30, 31, 40, 0, 0, 0, 162, 45, - 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, - 0, 0, 0, 35, 36, 0, 37, 0, 0, 0, - 30, 31, 0, 41, 0, 0, 0, 44, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, - 0, 35, 36, 0, 37, 51, 48, 50, 49, 0, - 52, 503, 0, 0, 0, 44, 0, 0, 0, 0, - 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, - 0, 0, 45, 51, 48, 50, 49, 0, 52, 0, - 0, 0, 30, 31, 0, 0, 0, 0, 0, 43, - 54, 32, 33, 0, 0, 40, 0, 0, 0, 34, - 45, 0, 0, 35, 36, 0, 37, 0, 0, 0, - 30, 31, 0, 41, 0, 0, 0, 44, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, - 0, 35, 36, 0, 37, 51, 48, 50, 49, 0, - 52, 503, 0, 0, 0, 44, 0, 0, 0, 0, - 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, - 0, 0, 45, 51, 48, 50, 49, 0, 52, 0, - 0, 0, 30, 31, 0, 0, 0, 0, 0, 43, - 54, 32, 33, 0, 0, 40, 0, 0, 0, 34, - 45, 0, 0, 35, 36, 0, 37, 0, 0, 0, - 30, 31, 0, 503, 0, 0, 0, 44, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, - 0, 35, 36, 0, 37, 51, 48, 50, 49, 0, - 52, 41, 0, 0, 0, 44, 0, 0, 0, 0, - 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, - 0, 0, 45, 51, 48, 50, 49, 0, 52, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, - 54, 32, 0, 0, 0, 40, 0, 0, 0, 0, - 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 502, 0, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 215, 0, 0, 0, 0, 0, 0, 34, - 0, 0, 0, 35, 36, 0, 37, 0, 0, 0, - 0, 0, 0, 503, 0, 0, 0, 44, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 51, 504, 506, 505, 0, - 52, 0, 0, 0, 0, 226, 0, 0, 0, 0, - 0, 43, 54, 32, 210, 0, 0, 40, 0, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 502, 0, 30, 31, 0, 0, 0, 0, - 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, - 0, 34, 0, 0, 0, 35, 36, 0, 37, 0, - 0, 0, 0, 0, 0, 503, 0, 0, 0, 44, - 0, 0, 0, 0, 0, 0, 0, 550, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 51, 504, 506, - 505, 0, 52, 0, 0, 0, 0, 226, 0, 0, - 0, 0, 0, 43, 54, 32, 210, 0, 0, 40, - 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 502, 0, 30, 31, 0, 0, - 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, - 0, 0, 0, 34, 0, 0, 0, 35, 36, 0, - 37, 0, 0, 0, 0, 0, 0, 503, 0, 0, - 0, 44, 0, 0, 0, 0, 0, 0, 0, 547, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, - 504, 506, 505, 0, 52, 0, 0, 0, 0, 226, - 0, 0, 0, 0, 0, 43, 54, 32, 210, 0, - 0, 40, 0, 0, 0, 0, 45, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 29, 30, 31, 0, - 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, - 0, 0, 0, 0, 34, 0, 0, 0, 35, 36, - 0, 37, 0, 0, 0, 38, 0, 39, 41, 42, - 0, 0, 44, 0, 0, 0, 46, 0, 47, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 51, 48, 50, 49, 0, 52, 0, 53, 0, 55, - 0, 56, 0, 0, 0, 0, 43, 54, 32, 0, - 0, 0, 40, 0, 0, 0, 0, 45, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, - 0, 29, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, - 0, 0, 0, 35, 36, 0, 37, 0, 0, 0, - 38, 0, 39, 41, 42, 0, 0, 44, 0, 0, - 0, 46, 0, 47, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 51, 48, 50, 49, 0, - 52, 0, 53, 0, 55, 0, 56, 0, 0, 0, - 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 29, 30, 31, 0, 0, 0, 0, 0, - 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 34, 0, 0, 0, 35, 36, 0, 37, 0, 0, - 0, 38, 0, 39, 41, 42, 0, 0, 44, 0, - 0, 0, 46, 0, 47, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 51, 48, 50, 49, - 0, 52, 0, 53, 0, 55, 271, 56, 0, 0, - 0, 0, 43, 54, 32, 0, 0, 0, 40, 0, - 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 475, 0, 0, 29, 30, 31, 0, - 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, - 0, 0, 0, 0, 34, 0, 0, 0, 35, 36, - 0, 37, 0, 0, 0, 38, 0, 39, 41, 42, - 0, 0, 44, 0, 0, 0, 46, 0, 47, 0, - 0, 476, 0, 0, 0, 0, 0, 0, 0, 0, - 51, 48, 50, 49, 0, 52, 0, 53, 0, 55, - 0, 56, 0, 0, 0, 0, 43, 54, 32, 0, - 0, 0, 40, 0, 0, 0, 0, 45, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, - 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, - 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, - 0, 0, 35, 36, 0, 37, 0, 0, 0, 38, - 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, - 46, 0, 47, 0, 0, 481, 0, 0, 0, 0, - 0, 0, 0, 0, 51, 48, 50, 49, 0, 52, - 0, 53, 0, 55, 0, 56, 0, 0, 0, 0, - 43, 54, 32, 0, 0, 0, 40, 0, 0, 0, - 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 483, 0, 0, 29, 30, 31, 0, 0, 0, - 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, - 0, 0, 34, 0, 0, 0, 35, 36, 0, 37, - 0, 0, 0, 38, 0, 39, 41, 42, 0, 0, - 44, 0, 0, 0, 46, 0, 47, 0, 0, 484, - 0, 0, 0, 0, 0, 0, 0, 0, 51, 48, - 50, 49, 0, 52, 0, 53, 0, 55, 0, 56, - 0, 0, 0, 0, 43, 54, 32, 0, 0, 0, - 40, 0, 0, 0, 0, 45, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 483, 0, 0, 29, 30, - 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, - 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, - 35, 36, 0, 37, 0, 0, 0, 38, 0, 39, - 41, 42, 0, 0, 44, 0, 0, 0, 46, 0, - 47, 0, 0, 486, 0, 0, 0, 0, 0, 0, - 0, 0, 51, 48, 50, 49, 0, 52, 0, 53, - 0, 55, 0, 56, 0, 0, 0, 0, 43, 54, - 32, 0, 0, 0, 40, 0, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, - 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 34, 217, 0, - 0, 218, 36, 0, 37, 0, 0, 0, 38, 0, - 39, 41, 42, 0, 0, 44, 0, 0, 0, 46, - 0, 47, 0, 0, 0, 0, 0, 0, 0, 221, - 0, 0, 0, 51, 48, 50, 49, 223, 52, 0, - 53, 225, 55, 0, 56, 0, 228, 0, 0, 43, - 54, 32, 0, 0, 0, 40, 0, 0, 0, 0, - 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, - 0, 33, 0, 0, 0, 0, 0, 0, 34, 217, - 0, 0, 582, 583, 0, 37, 0, 0, 0, 38, - 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, - 46, 0, 47, 0, 0, 0, 0, 0, 0, 0, - 221, 0, 0, 0, 51, 48, 50, 49, 223, 52, - 0, 53, 225, 55, 0, 56, 0, 228, 0, 0, - 43, 54, 32, 0, 0, 0, 40, 0, 0, 0, - 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 110, 111, 0, 0, 113, 115, 116, 0, - 0, 117, 0, 118, 0, 0, 0, 120, 121, 122, - 0, 0, 0, 0, 0, 0, 34, 123, 124, 125, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, - 0, 0, 0, 48, 50, 49, 130, 131, 132, 0, - 134, 135, 136, 137, 138, 139, 0, 0, 127, 133, - 119, 112, 114, 128, 0, 0, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, - 110, 111, 0, 0, 113, 115, 116, 0, 0, 117, - 0, 118, 0, 0, 0, 120, 121, 122, 0, 0, - 0, 0, 0, 0, 393, 123, 124, 125, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 126, 0, - 0, 0, 394, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 129, 0, 0, 0, 0, 0, - 398, 395, 397, 0, 130, 131, 132, 0, 134, 135, - 136, 137, 138, 139, 0, 0, 127, 133, 119, 112, - 114, 128, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 109, 110, 111, - 0, 0, 113, 115, 116, 0, 0, 117, 0, 118, - 0, 0, 0, 120, 121, 122, 0, 0, 0, 0, - 0, 0, 393, 123, 124, 125, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, - 394, 0, 0, 0, 0, 0, 0, 0, 396, 0, - 0, 0, 129, 0, 0, 0, 0, 0, 398, 395, - 397, 0, 130, 131, 132, 0, 134, 135, 136, 137, - 138, 139, 0, 0, 127, 133, 119, 112, 114, 128, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, - 211, 0, 29, 30, 31, 213, 0, 0, 0, 0, - 0, 0, 214, 215, 0, 0, 0, 0, 0, 0, - 216, 217, 0, 0, 218, 36, 0, 37, 0, 0, - 0, 38, 0, 39, 41, 42, 0, 0, 44, 0, - 0, 0, 46, 0, 47, 0, 0, 0, 0, 0, - 220, 0, 221, 0, 0, 0, 51, 219, 222, 49, - 223, 52, 224, 53, 225, 55, 226, 56, 227, 228, - 0, 0, 43, 54, 32, 210, 212, 0, 40, 0, - 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 209, 0, 0, 0, 0, 211, 0, - 29, 30, 31, 213, 0, 0, 0, 0, 0, 0, - 214, 33, 0, 0, 0, 0, 0, 0, 216, 217, - 0, 0, 218, 36, 0, 37, 0, 0, 0, 38, - 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, - 46, 0, 47, 0, 0, 0, 0, 0, 220, 0, - 221, 0, 0, 0, 51, 219, 222, 49, 223, 52, - 224, 53, 225, 55, 226, 56, 227, 228, 0, 0, - 43, 54, 32, 210, 212, 0, 40, 0, 0, 0, - 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 586, 110, 111, 0, 0, 588, 115, 590, 30, - 31, 591, 0, 118, 0, 0, 0, 120, 593, 594, - 0, 0, 0, 0, 0, 0, 595, 596, 124, 125, - 218, 36, 0, 37, 0, 0, 0, 38, 0, 39, - 597, 42, 0, 0, 599, 0, 0, 0, 46, 0, - 47, 0, 0, 0, 0, 0, 601, 0, 221, 0, - 0, 0, 603, 600, 602, 49, 604, 605, 606, 53, - 608, 609, 610, 611, 612, 613, 0, 0, 598, 607, - 592, 587, 589, 128, 40, 0, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 361, - 110, 111, 0, 0, 363, 115, 365, 30, 31, 366, - 0, 118, 0, 0, 0, 120, 368, 369, 0, 0, - 0, 0, 0, 0, 370, 371, 124, 125, 218, 36, - 0, 37, 0, 0, 0, 38, 0, 39, 372, 42, - 0, 0, 374, 0, 0, 0, 46, 0, 47, 0, - -268, 0, 0, 0, 376, 0, 221, 0, 0, 0, - 378, 375, 377, 49, 379, 380, 381, 53, 383, 384, - 385, 386, 387, 388, 0, 0, 373, 382, 367, 362, - 364, 128, 40, 0, 0, 0, 0, 45, 0, 0, - 0, 0, 0, 0, 0, 0, 0, + 572, 416, -124, -103, -121, 348, 346, -126, 399, 575, + 389, 340, 342, 343, 345, 545, 563, 538, 352, 391, + 257, 401, 533, 466, 531, 403, -132, -113, -124, 424, + 431, 430, -132, -113, 424, 346, 444, 440, -103, -121, + -129, 416, 71, 257, 348, 440, 446, 565, 448, 457, + 453, 457, 620, 335, 408, 560, 511, -129, 424, -126, + 545, 164, 141, 440, 141, 99, 147, 545, 414, 420, + 440, 453, 409, 440, 272, 453, 346, 164, 170, 416, + 187, 318, 71, 348, 644, 257, 292, 325, 296, 272, + 0, 183, 0, 477, -102, 190, 443, 0, 0, 252, + 141, 427, 306, 0, 0, 304, 149, 434, 141, 141, + 444, 179, 99, 141, 292, 236, 0, 189, 457, 141, + 141, 141, 0, 0, 101, 141, 327, 294, 331, 0, + 172, 0, 542, 141, 0, 0, 314, 62, 301, 333, + 315, 478, 542, 141, 577, 576, 428, 101, 63, 173, + 249, 248, 254, 251, 256, 255, 58, 413, 412, 247, + 246, 418, 141, 242, 241, 459, 0, 59, 620, 249, + 248, 455, 337, 350, 172, 249, 248, 310, 166, 328, + 543, 142, 167, 634, 633, 58, 58, 640, 639, 312, + 615, 58, 85, 173, 86, 488, 59, 59, 172, 85, + 64, 86, 59, 64, 512, 87, 512, 85, 0, 86, + 177, 85, 87, 86, 85, 554, 86, 173, 518, 406, + 87, 85, 469, 86, 87, 103, 0, 87, 512, 579, + 85, 529, 86, 512, 87, 512, 0, 637, 636, 567, + 141, 172, 0, 87, 104, 65, 105, 0, 65, 0, + 514, 66, 514, 0, 66, 545, 64, 0, 141, 0, + 173, 513, 406, 513, 568, 566, 0, 635, 0, 555, + 553, 0, 519, 517, 514, 470, 468, 514, 85, 514, + 86, 514, 85, 172, 86, 513, 0, 0, 513, 536, + 513, 87, 513, 235, 234, 87, 85, 85, 86, 86, + 0, 65, 173, 85, 174, 86, 85, 66, 86, 87, + 87, 438, 437, 630, 580, 0, 87, 34, 0, 87, + 274, 275, 274, 275, 73, 74, 34, 631, 629, 34, + 0, 73, 74, 0, 0, 0, 0, 0, 34, 0, + 0, 0, 0, 537, 535, 0, 0, 276, 277, 276, + 277, 75, 76, 0, 48, 50, 49, 628, 75, 76, + 279, 280, 0, 48, 50, 49, 48, 50, 49, 281, + 34, 0, 282, 34, 283, 48, 50, 49, 34, 0, + 45, 279, 280, 34, 172, 279, 280, 0, 34, 45, + 281, 0, 45, 282, 281, 283, 0, 282, 0, 283, + 0, 45, -90, 173, 0, 174, 0, 48, 50, 49, + 48, 50, 49, 0, 0, 48, 50, 49, 0, 0, + 48, 50, 49, 279, 280, 48, 50, 49, 0, 0, + 279, 280, 281, 45, 0, 282, 45, 283, 34, 281, + 0, 45, 282, 34, 283, -345, 45, 0, 0, 0, + -345, 45, 78, 79, 6, 5, 4, 1, 3, 2, + 80, 81, 0, 0, 82, 34, 83, 0, 0, 0, + 0, 34, 0, 0, 0, 48, 50, 49, 0, 34, + 48, 50, 49, 0, 0, 0, 0, 34, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 240, 239, 34, + 0, 45, 48, 50, 49, 0, 45, 0, 48, 50, + 49, 245, 244, 0, 0, 0, 48, 50, 49, 240, + 239, 0, 34, 0, 48, 50, 49, 0, 45, 0, + 0, 245, 244, 34, 45, 0, 48, 50, 49, 0, + 0, 0, 45, 0, 78, 79, 0, 0, 0, 0, + 45, 0, 80, 81, 245, 244, 82, 0, 83, 48, + 50, 49, 45, 151, 0, 240, 239, 0, 0, 0, + 48, 50, 49, 152, 0, 0, 0, 153, 0, 0, + 0, 0, 0, 0, 0, 45, 154, 0, 155, 0, + 0, 308, 0, 0, 0, 0, 45, 0, 0, 156, + 0, 157, 62, 0, 0, 0, 0, 0, 0, 158, + 30, 31, 159, 63, 0, 0, 0, 0, 160, 0, + 33, 0, 0, 151, 161, 0, 0, 34, 0, 0, + 0, 35, 36, 152, 37, 0, 0, 153, 0, 0, + 162, 41, 0, 0, 0, 44, 154, 0, 155, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, + 0, 157, 62, 51, 48, 50, 49, 0, 52, 158, + 0, 0, 159, 63, 0, 0, 0, 0, 160, 43, + 54, 32, 0, 0, 161, 40, 0, 0, 0, 0, + 45, 0, 0, 0, 30, 31, 0, 0, 0, 0, + 162, 0, 0, 0, 33, 0, 0, 0, 0, 0, + 0, 34, 0, 0, 0, 35, 36, 0, 37, 0, + 0, 0, 30, 31, 0, 41, 0, 0, 0, 44, + 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, + 0, 0, 0, 35, 36, 0, 37, 51, 48, 50, + 49, 0, 52, 503, 0, 0, 0, 44, 0, 0, + 0, 0, 0, 43, 54, 32, 0, 0, 0, 40, + 0, 0, 0, 0, 45, 51, 48, 50, 49, 0, + 52, 0, 0, 0, 30, 31, 0, 0, 0, 0, + 0, 43, 54, 32, 33, 0, 0, 40, 0, 0, + 0, 34, 45, 0, 0, 35, 36, 0, 37, 0, + 0, 0, 30, 31, 0, 41, 0, 0, 0, 44, + 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, + 0, 0, 0, 35, 36, 0, 37, 51, 48, 50, + 49, 0, 52, 503, 0, 0, 0, 44, 0, 0, + 0, 0, 0, 43, 54, 32, 0, 0, 0, 40, + 0, 0, 0, 0, 45, 51, 48, 50, 49, 0, + 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, + 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, + 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, + 0, 0, 0, 35, 36, 0, 37, 0, 0, 0, + 0, 0, 0, 503, 0, 0, 0, 44, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 51, 48, 50, 49, 0, + 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, + 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 502, 0, 30, 31, 0, 0, 0, 0, + 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, + 0, 34, 0, 0, 0, 35, 36, 0, 37, 0, + 0, 0, 0, 0, 0, 503, 0, 0, 0, 44, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 51, 504, 506, + 505, 0, 52, 0, 0, 0, 0, 226, 0, 0, + 0, 0, 0, 43, 54, 32, 210, 0, 0, 40, + 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 502, 0, 30, 31, 0, 0, + 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, + 0, 0, 0, 34, 0, 0, 0, 35, 36, 0, + 37, 0, 0, 0, 0, 0, 0, 503, 0, 0, + 0, 44, 0, 0, 0, 0, 0, 0, 0, 547, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, + 504, 506, 505, 0, 52, 0, 0, 0, 0, 226, + 0, 0, 0, 0, 0, 43, 54, 32, 210, 0, + 0, 40, 0, 0, 0, 0, 45, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 502, 0, 30, 31, + 0, 0, 0, 0, 0, 0, 0, 0, 215, 0, + 0, 0, 0, 0, 0, 34, 0, 0, 0, 35, + 36, 0, 37, 0, 0, 0, 0, 0, 0, 503, + 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, + 0, 550, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 51, 504, 506, 505, 0, 52, 0, 0, 0, + 0, 226, 0, 0, 0, 0, 0, 43, 54, 32, + 210, 0, 0, 40, 0, 0, 0, 0, 45, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, + 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, + 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, + 35, 36, 0, 37, 0, 0, 0, 38, 0, 39, + 41, 42, 0, 0, 44, 0, 0, 0, 46, 0, + 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 51, 48, 50, 49, 0, 52, 0, 53, + 0, 55, 0, 56, 0, 0, 0, 0, 43, 54, + 32, 0, 0, 0, 40, 0, 0, 0, 0, 45, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, + 0, 35, 36, 0, 37, 0, 0, 0, 38, 0, + 39, 41, 42, 0, 0, 44, 0, 0, 0, 46, + 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 51, 48, 50, 49, 0, 52, 0, + 53, 0, 55, 271, 56, 0, 0, 0, 0, 43, + 54, 32, 0, 0, 0, 40, 0, 0, 0, 0, + 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -122, 0, 0, 0, 29, 30, 31, 0, 0, 0, + 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, + 0, 0, 34, 0, 0, 0, 35, 36, 0, 37, + 0, 0, 0, 38, 0, 39, 41, 42, 0, 0, + 44, 0, 0, 0, 46, 0, 47, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 51, 48, + 50, 49, 0, 52, 0, 53, 0, 55, 0, 56, + 0, 0, 0, 0, 43, 54, 32, 0, 0, 0, + 40, 0, 0, 0, 0, 45, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 483, 0, 0, 29, 30, + 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, + 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, + 35, 36, 0, 37, 0, 0, 0, 38, 0, 39, + 41, 42, 0, 0, 44, 0, 0, 0, 46, 0, + 47, 0, 0, 486, 0, 0, 0, 0, 0, 0, + 0, 0, 51, 48, 50, 49, 0, 52, 0, 53, + 0, 55, 0, 56, 0, 0, 0, 0, 43, 54, + 32, 0, 0, 0, 40, 0, 0, 0, 0, 45, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 475, + 0, 0, 29, 30, 31, 0, 0, 0, 0, 0, + 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, + 34, 0, 0, 0, 35, 36, 0, 37, 0, 0, + 0, 38, 0, 39, 41, 42, 0, 0, 44, 0, + 0, 0, 46, 0, 47, 0, 0, 481, 0, 0, + 0, 0, 0, 0, 0, 0, 51, 48, 50, 49, + 0, 52, 0, 53, 0, 55, 0, 56, 0, 0, + 0, 0, 43, 54, 32, 0, 0, 0, 40, 0, + 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 483, 0, 0, 29, 30, 31, 0, + 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 0, 0, 34, 0, 0, 0, 35, 36, + 0, 37, 0, 0, 0, 38, 0, 39, 41, 42, + 0, 0, 44, 0, 0, 0, 46, 0, 47, 0, + 0, 484, 0, 0, 0, 0, 0, 0, 0, 0, + 51, 48, 50, 49, 0, 52, 0, 53, 0, 55, + 0, 56, 0, 0, 0, 0, 43, 54, 32, 0, + 0, 0, 40, 0, 0, 0, 0, 45, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, + 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, + 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, + 0, 0, 35, 36, 0, 37, 0, 0, 0, 38, + 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, + 46, 0, 47, 0, 0, 476, 0, 0, 0, 0, + 0, 0, 0, 0, 51, 48, 50, 49, 0, 52, + 0, 53, 0, 55, 0, 56, 0, 0, 0, 0, + 43, 54, 32, 0, 0, 0, 40, 0, 0, 0, + 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 29, 30, 31, 0, 0, 0, 0, 0, 0, + 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, + 217, 0, 0, 218, 36, 0, 37, 0, 0, 0, + 38, 0, 39, 41, 42, 0, 0, 44, 0, 0, + 0, 46, 0, 47, 0, 0, 0, 0, 0, 0, + 0, 221, 0, 0, 0, 51, 48, 50, 49, 223, + 52, 0, 53, 225, 55, 0, 56, 0, 228, 0, + 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, + 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 29, 30, 31, 0, 0, 0, 0, 0, + 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, + 34, 217, 0, 0, 582, 583, 0, 37, 0, 0, + 0, 38, 0, 39, 41, 42, 0, 0, 44, 0, + 0, 0, 46, 0, 47, 0, 0, 0, 0, 0, + 0, 0, 221, 0, 0, 0, 51, 48, 50, 49, + 223, 52, 0, 53, 225, 55, 0, 56, 0, 228, + 0, 0, 43, 54, 32, 0, 0, 0, 40, 0, + 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 109, 110, 111, 0, 0, 113, 115, + 116, 0, 0, 117, 0, 118, 0, 0, 0, 120, + 121, 122, 0, 0, 0, 0, 0, 0, 34, 123, + 124, 125, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 129, 0, + 0, 0, 0, 0, 0, 48, 50, 49, 130, 131, + 132, 0, 134, 135, 136, 137, 138, 139, 0, 0, + 127, 133, 119, 112, 114, 128, 0, 0, 0, 0, + 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 109, 110, 111, 0, 0, 113, 115, 116, 0, + 0, 117, 0, 118, 0, 0, 0, 120, 121, 122, + 0, 0, 0, 0, 0, 0, 393, 123, 124, 125, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 126, 0, 0, 0, 394, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, + 0, 0, 398, 395, 397, 0, 130, 131, 132, 0, + 134, 135, 136, 137, 138, 139, 0, 0, 127, 133, + 119, 112, 114, 128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, + 110, 111, 0, 0, 113, 115, 116, 0, 0, 117, + 0, 118, 0, 0, 0, 120, 121, 122, 0, 0, + 0, 0, 0, 0, 393, 123, 124, 125, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 126, 0, + 0, 0, 394, 0, 0, 0, 0, 0, 0, 0, + 396, 0, 0, 0, 129, 0, 0, 0, 0, 0, + 398, 395, 397, 0, 130, 131, 132, 0, 134, 135, + 136, 137, 138, 139, 0, 0, 127, 133, 119, 112, + 114, 128, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 209, 0, 0, + 0, 0, 211, 0, 29, 30, 31, 213, 0, 0, + 0, 0, 0, 0, 214, 33, 0, 0, 0, 0, + 0, 0, 216, 217, 0, 0, 218, 36, 0, 37, + 0, 0, 0, 38, 0, 39, 41, 42, 0, 0, + 44, 0, 0, 0, 46, 0, 47, 0, 0, 0, + 0, 0, 220, 0, 221, 0, 0, 0, 51, 219, + 222, 49, 223, 52, 224, 53, 225, 55, 226, 56, + 227, 228, 0, 0, 43, 54, 32, 210, 212, 0, + 40, 0, 0, 0, 0, 45, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, + 211, 0, 29, 30, 31, 213, 0, 0, 0, 0, + 0, 0, 214, 215, 0, 0, 0, 0, 0, 0, + 216, 217, 0, 0, 218, 36, 0, 37, 0, 0, + 0, 38, 0, 39, 41, 42, 0, 0, 44, 0, + 0, 0, 46, 0, 47, 0, 0, 0, 0, 0, + 220, 0, 221, 0, 0, 0, 51, 219, 222, 49, + 223, 52, 224, 53, 225, 55, 226, 56, 227, 228, + 0, 0, 43, 54, 32, 210, 212, 0, 40, 0, + 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 586, 110, 111, 0, 0, 588, 115, + 590, 30, 31, 591, 0, 118, 0, 0, 0, 120, + 593, 594, 0, 0, 0, 0, 0, 0, 595, 596, + 124, 125, 218, 36, 0, 37, 0, 0, 0, 38, + 0, 39, 597, 42, 0, 0, 599, 0, 0, 0, + 46, 0, 47, 0, 0, 0, 0, 0, 601, 0, + 221, 0, 0, 0, 603, 600, 602, 49, 604, 605, + 606, 53, 608, 609, 610, 611, 612, 613, 0, 0, + 598, 607, 592, 587, 589, 128, 40, 0, 0, 0, + 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 361, 110, 111, 0, 0, 363, 115, 365, 30, + 31, 366, 0, 118, 0, 0, 0, 120, 368, 369, + 0, 0, 0, 0, 0, 0, 370, 371, 124, 125, + 218, 36, 0, 37, 0, 0, 0, 38, 0, 39, + 372, 42, 0, 0, 374, 0, 0, 0, 46, 0, + 47, 0, -268, 0, 0, 0, 376, 0, 221, 0, + 0, 0, 378, 375, 377, 49, 379, 380, 381, 53, + 383, 384, 385, 386, 387, 388, 0, 0, 373, 382, + 367, 362, 364, 128, 40, 0, 0, 0, 0, 45, + 0, 0, 0, 0, 0, 0, 0, 0, 0, - 534, 311, 497, 309, 532, 461, 498, 499, 516, 515, - 619, 638, 16, 552, 436, 358, 616, 472, 562, 320, - 528, 238, 487, 182, 250, 243, 253, 182, 302, 641, - 627, 632, 150, 485, 143, 454, 439, 402, 445, 559, - 237, 574, 250, 578, 561, 186, 618, 458, 238, 349, - 573, 449, 447, 571, 243, 347, 450, 243, 460, 351, - 238, 353, 358, 410, 415, 439, 176, 188, 436, 250, - 467, 417, 433, 182, 425, 429, 302, 169, 456, 358, - 171, 140, 336, 334, 338, 344, 436, 392, 390, 400, - 163, 302, 307, 148, 146, 339, 439, 404, 302, 358, - 404, 358, 0, 482, 501, 480, 0, 642, 0, 479, - 0, 0, 0, 320, 60, 0, 186, 501, 90, 60, - 60, 489, 302, 60, 617, 93, 0, 88, 0, 405, - 0, 461, 405, 60, 60, 451, 180, 60, 0, 180, - 60, 60, 60, 451, 60, 95, 89, 146, 266, 287, - 60, 146, 407, 270, 60, 288, 178, 60, 106, 452, - 0, 60, 60, 60, 102, 60, 302, 332, 286, 60, - 92, 452, 60, 60, 451, 60, 165, 168, 285, 432, - 284, 435, 60, 60, 108, 501, 329, 94, 540, 96, - 60, 330, 60, 302, 494, 60, 77, 237, 60, 404, - 452, 341, 471, 72, 60, 60, 67, 69, 60, 60, - 68, 0, 70, 60, 60, 60, 61, 180, 60, 60, - 98, 491, 60, 91, 490, 60, 60, 60, 493, 60, - 84, 405, 60, 97, 492, 305, 0, 60, 0, 298, - 0, 100, 270, 298, 270, 298, 106, 298, 270, 0, - 270, 60, 270, 60, 316, 0, 270, 0, 270, 298, - 291, 326, 303, 60, 270, 319, 313, 300, 270, 297, - 60, 60, 108, 175, 295, 270, 270, 290, 60, 501, - 273, 317, 60, 270, 60, 278, 509, 270, 0, 270, - 0, 289, 0, 548, 0, 293, 551, 0, 500, 510, - 501, 501, 0, 544, 501, 0, 0, 0, 509, 0, - 0, 509, 520, 521, 522, 523, 527, 524, 525, 0, - 500, 510, 0, 500, 510, 564, 520, 521, 522, 523, - 527, 524, 525, 581, 0, 0, 0, 0, 0, 0, - 584, 585, 520, 521, 522, 523, 527, 524, 525, 556, - 0, 0, 0, 0, 0, 0, 557, 558, 520, 521, - 522, 523, 527, 524, 525, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 556, 0, 0, 540, 0, 614, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 472, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; + 16, 528, 320, 532, 534, 638, 552, 497, 498, 499, + 516, 559, 619, 461, 515, 574, 302, 472, 487, 250, + 182, 243, 253, 238, 358, 573, 436, 309, 616, 578, + 571, 618, 439, 562, 627, 182, 150, 641, 307, 250, + 561, 458, 632, 447, 454, 243, 238, 450, 402, 445, + 238, 449, 237, 460, 243, 148, 353, 351, 250, 186, + 349, 347, 188, 176, 410, 415, 456, 425, 417, 436, + 433, 143, 467, 169, 439, 429, 302, 358, 344, 302, + 392, 400, 390, 182, 171, 358, 237, 336, 163, 482, + 334, 439, 436, 338, 339, 140, 358, 146, 404, 358, + 485, 60, 302, 0, 311, 0, 94, 0, 320, 404, + 0, 302, 0, 0, 0, 0, 0, 0, 60, 60, + 60, 452, 490, 0, 0, 60, 60, 451, 180, 60, + 405, 302, 165, 88, 60, 60, 489, 461, 60, 146, + 285, 405, 90, 60, 178, 146, 60, 89, 451, 60, + 407, 60, 60, 266, 452, 60, 186, 60, 270, 102, + 288, 501, 60, 100, 642, 60, 60, 284, 494, 60, + 95, 330, 60, 168, 286, 60, 432, 287, 61, 435, + 332, 329, 60, 60, 60, 60, 0, 302, 98, 97, + 96, 77, 60, 60, 451, 452, 501, 60, 480, 540, + 303, 60, 479, 180, 60, 72, 404, 70, 471, 106, + 60, 0, 67, 60, 60, 68, 69, 60, 60, 180, + 493, 60, 60, 60, 492, 491, 93, 60, 60, 60, + 501, 106, 92, 91, 84, 108, 0, 617, 405, 298, + 60, 341, 0, 60, 270, 270, 60, 0, 270, 0, + 0, 270, 273, 0, 0, 313, 305, 108, 175, 293, + 60, 326, 0, 60, 0, 270, 60, 289, 270, 60, + 290, 270, 298, 278, 270, 0, 60, 270, 0, 0, + 295, 270, 60, 291, 298, 298, 298, 270, 548, 270, + 270, 270, 556, 501, 319, 540, 501, 614, 0, 316, + 509, 501, 0, 509, 544, 0, 297, 300, 317, 0, + 0, 0, 500, 510, 0, 500, 510, 0, 472, 520, + 521, 522, 523, 527, 524, 525, 564, 520, 521, 522, + 523, 527, 524, 525, 556, 0, 0, 0, 0, 0, + 0, 557, 558, 520, 521, 522, 523, 527, 524, 525, + 581, 0, 0, 0, 0, 0, 0, 584, 585, 520, + 521, 522, 523, 527, 524, 525, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 551, 0, 0, 0, 0, + 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, + 509, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 500, 510, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 +}; const short QmlJSGrammar::action_check [] = { - 36, 36, 24, 7, 55, 7, 7, 7, 60, 36, - 8, 7, 37, 7, 7, 33, 55, 55, 60, 36, - 36, 33, 33, 55, 8, 33, 7, 7, 34, 36, - 16, 20, 7, 36, 7, 7, 33, 36, 33, 60, - 7, 7, 7, 5, 7, 5, 5, 90, 33, 36, - 7, 33, 7, 36, 7, 33, 66, 36, 7, 36, - 29, 7, 33, 31, 1, 7, 17, 55, 60, 33, - 60, 2, 8, 7, 48, 66, 1, 7, 36, 2, - 8, 7, 36, 2, 60, 2, 8, 7, 17, 1, - 60, 36, 0, 36, 8, 36, 48, 36, 33, 8, - 61, 1, 6, 36, 60, 8, -1, 8, -1, 15, - 48, 10, 7, 8, 61, 8, 20, -1, -1, -1, - -1, -1, 8, -1, -1, -1, -1, 48, 34, 79, - 40, 79, 8, 77, 61, 8, 60, 8, 8, 79, - 8, 51, -1, 40, 42, 61, 62, 8, 61, 62, - 8, 7, -1, 56, 51, 53, 55, 8, 90, 60, - 50, 79, 8, 56, 54, 61, 62, 61, 62, 61, - 62, 40, 61, 62, 60, 40, 61, 62, 61, 62, - 56, 8, 51, 56, 50, 7, 51, 15, 54, 60, - 60, 25, 60, 27, 25, 56, 27, 61, 62, 61, - 62, 36, 60, 29, 38, 29, 34, 38, 36, 25, - 61, 27, 29, -1, 60, 25, 12, 27, 29, 25, - 29, 27, 38, 25, 29, 27, 61, 62, 38, 12, - 7, 12, 38, 60, 8, 25, 38, 27, -1, 61, - 62, 25, 8, 27, 7, -1, 15, 7, 38, 75, - 25, 75, 27, 8, 38, 25, 33, 27, 75, -1, - 86, 57, 86, 38, 75, 34, 75, 63, 38, 86, - 75, 15, 15, -1, 57, 86, 57, 86, -1, -1, - 63, 86, 63, 61, 62, -1, -1, 61, 62, 15, - 34, 34, 36, 36, -1, 61, 62, 47, 61, 62, - 15, 61, 62, -1, 18, 19, 61, 62, 34, 15, - 36, 61, 62, 91, -1, 92, 18, 19, 33, 34, - 29, 36, 18, 19, 18, 19, 29, 33, 34, 29, - 36, 45, 46, 25, 29, 27, -1, -1, -1, -1, - -1, 91, -1, 45, 46, -1, 38, -1, -1, 45, - 46, 45, 46, -1, -1, -1, -1, 66, 67, 68, - -1, -1, -1, 66, 67, 68, 66, 67, 68, -1, - -1, 66, 67, 68, -1, -1, 23, 24, -1, -1, - -1, 29, -1, 92, -1, 32, 23, 24, 35, 92, - 37, 29, 92, 23, 24, 32, 29, 92, 35, -1, - 37, 29, 32, 23, 24, 35, -1, 37, -1, -1, - 29, -1, 32, 23, 24, 35, -1, 37, 66, 67, - 68, 31, 32, -1, 29, 35, -1, 37, 66, 67, - 68, 36, -1, 66, 67, 68, -1, -1, 66, 67, - 68, -1, -1, -1, 92, -1, -1, 66, 67, 68, - -1, -1, -1, -1, 92, -1, -1, 23, 24, 92, - -1, 66, 67, 68, 92, 31, 32, 23, 24, 35, - -1, 37, -1, 92, -1, 31, 32, 23, 24, 35, - -1, 37, 29, 23, 24, 31, 32, 92, -1, 35, - 29, 37, 32, 29, -1, 35, -1, 37, 94, 95, - 96, 97, 98, 99, 29, -1, -1, -1, -1, -1, - -1, 36, -1, -1, 61, 62, -1, -1, -1, 66, - 67, 68, 61, 62, -1, 61, 62, 66, 67, 68, - 66, 67, 68, -1, -1, -1, -1, -1, -1, -1, - 29, 66, 67, 68, -1, 92, -1, -1, 29, -1, - -1, 29, -1, 92, -1, -1, 92, -1, -1, -1, - -1, -1, 23, 24, -1, -1, -1, 92, -1, -1, - 31, 32, 61, 62, 35, -1, 37, 66, 67, 68, - 61, 62, 3, 61, 62, 66, 67, 68, 66, 67, - 68, -1, 13, -1, -1, -1, 17, -1, -1, -1, - -1, -1, -1, 92, -1, 26, -1, 28, -1, -1, - 31, 92, -1, -1, 92, -1, -1, -1, 39, -1, - 41, 42, -1, -1, -1, -1, -1, -1, 49, -1, - -1, 52, 53, -1, -1, -1, -1, 58, -1, 12, - 13, 3, -1, 64, -1, -1, -1, -1, -1, 22, - -1, 13, -1, -1, -1, 17, 29, -1, -1, 80, - 33, 34, -1, 36, 26, -1, 28, -1, -1, -1, - 43, -1, -1, -1, 47, -1, -1, 39, -1, 41, - 42, -1, -1, -1, -1, -1, -1, 49, -1, -1, - 52, 53, 65, 66, 67, 68, 58, 70, -1, -1, - -1, -1, 64, -1, -1, -1, -1, -1, 81, 82, - 83, -1, 12, 13, 87, -1, -1, -1, 80, 92, - -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, - -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, - 12, 13, -1, 43, -1, -1, -1, 47, -1, -1, - 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, - -1, 33, 34, -1, 36, 65, 66, 67, 68, -1, - 70, 43, -1, -1, -1, 47, -1, -1, -1, -1, - -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, - -1, -1, 92, 65, 66, 67, 68, -1, 70, -1, - -1, -1, 12, 13, -1, -1, -1, -1, -1, 81, - 82, 83, 22, -1, -1, 87, -1, -1, -1, 29, - 92, -1, -1, 33, 34, -1, 36, -1, -1, -1, - 12, 13, -1, 43, -1, -1, -1, 47, -1, -1, - 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, - -1, 33, 34, -1, 36, 65, 66, 67, 68, -1, - 70, 43, -1, -1, -1, 47, -1, -1, -1, -1, - -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, - -1, -1, 92, 65, 66, 67, 68, -1, 70, -1, - -1, -1, 12, 13, -1, -1, -1, -1, -1, 81, - 82, 83, 22, -1, -1, 87, -1, -1, -1, 29, - 92, -1, -1, 33, 34, -1, 36, -1, -1, -1, - 12, 13, -1, 43, -1, -1, -1, 47, -1, -1, - 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, - -1, 33, 34, -1, 36, 65, 66, 67, 68, -1, - 70, 43, -1, -1, -1, 47, -1, -1, -1, -1, - -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, - -1, -1, 92, 65, 66, 67, 68, -1, 70, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 81, - 82, 83, -1, -1, -1, 87, -1, -1, -1, -1, - 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 10, -1, 12, 13, -1, -1, -1, -1, -1, -1, - -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, - -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, - -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, - 70, -1, -1, -1, -1, 75, -1, -1, -1, -1, - -1, 81, 82, 83, 84, -1, -1, 87, -1, -1, - -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 10, -1, 12, 13, -1, -1, -1, -1, - -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, - -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, - -1, -1, -1, -1, -1, 43, -1, -1, -1, 47, - -1, -1, -1, -1, -1, -1, -1, 55, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, - 68, -1, 70, -1, -1, -1, -1, 75, -1, -1, - -1, -1, -1, 81, 82, 83, 84, -1, -1, 87, - -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 10, -1, 12, 13, -1, -1, - -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, - -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, - 36, -1, -1, -1, -1, -1, -1, 43, -1, -1, - -1, 47, -1, -1, -1, -1, -1, -1, -1, 55, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, - 66, 67, 68, -1, 70, -1, -1, -1, -1, 75, - -1, -1, -1, -1, -1, 81, 82, 83, 84, -1, - -1, 87, -1, -1, -1, -1, 92, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 11, 12, 13, -1, - -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, - -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, - -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, - -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 65, 66, 67, 68, -1, 70, -1, 72, -1, 74, - -1, 76, -1, -1, -1, -1, 81, 82, 83, -1, - -1, -1, 87, -1, -1, -1, -1, 92, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, - -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, - -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, - -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, - 40, -1, 42, 43, 44, -1, -1, 47, -1, -1, - -1, 51, -1, 53, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, - 70, -1, 72, -1, 74, -1, 76, -1, -1, -1, - -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, - -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, - -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, - 29, -1, -1, -1, 33, 34, -1, 36, -1, -1, - -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, - -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, - -1, 70, -1, 72, -1, 74, 75, 76, -1, -1, - -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, - -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 8, -1, -1, 11, 12, 13, -1, - -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, - -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, - -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, - -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, - -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, - 65, 66, 67, 68, -1, 70, -1, 72, -1, 74, - -1, 76, -1, -1, -1, -1, 81, 82, 83, -1, - -1, -1, 87, -1, -1, -1, -1, 92, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 8, -1, -1, - 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, - -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, - -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, - -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, - 51, -1, 53, -1, -1, 56, -1, -1, -1, -1, - -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, - -1, 72, -1, 74, -1, 76, -1, -1, -1, -1, - 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, - -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 8, -1, -1, 11, 12, 13, -1, -1, -1, - -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, - -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, - -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, - 47, -1, -1, -1, 51, -1, 53, -1, -1, 56, - -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, - 67, 68, -1, 70, -1, 72, -1, 74, -1, 76, - -1, -1, -1, -1, 81, 82, 83, -1, -1, -1, - 87, -1, -1, -1, -1, 92, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 8, -1, -1, 11, 12, - 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, - -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, - 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, - 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, - 53, -1, -1, 56, -1, -1, -1, -1, -1, -1, - -1, -1, 65, 66, 67, 68, -1, 70, -1, 72, - -1, 74, -1, 76, -1, -1, -1, -1, 81, 82, - 83, -1, -1, -1, 87, -1, -1, -1, -1, 92, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, - 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, - 22, -1, -1, -1, -1, -1, -1, 29, 30, -1, - -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, - 42, 43, 44, -1, -1, 47, -1, -1, -1, 51, - -1, 53, -1, -1, -1, -1, -1, -1, -1, 61, - -1, -1, -1, 65, 66, 67, 68, 69, 70, -1, - 72, 73, 74, -1, 76, -1, 78, -1, -1, 81, - 82, 83, -1, -1, -1, 87, -1, -1, -1, -1, - 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, - -1, 22, -1, -1, -1, -1, -1, -1, 29, 30, - -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, - -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, - 51, -1, 53, -1, -1, -1, -1, -1, -1, -1, - 61, -1, -1, -1, 65, 66, 67, 68, 69, 70, - -1, 72, 73, 74, -1, 76, -1, 78, -1, -1, - 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, - -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4, 5, 6, -1, -1, 9, 10, 11, -1, - -1, 14, -1, 16, -1, -1, -1, 20, 21, 22, - -1, -1, -1, -1, -1, -1, 29, 30, 31, 32, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 59, -1, -1, -1, - -1, -1, -1, 66, 67, 68, 69, 70, 71, -1, - 73, 74, 75, 76, 77, 78, -1, -1, 81, 82, - 83, 84, 85, 86, -1, -1, -1, -1, -1, 92, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, - 5, 6, -1, -1, 9, 10, 11, -1, -1, 14, - -1, 16, -1, -1, -1, 20, 21, 22, -1, -1, - -1, -1, -1, -1, 29, 30, 31, 32, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, - -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 59, -1, -1, -1, -1, -1, - 65, 66, 67, -1, 69, 70, 71, -1, 73, 74, - 75, 76, 77, 78, -1, -1, 81, 82, 83, 84, - 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, - -1, -1, 9, 10, 11, -1, -1, 14, -1, 16, - -1, -1, -1, 20, 21, 22, -1, -1, -1, -1, - -1, -1, 29, 30, 31, 32, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 43, -1, -1, -1, - 47, -1, -1, -1, -1, -1, -1, -1, 55, -1, - -1, -1, 59, -1, -1, -1, -1, -1, 65, 66, - 67, -1, 69, 70, 71, -1, 73, 74, 75, 76, - 77, 78, -1, -1, 81, 82, 83, 84, 85, 86, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, - 9, -1, 11, 12, 13, 14, -1, -1, -1, -1, - -1, -1, 21, 22, -1, -1, -1, -1, -1, -1, - 29, 30, -1, -1, 33, 34, -1, 36, -1, -1, - -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, - -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, - 59, -1, 61, -1, -1, -1, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - -1, -1, 81, 82, 83, 84, 85, -1, 87, -1, - -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 4, -1, -1, -1, -1, 9, -1, - 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, - 21, 22, -1, -1, -1, -1, -1, -1, 29, 30, - -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, - -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, - 51, -1, 53, -1, -1, -1, -1, -1, 59, -1, - 61, -1, -1, -1, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, -1, -1, - 81, 82, 83, 84, 85, -1, 87, -1, -1, -1, - -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4, 5, 6, -1, -1, 9, 10, 11, 12, - 13, 14, -1, 16, -1, -1, -1, 20, 21, 22, - -1, -1, -1, -1, -1, -1, 29, 30, 31, 32, - 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, - 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, - 53, -1, -1, -1, -1, -1, 59, -1, 61, -1, - -1, -1, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, -1, -1, 81, 82, - 83, 84, 85, 86, 87, -1, -1, -1, -1, 92, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, - 5, 6, -1, -1, 9, 10, 11, 12, 13, 14, - -1, 16, -1, -1, -1, 20, 21, 22, -1, -1, - -1, -1, -1, -1, 29, 30, 31, 32, 33, 34, - -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, - -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, - 55, -1, -1, -1, 59, -1, 61, -1, -1, -1, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, -1, -1, 81, 82, 83, 84, - 85, 86, 87, -1, -1, -1, -1, 92, -1, -1, - -1, -1, -1, -1, -1, -1, -1, + 8, 36, 7, 7, 7, 36, 7, 7, 7, 60, + 7, 36, 60, 33, 55, 33, 7, 34, 16, 8, + 36, 55, 24, 17, 37, 55, 7, 7, 7, 5, + 7, 55, 7, 7, 5, 7, 20, 33, 7, 7, + 7, 36, 1, 36, 36, 33, 36, 29, 60, 36, + 36, 36, 90, 31, 60, 66, 66, 7, 5, 7, + 33, 2, 8, 33, 8, 48, 8, 33, 7, 33, + 33, 36, 7, 33, 1, 36, 7, 2, 7, 36, + 8, 7, 1, 36, 0, 36, 48, 17, 8, 1, + -1, 36, -1, 8, 7, 33, 6, -1, -1, 36, + 8, 10, 60, -1, -1, 61, 60, 7, 8, 8, + 20, 60, 48, 8, 48, 55, -1, 60, 36, 8, + 8, 8, -1, -1, 79, 8, 8, 79, 61, -1, + 15, -1, 8, 8, -1, -1, 50, 42, 61, 60, + 54, 56, 8, 8, 61, 62, 55, 79, 53, 34, + 61, 62, 60, 77, 61, 62, 40, 61, 62, 61, + 62, 60, 8, 61, 62, 60, -1, 51, 90, 61, + 62, 60, 60, 60, 15, 61, 62, 60, 50, 61, + 56, 56, 54, 61, 62, 40, 40, 61, 62, 2, + 56, 40, 25, 34, 27, 60, 51, 51, 15, 25, + 12, 27, 51, 12, 29, 38, 29, 25, -1, 27, + 56, 25, 38, 27, 25, 7, 27, 34, 7, 36, + 38, 25, 8, 27, 38, 15, -1, 38, 29, 7, + 25, 29, 27, 29, 38, 29, -1, 61, 62, 36, + 8, 15, -1, 38, 34, 57, 36, -1, 57, -1, + 75, 63, 75, -1, 63, 33, 12, -1, 8, -1, + 34, 86, 36, 86, 61, 62, -1, 91, -1, 61, + 62, -1, 61, 62, 75, 61, 62, 75, 25, 75, + 27, 75, 25, 15, 27, 86, -1, -1, 86, 7, + 86, 38, 86, 61, 62, 38, 25, 25, 27, 27, + -1, 57, 34, 25, 36, 27, 25, 63, 27, 38, + 38, 61, 62, 47, 92, -1, 38, 29, -1, 38, + 18, 19, 18, 19, 18, 19, 29, 61, 62, 29, + -1, 18, 19, -1, -1, -1, -1, -1, 29, -1, + -1, -1, -1, 61, 62, -1, -1, 45, 46, 45, + 46, 45, 46, -1, 66, 67, 68, 91, 45, 46, + 23, 24, -1, 66, 67, 68, 66, 67, 68, 32, + 29, -1, 35, 29, 37, 66, 67, 68, 29, -1, + 92, 23, 24, 29, 15, 23, 24, -1, 29, 92, + 32, -1, 92, 35, 32, 37, -1, 35, -1, 37, + -1, 92, 33, 34, -1, 36, -1, 66, 67, 68, + 66, 67, 68, -1, -1, 66, 67, 68, -1, -1, + 66, 67, 68, 23, 24, 66, 67, 68, -1, -1, + 23, 24, 32, 92, -1, 35, 92, 37, 29, 32, + -1, 92, 35, 29, 37, 36, 92, -1, -1, -1, + 36, 92, 23, 24, 94, 95, 96, 97, 98, 99, + 31, 32, -1, -1, 35, 29, 37, -1, -1, -1, + -1, 29, -1, -1, -1, 66, 67, 68, -1, 29, + 66, 67, 68, -1, -1, -1, -1, 29, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 61, 62, 29, + -1, 92, 66, 67, 68, -1, 92, -1, 66, 67, + 68, 61, 62, -1, -1, -1, 66, 67, 68, 61, + 62, -1, 29, -1, 66, 67, 68, -1, 92, -1, + -1, 61, 62, 29, 92, -1, 66, 67, 68, -1, + -1, -1, 92, -1, 23, 24, -1, -1, -1, -1, + 92, -1, 31, 32, 61, 62, 35, -1, 37, 66, + 67, 68, 92, 3, -1, 61, 62, -1, -1, -1, + 66, 67, 68, 13, -1, -1, -1, 17, -1, -1, + -1, -1, -1, -1, -1, 92, 26, -1, 28, -1, + -1, 31, -1, -1, -1, -1, 92, -1, -1, 39, + -1, 41, 42, -1, -1, -1, -1, -1, -1, 49, + 12, 13, 52, 53, -1, -1, -1, -1, 58, -1, + 22, -1, -1, 3, 64, -1, -1, 29, -1, -1, + -1, 33, 34, 13, 36, -1, -1, 17, -1, -1, + 80, 43, -1, -1, -1, 47, 26, -1, 28, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, + -1, 41, 42, 65, 66, 67, 68, -1, 70, 49, + -1, -1, 52, 53, -1, -1, -1, -1, 58, 81, + 82, 83, -1, -1, 64, 87, -1, -1, -1, -1, + 92, -1, -1, -1, 12, 13, -1, -1, -1, -1, + 80, -1, -1, -1, 22, -1, -1, -1, -1, -1, + -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, + -1, -1, 12, 13, -1, 43, -1, -1, -1, 47, + -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, + -1, -1, -1, 33, 34, -1, 36, 65, 66, 67, + 68, -1, 70, 43, -1, -1, -1, 47, -1, -1, + -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, + -1, -1, -1, -1, 92, 65, 66, 67, 68, -1, + 70, -1, -1, -1, 12, 13, -1, -1, -1, -1, + -1, 81, 82, 83, 22, -1, -1, 87, -1, -1, + -1, 29, 92, -1, -1, 33, 34, -1, 36, -1, + -1, -1, 12, 13, -1, 43, -1, -1, -1, 47, + -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, + -1, -1, -1, 33, 34, -1, 36, 65, 66, 67, + 68, -1, 70, 43, -1, -1, -1, 47, -1, -1, + -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, + -1, -1, -1, -1, 92, 65, 66, 67, 68, -1, + 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, + -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 12, 13, -1, -1, -1, -1, -1, -1, + -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, + -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, + -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, + 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, + -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 10, -1, 12, 13, -1, -1, -1, -1, + -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, + -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, + -1, -1, -1, -1, -1, 43, -1, -1, -1, 47, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, + 68, -1, 70, -1, -1, -1, -1, 75, -1, -1, + -1, -1, -1, 81, 82, 83, 84, -1, -1, 87, + -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 10, -1, 12, 13, -1, -1, + -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, + -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, + 36, -1, -1, -1, -1, -1, -1, 43, -1, -1, + -1, 47, -1, -1, -1, -1, -1, -1, -1, 55, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, + 66, 67, 68, -1, 70, -1, -1, -1, -1, 75, + -1, -1, -1, -1, -1, 81, 82, 83, 84, -1, + -1, 87, -1, -1, -1, -1, 92, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 10, -1, 12, 13, + -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, + -1, -1, -1, -1, -1, 29, -1, -1, -1, 33, + 34, -1, 36, -1, -1, -1, -1, -1, -1, 43, + -1, -1, -1, 47, -1, -1, -1, -1, -1, -1, + -1, 55, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 65, 66, 67, 68, -1, 70, -1, -1, -1, + -1, 75, -1, -1, -1, -1, -1, 81, 82, 83, + 84, -1, -1, 87, -1, -1, -1, -1, 92, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 11, 12, + 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, + -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, + 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, + 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, + 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 65, 66, 67, 68, -1, 70, -1, 72, + -1, 74, -1, 76, -1, -1, -1, -1, 81, 82, + 83, -1, -1, -1, 87, -1, -1, -1, -1, 92, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, + 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, + 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, + -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, + 42, 43, 44, -1, -1, 47, -1, -1, -1, 51, + -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, + 72, -1, 74, 75, 76, -1, -1, -1, -1, 81, + 82, 83, -1, -1, -1, 87, -1, -1, -1, -1, + 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 7, -1, -1, -1, 11, 12, 13, -1, -1, -1, + -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, + -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, + -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, + 47, -1, -1, -1, 51, -1, 53, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, + 67, 68, -1, 70, -1, 72, -1, 74, -1, 76, + -1, -1, -1, -1, 81, 82, 83, -1, -1, -1, + 87, -1, -1, -1, -1, 92, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8, -1, -1, 11, 12, + 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, + -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, + 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, + 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, + 53, -1, -1, 56, -1, -1, -1, -1, -1, -1, + -1, -1, 65, 66, 67, 68, -1, 70, -1, 72, + -1, 74, -1, 76, -1, -1, -1, -1, 81, 82, + 83, -1, -1, -1, 87, -1, -1, -1, -1, 92, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, + -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, + -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, + 29, -1, -1, -1, 33, 34, -1, 36, -1, -1, + -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, + -1, -1, 51, -1, 53, -1, -1, 56, -1, -1, + -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, + -1, 70, -1, 72, -1, 74, -1, 76, -1, -1, + -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, + -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8, -1, -1, 11, 12, 13, -1, + -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, + -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, + -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, + -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, + -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, + 65, 66, 67, 68, -1, 70, -1, 72, -1, 74, + -1, 76, -1, -1, -1, -1, 81, 82, 83, -1, + -1, -1, 87, -1, -1, -1, -1, 92, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8, -1, -1, + 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, + -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, + -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, + -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, + 51, -1, 53, -1, -1, 56, -1, -1, -1, -1, + -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, + -1, 72, -1, 74, -1, 76, -1, -1, -1, -1, + 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, + -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, + -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, + 30, -1, -1, 33, 34, -1, 36, -1, -1, -1, + 40, -1, 42, 43, 44, -1, -1, 47, -1, -1, + -1, 51, -1, 53, -1, -1, -1, -1, -1, -1, + -1, 61, -1, -1, -1, 65, 66, 67, 68, 69, + 70, -1, 72, 73, 74, -1, 76, -1, 78, -1, + -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, + -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, + -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, + 29, 30, -1, -1, 33, 34, -1, 36, -1, -1, + -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, + -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, + -1, -1, 61, -1, -1, -1, 65, 66, 67, 68, + 69, 70, -1, 72, 73, 74, -1, 76, -1, 78, + -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, + -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 4, 5, 6, -1, -1, 9, 10, + 11, -1, -1, 14, -1, 16, -1, -1, -1, 20, + 21, 22, -1, -1, -1, -1, -1, -1, 29, 30, + 31, 32, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 43, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 59, -1, + -1, -1, -1, -1, -1, 66, 67, 68, 69, 70, + 71, -1, 73, 74, 75, 76, 77, 78, -1, -1, + 81, 82, 83, 84, 85, 86, -1, -1, -1, -1, + -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4, 5, 6, -1, -1, 9, 10, 11, -1, + -1, 14, -1, 16, -1, -1, -1, 20, 21, 22, + -1, -1, -1, -1, -1, -1, 29, 30, 31, 32, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 43, -1, -1, -1, 47, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 59, -1, -1, -1, + -1, -1, 65, 66, 67, -1, 69, 70, 71, -1, + 73, 74, 75, 76, 77, 78, -1, -1, 81, 82, + 83, 84, 85, 86, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, + 5, 6, -1, -1, 9, 10, 11, -1, -1, 14, + -1, 16, -1, -1, -1, 20, 21, 22, -1, -1, + -1, -1, -1, -1, 29, 30, 31, 32, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, + -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, + 55, -1, -1, -1, 59, -1, -1, -1, -1, -1, + 65, 66, 67, -1, 69, 70, 71, -1, 73, 74, + 75, 76, 77, 78, -1, -1, 81, 82, 83, 84, + 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, + -1, -1, 9, -1, 11, 12, 13, 14, -1, -1, + -1, -1, -1, -1, 21, 22, -1, -1, -1, -1, + -1, -1, 29, 30, -1, -1, 33, 34, -1, 36, + -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, + 47, -1, -1, -1, 51, -1, 53, -1, -1, -1, + -1, -1, 59, -1, 61, -1, -1, -1, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, -1, -1, 81, 82, 83, 84, 85, -1, + 87, -1, -1, -1, -1, 92, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, + 9, -1, 11, 12, 13, 14, -1, -1, -1, -1, + -1, -1, 21, 22, -1, -1, -1, -1, -1, -1, + 29, 30, -1, -1, 33, 34, -1, 36, -1, -1, + -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, + -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, + 59, -1, 61, -1, -1, -1, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + -1, -1, 81, 82, 83, 84, 85, -1, 87, -1, + -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 4, 5, 6, -1, -1, 9, 10, + 11, 12, 13, 14, -1, 16, -1, -1, -1, 20, + 21, 22, -1, -1, -1, -1, -1, -1, 29, 30, + 31, 32, 33, 34, -1, 36, -1, -1, -1, 40, + -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, + 51, -1, 53, -1, -1, -1, -1, -1, 59, -1, + 61, -1, -1, -1, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, -1, -1, + 81, 82, 83, 84, 85, 86, 87, -1, -1, -1, + -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4, 5, 6, -1, -1, 9, 10, 11, 12, + 13, 14, -1, 16, -1, -1, -1, 20, 21, 22, + -1, -1, -1, -1, -1, -1, 29, 30, 31, 32, + 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, + 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, + 53, -1, 55, -1, -1, -1, 59, -1, 61, -1, + -1, -1, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, -1, -1, 81, 82, + 83, 84, 85, 86, 87, -1, -1, -1, -1, 92, + -1, -1, -1, -1, -1, -1, -1, -1, -1, - 15, 2, 105, 3, 29, 15, 4, 2, 15, 29, - 9, 15, 3, 15, 3, 2, 19, 39, 15, 15, - 13, 15, 3, 15, 2, 15, 3, 15, 3, 11, - 13, 15, 71, 39, 39, 3, 22, 2, 99, 19, - 4, 15, 2, 15, 29, 15, 19, 3, 15, 3, - 29, 22, 15, 29, 15, 2, 22, 15, 2, 2, - 15, 2, 2, 2, 2, 22, 3, 15, 3, 2, - 39, 3, 3, 15, 97, 94, 3, 39, 2, 2, - 39, 3, 3, 2, 2, 101, 3, 40, 39, 39, - 39, 3, 2, 39, 39, 15, 22, 13, 3, 2, - 13, 2, -1, 39, 13, 35, -1, 16, -1, 39, - -1, -1, -1, 15, 48, -1, 15, 13, 52, 48, - 48, 50, 3, 48, 20, 53, -1, 52, -1, 45, - -1, 15, 45, 48, 48, 50, 50, 48, -1, 50, - 48, 48, 48, 50, 48, 53, 52, 39, 48, 53, - 48, 39, 44, 53, 48, 53, 44, 48, 15, 50, - -1, 48, 48, 48, 58, 48, 3, 72, 53, 48, - 53, 50, 48, 48, 50, 48, 62, 64, 53, 82, - 53, 82, 48, 48, 41, 13, 88, 53, 16, 54, - 48, 72, 48, 3, 50, 48, 54, 4, 48, 13, - 50, 100, 86, 56, 48, 48, 50, 50, 48, 48, - 50, -1, 51, 48, 48, 48, 51, 50, 48, 48, - 54, 50, 48, 53, 50, 48, 48, 48, 50, 48, - 53, 45, 48, 54, 50, 72, -1, 48, -1, 48, - -1, 60, 53, 48, 53, 48, 15, 48, 53, -1, - 53, 48, 53, 48, 65, -1, 53, -1, 53, 48, - 55, 70, 72, 48, 53, 70, 63, 70, 53, 70, - 48, 48, 41, 42, 59, 53, 53, 55, 48, 13, - 57, 70, 48, 53, 48, 55, 20, 53, -1, 53, - -1, 55, -1, 5, -1, 61, 5, -1, 32, 33, - 13, 13, -1, 16, 13, -1, -1, -1, 20, -1, - -1, 20, 22, 23, 24, 25, 26, 27, 28, -1, - 32, 33, -1, 32, 33, 21, 22, 23, 24, 25, - 26, 27, 28, 13, -1, -1, -1, -1, -1, -1, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 13, - -1, -1, -1, -1, -1, -1, 20, 21, 22, 23, - 24, 25, 26, 27, 28, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 13, -1, -1, 16, -1, 18, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1}; + 3, 13, 15, 29, 15, 15, 15, 105, 4, 2, + 15, 19, 9, 15, 29, 15, 3, 39, 3, 2, + 15, 15, 3, 15, 2, 29, 3, 3, 19, 15, + 29, 19, 22, 15, 13, 15, 71, 11, 2, 2, + 29, 3, 15, 15, 3, 15, 15, 22, 2, 99, + 15, 22, 4, 2, 15, 39, 2, 2, 2, 15, + 3, 2, 15, 3, 2, 2, 2, 97, 3, 3, + 3, 39, 39, 39, 22, 94, 3, 2, 101, 3, + 40, 39, 39, 15, 39, 2, 4, 3, 39, 39, + 2, 22, 3, 2, 15, 3, 2, 39, 13, 2, + 39, 48, 3, -1, 2, -1, 53, -1, 15, 13, + -1, 3, -1, -1, -1, -1, -1, -1, 48, 48, + 48, 50, 50, -1, -1, 48, 48, 50, 50, 48, + 45, 3, 62, 52, 48, 48, 50, 15, 48, 39, + 53, 45, 52, 48, 44, 39, 48, 52, 50, 48, + 44, 48, 48, 48, 50, 48, 15, 48, 53, 58, + 53, 13, 48, 60, 16, 48, 48, 53, 50, 48, + 53, 72, 48, 64, 53, 48, 82, 53, 51, 82, + 72, 88, 48, 48, 48, 48, -1, 3, 54, 54, + 54, 54, 48, 48, 50, 50, 13, 48, 35, 16, + 72, 48, 39, 50, 48, 56, 13, 51, 86, 15, + 48, -1, 50, 48, 48, 50, 50, 48, 48, 50, + 50, 48, 48, 48, 50, 50, 53, 48, 48, 48, + 13, 15, 53, 53, 53, 41, -1, 20, 45, 48, + 48, 100, -1, 48, 53, 53, 48, -1, 53, -1, + -1, 53, 57, -1, -1, 63, 72, 41, 42, 61, + 48, 70, -1, 48, -1, 53, 48, 55, 53, 48, + 55, 53, 48, 55, 53, -1, 48, 53, -1, -1, + 59, 53, 48, 55, 48, 48, 48, 53, 5, 53, + 53, 53, 13, 13, 70, 16, 13, 18, -1, 65, + 20, 13, -1, 20, 16, -1, 70, 70, 70, -1, + -1, -1, 32, 33, -1, 32, 33, -1, 39, 22, + 23, 24, 25, 26, 27, 28, 21, 22, 23, 24, + 25, 26, 27, 28, 13, -1, -1, -1, -1, -1, + -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 13, -1, -1, -1, -1, -1, -1, 20, 21, 22, + 23, 24, 25, 26, 27, 28, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 5, -1, -1, -1, -1, + -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, + 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 32, 33, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1 +}; -} // namespace QbsQmlJS +} // end of namespace QbsQmlJS diff --git a/src/lib/corelib/parser/qmljsgrammar_p.h b/src/lib/corelib/parser/qmljsgrammar_p.h index a3525408b..aa41562de 100644 --- a/src/lib/corelib/parser/qmljsgrammar_p.h +++ b/src/lib/corelib/parser/qmljsgrammar_p.h @@ -52,156 +52,155 @@ #ifndef QMLJSGRAMMAR_P_H #define QMLJSGRAMMAR_P_H -#include "qmljsglobal_p.h" #include <QtCore/qglobal.h> namespace QbsQmlJS { -class QML_PARSER_EXPORT QmlJSGrammar +class QmlJSGrammar { public: - enum VariousConstants { - EOF_SYMBOL = 0, - REDUCE_HERE = 101, - SHIFT_THERE = 100, - T_AND = 1, - T_AND_AND = 2, - T_AND_EQ = 3, - T_AS = 91, - T_AUTOMATIC_SEMICOLON = 62, - T_BREAK = 4, - T_CASE = 5, - T_CATCH = 6, - T_COLON = 7, - T_COMMA = 8, - T_COMMENT = 88, - T_CONST = 84, - T_CONTINUE = 9, - T_DEBUGGER = 85, - T_DEFAULT = 10, - T_DELETE = 11, - T_DIVIDE_ = 12, - T_DIVIDE_EQ = 13, - T_DO = 14, - T_DOT = 15, - T_ELSE = 16, - T_EQ = 17, - T_EQ_EQ = 18, - T_EQ_EQ_EQ = 19, - T_ERROR = 93, - T_FALSE = 83, - T_FEED_JS_EXPRESSION = 97, - T_FEED_JS_PROGRAM = 99, - T_FEED_JS_SOURCE_ELEMENT = 98, - T_FEED_JS_STATEMENT = 96, - T_FEED_UI_OBJECT_MEMBER = 95, - T_FEED_UI_PROGRAM = 94, - T_FINALLY = 20, - T_FOR = 21, - T_FUNCTION = 22, - T_GE = 23, - T_GT = 24, - T_GT_GT = 25, - T_GT_GT_EQ = 26, - T_GT_GT_GT = 27, - T_GT_GT_GT_EQ = 28, - T_IDENTIFIER = 29, - T_IF = 30, - T_IMPORT = 90, - T_IN = 31, - T_INSTANCEOF = 32, - T_LBRACE = 33, - T_LBRACKET = 34, - T_LE = 35, - T_LPAREN = 36, - T_LT = 37, - T_LT_LT = 38, - T_LT_LT_EQ = 39, - T_MINUS = 40, - T_MINUS_EQ = 41, - T_MINUS_MINUS = 42, - T_MULTILINE_STRING_LITERAL = 87, - T_NEW = 43, - T_NOT = 44, - T_NOT_EQ = 45, - T_NOT_EQ_EQ = 46, - T_NULL = 81, - T_NUMERIC_LITERAL = 47, - T_ON = 92, - T_OR = 48, - T_OR_EQ = 49, - T_OR_OR = 50, - T_PLUS = 51, - T_PLUS_EQ = 52, - T_PLUS_PLUS = 53, - T_PROPERTY = 66, - T_PUBLIC = 89, - T_QUESTION = 54, - T_RBRACE = 55, - T_RBRACKET = 56, - T_READONLY = 68, - T_REMAINDER = 57, - T_REMAINDER_EQ = 58, - T_RESERVED_WORD = 86, - T_RETURN = 59, - T_RPAREN = 60, - T_SEMICOLON = 61, - T_SIGNAL = 67, - T_STAR = 63, - T_STAR_EQ = 64, - T_STRING_LITERAL = 65, - T_SWITCH = 69, - T_THIS = 70, - T_THROW = 71, - T_TILDE = 72, - T_TRUE = 82, - T_TRY = 73, - T_TYPEOF = 74, - T_VAR = 75, - T_VOID = 76, - T_WHILE = 77, - T_WITH = 78, - T_XOR = 79, - T_XOR_EQ = 80, - - ACCEPT_STATE = 644, - RULE_COUNT = 349, - STATE_COUNT = 645, - TERMINAL_COUNT = 102, - NON_TERMINAL_COUNT = 107, - - GOTO_INDEX_OFFSET = 645, - GOTO_INFO_OFFSET = 2807, - GOTO_CHECK_OFFSET = 2807 - }; - - static const char *const spell []; - static const short lhs []; - static const short rhs []; - static const short goto_default []; - static const short action_default []; - static const short action_index []; - static const short action_info []; - static const short action_check []; - - static inline int nt_action (int state, int nt) - { - const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt; - if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt) - return goto_default [nt]; - - return action_info [GOTO_INFO_OFFSET + yyn]; - } - - static inline int t_action (int state, int token) - { - const int yyn = action_index [state] + token; - - if (yyn < 0 || action_check [yyn] != token) - return - action_default [state]; - - return action_info [yyn]; - } + enum VariousConstants { + EOF_SYMBOL = 0, + REDUCE_HERE = 101, + SHIFT_THERE = 100, + T_AND = 1, + T_AND_AND = 2, + T_AND_EQ = 3, + T_AS = 91, + T_AUTOMATIC_SEMICOLON = 62, + T_BREAK = 4, + T_CASE = 5, + T_CATCH = 6, + T_COLON = 7, + T_COMMA = 8, + T_COMMENT = 88, + T_CONST = 84, + T_CONTINUE = 9, + T_DEBUGGER = 85, + T_DEFAULT = 10, + T_DELETE = 11, + T_DIVIDE_ = 12, + T_DIVIDE_EQ = 13, + T_DO = 14, + T_DOT = 15, + T_ELSE = 16, + T_EQ = 17, + T_EQ_EQ = 18, + T_EQ_EQ_EQ = 19, + T_ERROR = 93, + T_FALSE = 83, + T_FEED_JS_EXPRESSION = 97, + T_FEED_JS_PROGRAM = 99, + T_FEED_JS_SOURCE_ELEMENT = 98, + T_FEED_JS_STATEMENT = 96, + T_FEED_UI_OBJECT_MEMBER = 95, + T_FEED_UI_PROGRAM = 94, + T_FINALLY = 20, + T_FOR = 21, + T_FUNCTION = 22, + T_GE = 23, + T_GT = 24, + T_GT_GT = 25, + T_GT_GT_EQ = 26, + T_GT_GT_GT = 27, + T_GT_GT_GT_EQ = 28, + T_IDENTIFIER = 29, + T_IF = 30, + T_IMPORT = 90, + T_IN = 31, + T_INSTANCEOF = 32, + T_LBRACE = 33, + T_LBRACKET = 34, + T_LE = 35, + T_LPAREN = 36, + T_LT = 37, + T_LT_LT = 38, + T_LT_LT_EQ = 39, + T_MINUS = 40, + T_MINUS_EQ = 41, + T_MINUS_MINUS = 42, + T_MULTILINE_STRING_LITERAL = 87, + T_NEW = 43, + T_NOT = 44, + T_NOT_EQ = 45, + T_NOT_EQ_EQ = 46, + T_NULL = 81, + T_NUMERIC_LITERAL = 47, + T_ON = 92, + T_OR = 48, + T_OR_EQ = 49, + T_OR_OR = 50, + T_PLUS = 51, + T_PLUS_EQ = 52, + T_PLUS_PLUS = 53, + T_PROPERTY = 66, + T_PUBLIC = 89, + T_QUESTION = 54, + T_RBRACE = 55, + T_RBRACKET = 56, + T_READONLY = 68, + T_REMAINDER = 57, + T_REMAINDER_EQ = 58, + T_RESERVED_WORD = 86, + T_RETURN = 59, + T_RPAREN = 60, + T_SEMICOLON = 61, + T_SIGNAL = 67, + T_STAR = 63, + T_STAR_EQ = 64, + T_STRING_LITERAL = 65, + T_SWITCH = 69, + T_THIS = 70, + T_THROW = 71, + T_TILDE = 72, + T_TRUE = 82, + T_TRY = 73, + T_TYPEOF = 74, + T_VAR = 75, + T_VOID = 76, + T_WHILE = 77, + T_WITH = 78, + T_XOR = 79, + T_XOR_EQ = 80, + + ACCEPT_STATE = 644, + RULE_COUNT = 349, + STATE_COUNT = 645, + TERMINAL_COUNT = 102, + NON_TERMINAL_COUNT = 107, + + GOTO_INDEX_OFFSET = 645, + GOTO_INFO_OFFSET = 2789, + GOTO_CHECK_OFFSET = 2789 + }; + + static const char *const spell[]; + static const short lhs[]; + static const short rhs[]; + static const short goto_default[]; + static const short action_default[]; + static const short action_index[]; + static const short action_info[]; + static const short action_check[]; + + static inline int nt_action (int state, int nt) + { + const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt; + if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt) + return goto_default [nt]; + + return action_info [GOTO_INFO_OFFSET + yyn]; + } + + static inline int t_action (int state, int token) + { + const int yyn = action_index [state] + token; + + if (yyn < 0 || action_check [yyn] != token) + return - action_default [state]; + + return action_info [yyn]; + } }; diff --git a/src/lib/corelib/parser/qmljslexer.cpp b/src/lib/corelib/parser/qmljslexer.cpp index 931704339..db3004fc8 100644 --- a/src/lib/corelib/parser/qmljslexer.cpp +++ b/src/lib/corelib/parser/qmljslexer.cpp @@ -82,7 +82,7 @@ static QChar convertHex(QChar c1, QChar c2) static QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4) { - return {uchar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode())), + return QChar{uchar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode())), uchar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()))}; } diff --git a/src/lib/corelib/parser/qmljslexer_p.h b/src/lib/corelib/parser/qmljslexer_p.h index cf41fb255..aef68e0c5 100644 --- a/src/lib/corelib/parser/qmljslexer_p.h +++ b/src/lib/corelib/parser/qmljslexer_p.h @@ -56,6 +56,10 @@ #include <tools/qbs_export.h> #include <QtCore/qstring.h> +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#include <QtCore5Compat/qstringref.h> +#endif + namespace QbsQmlJS { class Engine; diff --git a/src/lib/corelib/tools/buildoptions.h b/src/lib/corelib/tools/buildoptions.h index bd0fb22cb..59b87237d 100644 --- a/src/lib/corelib/tools/buildoptions.h +++ b/src/lib/corelib/tools/buildoptions.h @@ -45,10 +45,10 @@ #include "joblimits.h" #include <QtCore/qshareddata.h> +#include <QtCore/qstringlist.h> QT_BEGIN_NAMESPACE class QJsonObject; -class QStringList; QT_END_NAMESPACE namespace qbs { diff --git a/src/lib/corelib/tools/clangclinfo.cpp b/src/lib/corelib/tools/clangclinfo.cpp index 4e1022c28..0090b8f2c 100644 --- a/src/lib/corelib/tools/clangclinfo.cpp +++ b/src/lib/corelib/tools/clangclinfo.cpp @@ -102,8 +102,7 @@ ClangClInfo ClangClInfo::fromCompilerFilePath(const QString &path, Logger &logge return {}; } - const auto toolchainInstallPath = getToolchainInstallPath(path); - return {toolchainInstallPath, vcvarsallPath}; + return {getToolchainInstallPath(QFileInfo(path)), vcvarsallPath}; } std::vector<ClangClInfo> ClangClInfo::installedCompilers( @@ -151,7 +150,7 @@ std::vector<ClangClInfo> ClangClInfo::installedCompilers( result.reserve(compilerPaths.size() + msvcs.size()); for (const auto &path: compilerPaths) - result.push_back({getToolchainInstallPath(path), vcvarsallPath}); + result.push_back({getToolchainInstallPath(QFileInfo(path)), vcvarsallPath}); // If we didn't find custom LLVM installation, try to find if it's installed with Visual Studio for (const auto &msvc : msvcs) { @@ -165,7 +164,7 @@ std::vector<ClangClInfo> ClangClInfo::installedCompilers( .arg(msvc.installDir); } - result.push_back({getToolchainInstallPath(compilerPath), vcvarsallPath}); + result.push_back({getToolchainInstallPath(QFileInfo(compilerPath)), vcvarsallPath}); } } diff --git a/src/lib/corelib/tools/commandechomode.h b/src/lib/corelib/tools/commandechomode.h index 88d8377ad..e7b315563 100644 --- a/src/lib/corelib/tools/commandechomode.h +++ b/src/lib/corelib/tools/commandechomode.h @@ -43,11 +43,7 @@ #include "qbs_export.h" #include <QtCore/qglobal.h> - -QT_BEGIN_NAMESPACE -class QString; -class QStringList; -QT_END_NAMESPACE +#include <QtCore/qstringlist.h> namespace qbs { diff --git a/src/lib/corelib/tools/error.h b/src/lib/corelib/tools/error.h index 3ae9399f1..ea8ddb5ec 100644 --- a/src/lib/corelib/tools/error.h +++ b/src/lib/corelib/tools/error.h @@ -45,12 +45,10 @@ #include <QtCore/qhash.h> #include <QtCore/qmetatype.h> #include <QtCore/qshareddata.h> +#include <QtCore/qstringlist.h> QT_BEGIN_NAMESPACE class QJsonObject; -template <class T> class QList; -class QString; -class QStringList; QT_END_NAMESPACE namespace qbs { diff --git a/src/lib/corelib/tools/fileinfo.cpp b/src/lib/corelib/tools/fileinfo.cpp index 6fdd90fb1..382843a33 100644 --- a/src/lib/corelib/tools/fileinfo.cpp +++ b/src/lib/corelib/tools/fileinfo.cpp @@ -133,16 +133,16 @@ void FileInfo::splitIntoDirectoryAndFileName(const QString &filePath, QString *d *fileName = filePath.mid(idx + 1); } -void FileInfo::splitIntoDirectoryAndFileName(const QString &filePath, QStringRef *dirPath, QStringRef *fileName) +void FileInfo::splitIntoDirectoryAndFileName(const QString &filePath, QStringView *dirPath, QStringView *fileName) { int idx = filePath.lastIndexOf(QLatin1Char('/')); if (idx < 0) { - dirPath->clear(); - *fileName = QStringRef(&filePath); + *dirPath = QStringView(); + *fileName = QStringView(filePath); return; } - *dirPath = filePath.leftRef(idx); - *fileName = filePath.midRef(idx + 1); + *dirPath = QStringView(filePath).left(idx); + *fileName = QStringView(filePath).mid(idx + 1); } bool FileInfo::exists(const QString &fp) @@ -180,12 +180,7 @@ bool FileInfo::isAbsolute(const QString &path, HostOsInfo::HostOs hostOs) return false; } -bool FileInfo::isPattern(const QString &str) -{ - return isPattern(QStringRef(&str)); -} - -bool FileInfo::isPattern(const QStringRef &str) +bool FileInfo::isPattern(QStringView str) { for (const QChar &ch : str) { if (ch == QLatin1Char('*') || ch == QLatin1Char('?') diff --git a/src/lib/corelib/tools/fileinfo.h b/src/lib/corelib/tools/fileinfo.h index c4ca5931a..f0a09a16b 100644 --- a/src/lib/corelib/tools/fileinfo.h +++ b/src/lib/corelib/tools/fileinfo.h @@ -72,11 +72,10 @@ public: static QString completeSuffix(const QString &fp); static QString path(const QString &fp, HostOsInfo::HostOs hostOs = HostOsInfo::hostOs()); static void splitIntoDirectoryAndFileName(const QString &filePath, QString *dirPath, QString *fileName); - static void splitIntoDirectoryAndFileName(const QString &filePath, QStringRef *dirPath, QStringRef *fileName); + static void splitIntoDirectoryAndFileName(const QString &filePath, QStringView *dirPath, QStringView *fileName); static bool exists(const QString &fp); static bool isAbsolute(const QString &fp, HostOsInfo::HostOs hostOs = HostOsInfo::hostOs()); - static bool isPattern(const QStringRef &str); - static bool isPattern(const QString &str); + static bool isPattern(QStringView str); static QString resolvePath(const QString &base, const QString &rel, HostOsInfo::HostOs hostOs = HostOsInfo::hostOs()); static bool isFileCaseCorrect(const QString &filePath); diff --git a/src/lib/corelib/tools/jsliterals.cpp b/src/lib/corelib/tools/jsliterals.cpp index 69d170336..647bdc640 100644 --- a/src/lib/corelib/tools/jsliterals.cpp +++ b/src/lib/corelib/tools/jsliterals.cpp @@ -40,6 +40,7 @@ #include "jsliterals.h" #include <tools/stringconstants.h> +#include <tools/qttools.h> #include <QtCore/qregularexpression.h> @@ -75,7 +76,7 @@ QString toJSLiteral(const QVariant &val) { if (!val.isValid()) return Internal::StringConstants::undefinedValue(); - if (val.type() == QVariant::List || val.type() == QVariant::StringList) { + if (val.userType() == QMetaType::QVariantList || val.userType() == QMetaType::QStringList) { QString res; const auto list = val.toList(); for (const QVariant &child : list) { @@ -86,7 +87,7 @@ QString toJSLiteral(const QVariant &val) res.append(QLatin1Char(']')); return res; } - if (val.type() == QVariant::Map) { + if (val.userType() == QMetaType::QVariantMap) { const QVariantMap &vm = val.toMap(); QString str = QStringLiteral("{"); for (QVariantMap::const_iterator it = vm.begin(); it != vm.end(); ++it) { @@ -97,9 +98,9 @@ QString toJSLiteral(const QVariant &val) str += QLatin1Char('}'); return str; } - if (val.type() == QVariant::Bool) + if (val.userType() == QMetaType::Bool) return toJSLiteral(val.toBool()); - if (val.canConvert(QVariant::String)) + if (qVariantCanConvert(val, QMetaType::QString)) return toJSLiteral(val.toString()); return QStringLiteral("Unconvertible type %1").arg(QLatin1String(val.typeName())); } diff --git a/src/lib/corelib/tools/launcherinterface.cpp b/src/lib/corelib/tools/launcherinterface.cpp index d2cdf44df..cd877c154 100644 --- a/src/lib/corelib/tools/launcherinterface.cpp +++ b/src/lib/corelib/tools/launcherinterface.cpp @@ -61,11 +61,23 @@ namespace Internal { class LauncherProcess : public QProcess { public: - LauncherProcess(QObject *parent) : QProcess(parent) { } + LauncherProcess(QObject *parent) : QProcess(parent) + { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && defined(Q_OS_UNIX) + setChildProcessModifier([this] { setupChildProcess_impl(); }); +#endif + } private: +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) void setupChildProcess() override { + setupChildProcess_impl(); + } +#endif + + void setupChildProcess_impl() + { #ifdef Q_OS_UNIX const auto pid = static_cast<pid_t>(processId()); setpgid(pid, pid); diff --git a/src/lib/corelib/tools/msvcinfo.cpp b/src/lib/corelib/tools/msvcinfo.cpp index 42cfefe7b..ed94613d9 100644 --- a/src/lib/corelib/tools/msvcinfo.cpp +++ b/src/lib/corelib/tools/msvcinfo.cpp @@ -43,6 +43,7 @@ #include <logging/logger.h> #include <tools/error.h> #include <tools/profile.h> +#include <tools/stlutils.h> #include <tools/stringconstants.h> #include <QtCore/qbytearray.h> @@ -471,12 +472,20 @@ static std::vector<MSVC> installedCompilersHelper(Logger &logger) QDir vcInstallDir = vsInstallDir; vcInstallDir.cd(QStringLiteral("Tools/MSVC")); const auto vcVersionStrs = vcInstallDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + std::vector<Version> vcVersions; + vcVersions.reserve(vcVersionStrs.size()); for (const QString &vcVersionStr : vcVersionStrs) { const Version vcVersion = Version::fromString(vcVersionStr); if (!vcVersion.isValid()) continue; + vcVersions.push_back(vcVersion); + } + // sort the versions so the new one comes first + std::sort(vcVersions.begin(), vcVersions.end(), std::greater<>()); + + for (const Version &vcVersion : vcVersions) { QDir specificVcInstallDir = vcInstallDir; - if (!specificVcInstallDir.cd(vcVersionStr) + if (!specificVcInstallDir.cd(vcVersion.toString()) || !specificVcInstallDir.cd(QStringLiteral("bin"))) { continue; } diff --git a/src/lib/corelib/tools/msvcinfo.h b/src/lib/corelib/tools/msvcinfo.h index de4470bf0..d081e5c15 100644 --- a/src/lib/corelib/tools/msvcinfo.h +++ b/src/lib/corelib/tools/msvcinfo.h @@ -81,12 +81,14 @@ public: QString binPath; QString pathPrefix; QString architecture; + QString sdkVersion; QProcessEnvironment environment; MSVC() = default; - MSVC(const QString &clPath, QString arch): - architecture(std::move(arch)) + MSVC(const QString &clPath, QString arch, QString sdkVersion = {}): + architecture(std::move(arch)), + sdkVersion(std::move(sdkVersion)) { QDir parentDir = QFileInfo(clPath).dir(); binPath = parentDir.absolutePath(); diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp index 4674b24ae..7c4458b5f 100644 --- a/src/lib/corelib/tools/persistence.cpp +++ b/src/lib/corelib/tools/persistence.cpp @@ -140,7 +140,7 @@ void PersistentPool::finalizeWriteStream() void PersistentPool::storeVariant(const QVariant &variant) { - const auto type = static_cast<quint32>(variant.type()); + const auto type = static_cast<quint32>(variant.userType()); m_stream << type; switch (type) { case QMetaType::QString: @@ -218,7 +218,7 @@ void PersistentPool::doStoreValue(const QString &s) void PersistentPool::doStoreValue(const QStringList &l) { - m_stream << l.size(); + m_stream << int(l.size()); for (const QString &s : l) store(s); } diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h index b0fed9f68..29d586177 100644 --- a/src/lib/corelib/tools/persistence.h +++ b/src/lib/corelib/tools/persistence.h @@ -50,6 +50,7 @@ #include <QtCore/qprocess.h> #include <QtCore/qregularexpression.h> #include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> #include <QtCore/qvariant.h> #include <memory> @@ -467,6 +468,7 @@ template<typename T> struct PPHelper<QFlags<T>> template<typename T> struct IsSimpleContainer : std::false_type { }; template<typename T> struct IsSimpleContainer<QList<T>> : std::true_type { }; +template<> struct IsSimpleContainer<QStringList> : std::false_type { }; template<typename T> struct IsSimpleContainer<std::vector<T>> : std::true_type { }; template<typename T> struct PPHelper<T, std::enable_if_t<IsSimpleContainer<T>::value>> @@ -496,7 +498,7 @@ struct PPHelper<T, std::enable_if_t<IsKeyValueContainer<T>::value>> { static void store(const T &container, PersistentPool *pool) { - pool->store(container.size()); + pool->store(int(container.size())); for (auto it = container.cbegin(); it != container.cend(); ++it) { pool->store(it.key()); pool->store(it.value()); diff --git a/src/lib/corelib/tools/processresult.h b/src/lib/corelib/tools/processresult.h index 92408aa31..3870a3ae5 100644 --- a/src/lib/corelib/tools/processresult.h +++ b/src/lib/corelib/tools/processresult.h @@ -44,11 +44,10 @@ #include <QtCore/qshareddata.h> #include <QtCore/qmetatype.h> #include <QtCore/qprocess.h> +#include <QtCore/qstringlist.h> QT_BEGIN_NAMESPACE class QJsonObject; -class QString; -class QStringList; QT_END_NAMESPACE namespace qbs { diff --git a/src/lib/corelib/tools/profile.h b/src/lib/corelib/tools/profile.h index 0eee23ae4..b7fc7ff67 100644 --- a/src/lib/corelib/tools/profile.h +++ b/src/lib/corelib/tools/profile.h @@ -42,12 +42,9 @@ #include "qbs_export.h" #include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> #include <QtCore/qvariant.h> -QT_BEGIN_NAMESPACE -class QStringList; -QT_END_NAMESPACE - namespace qbs { class ErrorInfo; class Settings; diff --git a/src/lib/corelib/tools/projectgeneratormanager.h b/src/lib/corelib/tools/projectgeneratormanager.h index 469d650b9..1efe593fc 100644 --- a/src/lib/corelib/tools/projectgeneratormanager.h +++ b/src/lib/corelib/tools/projectgeneratormanager.h @@ -45,10 +45,7 @@ #include <QtCore/qmap.h> #include <QtCore/qstring.h> - -QT_BEGIN_NAMESPACE -class QStringList; -QT_END_NAMESPACE +#include <QtCore/qstringlist.h> namespace qbs { class ProjectGenerator; diff --git a/src/lib/corelib/tools/qttools.h b/src/lib/corelib/tools/qttools.h index 2d4a38544..bbec32544 100644 --- a/src/lib/corelib/tools/qttools.h +++ b/src/lib/corelib/tools/qttools.h @@ -43,6 +43,7 @@ #include <QtCore/qhash.h> #include <QtCore/qstringlist.h> #include <QtCore/qtextstream.h> +#include <QtCore/qvariant.h> #include <functional> @@ -118,6 +119,33 @@ QHash<K, V> &unite(QHash<K, V> &h, const QHash<K, V> &other) #endif } +inline void setupDefaultCodec(QTextStream &stream) +{ +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + stream.setCodec("UTF-8"); +#else + Q_UNUSED(stream); +#endif +} + +inline bool qVariantCanConvert(const QVariant &variant, int typeId) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + return variant.canConvert(QMetaType(typeId)); +#else + return variant.canConvert(typeId); // deprecated in Qt6 +#endif +} + +inline bool qVariantConvert(QVariant &variant, int typeId) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + return variant.convert(QMetaType(typeId)); +#else + return variant.convert(typeId); // deprecated in Qt6 +#endif +} + } // namespace qbs #endif // QBSQTTOOLS_H diff --git a/src/lib/corelib/tools/set.h b/src/lib/corelib/tools/set.h index 75db0528b..463d3beb6 100644 --- a/src/lib/corelib/tools/set.h +++ b/src/lib/corelib/tools/set.h @@ -112,8 +112,8 @@ public: Set &operator&=(const Set &other) { return intersect(other); } Set &operator&=(const T &v) { return intersect(Set{ v }); } - iterator find(const T &v) { return std::find(m_data.begin(), m_data.end(), v); } - const_iterator find(const T &v) const { return std::find(m_data.cbegin(), m_data.cend(), v); } + iterator find(const T &v) { return binaryFind(m_data.begin(), m_data.end(), v); } + const_iterator find(const T &v) const { return binaryFind(m_data.cbegin(), m_data.cend(), v); } std::pair<iterator, bool> insert(const T &v); Set &operator+=(const T &v) { insert(v); return *this; } Set &operator|=(const T &v) { return operator+=(v); } diff --git a/src/lib/corelib/tools/settings.cpp b/src/lib/corelib/tools/settings.cpp index fccb9c9b2..8b22c45e5 100644 --- a/src/lib/corelib/tools/settings.cpp +++ b/src/lib/corelib/tools/settings.cpp @@ -117,9 +117,9 @@ QVariant Settings::value(const QString &key, Scopes scopes, const QVariant &defa } if (!systemValue.isValid()) return userValue; - if (static_cast<QMetaType::Type>(userValue.type()) == QMetaType::QStringList) + if (static_cast<QMetaType::Type>(userValue.userType()) == QMetaType::QStringList) return userValue.toStringList() + systemValue.toStringList(); - if (static_cast<QMetaType::Type>(userValue.type()) == QMetaType::QVariantList) + if (static_cast<QMetaType::Type>(userValue.userType()) == QMetaType::QVariantList) return userValue.toList() + systemValue.toList(); return userValue; } diff --git a/src/lib/corelib/tools/settings.h b/src/lib/corelib/tools/settings.h index 638216669..4ea148af0 100644 --- a/src/lib/corelib/tools/settings.h +++ b/src/lib/corelib/tools/settings.h @@ -43,13 +43,13 @@ #include "qbs_export.h" #include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> #include <QtCore/qvariant.h> #include <memory> QT_BEGIN_NAMESPACE class QSettings; -class QStringList; QT_END_NAMESPACE namespace qbs { diff --git a/src/lib/corelib/tools/settingscreator.cpp b/src/lib/corelib/tools/settingscreator.cpp index 36e67440c..3fdaf0bc3 100644 --- a/src/lib/corelib/tools/settingscreator.cpp +++ b/src/lib/corelib/tools/settingscreator.cpp @@ -109,11 +109,11 @@ void SettingsCreator::migrate() const auto allKeys = m_settings->allKeys(); for (const QString &key : allKeys) { QVariant v = m_settings->value(key); - if (v.type() == QVariant::String) { + if (v.userType() == QMetaType::QString) { QString s = v.toString(); if (s.contains(oldProfilesDir)) m_settings->setValue(key, s.replace(oldProfilesDir, newProfilesDir)); - } else if (v.type() == QVariant::StringList) { + } else if (v.userType() == QMetaType::QStringList) { const QStringList oldList = v.toStringList(); QStringList newList; for (const QString &oldString : oldList) { diff --git a/src/lib/corelib/tools/settingsrepresentation.cpp b/src/lib/corelib/tools/settingsrepresentation.cpp index 256c60c0e..7790f1aa1 100644 --- a/src/lib/corelib/tools/settingsrepresentation.cpp +++ b/src/lib/corelib/tools/settingsrepresentation.cpp @@ -67,8 +67,8 @@ QVariant representationToSettingsValue(const QString &representation) QVariant variant = variantFromString(representation, ok); // We have no floating-point properties, so this is most likely intended to be a string. - if (static_cast<QMetaType::Type>(variant.type()) == QMetaType::Float - || static_cast<QMetaType::Type>(variant.type()) == QMetaType::Double) { + if (static_cast<QMetaType::Type>(variant.userType()) == QMetaType::Float + || static_cast<QMetaType::Type>(variant.userType()) == QMetaType::Double) { variant = variantFromString(QLatin1Char('"') + representation + QLatin1Char('"'), ok); } diff --git a/src/lib/corelib/tools/setupprojectparameters.h b/src/lib/corelib/tools/setupprojectparameters.h index a4d090ec5..2617a34cd 100644 --- a/src/lib/corelib/tools/setupprojectparameters.h +++ b/src/lib/corelib/tools/setupprojectparameters.h @@ -44,10 +44,10 @@ #include <tools/error.h> #include <QtCore/qshareddata.h> +#include <QtCore/qstringlist.h> QT_BEGIN_NAMESPACE class QProcessEnvironment; -class QStringList; using QVariantMap = QMap<QString, QVariant>; QT_END_NAMESPACE diff --git a/src/lib/corelib/tools/stlutils.h b/src/lib/corelib/tools/stlutils.h index 63b9c098e..d4c569a95 100644 --- a/src/lib/corelib/tools/stlutils.h +++ b/src/lib/corelib/tools/stlutils.h @@ -75,6 +75,17 @@ bool containsKey(const C &container, const typename C::key_type &v) return container.find(v) != end; } +template <class C> +typename C::mapped_type mapValue( + const C &container, + const typename C::key_type &key, + const typename C::mapped_type &value = typename C::mapped_type()) +{ + const auto end = container.cend(); + const auto it = container.find(key); + return it != end ? it->second : value; +} + template <typename C> bool removeOne(C &container, const typename C::value_type &v) { @@ -112,6 +123,21 @@ bool none_of(const Container &container, const UnaryPredicate &predicate) return std::none_of(std::begin(container), std::end(container), predicate); } +template <class It, class T, class Compare> +It binaryFind(It begin, It end, const T &value, Compare comp) +{ + const auto it = std::lower_bound(begin, end, value, comp); + if (it == end || comp(value, *it)) + return end; + return it; +} + +template <class It, class T> +It binaryFind(It begin, It end, const T &value) +{ + return binaryFind(begin, end, value, std::less<T>()); +} + template <class C> C &operator<<(C &container, const typename C::value_type &v) { diff --git a/src/lib/corelib/tools/vsenvironmentdetector.cpp b/src/lib/corelib/tools/vsenvironmentdetector.cpp index b0788823f..a11934d52 100644 --- a/src/lib/corelib/tools/vsenvironmentdetector.cpp +++ b/src/lib/corelib/tools/vsenvironmentdetector.cpp @@ -241,8 +241,10 @@ void VsEnvironmentDetector::writeBatchFile(QIODevice *device, const QString &vcv << "setlocal" << endl; batClearVars(s, varnames); s << "set PATH=" << m_windowsSystemDirPath << endl; // vcvarsall.bat needs tools from here - s << "call \"" << vcvarsallbat << "\" " << vcArchitecture(msvc) - << " || exit /b 1" << endl; + s << "call \"" << vcvarsallbat << "\" " << vcArchitecture(msvc); + if (!msvc->sdkVersion.isEmpty()) + s << " " << msvc->sdkVersion; + s << " || exit /b 1" << endl; batPrintVars(s, varnames); s << "endlocal" << endl; } diff --git a/src/lib/msbuild/io/msbuildprojectwriter.cpp b/src/lib/msbuild/io/msbuildprojectwriter.cpp index 12fbe2da5..aaab11aa6 100644 --- a/src/lib/msbuild/io/msbuildprojectwriter.cpp +++ b/src/lib/msbuild/io/msbuildprojectwriter.cpp @@ -178,7 +178,7 @@ void MSBuildProjectWriterPrivate::visitEnd(const MSBuildItemGroup *) void MSBuildProjectWriterPrivate::visitStart(const MSBuildItemMetadata *itemMetadata) { QString stringValue; - if (itemMetadata->value().type() == QVariant::Bool) { + if (itemMetadata->value().userType() == QMetaType::Bool) { stringValue = itemMetadata->value().toBool() ? QStringLiteral("True") : QStringLiteral("False"); @@ -210,7 +210,7 @@ void MSBuildProjectWriterPrivate::visitEnd(const MSBuildProject *) void MSBuildProjectWriterPrivate::visitStart(const MSBuildProperty *property) { QString stringValue; - if (property->value().type() == QVariant::Bool) + if (property->value().userType() == QMetaType::Bool) stringValue = property->value().toBool() ? QStringLiteral("True") : QStringLiteral("False"); else stringValue = property->value().toString(); diff --git a/src/lib/msbuild/solution/visualstudiosolutionfileproject.cpp b/src/lib/msbuild/solution/visualstudiosolutionfileproject.cpp index ab5db088d..7a67ce22b 100644 --- a/src/lib/msbuild/solution/visualstudiosolutionfileproject.cpp +++ b/src/lib/msbuild/solution/visualstudiosolutionfileproject.cpp @@ -60,7 +60,7 @@ QString VisualStudioSolutionFileProject::name() const QUuid VisualStudioSolutionFileProject::projectTypeGuid() const { - return QStringLiteral("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"); // C++ + return QUuid::fromString(QStringLiteral("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")); // C++ } QString VisualStudioSolutionFileProject::filePath() const diff --git a/src/lib/msbuild/solution/visualstudiosolutionfolderproject.cpp b/src/lib/msbuild/solution/visualstudiosolutionfolderproject.cpp index d59d1e1ed..8b0997040 100644 --- a/src/lib/msbuild/solution/visualstudiosolutionfolderproject.cpp +++ b/src/lib/msbuild/solution/visualstudiosolutionfolderproject.cpp @@ -41,7 +41,7 @@ VisualStudioSolutionFolderProject::VisualStudioSolutionFolderProject(QObject *pa QUuid VisualStudioSolutionFolderProject::projectTypeGuid() const { - return QStringLiteral("{2150E333-8FDC-42A3-9474-1A3956D46DE8}"); + return QUuid::fromString(QStringLiteral("{2150E333-8FDC-42A3-9474-1A3956D46DE8}")); } } // namespace qbs diff --git a/src/lib/scriptengine/scriptengine.qbs b/src/lib/scriptengine/scriptengine.qbs index 660b64a82..3225ceaac 100644 --- a/src/lib/scriptengine/scriptengine.qbs +++ b/src/lib/scriptengine/scriptengine.qbs @@ -1,6 +1,7 @@ import qbs import qbs.File import qbs.FileInfo +import qbs.Probes import qbs.Process Project { @@ -382,6 +383,13 @@ Project { Product { type: ["hpp"] name: "QtScriptFwdHeaders" + condition: qbsbuildconfig.useBundledQtScript || !Qt.script.present + Depends { name: "qbsbuildconfig" } + Depends { + name: "Qt.script" + condition: !qbsbuildconfig.useBundledQtScript + required: false + } Depends { name: "Qt.core" } Group { files: [ @@ -389,6 +397,11 @@ Project { ] fileTags: ["qtscriptheader"] } + Probes.BinaryProbe { + id: perlProbe + names: "perl" + } + property string perlPath: perlProbe.found ? perlProbe.filePath : undefined Rule { multiplex: true inputs: ["qtscriptheader"] @@ -413,7 +426,7 @@ Project { var qtScriptSrcPath = FileInfo.cleanPath( FileInfo.path(inputs["qtscriptheader"][0].filePath) + "/../../.."); console.info("qtScriptSrcPath: " + qtScriptSrcPath); - var cmd = new Command("perl", [ + var cmd = new Command(product.perlPath, [ syncQtPath, "-minimal", "-version", product.Qt.core.version, diff --git a/src/plugins/generator/visualstudio/msbuildtargetproject.cpp b/src/plugins/generator/visualstudio/msbuildtargetproject.cpp index bcd654061..33ce9d9ae 100644 --- a/src/plugins/generator/visualstudio/msbuildtargetproject.cpp +++ b/src/plugins/generator/visualstudio/msbuildtargetproject.cpp @@ -92,7 +92,7 @@ const Internal::VisualStudioVersionInfo &MSBuildTargetProject::versionInfo() con QUuid MSBuildTargetProject::guid() const { - return {d->projectGuidProperty->value().toString()}; + return QUuid{d->projectGuidProperty->value().toString()}; } void MSBuildTargetProject::setGuid(const QUuid &guid) diff --git a/src/plugins/scanner/cpp/cppscanner.cpp b/src/plugins/scanner/cpp/cppscanner.cpp index 6800ce608..6a500f013 100644 --- a/src/plugins/scanner/cpp/cppscanner.cpp +++ b/src/plugins/scanner/cpp/cppscanner.cpp @@ -204,7 +204,7 @@ static void scanCppFile(void *opaq, CPlusPlus::Lexer &yylex, bool scanForFileTag static void *openScanner(const unsigned short *filePath, const char *fileTags, int flags) { std::unique_ptr<Opaq> opaque(new Opaq); - opaque->fileName = QString::fromUtf16(filePath); + opaque->fileName = QString::fromUtf16(reinterpret_cast<const char16_t *>(filePath)); const int fileTagsLength = static_cast<int>(std::strlen(fileTags)); const QList<QByteArray> &tagList = QByteArray::fromRawData(fileTags, fileTagsLength).split(','); if (tagList.contains("hpp")) diff --git a/src/plugins/scanner/qt/qtscanner.cpp b/src/plugins/scanner/qt/qtscanner.cpp index 73f1e7816..310de33fc 100644 --- a/src/plugins/scanner/qt/qtscanner.cpp +++ b/src/plugins/scanner/qt/qtscanner.cpp @@ -100,7 +100,7 @@ static void *openScannerQrc(const unsigned short *filePath, const char *fileTags std::unique_ptr<OpaqQrc> opaque(new OpaqQrc); #ifdef Q_OS_UNIX - QString filePathS = QString::fromUtf16(filePath); + QString filePathS = QString::fromUtf16(reinterpret_cast<const char16_t *>(filePath)); opaque->fd = open(qPrintable(filePathS), O_RDONLY); if (opaque->fd == -1) { opaque->fd = 0; @@ -118,7 +118,7 @@ static void *openScannerQrc(const unsigned short *filePath, const char *fileTags if (map == nullptr) return nullptr; #else - opaque->file = new QFile(QString::fromUtf16(filePath)); + opaque->file = new QFile(QString::fromUtf16(reinterpret_cast<const char16_t *>(filePath))); if (!opaque->file->open(QFile::ReadOnly)) return nullptr; diff --git a/src/shared/bundledqt/bundledqt.qbs b/src/shared/bundledqt/bundledqt.qbs index 5995ae4d6..c6f3ebbf8 100644 --- a/src/shared/bundledqt/bundledqt.qbs +++ b/src/shared/bundledqt/bundledqt.qbs @@ -1,6 +1,7 @@ import qbs import qbs.File import qbs.FileInfo +import qbs.Utilities Product { Depends { name: "qbsbuildconfig" } @@ -8,6 +9,10 @@ Product { Depends { name: "Qt.test"; condition: project.withTests === true } Depends { name: "Qt.script"; condition: !qbsbuildconfig.useBundledQtScript; required: false } Depends { + name: "Qt.core5compat"; + condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 + } + Depends { name: "Qt"; submodules: [ "dbus", "xcb_qpa_lib-private" ]; required: false @@ -61,8 +66,15 @@ Product { var dir = FileInfo.path(fp); list.push(dir + "/" + basename + ".so"); list.push(dir + "/" + basename + ".so." + Qt.core.versionMajor); - list.push(dir + "/" + basename + ".so." + Qt.core.versionMajor + "." + Qt.core.versionMinor); - list.push(fp); + if (Utilities.versionCompare(Qt.core.version, "6") < 0) { + list.push(dir + "/" + basename + ".so." + + Qt.core.versionMajor + "." + + Qt.core.versionMinor); + } + list.push(dir + "/" + basename + ".so." + + Qt.core.versionMajor + "." + + Qt.core.versionMinor + "." + + Qt.core.versionPatch); } else if (Qt.core.frameworkBuild) { var fp = Qt[mod].libFilePathRelease; @@ -74,7 +86,9 @@ Product { var suffix = ".framework/"; var frameworkPath = fp.substr(0, fp.lastIndexOf(suffix) + suffix.length - 1); var versionsPath = frameworkPath + "/Versions"; - var versionPath = versionsPath + "/" + Qt.core.versionMajor; + var versionName = Utilities.versionCompare(Qt.core.version, "6") >= 0 + ? "A" : Qt.core.versionMajor; + var versionPath = versionsPath + "/" + versionName; list.push(frameworkPath + "/Resources"); list.push(versionPath + "/Resources/Info.plist"); list.push(versionPath + "/" + FileInfo.fileName(fp)); @@ -105,6 +119,8 @@ Product { return libraries; } + fileTags: [] + qbs.install: true qbs.installDir: qbsbuildconfig.libInstallDir qbs.installSourceBase: qbs.targetOS.contains("windows") ? Qt.core.binPath : Qt.core.libPath diff --git a/tests/auto/api/tst_api.cpp b/tests/auto/api/tst_api.cpp index 7a585f641..a51eb3e0c 100644 --- a/tests/auto/api/tst_api.cpp +++ b/tests/auto/api/tst_api.cpp @@ -2507,7 +2507,9 @@ qbs::SetupProjectParameters TestApi::defaultSetupParameters(const QString &proje } qbs::SetupProjectParameters setupParams; - setupParams.setEnvironment(QProcessEnvironment::systemEnvironment()); + auto environment = QProcessEnvironment::systemEnvironment(); + environment.insert("QBS_AUTOTEST_CODE_SIGNING_REQUIRED", "0"); + setupParams.setEnvironment(environment); setupParams.setProjectFilePath(projectFilePath); setupParams.setPropertyCheckingMode(qbs::ErrorHandlingMode::Strict); setupParams.setOverrideBuildGraphData(true); diff --git a/tests/auto/blackbox/testdata-android/qt-app/test.keystore b/tests/auto/blackbox/testdata-android/qt-app/test.keystore Binary files differnew file mode 100644 index 000000000..5713d10d2 --- /dev/null +++ b/tests/auto/blackbox/testdata-android/qt-app/test.keystore diff --git a/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs b/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs index c1d35eb8c..6b7fab390 100644 --- a/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs +++ b/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs @@ -1,6 +1,6 @@ import qbs.Utilities -import "helpers.js" as Helpers +import "../multiarch-helpers.js" as Helpers Project { minimumQbsVersion: "1.8" diff --git a/tests/auto/blackbox/testdata-apple/codesign/app.cpp b/tests/auto/blackbox/testdata-apple/codesign/app.cpp new file mode 100644 index 000000000..76e819701 --- /dev/null +++ b/tests/auto/blackbox/testdata-apple/codesign/app.cpp @@ -0,0 +1 @@ +int main() { return 0; } diff --git a/tests/auto/blackbox/testdata-apple/codesign/codesign.qbs b/tests/auto/blackbox/testdata-apple/codesign/codesign.qbs new file mode 100644 index 000000000..eafb0be84 --- /dev/null +++ b/tests/auto/blackbox/testdata-apple/codesign/codesign.qbs @@ -0,0 +1,48 @@ +import "../multiarch-helpers.js" as Helpers + +Project { + name: "p" + property string xcodeVersion + + property bool isBundle: true + property bool enableSigning: true + + CppApplication { + name: "A" + bundle.isBundle: project.isBundle + files: "app.cpp" + codesign.enableCodeSigning: project.enableSigning + codesign.signingType: "ad-hoc" + install: true + installDir: "" + + qbs.architectures: + project.xcodeVersion ? Helpers.getArchitectures(qbs, project.xcodeVersion) : [] + } + + DynamicLibrary { + Depends { name: "cpp" } + name: "B" + bundle.isBundle: project.isBundle + files: "app.cpp" + codesign.enableCodeSigning: project.enableSigning + codesign.signingType: "ad-hoc" + install: true + installDir: "" + qbs.architectures: + project.xcodeVersion ? Helpers.getArchitectures(qbs, project.xcodeVersion) : [] + } + + LoadableModule { + Depends { name: "cpp" } + name: "C" + bundle.isBundle: project.isBundle + files: "app.cpp" + codesign.enableCodeSigning: project.enableSigning + codesign.signingType: "ad-hoc" + install: true + installDir: "" + qbs.architectures: + project.xcodeVersion ? Helpers.getArchitectures(qbs, project.xcodeVersion) : [] + } +} diff --git a/tests/auto/blackbox/testdata-apple/apple-multiconfig/helpers.js b/tests/auto/blackbox/testdata-apple/multiarch-helpers.js index 16ba00fa9..5d1c0f273 100644 --- a/tests/auto/blackbox/testdata-apple/apple-multiconfig/helpers.js +++ b/tests/auto/blackbox/testdata-apple/multiarch-helpers.js @@ -36,12 +36,16 @@ var Utilities = require("qbs.Utilities"); function enableOldArch(qbs, xcodeVersion) { return qbs.targetOS.contains("macos") && xcodeVersion - && Utilities.versionCompare(xcodeVersion, "10") < 0 + && (Utilities.versionCompare(xcodeVersion, "10") < 0 + || Utilities.versionCompare(xcodeVersion, "12.2") >= 0) || qbs.targetOS.contains("ios") } -function getNewArch(qbs) { - if (qbs.targetOS.contains("macos") || qbs.targetOS.contains("ios-simulator")) +function getNewArch(qbs, xcodeVersion) { + if (qbs.targetOS.contains("macos")) + return xcodeVersion + && Utilities.versionCompare(xcodeVersion, "12.2") >= 0 ? "arm64" : "x86_64"; + else if (qbs.targetOS.contains("ios-simulator")) return "x86_64" else if (qbs.targetOS.contains("ios")) return "arm64" @@ -52,8 +56,11 @@ function getNewArch(qbs) { throw "unsupported targetOS: " + qbs.targetOS; } -function getOldArch(qbs) { - if (qbs.targetOS.contains("macos") || qbs.targetOS.contains("ios-simulator")) +function getOldArch(qbs, xcodeVersion) { + if (qbs.targetOS.contains("macos")) + return xcodeVersion + && Utilities.versionCompare(xcodeVersion, "12.2") >= 0 ? "x86_64" : "x86"; + else if (qbs.targetOS.contains("ios-simulator")) return "x86" else if (qbs.targetOS.contains("ios")) return "armv7a" @@ -62,6 +69,6 @@ function getOldArch(qbs) { function getArchitectures(qbs, xcodeVersion) { return enableOldArch(qbs, xcodeVersion) - ? [getOldArch(qbs), getNewArch(qbs)] - : [getNewArch(qbs)]; + ? [getOldArch(qbs, xcodeVersion), getNewArch(qbs, xcodeVersion)] + : [getNewArch(qbs, xcodeVersion)]; } diff --git a/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs b/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs index fa678ebb2..a52bb4c4e 100644 --- a/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs +++ b/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs @@ -1,104 +1,3 @@ -CppApplication { - cpp.positionIndependentCode: false - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "stm8" - cpp.driverLinkerFlags: [ - "--config_def", "_CSTACK_SIZE=0x100", - "--config_def", "_HEAP_SIZE=0x100", - ] - } - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "rl78" - cpp.driverLinkerFlags: [ - "--config_def", "_NEAR_HEAP_SIZE=256", - "--config_def", "_FAR_HEAP_SIZE=4096", - "--config_def", "_HUGE_HEAP_SIZE=0", - "--config_def", "_STACK_SIZE=128", - "--config_def", "_NEAR_CONST_LOCATION_SIZE=0x6F00", - "--config_def", "_NEAR_CONST_LOCATION_START=0x3000", - "--define_symbol", "_NEAR_CONST_LOCATION=0", - "--config", cpp.toolchainInstallPath + "/../config/lnkrl78_s3.icf" - ] - } - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "rh850" - cpp.driverLinkerFlags: [ - "--config_def", "CSTACK_SIZE=0x1000", - "--config_def", "HEAP_SIZE=0x1000", - "--config", cpp.toolchainInstallPath + "/../config/lnkrh850_g3m.icf" - ] - } - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "v850" - cpp.driverLinkerFlags: [ - "-D_CSTACK_SIZE=1000", - "-D_HEAP_SIZE=1000", - "-f", cpp.toolchainInstallPath + "/../config/lnk85.xcl" - ] - } - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "78k" - cpp.cFlags: [ - "--core", "78k0", - "--code_model", "standard" - ] - cpp.driverLinkerFlags: [ - "-D_CSTACK_SIZE=80", - "-D_HEAP_SIZE=200", - "-D_CODEBANK_START=0", - "-D_CODEBANK_END=0", - "-D_CODEBANK_BANKS=0", - "-f", cpp.toolchainInstallPath + "/../config/lnk.xcl", - cpp.toolchainInstallPath + "/../lib/clib/cl78ks1.r26" - ] - } - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "sh" - cpp.driverLinkerFlags: [ - "--config_def", "_CSTACK_SIZE=0x800", - "--config_def", "_HEAP_SIZE=0x800", - "--config_def", "_INT_TABLE=0x10", - "--config", cpp.toolchainInstallPath + "/../config/generic.icf" - ] - } - Properties { - condition: qbs.toolchain.contains("keil") - && qbs.architecture.startsWith("arm") - && cpp.compilerName.startsWith("armcc") - cpp.assemblerFlags: ["--cpu", "cortex-m0"] - cpp.driverFlags: ["--cpu", "cortex-m0"] - } - Properties { - condition: qbs.toolchain.contains("keil") - && qbs.architecture.startsWith("arm") - && cpp.compilerName.startsWith("armclang") - cpp.assemblerFlags: ["--cpu", "cortex-m0"] - cpp.driverFlags: ["-mcpu=cortex-m0", "--target=arm-arm-none-eabi"] - } - Properties { - condition: qbs.toolchain.contains("gcc") - && qbs.architecture.startsWith("arm") - cpp.driverFlags: ["-specs=nosys.specs"] - } - Properties { - condition: qbs.toolchain.contains("gcc") - && qbs.architecture === "xtensa" - cpp.driverFlags: ["-nostdlib"] - } - Properties { - condition: qbs.toolchain.contains("gcc") - && qbs.architecture === "msp430" - cpp.driverFlags: ["-mmcu=msp430f5529"] - } - Properties { - condition: qbs.toolchain.contains("gcc") - && qbs.architecture === "m32r" - cpp.driverFlags: ["-nostdlib"] - } +BareMetalProduct { + type: "application" } diff --git a/tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs b/tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs new file mode 100644 index 000000000..5db988078 --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs @@ -0,0 +1,158 @@ +Product { + Depends { name: "cpp" } + cpp.positionIndependentCode: false + Properties { + condition: qbs.toolchain.contains("iar") + && qbs.architecture === "stm8" + cpp.driverLinkerFlags: [ + "--config_def", "_CSTACK_SIZE=0x100", + "--config_def", "_HEAP_SIZE=0x100", + ] + } + Properties { + condition: qbs.toolchain.contains("iar") + && qbs.architecture === "rl78" + cpp.driverLinkerFlags: [ + "--config_def", "_NEAR_HEAP_SIZE=256", + "--config_def", "_FAR_HEAP_SIZE=4096", + "--config_def", "_HUGE_HEAP_SIZE=0", + "--config_def", "_STACK_SIZE=128", + "--config_def", "_NEAR_CONST_LOCATION_SIZE=0x6F00", + "--config_def", "_NEAR_CONST_LOCATION_START=0x3000", + "--define_symbol", "_NEAR_CONST_LOCATION=0", + "--config", cpp.toolchainInstallPath + "/../config/lnkrl78_s3.icf" + ] + } + Properties { + condition: qbs.toolchain.contains("iar") + && qbs.architecture === "rh850" + cpp.driverLinkerFlags: [ + "--config_def", "CSTACK_SIZE=0x1000", + "--config_def", "HEAP_SIZE=0x1000", + "--config", cpp.toolchainInstallPath + "/../config/lnkrh850_g3m.icf" + ] + } + Properties { + condition: qbs.toolchain.contains("iar") + && qbs.architecture === "v850" + cpp.driverLinkerFlags: [ + "-D_CSTACK_SIZE=1000", + "-D_HEAP_SIZE=1000", + "-f", cpp.toolchainInstallPath + "/../config/lnk85.xcl" + ] + } + Properties { + condition: qbs.toolchain.contains("iar") + && qbs.architecture === "78k" + cpp.commonCompilerFlags: [ + "--core", "78k0", + "--code_model", "standard" + ] + cpp.driverLinkerFlags: [ + "-D_CSTACK_SIZE=80", + "-D_HEAP_SIZE=200", + "-D_CODEBANK_START=0", + "-D_CODEBANK_END=0", + "-D_CODEBANK_BANKS=0", + "-f", cpp.toolchainInstallPath + "/../config/lnk.xcl", + cpp.toolchainInstallPath + "/../lib/clib/cl78ks1.r26" + ] + } + Properties { + condition: qbs.toolchain.contains("iar") + && qbs.architecture === "sh" + cpp.driverLinkerFlags: [ + "--config_def", "_CSTACK_SIZE=0x800", + "--config_def", "_HEAP_SIZE=0x800", + "--config_def", "_INT_TABLE=0x10", + "--config", cpp.toolchainInstallPath + "/../config/generic.icf" + ] + } + Properties { + condition: qbs.toolchain.contains("iar") + && qbs.architecture === "hcs8" + cpp.driverLinkerFlags: [ + "-D_CSTACK_SIZE=200", + "-D_HEAP_SIZE=200", + "-f", cpp.toolchainInstallPath + "/../config/lnkunspecifieds08.xcl" + ] + } + Properties { + condition: qbs.toolchain.contains("iar") + && qbs.architecture === "m32c" + cpp.driverLinkerFlags: [ + "-D_CSTACK_SIZE=100", + "-D_NEAR_HEAP_SIZE=400", + "-D_FAR_HEAP_SIZE=400", + "-D_HUGE_HEAP_SIZE=400", + "-D_ISTACK_SIZE=40", + "-f", cpp.toolchainInstallPath + "/../config/lnkm32c.xcl", + cpp.toolchainInstallPath + (qbs.debugInformation ? "/../lib/dlib/dlm32cnf.r48" : "/../lib/clib/clm32cf.r48") + ] + } + Properties { + condition: qbs.toolchain.contains("iar") + && qbs.architecture === "riscv" + cpp.driverLinkerFlags: [ + "--config_def", "CSTACK_SIZE=0x1000", + "--config_def", "HEAP_SIZE=0x1000" + ] + } + Properties { + condition: qbs.toolchain.contains("iar") + && qbs.architecture === "m68k" + cpp.cFlags: [ + "--no_div" + ] + cpp.driverLinkerFlags: [ + "-D__FLASHBEGIN=0", + "-D__FLASHEND=1FFFF", + "-D__RAMBEGIN=800000", + "-D__RAMEND=803FFF", + "-D_CSTACK_SIZE=200", + "-D_HEAP_SIZE=1000", + "-D_VBR_ADDRESS=0", + "-f", cpp.toolchainInstallPath + "/../config/lnkm51ac128.xcl", + cpp.toolchainInstallPath + "/../lib/dlcfcffdn.r68" + ] + } + Properties { + condition: qbs.toolchain.contains("keil") + && qbs.architecture.startsWith("arm") + && cpp.compilerName.startsWith("armcc") + cpp.assemblerFlags: ["--cpu", "cortex-m0"] + cpp.driverFlags: ["--cpu", "cortex-m0"] + } + Properties { + condition: qbs.toolchain.contains("keil") + && qbs.architecture.startsWith("arm") + && cpp.compilerName.startsWith("armclang") + cpp.assemblerFlags: ["--cpu", "cortex-m0"] + cpp.driverFlags: ["-mcpu=cortex-m0", "--target=arm-arm-none-eabi"] + } + Properties { + condition: qbs.toolchain.contains("gcc") + && qbs.architecture.startsWith("arm") + cpp.driverFlags: ["-specs=nosys.specs"] + } + Properties { + condition: qbs.toolchain.contains("gcc") + && qbs.architecture === "xtensa" + cpp.driverFlags: ["-nostdlib"] + } + Properties { + condition: qbs.toolchain.contains("gcc") + && qbs.architecture === "msp430" + cpp.driverFlags: ["-mmcu=msp430f5529", "-nostdlib"] + } + Properties { + condition: qbs.toolchain.contains("gcc") + && qbs.architecture === "m32r" + cpp.driverFlags: ["-nostdlib"] + } + Properties { + condition: qbs.toolchain.contains("gcc") + && qbs.architecture === "riscv" + cpp.driverFlags: ["-nostdlib"] + } +} diff --git a/tests/auto/blackbox/testdata-baremetal/BareMetalStaticLibrary.qbs b/tests/auto/blackbox/testdata-baremetal/BareMetalStaticLibrary.qbs index 560455162..7259b1446 100644 --- a/tests/auto/blackbox/testdata-baremetal/BareMetalStaticLibrary.qbs +++ b/tests/auto/blackbox/testdata-baremetal/BareMetalStaticLibrary.qbs @@ -1,104 +1,3 @@ -StaticLibrary { - cpp.positionIndependentCode: false - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "stm8" - cpp.driverLinkerFlags: [ - "--config_def", "_CSTACK_SIZE=0x100", - "--config_def", "_HEAP_SIZE=0x100", - ] - } - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "rl78" - cpp.driverLinkerFlags: [ - "--config_def", "_NEAR_HEAP_SIZE=256", - "--config_def", "_FAR_HEAP_SIZE=4096", - "--config_def", "_HUGE_HEAP_SIZE=0", - "--config_def", "_STACK_SIZE=128", - "--config_def", "_NEAR_CONST_LOCATION_SIZE=0x6F00", - "--config_def", "_NEAR_CONST_LOCATION_START=0x3000", - "--define_symbol", "_NEAR_CONST_LOCATION=0", - "--config", cpp.toolchainInstallPath + "/../config/lnkrl78_s3.icf" - ] - } - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "rh850" - cpp.driverLinkerFlags: [ - "--config_def", "CSTACK_SIZE=0x1000", - "--config_def", "HEAP_SIZE=0x1000", - "--config", cpp.toolchainInstallPath + "/../config/lnkrh850_g3m.icf" - ] - } - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "v850" - cpp.driverLinkerFlags: [ - "-D_CSTACK_SIZE=1000", - "-D_HEAP_SIZE=1000", - "-f", cpp.toolchainInstallPath + "/../config/lnk85.xcl" - ] - } - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "78k" - cpp.cFlags: [ - "--core", "78k0", - "--code_model", "standard" - ] - cpp.driverLinkerFlags: [ - "-D_CSTACK_SIZE=80", - "-D_HEAP_SIZE=200", - "-D_CODEBANK_START=0", - "-D_CODEBANK_END=0", - "-D_CODEBANK_BANKS=0", - "-f", cpp.toolchainInstallPath + "/../config/lnk.xcl", - cpp.toolchainInstallPath + "/../lib/clib/cl78ks1.r26" - ] - } - Properties { - condition: qbs.toolchain.contains("iar") - && qbs.architecture === "sh" - cpp.driverLinkerFlags: [ - "--config_def", "_CSTACK_SIZE=0x800", - "--config_def", "_HEAP_SIZE=0x800", - "--config_def", "_INT_TABLE=0x10", - "--config", cpp.toolchainInstallPath + "/../config/generic.icf" - ] - } - Properties { - condition: qbs.toolchain.contains("keil") - && qbs.architecture.startsWith("arm") - && cpp.compilerName.startsWith("armcc") - cpp.assemblerFlags: ["--cpu", "cortex-m0"] - cpp.driverFlags: ["--cpu", "cortex-m0"] - } - Properties { - condition: qbs.toolchain.contains("keil") - && qbs.architecture.startsWith("arm") - && cpp.compilerName.startsWith("armclang") - cpp.assemblerFlags: ["--cpu", "cortex-m0"] - cpp.driverFlags: ["-mcpu=cortex-m0", "--target=arm-arm-none-eabi"] - } - Properties { - condition: qbs.toolchain.contains("gcc") - && qbs.architecture.startsWith("arm") - cpp.driverFlags: ["-specs=nosys.specs"] - } - Properties { - condition: qbs.toolchain.contains("gcc") - && qbs.architecture === "xtensa" - cpp.driverFlags: ["-nostdlib"] - } - Properties { - condition: qbs.toolchain.contains("gcc") - && qbs.architecture === "msp430" - cpp.driverFlags: ["-mmcu=msp430f5529"] - } - Properties { - condition: qbs.toolchain.contains("gcc") - && qbs.architecture === "m32r" - cpp.driverFlags: ["-nostdlib"] - } +BareMetalProduct { + type: "staticlibrary" } diff --git a/tests/auto/blackbox/testdata-baremetal/do-not-generate-linker-map/main.c b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/app.c index 58fe69254..58fe69254 100644 --- a/tests/auto/blackbox/testdata-baremetal/do-not-generate-linker-map/main.c +++ b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/app.c diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/compiler-defines-by-language.qbs b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/compiler-defines-by-language.qbs new file mode 100644 index 000000000..5e8bbd62d --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/compiler-defines-by-language.qbs @@ -0,0 +1,69 @@ +import "../BareMetalApplication.qbs" as BareMetalApplication + +Project { + property bool supportsCpp: { + if (qbs.toolchain.contains("sdcc")) + return false; + if (qbs.toolchain.contains("keil")) { + if (qbs.architecture === "mcs51" + || qbs.architecture === "mcs251" + || qbs.architecture === "c166") { + return false; + } + } + return true; + } + + BareMetalApplication { + name: "c_language" + files: ["app.c", "ctest.c"] + cpp.enableCompilerDefinesByLanguage: [] + property var foo: { + if (!cpp.compilerDefinesByLanguage) + throw "ASSERT cpp.compilerDefinesByLanguage: " + + cpp.compilerDefinesByLanguage; + if (!cpp.compilerDefinesByLanguage["c"]) + throw "ASSERT cpp.compilerDefinesByLanguage[\"c\"]: " + + cpp.compilerDefinesByLanguage["c"]; + if (cpp.compilerDefinesByLanguage["cpp"]) + throw "ASSERT !cpp.compilerDefinesByLanguage[\"cpp\"]: " + + cpp.compilerDefinesByLanguage["cpp"]; + } + } + + BareMetalApplication { + condition: supportsCpp + name: "cpp_language" + files: ["app.c", "cpptest.cpp"] + cpp.enableCompilerDefinesByLanguage: ["cpp"] + property var foo: { + if (!cpp.compilerDefinesByLanguage) + throw "ASSERT cpp.compilerDefinesByLanguage: " + + cpp.compilerDefinesByLanguage; + if (cpp.compilerDefinesByLanguage["c"]) + throw "ASSERT !cpp.compilerDefinesByLanguage[\"c\"]: " + + cpp.compilerDefinesByLanguage["c"]; + if (!cpp.compilerDefinesByLanguage["cpp"]) + throw "ASSERT cpp.compilerDefinesByLanguage[\"cpp\"]: " + + cpp.compilerDefinesByLanguage["cpp"]; + } + } + + BareMetalApplication { + condition: supportsCpp + name: "c_and_cpp_language" + files: ["app.c", "ctest.c", "cpptest.cpp"] + cpp.enableCompilerDefinesByLanguage: ["c", "cpp"] + property var foo: { + if (!cpp.compilerDefinesByLanguage) + throw "ASSERT cpp.compilerDefinesByLanguage: " + + cpp.compilerDefinesByLanguage; + if (!cpp.compilerDefinesByLanguage["c"]) + throw "ASSERT cpp.compilerDefinesByLanguage[\"c\"]: " + + cpp.compilerDefinesByLanguage["c"]; + if (!cpp.compilerDefinesByLanguage["cpp"]) + throw "ASSERT cpp.compilerDefinesByLanguage[\"cpp\"]: " + + cpp.compilerDefinesByLanguage["cpp"]; + } + } +} diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/cpptest.cpp b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/cpptest.cpp new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/cpptest.cpp diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/ctest.c b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/ctest.c new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/ctest.c diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/compiler-include-paths.qbs b/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/compiler-include-paths.qbs new file mode 100644 index 000000000..5c73302ad --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/compiler-include-paths.qbs @@ -0,0 +1,9 @@ +import "../BareMetalApplication.qbs" as BareMetalApplication + +BareMetalApplication { + files: ["main.c"] + property bool dummy: { + console.info("compilerIncludePaths: %%" + cpp.compilerIncludePaths + "%%"); + return true; + } +} diff --git a/tests/auto/blackbox/testdata-baremetal/generate-linker-map/main.c b/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/main.c index 58fe69254..58fe69254 100644 --- a/tests/auto/blackbox/testdata-baremetal/generate-linker-map/main.c +++ b/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/main.c diff --git a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/generate-compiler-listing.qbs b/tests/auto/blackbox/testdata-baremetal/compiler-listing/compiler-listing.qbs index a6731d224..bcf983c88 100644 --- a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/generate-compiler-listing.qbs +++ b/tests/auto/blackbox/testdata-baremetal/compiler-listing/compiler-listing.qbs @@ -3,14 +3,12 @@ import "../BareMetalApplication.qbs" as BareMetalApplication BareMetalApplication { condition: { if (!qbs.toolchain.contains("gcc")) { - if (cpp.compilerName.startsWith("armcc")) - console.info("using short listing file names"); + console.info("compiler listing suffix: %%" + cpp.compilerListingSuffix + "%%"); return true; } console.info("unsupported toolset: %%" + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%"); return false; } - cpp.generateCompilerListingFiles: true files: ["main.c", "fun.c"] } diff --git a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/fun.c b/tests/auto/blackbox/testdata-baremetal/compiler-listing/fun.c index 3b8c8f2f4..3b8c8f2f4 100644 --- a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/fun.c +++ b/tests/auto/blackbox/testdata-baremetal/compiler-listing/fun.c diff --git a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/main.c b/tests/auto/blackbox/testdata-baremetal/compiler-listing/main.c index 2c3d7726c..2c3d7726c 100644 --- a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/main.c +++ b/tests/auto/blackbox/testdata-baremetal/compiler-listing/main.c diff --git a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/do-not-generate-compiler-listing.qbs b/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/do-not-generate-compiler-listing.qbs deleted file mode 100644 index 1bc4ba208..000000000 --- a/tests/auto/blackbox/testdata-baremetal/do-not-generate-compiler-listing/do-not-generate-compiler-listing.qbs +++ /dev/null @@ -1,16 +0,0 @@ -import "../BareMetalApplication.qbs" as BareMetalApplication - -BareMetalApplication { - condition: { - if (!qbs.toolchain.contains("gcc")) { - if (cpp.compilerName.startsWith("armcc")) - console.info("using short listing file names"); - return true; - } - console.info("unsupported toolset: %%" - + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%"); - return false; - } - cpp.generateCompilerListingFiles: false - files: ["main.c", "fun.c"] -} diff --git a/tests/auto/blackbox/testdata-baremetal/do-not-generate-linker-map/do-not-generate-linker-map.qbs b/tests/auto/blackbox/testdata-baremetal/do-not-generate-linker-map/do-not-generate-linker-map.qbs deleted file mode 100644 index 0ff952b22..000000000 --- a/tests/auto/blackbox/testdata-baremetal/do-not-generate-linker-map/do-not-generate-linker-map.qbs +++ /dev/null @@ -1,11 +0,0 @@ -import "../BareMetalApplication.qbs" as BareMetalApplication - -BareMetalApplication { - condition: { - console.info("current toolset: %%" - + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%"); - return true; - } - cpp.generateLinkerMapFile: false - files: ["main.c"] -} diff --git a/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs index 6fbbb8647..fffb6a03d 100644 --- a/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs +++ b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs @@ -2,20 +2,6 @@ import "../BareMetalApplication.qbs" as BareMetalApplication import "../BareMetalStaticLibrary.qbs" as BareMetalStaticLibrary Project { - condition: { - // The KEIL C51/C251/C166 toolchains support only a - // full paths to the external libraries. - if (qbs.toolchainType === "keil") { - if (qbs.architecture === "mcs51" - || qbs.architecture === "mcs251" - || qbs.architecture === "c166") { - console.info("unsupported toolset: %%" - + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%"); - return false; - } - } - return true; - } property string outputLibrariesDirectory: sourceDirectory + "/libs" BareMetalStaticLibrary { name: "lib-a" diff --git a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/main.c b/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/main.c deleted file mode 100644 index 2c3d7726c..000000000 --- a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/main.c +++ /dev/null @@ -1,6 +0,0 @@ -extern int f(void); - -int main(void) -{ - return f(); -} diff --git a/tests/auto/blackbox/testdata-baremetal/generate-linker-map/generate-linker-map.qbs b/tests/auto/blackbox/testdata-baremetal/generate-linker-map/generate-linker-map.qbs deleted file mode 100644 index a6ab5ba32..000000000 --- a/tests/auto/blackbox/testdata-baremetal/generate-linker-map/generate-linker-map.qbs +++ /dev/null @@ -1,11 +0,0 @@ -import "../BareMetalApplication.qbs" as BareMetalApplication - -BareMetalApplication { - condition: { - console.info("current toolset: %%" - + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%"); - return true; - } - cpp.generateLinkerMapFile: true - files: ["main.c"] -} diff --git a/tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs b/tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs new file mode 100644 index 000000000..fe93ac144 --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs @@ -0,0 +1,8 @@ +import "../BareMetalApplication.qbs" as BareMetalApplication + +BareMetalApplication { + property bool dummy: { + console.info("linker map suffix: %%" + cpp.linkerMapSuffix + "%%"); + } + files: ["main.c"] +} diff --git a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/fun.c b/tests/auto/blackbox/testdata-baremetal/linker-map/main.c index 3b8c8f2f4..58fe69254 100644 --- a/tests/auto/blackbox/testdata-baremetal/generate-compiler-listing/fun.c +++ b/tests/auto/blackbox/testdata-baremetal/linker-map/main.c @@ -1,4 +1,4 @@ -int f(void) +int main(void) { return 0; } diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs12-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs12-iar.s new file mode 100644 index 000000000..4344e757f --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs12-iar.s @@ -0,0 +1,7 @@ + PUBLIC main + RSEG CODE:CODE:REORDER:NOROOT(0) +main: + CLRB + CLRA + RTS + END diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-iar.s new file mode 100644 index 000000000..883dfdcad --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-iar.s @@ -0,0 +1,6 @@ + PUBLIC main + RSEG CODE:CODE:REORDER:NOROOT(0) +main: + LDHX #0x0000 + RTS + END diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-sdcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-sdcc.s new file mode 100644 index 000000000..f47fed1be --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-sdcc.s @@ -0,0 +1,6 @@ + .globl main + .area DSEG (PAG) + .area HOME (CODE) +main: + clra + tax diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-iar.s new file mode 100644 index 000000000..4153f290e --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-iar.s @@ -0,0 +1,6 @@ + PUBLIC main + RSEG CODE:CODE:REORDER:NOROOT(0) +main: + MOV.W #0x0, R0 + RTS + END diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-iar.s new file mode 100644 index 000000000..9811be134 --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-iar.s @@ -0,0 +1,6 @@ + PUBLIC main + RSEG FCODE:CODE:NOROOT(1) +main: + CLR.L D0 + RTS + END diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/one-object-asm-application.qbs b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/one-object-asm-application.qbs index 7650810a9..ed38f79b6 100644 --- a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/one-object-asm-application.qbs +++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/one-object-asm-application.qbs @@ -40,11 +40,25 @@ BareMetalApplication { return true; if (qbs.architecture === "m16c") return true; + if (qbs.architecture === "hcs8") + return true; + if (qbs.architecture === "hcs12") + return true; + if (qbs.architecture === "rx") + return true; + if (qbs.architecture === "m32c") + return true; + if (qbs.architecture === "riscv") + return true; + if (qbs.architecture === "m68k") + return true; } else if (qbs.toolchainType === "sdcc") { if (qbs.architecture === "mcs51") return true; if (qbs.architecture === "stm8") return true; + if (qbs.architecture === "hcs8") + return true; } else if (qbs.toolchainType === "gcc") { if (qbs.architecture.startsWith("arm")) return true; diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-iar.s new file mode 100644 index 000000000..e19fdfddb --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-iar.s @@ -0,0 +1,7 @@ + PUBLIC main + SECTION `.text`:CODE:REORDER:NOROOT(2) + CODE +main: + MV A0, ZERO + RET + END diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-iar.s new file mode 100644 index 000000000..cc1573431 --- /dev/null +++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-iar.s @@ -0,0 +1,5 @@ + PUBLIC _main + SECTION CODE:CODE:ROOT(2) +_main: + BRA _main + END diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js index bd596fbca..b925effcf 100644 --- a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js +++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js @@ -35,7 +35,7 @@ ** ****************************************************************************/ -// needs import qbs.TextFile +var TextFile = require("qbs.TextFile"); function readFlexOptions(filePath) { @@ -82,7 +82,7 @@ function readFlexOptions(filePath) } } - var tf = new TextFile(input.filePath); + var tf = new TextFile(filePath); var line; var optrex = /^%option\s+(.*$)/; var res; diff --git a/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs b/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs index acafdb52b..62871698e 100644 --- a/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs +++ b/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs @@ -61,7 +61,7 @@ Product { if (lhs.length !== rhs.length) return false; for (var i = 0; i < lhs.length; ++i) { - if (Array.isArray(lhs[i]) && Array.isArray(rhs[i])) { + if ((lhs[i] instanceof Array) && (rhs[i] instanceof Array)) { if (!compareArrays(lhs[i], rhs[i])) return false; } else if (FileInfo.resolvePath(path, lhs[i]) !== FileInfo.resolvePath(path, rhs[i])) { diff --git a/tests/auto/blackbox/testdata/undefined-target-platform/undefined-target-platform.qbs b/tests/auto/blackbox/testdata/undefined-target-platform/undefined-target-platform.qbs index 2b3724c26..4a738afcc 100644 --- a/tests/auto/blackbox/testdata/undefined-target-platform/undefined-target-platform.qbs +++ b/tests/auto/blackbox/testdata/undefined-target-platform/undefined-target-platform.qbs @@ -6,7 +6,7 @@ Product { qbs.targetPlatform: undefined readonly property bool _validate: { - if (Array.isArray(qbs.targetOS) && qbs.targetOS.length === 0) + if ((qbs.targetOS instanceof Array) && qbs.targetOS.length === 0) return true; throw "Invalid qbs.targetOS value: " + qbs.targetOS; } diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 20116ff56..1b9fa0b15 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -2173,7 +2173,7 @@ void TestBlackbox::trackExternalProductChanges() const QStringList toolchainTypes = profileToolchain(profile); if (!toolchainTypes.contains("gcc")) QSKIP("Need GCC-like compiler to run this test"); - params.environment = QProcessEnvironment::systemEnvironment(); + params.environment = QbsRunParameters::defaultEnvironment(); params.environment.insert("INCLUDE_PATH_TEST", "1"); params.expectFailure = true; QVERIFY(runQbs(params) != 0); @@ -3598,16 +3598,14 @@ void TestBlackbox::propertyEvaluationContext() void TestBlackbox::qtBug51237() { - const QString profileName = "profile-qtBug51237"; - const QString propertyName = "mymodule.theProperty"; - { - const SettingsPtr s = settings(); - Profile profile(profileName, s.get()); - profile.setValue(propertyName, QStringList()); - } + const SettingsPtr s = settings(); + qbs::Internal::TemporaryProfile profile("qbs_autotests_qtBug51237", s.get()); + profile.p.setValue("mymodule.theProperty", QStringList()); + s->sync(); + QDir::setCurrent(testDataDir + "/QTBUG-51237"); QbsRunParameters params; - params.profile = profileName; + params.profile = profile.p.name(); QCOMPARE(runQbs(params), 0); } @@ -6054,7 +6052,7 @@ void TestBlackbox::qbsSession() QJsonObject overriddenValues; overriddenValues.insert("products.theLib.cpp.cxxLanguageVersion", "c++17"); resolveMessage.insert("overridden-properties", overriddenValues); - resolveMessage.insert("environment", envToJson(QProcessEnvironment::systemEnvironment())); + resolveMessage.insert("environment", envToJson(QbsRunParameters::defaultEnvironment())); resolveMessage.insert("data-mode", "only-if-changed"); resolveMessage.insert("log-time", true); resolveMessage.insert("module-properties", diff --git a/tests/auto/blackbox/tst_blackboxandroid.cpp b/tests/auto/blackbox/tst_blackboxandroid.cpp index a03c9e318..f8ed8a0b9 100644 --- a/tests/auto/blackbox/tst_blackboxandroid.cpp +++ b/tests/auto/blackbox/tst_blackboxandroid.cpp @@ -268,14 +268,19 @@ void TestBlackboxAndroid::android_data() return result; }; - auto commonFiles = [](bool generateAab) { + auto commonFiles = [](bool generateAab, bool codeSign = true, + QString keyAlias="androiddebugkey") { + QByteArrayList files; if (generateAab) - return (QByteArrayList() - << "base/manifest/AndroidManifest.xml" << "base/dex/classes.dex" - << "BundleConfig.pb"); - return (QByteArrayList() - << "AndroidManifest.xml" << "META-INF/ANDROIDD.RSA" << "META-INF/ANDROIDD.SF" - << "META-INF/MANIFEST.MF" << "classes.dex"); + files << "base/manifest/AndroidManifest.xml" << "base/dex/classes.dex" + << "BundleConfig.pb"; + else + files << "AndroidManifest.xml" << "classes.dex"; + if (codeSign) + files << QByteArray("META-INF/" + keyAlias.toUpper().left(8).toUtf8() + ".RSA") + << QByteArray("META-INF/" + keyAlias.toUpper().left(8).toUtf8() + ".SF") + << "META-INF/MANIFEST.MF"; + return files; }; QTest::addColumn<QString>("projectDir"); @@ -296,10 +301,11 @@ void TestBlackboxAndroid::android_data() bool generateAab = false; bool isIncrementalBuild = false; - auto qtAppExpectedFiles = [&](bool generateAab, bool enableAapt2) { + auto qtAppExpectedFiles = [&](bool generateAab, bool enableAapt2, bool codeSign = true, + QString keyAlias="androiddebugkey") { QByteArrayList expectedFile; if (singleArchQt) { - expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, { + expectedFile << commonFiles(generateAab, codeSign, keyAlias) + expandArchs(ndkArchsForQt, { cxxLibPath("libgnustl_shared.so", true), "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list", "lib/${ARCH}/libplugins_imageformats_libqgif.so", @@ -317,7 +323,7 @@ void TestBlackboxAndroid::android_data() "lib/${ARCH}/libQt5Widgets.so", "lib/${ARCH}/libqt-app.so"}, generateAab); } else { - expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, { + expectedFile << commonFiles(generateAab, codeSign, keyAlias) + expandArchs(ndkArchsForQt, { cxxLibPath("libgnustl_shared.so", true), "lib/${ARCH}/libplugins_imageformats_qgif_${ARCH}.so", "lib/${ARCH}/libplugins_imageformats_qico_${ARCH}.so", @@ -329,7 +335,7 @@ void TestBlackboxAndroid::android_data() "lib/${ARCH}/libqt-app_${ARCH}.so"}, generateAab); } if (generateAab) - expectedFile << "base/resources.pb" << "base/assets.pb" << "base/native.pb"; + expectedFile << "base/resources.pb" << "base/native.pb"; else expectedFile << "resources.arsc"; if (version >= qbs::Version(5, 14)) @@ -346,11 +352,82 @@ void TestBlackboxAndroid::android_data() expectedFile << "res/layout/splash.xml"; return expectedFile; }; + auto codeSignProperties = [&](bool codeSign, QString keyStorePath, QString keystorePassword, + QString keyPassword, QString keyAlias) { + if (!codeSign) + return QStringList{"modules.codesign.enableCodeSigning:false"}; + return QStringList{ + "modules.codesign.enableCodeSigning:true", + "modules.codesign.keystorePath:" + keyStorePath, + "modules.codesign.keystorePassword:" + keystorePassword, + "modules.codesign.keyPassword:" + keyPassword, + "modules.codesign.keyAlias:" + keyAlias, + }; + }; + bool codeSign = true; + QString keyStorePath(testDataDir + "/qt-app/test.keystore"); + QString keystorePassword("qbsKeystoreTest"); + QString keyPassword("qbsKeyTest"); + QString keyAlias("qbsTest"); QTest::newRow("qt app") << "qt-app" << QStringList("qt-app") << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab, - enableAapt2))) - << QStringList{aaptVersion(enableAapt2), packageType(generateAab)} + enableAapt2, + codeSign, + keyAlias))) + << (QStringList() << codeSignProperties(codeSign, keyStorePath, keystorePassword, + keyPassword, keyAlias) + << aaptVersion(enableAapt2) + << packageType(generateAab)) + << enableAapt2 << generateAab << isIncrementalBuild; + codeSign = false; + QTest::newRow("qt app no signing") + << "qt-app" << QStringList("qt-app") + << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab, + enableAapt2, + codeSign, + keyAlias))) + << (QStringList() << codeSignProperties(codeSign, keyStorePath, keystorePassword, + keyPassword, keyAlias) + << aaptVersion(enableAapt2) + << packageType(generateAab)) + << enableAapt2 << generateAab << isIncrementalBuild; + enableAapt2 = true; + codeSign = true; + QTest::newRow("qt app aapt2") + << "qt-app" << QStringList("qt-app") + << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab, + enableAapt2, + codeSign, + keyAlias))) + << (QStringList() << codeSignProperties(codeSign, keyStorePath, keystorePassword, + keyPassword, keyAlias) + << aaptVersion(enableAapt2) + << packageType(generateAab)) + << enableAapt2 << generateAab << isIncrementalBuild; + generateAab = true; + QTest::newRow("qt app aab") + << "qt-app" << QStringList("qt-app") + << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab, + enableAapt2, + codeSign, + keyAlias))) + << (QStringList() << codeSignProperties(codeSign, keyStorePath, keystorePassword, + keyPassword, keyAlias) + << aaptVersion(enableAapt2) + << packageType(generateAab)) + << enableAapt2 << generateAab << isIncrementalBuild; + codeSign = false; + QTest::newRow("qt app aab no signing") + << "qt-app" << QStringList("qt-app") + << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab, + enableAapt2, + codeSign, + keyAlias))) + << (QStringList() << codeSignProperties(codeSign, keyStorePath, keystorePassword, + keyPassword, keyAlias) + << aaptVersion(enableAapt2) + << packageType(generateAab)) << enableAapt2 << generateAab << isIncrementalBuild; const QByteArrayList ndkArchsForQtSave = ndkArchsForQt; @@ -383,6 +460,8 @@ void TestBlackboxAndroid::android_data() return expectedFile; }; + generateAab = false; + enableAapt2 = false; QTest::newRow("teapot") << "teapot" << QStringList("TeapotNativeActivity") << (QList<QByteArrayList>() << teaPotAppExpectedFiles(archs, generateAab)) @@ -437,6 +516,7 @@ void TestBlackboxAndroid::android_data() "modules.qbs.architecture:" + archsStringList.first(), aaptVersion(enableAapt2), packageType(generateAab)} << enableAapt2 << generateAab << isIncrementalBuild; + auto qmlAppExpectedFiles = [&](bool generateAab, bool enableAapt2) { QByteArrayList expectedFile; if (singleArchQt) { @@ -730,7 +810,6 @@ void TestBlackboxAndroid::android_data() } else { qmlAppCustomProperties = QStringList{"modules.Android.sdk.automaticSources:false"}; } - // aapt tool for the resources works with a directory option pointing to the parent directory // of the resources (res). // The Qt.android_support module adds res/values/libs.xml (from Qt install dir). So the res from @@ -851,6 +930,7 @@ void TestBlackboxAndroid::android_data() expectedFile << "resources.arsc"; return expectedFile; }; + QTest::newRow("no native") << "no-native" << QStringList("com.example.android.basicmediadecoder") diff --git a/tests/auto/blackbox/tst_blackboxapple.cpp b/tests/auto/blackbox/tst_blackboxapple.cpp index e62eb3391..884d2c077 100644 --- a/tests/auto/blackbox/tst_blackboxapple.cpp +++ b/tests/auto/blackbox/tst_blackboxapple.cpp @@ -140,6 +140,39 @@ static QString findFatLibrary(const QString &dir, const QString &libraryName) return {}; } +enum class CodeSignResult { Failed = 0, Signed, Unsigned }; +using CodeSignData = QMap<QByteArray, QByteArray>; +static std::pair<CodeSignResult, CodeSignData> parseCodeSignOutput(const QByteArray &output) +{ + CodeSignData data; + if (output.contains("code object is not signed at all")) + return {CodeSignResult::Unsigned, data}; + const auto lines = output.split('\n'); + for (const auto &line: lines) { + if (line.isEmpty() + || line.startsWith("CodeDirectory") + || line.startsWith("Sealed Resources") + || line.startsWith("Internal requirements")) { + continue; + } + const int index = line.indexOf('='); + if (index == -1) + return {CodeSignResult::Failed, {}}; + data[line.mid(0, index)] = line.mid(index + 1); + } + return {CodeSignResult::Signed, data}; +} + +static std::pair<CodeSignResult, CodeSignData> getCodeSignInfo(const QString &path) +{ + QProcess codesign; + codesign.start("codesign", { QStringLiteral("-dv"), path }); + if (!codesign.waitForStarted() || !codesign.waitForFinished()) + return {CodeSignResult::Failed, {}}; + const auto output = codesign.readAllStandardError(); + return parseCodeSignOutput(output); +} + TestBlackboxApple::TestBlackboxApple() : TestBlackboxBase (SRCDIR "/testdata-apple", "blackbox-apple") { @@ -273,7 +306,7 @@ void TestBlackboxApple::aggregateDependencyLinking() const auto xcodeVersion = findXcodeVersion(); // XCode 11 produces warning about deprecation of 32-bit apps, but still works const bool hasX86Mac = xcodeVersion < qbs::Version(12); - const bool hasArmMac = false; + const bool hasArmMac = xcodeVersion >= qbs::Version(12, 2); QDir::setCurrent(testDataDir + "/aggregateDependencyLinking"); QbsRunParameters params{QStringList{"-p", "multi_arch_lib"}}; @@ -680,6 +713,85 @@ void TestBlackboxApple::bundleStructure_data() QTest::newRow("G") << "G" << "com.apple.product-type.in-app-purchase-content"; } +void TestBlackboxApple::codesign() +{ + QFETCH(bool, isBundle); + QFETCH(bool, enableSigning); + QFETCH(bool, multiArch); + + const auto xcodeVersion = findXcodeVersion(); + + QDir::setCurrent(testDataDir + "/codesign"); + QbsRunParameters params(QStringList{"qbs.installPrefix:''"}); + params.arguments + << QStringLiteral("project.isBundle:%1").arg(isBundle ? "true" : "false"); + params.arguments + << QStringLiteral("project.enableSigning:%1").arg(enableSigning ? "true" : "false"); + if (multiArch) + params.arguments << QStringLiteral("project.xcodeVersion:") + xcodeVersion.toString(); + + rmDirR(relativeBuildDir()); + QCOMPARE(runQbs(params), 0); + + const int codeSignCount = + QString::fromUtf8(m_qbsStdout).count(QStringLiteral("codesign")); + // We have 3 products, we have to sign each exactly once, even in the multiplexed case + QCOMPARE(codeSignCount, enableSigning ? 3 : 0); + + const auto appName = isBundle ? QStringLiteral("A.app") : QStringLiteral("A"); + const auto appPath = defaultInstallRoot + "/" + appName; + QVERIFY(QFileInfo(appPath).exists()); + auto codeSignInfo = getCodeSignInfo(appPath); + QVERIFY(codeSignInfo.first != CodeSignResult::Failed); + QCOMPARE(codeSignInfo.first == CodeSignResult::Signed, enableSigning); + QCOMPARE(codeSignInfo.second.isEmpty(), !enableSigning); + if (!codeSignInfo.second.isEmpty()) { + QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Executable"))); + QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Identifier"))); + QCOMPARE(codeSignInfo.second.value(QByteArrayLiteral("Signature")), "adhoc"); + } + + const auto libName = isBundle ? QStringLiteral("B.framework") : QStringLiteral("libB.dylib"); + const auto libPath = defaultInstallRoot + "/" + libName; + QVERIFY(QFileInfo(libPath).exists()); + codeSignInfo = getCodeSignInfo(libPath); + QVERIFY(codeSignInfo.first != CodeSignResult::Failed); + QCOMPARE(codeSignInfo.first == CodeSignResult::Signed, enableSigning); + QCOMPARE(codeSignInfo.second.isEmpty(), !enableSigning); + if (!codeSignInfo.second.isEmpty()) { + QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Executable"))); + QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Identifier"))); + QCOMPARE(codeSignInfo.second.value(QByteArrayLiteral("Signature")), "adhoc"); + } + + const auto pluginPath = defaultInstallRoot + "/" + QStringLiteral("C.bundle"); + QVERIFY(QFileInfo(pluginPath).exists()); + QVERIFY(QFileInfo(pluginPath).isDir() == isBundle); + codeSignInfo = getCodeSignInfo(pluginPath); + QVERIFY(codeSignInfo.first != CodeSignResult::Failed); + QCOMPARE(codeSignInfo.first == CodeSignResult::Signed, enableSigning); + QCOMPARE(codeSignInfo.second.isEmpty(), !enableSigning); + if (!codeSignInfo.second.isEmpty()) { + QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Executable"))); + QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Identifier"))); + QCOMPARE(codeSignInfo.second.value(QByteArrayLiteral("Signature")), "adhoc"); + } +} + +void TestBlackboxApple::codesign_data() +{ + QTest::addColumn<bool>("isBundle"); + QTest::addColumn<bool>("enableSigning"); + QTest::addColumn<bool>("multiArch"); + + QTest::newRow("bundle, unsigned") << true << false << false; + QTest::newRow("standalone, unsigned") << false << false << false; + QTest::newRow("bundle, signed") << true << true << false; + QTest::newRow("standalone, signed") << false << true << false; + QTest::newRow("bundle, signed, multiarch") << true << true << true; + QTest::newRow("standalone, signed, multiarch") << false << true << true; +} + void TestBlackboxApple::deploymentTarget() { QFETCH(QString, sdk); diff --git a/tests/auto/blackbox/tst_blackboxapple.h b/tests/auto/blackbox/tst_blackboxapple.h index eeaa28d2f..32eee2432 100644 --- a/tests/auto/blackbox/tst_blackboxapple.h +++ b/tests/auto/blackbox/tst_blackboxapple.h @@ -55,6 +55,8 @@ private slots: void assetCatalogsMultiple(); void bundleStructure(); void bundleStructure_data(); + void codesign(); + void codesign_data(); void deploymentTarget(); void deploymentTarget_data(); void dmg(); diff --git a/tests/auto/blackbox/tst_blackboxbaremetal.cpp b/tests/auto/blackbox/tst_blackboxbaremetal.cpp index 41f50a0ed..e0a068bc6 100644 --- a/tests/auto/blackbox/tst_blackboxbaremetal.cpp +++ b/tests/auto/blackbox/tst_blackboxbaremetal.cpp @@ -32,6 +32,7 @@ #include "../shared.h" +#include <QtCore/qdir.h> #include <QtCore/qregularexpression.h> static bool extractToolset(const QByteArray &output, @@ -47,6 +48,27 @@ static bool extractToolset(const QByteArray &output, return true; } +static bool extractCompilerIncludePaths(const QByteArray &output, QStringList &compilerIncludePaths) +{ + const QRegularExpression re("%%([^%%]+)%%"); + QRegularExpressionMatchIterator it = re.globalMatch(output); + if (!it.hasNext()) + return false; + const QRegularExpressionMatch match = it.next(); + compilerIncludePaths = match.captured(1).split(","); + return true; +} + +static bool extractQuitedValue(const QByteArray &output, QString &pattern) +{ + const QRegularExpression re("%%(.+)%%"); + const QRegularExpressionMatch match = re.match(output); + if (!match.hasMatch()) + return false; + pattern = match.captured(1); + return true; +} + static QByteArray unsupportedToolsetMessage(const QByteArray &output) { QByteArray toolchain; @@ -56,17 +78,6 @@ static QByteArray unsupportedToolsetMessage(const QByteArray &output) + "' for architecture '" + architecture + "'"; } -static QString linkerMapFileExtension(const QByteArray &toolchain, const QByteArray &architecture) -{ - if (toolchain == "keil") { - if (architecture == "mcs51") - return QStringLiteral(".m51"); - if (architecture == "c166") - return QStringLiteral(".m66"); - } - return QStringLiteral(".map"); -} - TestBlackboxBareMetal::TestBlackboxBareMetal() : TestBlackboxBase (SRCDIR "/testdata-baremetal", "blackbox-baremetal") { @@ -142,6 +153,22 @@ void TestBlackboxBareMetal::distributionIncludePaths() QCOMPARE(runQbs(), 0); } +void TestBlackboxBareMetal::compilerIncludePaths() +{ + QDir::setCurrent(testDataDir + "/compiler-include-paths"); + QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0); + if (!m_qbsStdout.contains("compilerIncludePaths:")) + QFAIL("No compiler include paths exists"); + + QStringList includePaths; + QVERIFY(extractCompilerIncludePaths(m_qbsStdout, includePaths)); + QVERIFY(includePaths.count() > 0); + for (const auto &includePath : includePaths) { + const QDir dir(includePath); + QVERIFY(dir.exists()); + } +} + void TestBlackboxBareMetal::preincludeHeaders() { QDir::setCurrent(testDataDir + "/preinclude-headers"); @@ -159,61 +186,92 @@ void TestBlackboxBareMetal::defines() void TestBlackboxBareMetal::compilerListingFiles_data() { - QTest::addColumn<QString>("testPath"); QTest::addColumn<bool>("generateListing"); - QTest::newRow("do-not-generate-compiler-listing") << "/do-not-generate-compiler-listing" << false; - QTest::newRow("generate-compiler-listing") << "/generate-compiler-listing" << true; + QTest::addColumn<QString>("customListingSuffix"); + QTest::newRow("do-not-generate-compiler-listing") << false << ""; + QTest::newRow("generate-default-compiler-listing") << true << ""; + QTest::newRow("generate-custom-compiler-listing") << true << ".lll"; } void TestBlackboxBareMetal::compilerListingFiles() { - QFETCH(QString, testPath); QFETCH(bool, generateListing); - QDir::setCurrent(testDataDir + testPath); - QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0); + QFETCH(QString, customListingSuffix); + QDir::setCurrent(testDataDir + "/compiler-listing"); + + rmDirR(relativeBuildDir()); + QStringList args = {QStringLiteral("modules.cpp.generateCompilerListingFiles:%1") + .arg(generateListing ? "true" : "false")}; + if (!customListingSuffix.isEmpty()) + args << QStringLiteral("modules.cpp.compilerListingSuffix:%1").arg(customListingSuffix); + + QCOMPARE(runQbs(QbsRunParameters("resolve", args)), 0); if (m_qbsStdout.contains("unsupported toolset:")) QSKIP(unsupportedToolsetMessage(m_qbsStdout)); - QCOMPARE(runQbs(), 0); - const bool isShortListingNames = m_qbsStdout.contains("using short listing file names"); - const QString productName = testPath.mid(1); - const QString productBuildDir = relativeProductBuildDir(productName); + if (!m_qbsStdout.contains("compiler listing suffix:")) + QFAIL("No current compiler listing suffix pattern exists"); + + QString compilerListingSuffix; + if (!extractQuitedValue(m_qbsStdout, compilerListingSuffix)) + QFAIL("Unable to extract current compiler listing suffix"); + + if (!customListingSuffix.isEmpty()) + QCOMPARE(compilerListingSuffix, customListingSuffix); + + QCOMPARE(runQbs(QbsRunParameters(args)), 0); + const QString productBuildDir = relativeProductBuildDir("compiler-listing"); const QString hash = inputDirHash("."); - const QString mainListing = productBuildDir + "/" + hash + (isShortListingNames ? "/main.lst" : "/main.c.lst"); + const QString mainListing = productBuildDir + "/" + hash + + "/main.c" + compilerListingSuffix; QCOMPARE(regularFileExists(mainListing), generateListing); - const QString funListing = productBuildDir + "/" + hash + (isShortListingNames ? "/fun.lst" : "/fun.c.lst"); + const QString funListing = productBuildDir + "/" + hash + + "/fun.c" + compilerListingSuffix; QCOMPARE(regularFileExists(funListing), generateListing); } void TestBlackboxBareMetal::linkerMapFile_data() { - QTest::addColumn<QString>("testPath"); QTest::addColumn<bool>("generateMap"); - QTest::newRow("do-not-generate-linker-map") << "/do-not-generate-linker-map" << false; - QTest::newRow("generate-linker-map") << "/generate-linker-map" << true; + QTest::addColumn<QString>("customMapSuffix"); + QTest::newRow("do-not-generate-linker-map") << false << ""; + QTest::newRow("generate-default-linker-map") << true << ""; + QTest::newRow("generate-custom-linker-map") << true << ".mmm"; } void TestBlackboxBareMetal::linkerMapFile() { - QFETCH(QString, testPath); QFETCH(bool, generateMap); - QDir::setCurrent(testDataDir + testPath); - QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0); - if (m_qbsStdout.contains("unsupported toolset:")) - QSKIP(unsupportedToolsetMessage(m_qbsStdout)); - if (!m_qbsStdout.contains("current toolset:")) - QFAIL("No current toolset pattern exists"); + QFETCH(QString, customMapSuffix); + QDir::setCurrent(testDataDir + "/linker-map"); - QByteArray toolchain; - QByteArray architecture; - if (!extractToolset(m_qbsStdout, toolchain, architecture)) - QFAIL("Unable to extract current toolset"); + rmDirR(relativeBuildDir()); + QStringList args = {QStringLiteral("modules.cpp.generateLinkerMapFile:%1") + .arg(generateMap ? "true" : "false")}; + if (!customMapSuffix.isEmpty()) + args << QStringLiteral("modules.cpp.linkerMapSuffix:%1").arg(customMapSuffix); - QCOMPARE(runQbs(), 0); - const QString productName = testPath.mid(1); - const QString productBuildDir = relativeProductBuildDir(productName); - const auto extension = linkerMapFileExtension(toolchain, architecture); - const QString linkerMap = productBuildDir + "/" + productName + extension; + QCOMPARE(runQbs(QbsRunParameters("resolve", args)), 0); + if (!m_qbsStdout.contains("linker map suffix:")) + QFAIL("No current linker map suffix pattern exists"); + + QString linkerMapSuffix; + if (!extractQuitedValue(m_qbsStdout, linkerMapSuffix)) + QFAIL("Unable to extract current linker map suffix"); + + if (!customMapSuffix.isEmpty()) + QCOMPARE(linkerMapSuffix, customMapSuffix); + + QCOMPARE(runQbs(QbsRunParameters(args)), 0); + const QString productBuildDir = relativeProductBuildDir("linker-map"); + const QString linkerMap = productBuildDir + "/linker-map" + linkerMapSuffix; QCOMPARE(regularFileExists(linkerMap), generateMap); } +void TestBlackboxBareMetal::compilerDefinesByLanguage() +{ + QDir::setCurrent(testDataDir + "/compiler-defines-by-language"); + QbsRunParameters params(QStringList{ "-f", "compiler-defines-by-language.qbs" }); + QCOMPARE(runQbs(params), 0); +} + QTEST_MAIN(TestBlackboxBareMetal) diff --git a/tests/auto/blackbox/tst_blackboxbaremetal.h b/tests/auto/blackbox/tst_blackboxbaremetal.h index 3695cb1c3..39d2f36c9 100644 --- a/tests/auto/blackbox/tst_blackboxbaremetal.h +++ b/tests/auto/blackbox/tst_blackboxbaremetal.h @@ -52,6 +52,7 @@ private slots: void userIncludePaths(); void systemIncludePaths(); void distributionIncludePaths(); + void compilerIncludePaths(); void preincludeHeaders(); @@ -63,6 +64,8 @@ private slots: void linkerMapFile_data(); void linkerMapFile(); + void compilerDefinesByLanguage(); + private: }; diff --git a/tests/auto/blackbox/tst_blackboxbase.h b/tests/auto/blackbox/tst_blackboxbase.h index ed9a233de..d020b7cd9 100644 --- a/tests/auto/blackbox/tst_blackboxbase.h +++ b/tests/auto/blackbox/tst_blackboxbase.h @@ -60,7 +60,14 @@ public: expectCrash = false; profile = profileName(); settingsDir = settings()->baseDirectory(); - environment = QProcessEnvironment::systemEnvironment(); + environment = defaultEnvironment(); + } + + static QProcessEnvironment defaultEnvironment() + { + auto result = QProcessEnvironment::systemEnvironment(); + result.insert(QStringLiteral("QBS_AUTOTEST_CODE_SIGNING_REQUIRED"), QStringLiteral("0")); + return result; } QString command; diff --git a/tests/auto/buildgraph/buildgraph.qbs b/tests/auto/buildgraph/buildgraph.qbs index 3fbb57575..c6414b688 100644 --- a/tests/auto/buildgraph/buildgraph.qbs +++ b/tests/auto/buildgraph/buildgraph.qbs @@ -1,6 +1,6 @@ import qbs -QbsAutotest { +QbsUnittest { Depends { name: "qbsconsolelogger" } testName: "buildgraph" condition: qbsbuildconfig.enableUnitTests diff --git a/tests/auto/language/language.qbs b/tests/auto/language/language.qbs index 22fef1618..d3619a243 100644 --- a/tests/auto/language/language.qbs +++ b/tests/auto/language/language.qbs @@ -1,14 +1,9 @@ import qbs import qbs.Utilities -QbsAutotest { +QbsUnittest { Depends { name: "qbsversion" } Depends { name: "qbsconsolelogger" } - Depends { - name: "Qt.script" - condition: !qbsbuildconfig.useBundledQtScript - required: false - } testName: "language" condition: qbsbuildconfig.enableUnitTests diff --git a/tests/auto/shared.h b/tests/auto/shared.h index 8dced2062..e97fa9166 100644 --- a/tests/auto/shared.h +++ b/tests/auto/shared.h @@ -159,7 +159,10 @@ inline QByteArray diffText(const QByteArray &actual, const QByteArray &expected) } auto addLines = [&result, &n] (const QList<QByteArray> &lines) { for (const QByteArray &line : qAsConst(lines)) { - result += QStringLiteral("%1: %2\n").arg(n).arg(QString::fromUtf8(line)); + result += QStringLiteral("%1: %2\n") + .arg(n) + .arg(QString::fromUtf8(line)) + .toUtf8(); n++; } }; diff --git a/tests/auto/tools/tools.qbs b/tests/auto/tools/tools.qbs index 64cced80e..384ba74eb 100644 --- a/tests/auto/tools/tools.qbs +++ b/tests/auto/tools/tools.qbs @@ -1,7 +1,7 @@ import qbs import qbs.Utilities -QbsAutotest { +QbsUnittest { Depends { name: "qbsversion" } testName: "tools" diff --git a/tests/auto/tools/tst_tools.cpp b/tests/auto/tools/tst_tools.cpp index edf5a1308..92e0978b5 100644 --- a/tests/auto/tools/tst_tools.cpp +++ b/tests/auto/tools/tst_tools.cpp @@ -673,6 +673,30 @@ void TestTools::set_containsSet() QVERIFY(set3.contains(set4)); } +void TestTools::set_find() +{ + Set<QString> set1; + + for (int i = 0; i < 500; ++i) { + QVERIFY(set1.find(QString::number(i)) == set1.end()); + set1.insert(QString::number(i)); + const auto it = set1.find(QString::number(i)); + QVERIFY(it != set1.end()); + QVERIFY(*it == QString::number(i)); + } + + QCOMPARE(set1.size(), size_t { 500 }); + + for (int j = 0; j < 500; ++j) { + int i = (j * 17) % 500; + const auto it = set1.find(QString::number(i)); + QVERIFY(it != set1.end()); + QVERIFY(*it == QString::number(i)); + set1.remove(QString::number(i)); + QVERIFY(set1.find(QString::number(i)) == set1.end()); + } +} + void TestTools::set_begin() { Set<int> set1; diff --git a/tests/auto/tools/tst_tools.h b/tests/auto/tools/tst_tools.h index bd8538be2..d1ba0a57b 100644 --- a/tests/auto/tools/tst_tools.h +++ b/tests/auto/tools/tst_tools.h @@ -79,6 +79,7 @@ private slots: void set_remove(); void set_contains(); void set_containsSet(); + void set_find(); void set_begin(); void set_end(); void set_insert(); diff --git a/tests/benchmarker/benchmarker.cpp b/tests/benchmarker/benchmarker.cpp index 2cc442a72..3c5fcde4e 100644 --- a/tests/benchmarker/benchmarker.cpp +++ b/tests/benchmarker/benchmarker.cpp @@ -77,8 +77,8 @@ void Benchmarker::benchmark() m_baseOutputDir.path() + "/benchmark-data." + m_oldCommit); ValgrindRunner newDataRetriever(m_activities, m_testProject, newQbsBuildDir, m_baseOutputDir.path() + "/benchmark-data." + m_newCommit); - QFuture<void> oldFuture = QtConcurrent::run(&oldDataRetriever, &ValgrindRunner::run); - QFuture<void> newFuture = QtConcurrent::run(&newDataRetriever, &ValgrindRunner::run); + QFuture<void> oldFuture = QtConcurrent::run([&oldDataRetriever]{ oldDataRetriever.run(); }); + QFuture<void> newFuture = QtConcurrent::run([&newDataRetriever]{ newDataRetriever.run(); }); oldFuture.waitForFinished(); const auto oldValgrindResults = oldDataRetriever.results(); for (const ValgrindResult &valgrindResult : oldValgrindResults) { diff --git a/tests/benchmarker/benchmarker.h b/tests/benchmarker/benchmarker.h index 6313e8094..8c94e7f74 100644 --- a/tests/benchmarker/benchmarker.h +++ b/tests/benchmarker/benchmarker.h @@ -32,12 +32,9 @@ #include <QtCore/qhash.h> #include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> #include <QtCore/qtemporarydir.h> -QT_BEGIN_NAMESPACE -class QStringList; -QT_END_NAMESPACE - namespace qbsBenchmarker { class BenchmarkResult diff --git a/tests/benchmarker/runsupport.h b/tests/benchmarker/runsupport.h index 6ee831007..39f485a02 100644 --- a/tests/benchmarker/runsupport.h +++ b/tests/benchmarker/runsupport.h @@ -30,10 +30,10 @@ #include <QtCore/qglobal.h> #include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> QT_BEGIN_NAMESPACE class QByteArray; -class QStringList; QT_END_NAMESPACE namespace qbsBenchmarker { diff --git a/tests/benchmarker/valgrindrunner.cpp b/tests/benchmarker/valgrindrunner.cpp index 174781318..72745dc16 100644 --- a/tests/benchmarker/valgrindrunner.cpp +++ b/tests/benchmarker/valgrindrunner.cpp @@ -59,11 +59,11 @@ void ValgrindRunner::run() { std::deque<QFuture<void>> futures; if (m_activities & ActivityResolving) - futures.push_back(QtConcurrent::run(this, &ValgrindRunner::traceResolving)); + futures.push_back(QtConcurrent::run([this]{ traceResolving(); })); if (m_activities & ActivityRuleExecution) - futures.push_back(QtConcurrent::run(this, &ValgrindRunner::traceRuleExecution)); + futures.push_back(QtConcurrent::run([this]{ traceRuleExecution(); })); if (m_activities & ActivityNullBuild) - futures.push_back(QtConcurrent::run(this, &ValgrindRunner::traceNullBuild)); + futures.push_back(QtConcurrent::run([this]{ traceNullBuild(); })); while (!futures.empty()) { futures.front().waitForFinished(); futures.pop_front(); @@ -100,12 +100,11 @@ void ValgrindRunner::traceActivity(Activity activity, const QString &buildDirCal { QString activityString; QString qbsCommand; - bool dryRun; + bool dryRun = false; switch (activity) { case ActivityResolving: activityString = "resolving"; qbsCommand = "resolve"; - dryRun = false; break; case ActivityRuleExecution: activityString = "rule-execution"; @@ -115,16 +114,21 @@ void ValgrindRunner::traceActivity(Activity activity, const QString &buildDirCal case ActivityNullBuild: activityString = "null-build"; qbsCommand = "build"; - dryRun = false; break; } const QString outFileCallgrind = m_baseOutputDir + "/outfile." + activityString + ".callgrind"; const QString outFileMassif = m_baseOutputDir + "/outfile." + activityString + ".massif"; - QFuture<qint64> callGrindFuture = QtConcurrent::run(this, &ValgrindRunner::runCallgrind, - qbsCommand, buildDirCallgrind, dryRun, outFileCallgrind); - QFuture<qint64> massifFuture = QtConcurrent::run(this, &ValgrindRunner::runMassif, qbsCommand, - buildDirMassif, dryRun, outFileMassif); + QFuture<qint64> callGrindFuture = QtConcurrent::run( + [this, qbsCommand, buildDirCallgrind, dryRun, outFileCallgrind] + { + return runCallgrind(qbsCommand, buildDirCallgrind, dryRun, outFileCallgrind); + }); + QFuture<qint64> massifFuture = QtConcurrent::run( + [this, qbsCommand, buildDirMassif, dryRun, outFileMassif] + { + return runMassif(qbsCommand, buildDirMassif, dryRun, outFileMassif); + }); callGrindFuture.waitForFinished(); massifFuture.waitForFinished(); addToResults(ValgrindResult(activity, callGrindFuture.result(), massifFuture.result())); diff --git a/tests/benchmarker/valgrindrunner.h b/tests/benchmarker/valgrindrunner.h index 378723868..c83fea468 100644 --- a/tests/benchmarker/valgrindrunner.h +++ b/tests/benchmarker/valgrindrunner.h @@ -30,15 +30,10 @@ #include "activities.h" -#include <QtCore/qlist.h> -#include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> #include <mutex> -QT_BEGIN_NAMESPACE -class QStringList; -QT_END_NAMESPACE - namespace qbsBenchmarker { class ValgrindResult diff --git a/tests/fuzzy-test/fuzzytester.cpp b/tests/fuzzy-test/fuzzytester.cpp index 2af8c6898..f38ad4736 100644 --- a/tests/fuzzy-test/fuzzytester.cpp +++ b/tests/fuzzy-test/fuzzytester.cpp @@ -67,7 +67,7 @@ void FuzzyTester::runTest(const QString &profile, const QString &startCommit, qDebug("Found buildable start commit %s.", qPrintable(workingStartCommit)); QStringList allCommits = findAllCommits(workingStartCommit); qDebug("The test set comprises all %d commits between the start commit and HEAD.", - allCommits.size()); + int(allCommits.size())); // Shuffle the initial sequence. Otherwise all invocations of the tool with the same start // commit would try the same sequence of commits. @@ -94,7 +94,7 @@ void FuzzyTester::runTest(const QString &profile, const QString &startCommit, m_currentCommit = currentCommit; buildSequence << currentCommit; checkoutCommit(currentCommit); - qDebug("Testing incremental build #%d (%s)", buildSequence.size() - 1, + qDebug("Testing incremental build #%d (%s)", int(buildSequence.size()) - 1, qPrintable(currentCommit)); // Doing "resolve" and "build" separately introduces additional possibilities |