aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/actions/download-mingw/action.yml19
-rw-r--r--.github/actions/download-qtc/action.yml2
-rw-r--r--.github/workflows/main.yml115
-rw-r--r--.github/workflows/release.yml4
-rw-r--r--.gitignore1
-rw-r--r--CMakeLists.txt27
-rw-r--r--VERSION2
-rw-r--r--cmake/QbsBuildConfig.cmake7
-rw-r--r--doc/CMakeLists.txt2
-rw-r--r--doc/qbs-hugo.qdocconf3
-rw-r--r--doc/reference/cli/cli-options.qdocinc2
-rw-r--r--doc/reference/items/language/export.qdoc4
-rw-r--r--doc/reference/items/probe/dmc-probe.qdoc104
-rw-r--r--doc/reference/modules/qbs-module.qdoc6
-rw-r--r--doc/reference/modules/qt-android_support-module.qdoc11
-rw-r--r--docker-compose.yml14
-rw-r--r--docker/focal/test-android.Dockerfile10
-rw-r--r--examples/app-and-lib/lib/lib.qbs2
-rw-r--r--qbs-resources/imports/QbsApp.qbs2
-rw-r--r--qbs-resources/imports/QbsLibrary.qbs14
-rw-r--r--qbs-resources/imports/QbsStaticLibrary.qbs2
-rwxr-xr-xscripts/install-qt.sh20
-rw-r--r--share/qbs/imports/qbs/ModUtils/utils.js13
-rw-r--r--share/qbs/imports/qbs/Probes/CosmicProbe.qbs87
-rw-r--r--share/qbs/imports/qbs/Probes/DmcProbe.qbs89
-rw-r--r--share/qbs/module-providers/Qt/setup-qt.js36
-rw-r--r--share/qbs/module-providers/Qt/templates/android_support.qbs72
-rw-r--r--share/qbs/module-providers/Qt/templates/core.qbs3
-rw-r--r--share/qbs/module-providers/Qt/templates/qml.qbs2
-rw-r--r--share/qbs/module-providers/Qt/templates/qmlcache.qbs2
-rw-r--r--share/qbs/modules/Android/sdk/sdk.qbs11
-rw-r--r--share/qbs/modules/Android/sdk/utils.js55
-rw-r--r--share/qbs/modules/bundle/MacOSX-Package-Types.xcspec943
-rw-r--r--share/qbs/modules/bundle/MacOSX-Product-Types.xcspec1345
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs22
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs43
-rw-r--r--share/qbs/modules/cpp/cosmic.js460
-rw-r--r--share/qbs/modules/cpp/cosmic.qbs150
-rw-r--r--share/qbs/modules/cpp/cpp.js378
-rw-r--r--share/qbs/modules/cpp/darwin.js21
-rw-r--r--share/qbs/modules/cpp/dmc.js462
-rw-r--r--share/qbs/modules/cpp/dmc.qbs177
-rw-r--r--share/qbs/modules/cpp/gcc.js193
-rw-r--r--share/qbs/modules/cpp/iar.js461
-rw-r--r--share/qbs/modules/cpp/iar.qbs54
-rw-r--r--share/qbs/modules/cpp/keil.js463
-rw-r--r--share/qbs/modules/cpp/keil.qbs52
-rw-r--r--share/qbs/modules/cpp/msvc.js88
-rw-r--r--share/qbs/modules/cpp/sdcc.js360
-rw-r--r--share/qbs/modules/cpp/sdcc.qbs46
-rw-r--r--share/qbs/modules/cpp/windows-msvc-base.qbs21
-rw-r--r--src/app/config-ui/CMakeLists.txt2
-rw-r--r--src/app/config/configcommand.h2
-rw-r--r--src/app/config/configcommandexecutor.cpp12
-rw-r--r--src/app/config/configcommandlineparser.cpp31
-rw-r--r--src/app/qbs-setup-toolchains/CMakeLists.txt4
-rw-r--r--src/app/qbs-setup-toolchains/cosmicprobe.cpp181
-rw-r--r--src/app/qbs-setup-toolchains/cosmicprobe.h61
-rw-r--r--src/app/qbs-setup-toolchains/dmcprobe.cpp221
-rw-r--r--src/app/qbs-setup-toolchains/dmcprobe.h61
-rw-r--r--src/app/qbs-setup-toolchains/probe.cpp30
-rw-r--r--src/app/qbs-setup-toolchains/probe.h6
-rw-r--r--src/app/qbs-setup-toolchains/qbs-setup-toolchains.pro4
-rw-r--r--src/app/qbs-setup-toolchains/qbs-setup-toolchains.qbs4
-rw-r--r--src/app/qbs/parser/commandlineparser.cpp12
-rw-r--r--src/app/qbs/parser/commandlineparser.h4
-rw-r--r--src/lib/CMakeLists.txt6
-rw-r--r--src/lib/corelib/CMakeLists.txt11
-rw-r--r--src/lib/corelib/api/runenvironment.cpp9
-rw-r--r--src/lib/corelib/api/runenvironment.h4
-rw-r--r--src/lib/corelib/buildgraph/buildgraphloader.cpp19
-rw-r--r--src/lib/corelib/corelib.qbs4
-rw-r--r--src/lib/corelib/generators/generator.cpp7
-rw-r--r--src/lib/corelib/generators/generator.h4
-rw-r--r--src/lib/corelib/jsextensions/binaryfile.cpp16
-rw-r--r--src/lib/corelib/jsextensions/process.cpp13
-rw-r--r--src/lib/corelib/jsextensions/propertylist_darwin.h4
-rw-r--r--src/lib/corelib/jsextensions/propertylist_darwin.mm7
-rw-r--r--src/lib/corelib/jsextensions/textfile.cpp16
-rw-r--r--src/lib/corelib/language/itemreader.cpp13
-rw-r--r--src/lib/corelib/language/itemreader.h3
-rw-r--r--src/lib/corelib/language/language.pri2
-rw-r--r--src/lib/corelib/language/moduleloader.cpp253
-rw-r--r--src/lib/corelib/language/moduleloader.h21
-rw-r--r--src/lib/corelib/language/moduleproviderloader.cpp288
-rw-r--r--src/lib/corelib/language/moduleproviderloader.h117
-rw-r--r--src/lib/corelib/logging/ilogsink.cpp7
-rw-r--r--src/lib/corelib/logging/ilogsink.h4
-rw-r--r--src/lib/corelib/tools/persistence.h27
-rw-r--r--src/lib/corelib/tools/profiling.cpp5
-rw-r--r--src/lib/corelib/tools/profiling.h4
-rw-r--r--src/lib/corelib/tools/qttools.cpp20
-rw-r--r--src/lib/corelib/tools/qttools.h82
-rw-r--r--src/lib/corelib/tools/settingsmodel.cpp8
-rw-r--r--src/lib/corelib/tools/settingsmodel.h4
-rw-r--r--src/lib/corelib/tools/stlutils.h31
-rw-r--r--src/lib/msbuild/io/msbuildprojectwriter.cpp9
-rw-r--r--src/lib/msbuild/io/msbuildprojectwriter.h4
-rw-r--r--src/lib/scriptengine/CMakeLists.txt361
-rw-r--r--src/lib/scriptengine/scriptengine.qbs6
-rw-r--r--src/libexec/qbs_processlauncher/CMakeLists.txt2
-rw-r--r--src/plugins/scanner/qt/qtscanner.cpp13
m---------src/shared/qtscript0
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs2
-rw-r--r--tests/auto/api/testdata/link-static-lib/link-static-lib.qbs4
-rw-r--r--tests/auto/blackbox/find/find-android.qbs1
-rw-r--r--tests/auto/blackbox/testdata-android/qt-app/TestQt6.java54
-rw-r--r--tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs11
-rw-r--r--tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/compiler-defines-by-language.qbs2
-rw-r--r--tests/auto/blackbox/testdata-baremetal/cosmic.lkf1
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-cosmic.s5
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs12-cosmic.s5
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-cosmic.s5
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-cosmic.s5
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/one-object-asm-application.qbs13
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-cosmic.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/target-platform/target-platform.qbs3
-rw-r--r--tests/auto/blackbox/testdata-windows/innosetup/inc/qbsinc.iss (renamed from tests/auto/blackbox/testdata/innosetup/inc/qbsinc.iss)0
-rw-r--r--tests/auto/blackbox/testdata-windows/innosetup/innosetup.qbs (renamed from tests/auto/blackbox/testdata/innosetup/innosetup.qbs)0
-rw-r--r--tests/auto/blackbox/testdata-windows/innosetup/test.iss (renamed from tests/auto/blackbox/testdata/innosetup/test.iss)0
-rw-r--r--tests/auto/blackbox/testdata-windows/innosetupDependencies/innosetupDependencies.qbs (renamed from tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs)0
-rw-r--r--tests/auto/blackbox/testdata-windows/innosetupDependencies/main.c (renamed from tests/auto/blackbox/testdata/innosetupDependencies/main.c)0
-rw-r--r--tests/auto/blackbox/testdata-windows/innosetupDependencies/test.iss (renamed from tests/auto/blackbox/testdata/innosetupDependencies/test.iss)0
-rw-r--r--tests/auto/blackbox/testdata-windows/wix/ExampleScript.bat (renamed from tests/auto/blackbox/testdata/wix/ExampleScript.bat)0
-rw-r--r--tests/auto/blackbox/testdata-windows/wix/QbsBootstrapper.wxs (renamed from tests/auto/blackbox/testdata/wix/QbsBootstrapper.wxs)0
-rw-r--r--tests/auto/blackbox/testdata-windows/wix/QbsSetup.wxs (renamed from tests/auto/blackbox/testdata/wix/QbsSetup.wxs)0
-rw-r--r--tests/auto/blackbox/testdata-windows/wix/Qt.wxs (renamed from tests/auto/blackbox/testdata/wix/Qt.wxs)0
-rw-r--r--tests/auto/blackbox/testdata-windows/wix/WiXInstallers.qbs (renamed from tests/auto/blackbox/testdata/wix/WiXInstallers.qbs)4
-rw-r--r--tests/auto/blackbox/testdata-windows/wix/de.wxl (renamed from tests/auto/blackbox/testdata/wix/de.wxl)0
-rw-r--r--tests/auto/blackbox/testdata-windows/wixDependencies/QbsSetup.wxs (renamed from tests/auto/blackbox/testdata/wixDependencies/QbsSetup.wxs)0
-rw-r--r--tests/auto/blackbox/testdata-windows/wixDependencies/main.c (renamed from tests/auto/blackbox/testdata/wixDependencies/main.c)0
-rw-r--r--tests/auto/blackbox/testdata-windows/wixDependencies/wixDependencies.qbs (renamed from tests/auto/blackbox/testdata/wixDependencies/wixDependencies.qbs)0
-rw-r--r--tests/auto/blackbox/testdata/proper quoting/proper quoting.qbs2
-rw-r--r--tests/auto/blackbox/testdata/protobuf/create-proto-library.qbs2
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp190
-rw-r--r--tests/auto/blackbox/tst_blackbox.h6
-rw-r--r--tests/auto/blackbox/tst_blackboxandroid.cpp165
-rw-r--r--tests/auto/blackbox/tst_blackboxapple.cpp4
-rw-r--r--tests/auto/blackbox/tst_blackboxbase.cpp10
-rw-r--r--tests/auto/blackbox/tst_blackboxwindows.cpp133
-rw-r--r--tests/auto/blackbox/tst_blackboxwindows.h4
-rw-r--r--tests/auto/buildgraph/CMakeLists.txt2
-rw-r--r--tests/auto/language/CMakeLists.txt2
-rw-r--r--tests/auto/tools/tst_tools.cpp44
-rw-r--r--tests/auto/tools/tst_tools.h3
-rw-r--r--tests/benchmarker/CMakeLists.txt2
-rw-r--r--tests/benchmarker/benchmarker.cpp13
-rw-r--r--tests/benchmarker/valgrindrunner.cpp2
-rw-r--r--tests/fuzzy-test/CMakeLists.txt2
151 files changed, 6319 insertions, 2920 deletions
diff --git a/.github/actions/download-mingw/action.yml b/.github/actions/download-mingw/action.yml
new file mode 100644
index 000000000..f8fb47f28
--- /dev/null
+++ b/.github/actions/download-mingw/action.yml
@@ -0,0 +1,19 @@
+name: 'Download MinGW'
+description: 'Downloads MinGW'
+inputs:
+ version:
+ description: 'MinGW version'
+ required: false
+ default: '8.1.0'
+ toolchain:
+ description: 'Toolchain'
+ required: false
+ default: 'win64_mingw'
+runs:
+ using: "composite"
+ steps:
+ - name: Install MinGW
+ run: |
+ MINGW_DIR=$(./scripts/install-qt.sh -d $HOME/Qt --version ${{ inputs.version }} --toolchain ${{ inputs.toolchain }} mingw)
+ (cygpath -w ${MINGW_DIR} 2>/dev/null || echo ${MINGW_DIR}) >> ${GITHUB_PATH}
+ shell: bash
diff --git a/.github/actions/download-qtc/action.yml b/.github/actions/download-qtc/action.yml
index 3e201670b..d6ed2e6f8 100644
--- a/.github/actions/download-qtc/action.yml
+++ b/.github/actions/download-qtc/action.yml
@@ -4,7 +4,7 @@ inputs:
version:
description: 'Qt Creator version'
required: false
- default: '4.13.3'
+ default: '4.14.2'
runs:
using: "composite"
steps:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 953f19949..6d0bfad56 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -62,17 +62,20 @@ jobs:
- {
name: 'Build on Linux (clang_tidy)',
script: './scripts/run-analyzer.sh',
+ image: 'focal',
options: 'profile:qt-clang_64 modules.cpp.compilerWrapper:ccache',
cacheid: 'clang',
}
- {
name: 'Build on Linux (CMake)',
script: './scripts/build-qbs-with-cmake.sh',
+ image: 'focal-qt6',
cacheid: 'cmake',
}
- {
name: 'Build on Linux (QMake)',
script: './scripts/build-qbs-with-qmake.sh',
+ image: 'focal',
options: 'CONFIG+=ccache',
cacheid: 'qmake',
}
@@ -81,6 +84,8 @@ jobs:
QTEST_FUNCTION_TIMEOUT: 9000000
steps:
- uses: actions/checkout@v1
+ with:
+ submodules: true
- name: Create .ccache dir
run: mkdir -p ~/.ccache
- name: prepare timestamp
@@ -93,13 +98,13 @@ jobs:
key: ${{ runner.os }}-${{ matrix.config.cacheid }}-ccache-${{ steps.get-timestamp.outputs.timestamp }}
restore-keys: ${{ runner.os }}-${{ matrix.config.cacheid }}-ccache-
- name: Pull the Focal Image
- run: docker-compose pull focal
+ run: docker-compose pull ${{ matrix.config.image }}
- name: Print ccache stats
- run: docker-compose run focal ccache -s
+ run: docker-compose run ${{ matrix.config.image }} ccache -s
- name: Build Qbs
- run: docker-compose run focal ${{ matrix.config.script }}
+ run: docker-compose run ${{ matrix.config.image }} ${{ matrix.config.script }}
- name: Print ccache stats
- run: docker-compose run focal ccache -s
+ run: docker-compose run ${{ matrix.config.image }} ccache -s
build-macos:
name: Build on macOS
@@ -137,8 +142,6 @@ jobs:
toolchain: clang_64
- name: Install Qt Creator
uses: ./.github/actions/download-qtc
- with:
- version: 4.13.2
- name: Setup Qbs
run: |
qbs setup-toolchains --detect
@@ -165,6 +168,7 @@ jobs:
env:
BUILD_OPTIONS: |
modules.cpp.compilerWrapper:clcache
+ modules.qbs.debugInformation:true
modules.qbsbuildconfig.enableAddressSanitizer:false
modules.qbsbuildconfig.enableBundledQt:true
products.qbs_archive.targetName:qbs-windows-${{ github.run_id }}
@@ -218,6 +222,71 @@ jobs:
name: qbs-windows-${{ github.run_id }}.zip
path: release/qbs-windows-${{ github.run_id }}.zip
+ build-windows-mingw:
+ name: Build on Windows (MinGW)
+ runs-on: windows-latest
+ timeout-minutes: 60
+ env:
+ BUILD_OPTIONS: |
+ modules.cpp.compilerWrapper:ccache
+ modules.qbsbuildconfig.enableAddressSanitizer:false
+ modules.qbsbuildconfig.enableBundledQt:true
+ products.qbs_archive.targetName:qbs-windows-mingw-${{ github.run_id }}
+ products.qbs_archive.includeTests:true,
+ QT_ASSUME_STDERR_HAS_CONSOLE: 1
+ WITH_TESTS: 0
+ CCACHE_DIR: ${{ github.workspace }}\ccache
+ steps:
+ - uses: actions/checkout@v1
+ - name: prepare timestamp
+ id: get-timestamp
+ run: echo ::set-output name=timestamp::$(date -u +"%Y-%m-%dT%H:%M:%SZ")
+ shell: bash
+ - name: ccache cache files
+ uses: actions/cache@v2
+ with:
+ path: ${{ github.workspace }}/ccache
+ key: ${{ runner.os }}-mingw-ccache-${{ steps.get-timestamp.outputs.timestamp }}
+ restore-keys: ${{ runner.os }}-mingw-ccache-
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: 3.8
+ - name: Install required packages
+ run: |
+ choco install ccache
+ python -m pip install --upgrade pip
+ pip install beautifulsoup4 lxml
+ - name: Install Qt
+ uses: ./.github/actions/download-qt
+ with:
+ toolchain: win64_mingw81
+ - name: Install Qt Creator
+ uses: ./.github/actions/download-qtc
+ - name: Install MinGW
+ uses: ./.github/actions/download-mingw
+ - name: Setup Qbs
+ run: |
+ qbs setup-toolchains --detect
+ qbs setup-toolchains --type mingw $(which g++).exe mingw-qt
+ qbs setup-qt $(which qmake).exe qt
+ qbs config profiles.qt.baseProfile mingw-qt
+ qbs config defaultProfile qt
+ qbs config --list
+ shell: bash
+ - name: Print ccache stats
+ run: ccache -s
+ - name: Build Qbs
+ run: scripts/build-qbs-with-qbs.sh
+ shell: bash
+ - name: Print ccache stats
+ run: ccache -s
+ - name: Upload artifacts
+ uses: 'actions/upload-artifact@v2'
+ with:
+ name: qbs-windows-mingw-${{ github.run_id }}.zip
+ path: release/qbs-windows-mingw-${{ github.run_id }}.zip
+
test-linux:
name: ${{ matrix.config.name }}
runs-on: ubuntu-latest
@@ -264,6 +333,12 @@ jobs:
script: './scripts/test-qt-for-android.sh',
}
- {
+ name: 'Run Android tests (Qt 6.0.0)',
+ image: 'focal-android-600',
+ profile: '',
+ script: './scripts/test-qt-for-android.sh',
+ }
+ - {
name: 'Run Linux tests (Qt 4.8.7)',
image: 'focal-qt4',
profile: '',
@@ -328,9 +403,11 @@ jobs:
runs-on: [self-hosted, windows, x64]
timeout-minutes: 30
needs: build-windows
+ if: ${{ github.actor == 'rweickelt' }}
env:
QBS_TEST_SOURCE_ROOT: 'tests'
QT_ASSUME_STDERR_HAS_CONSOLE: 1
+ QTEST_FUNCTION_TIMEOUT: 9000000
steps:
- uses: actions/checkout@v1
- name: Download artifact
@@ -455,6 +532,21 @@ jobs:
- 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
+ - name: cosmic-4_3_11-arm
+ run: QBS_AUTOTEST_PROFILE=cosmic-4_3_11-arm scripts/test-baremetal.sh release/install-root/bin
+ shell: bash
+ - name: cosmic-4_5_2-stm8
+ run: QBS_AUTOTEST_PROFILE=cosmic-4_5_2-stm8 scripts/test-baremetal.sh release/install-root/bin
+ shell: bash
+ - name: cosmic-4_6_3-hcs8
+ run: QBS_AUTOTEST_PROFILE=cosmic-4_6_3-hcs8 scripts/test-baremetal.sh release/install-root/bin
+ shell: bash
+ - name: cosmic-4_8_11-hcs12
+ run: QBS_AUTOTEST_PROFILE=cosmic-4_8_11-hcs12 scripts/test-baremetal.sh release/install-root/bin
+ shell: bash
+ - name: cosmic-4_1_0-m68k
+ run: QBS_AUTOTEST_PROFILE=cosmic-4_1_0-m68k scripts/test-baremetal.sh release/install-root/bin
+ shell: bash
test-macos:
name: ${{ matrix.config.name }}
@@ -590,6 +682,14 @@ jobs:
qtVersion: '5.15.2',
script: './scripts/test-qbs.sh',
}
+ - {
+ name: 'Run Windows tests (MinGW)',
+ target: 'desktop',
+ toolchain: 'win64_mingw81',
+ testProfile: 'mingw-qt',
+ qtVersion: '5.15.2',
+ script: './scripts/test-qbs.sh',
+ }
env:
QTEST_FUNCTION_TIMEOUT: 9000000
QBS_AUTOTEST_PROFILE: 'qt'
@@ -617,9 +717,12 @@ jobs:
with:
toolchain: ${{ matrix.config.toolchain }}
version: ${{ matrix.config.qtVersion }}
+ - name: Install MinGW
+ uses: ./.github/actions/download-mingw
- name: Setup Qbs
run: |
qbs setup-toolchains --detect
+ qbs setup-toolchains --type mingw $(which g++).exe mingw-qt
qbs setup-qt $(which qmake).exe qt
qbs config profiles.qt.baseProfile ${{ matrix.config.testProfile }}
qbs config defaultProfile qt
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f807e9117..2eb5fbe7f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -20,7 +20,6 @@ jobs:
name: 'Build on Linux (gcc)',
options: 'qbs.installPrefix:""
modules.cpp.compilerWrapper:ccache
- modules.qbs.debugInformation:true
modules.qbsbuildconfig.enableAddressSanitizer:false
modules.qbsbuildconfig.enableProjectFileUpdates:false
modules.qbsbuildconfig.enableUnitTests:false
@@ -71,7 +70,6 @@ jobs:
BUILD_OPTIONS: |
qbs.installPrefix:""
modules.cpp.compilerWrapper:ccache
- modules.qbs.debugInformation:true
modules.qbsbuildconfig.enableUnitTests:false
modules.qbsbuildconfig.enableProjectFileUpdates:false
modules.qbsbuildconfig.enableAddressSanitizer:false
@@ -101,7 +99,7 @@ jobs:
- name: Install Qt Creator
uses: ./.github/actions/download-qtc
with:
- version: 4.13.2
+ version: 4.14.2
- name: Setup Qbs
run: |
qbs setup-toolchains --detect
diff --git a/.gitignore b/.gitignore
index 07a115a1d..bd27569df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
.qmake.cache
.qmake.stash
.qbs
+.vscode*
build
*.dll
*.dylib
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8b95f959d..b167aab4a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.15)
## Add paths to check for cmake modules:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
@@ -22,17 +22,36 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
+find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
+
if(WITH_TESTS)
enable_testing()
set(QT_TEST_COMPONENT Test)
- set(IMPLICIT_DEPENDS Qt5::Test)
+ set(IMPLICIT_DEPENDS Qt${QT_VERSION_MAJOR}::Test)
endif()
-find_package(Qt5
- COMPONENTS Concurrent Core Gui Network Script Widgets Xml ${QT_TEST_COMPONENT}
+find_package(Qt${QT_VERSION_MAJOR}
+ COMPONENTS Concurrent Core Gui Network Widgets Xml ${QT_TEST_COMPONENT}
REQUIRED
)
+find_package(Qt${QT_VERSION_MAJOR} OPTIONAL_COMPONENTS Script)
+
+if (Qt6_FOUND)
+ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core5Compat REQUIRED)
+ if(NOT TARGET Qt6Core5Compat)
+ set_property(TARGET Qt6::Core5Compat PROPERTY IMPORTED_GLOBAL TRUE) # hack for CMake < 1.18
+ add_library(Qt6Core5Compat ALIAS Qt6::Core5Compat)
+ endif()
+else()
+ if(NOT TARGET Qt6Core5Compat)
+ add_library(Qt6Core5Compat INTERFACE)
+ endif()
+ if(Qt5Script_FOUND)
+ set_property(TARGET Qt5::Script PROPERTY IMPORTED_GLOBAL TRUE)
+ endif()
+endif()
+
add_subdirectory(src)
add_subdirectory(doc)
add_subdirectory(share)
diff --git a/VERSION b/VERSION
index 836ae4eda..398935591 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.19.2
+1.20.0
diff --git a/cmake/QbsBuildConfig.cmake b/cmake/QbsBuildConfig.cmake
index b6614ce3f..8bdfec77e 100644
--- a/cmake/QbsBuildConfig.cmake
+++ b/cmake/QbsBuildConfig.cmake
@@ -3,6 +3,7 @@ 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_USE_BUNDLED_QT_SCRIPT "Whether to use bundled QtScript module" OFF)
option(QBS_INSTALL_HTML_DOCS "Whether to install HTML Documentation" OFF)
option(QBS_INSTALL_QCH_DOCS "Whether to install QCH Documentation" OFF)
@@ -54,9 +55,9 @@ endif()
function(get_update_path_command var)
if(WIN32)
- get_target_property(_QTCORE_LIBRARY Qt5::Core IMPORTED_LOCATION_RELEASE)
+ get_target_property(_QTCORE_LIBRARY Qt${QT_VERSION_MAJOR}::Core IMPORTED_LOCATION_RELEASE)
if(NOT _QTCORE_LIBRARY)
- get_target_property(_QTCORE_LIBRARY Qt5::Core IMPORTED_LOCATION_DEBUG)
+ get_target_property(_QTCORE_LIBRARY Qt${QT_VERSION_MAJOR}::Core IMPORTED_LOCATION_DEBUG)
endif()
get_filename_component(_QT_LIBRARY_PATH "${_QTCORE_LIBRARY}" DIRECTORY)
get_target_property(_QBS_LIBRARY_PATH qbscore LIBRARY_OUTPUT_DIRECTORY)
@@ -239,7 +240,7 @@ function(add_qbs_test test_name)
)
target_link_libraries(
${target_name}
- PRIVATE ${_arg_DEPENDS} qbscore qbsconsolelogger Qt5::Test
+ PRIVATE ${_arg_DEPENDS} qbscore qbsconsolelogger Qt${QT_VERSION_MAJOR}::Test
PUBLIC ${_arg_PUBLIC_DEPENDS}
)
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 0b5922a1a..96cdab897 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -42,7 +42,7 @@ if (QBS_INSTALL_HTML_DOCS OR QBS_INSTALL_QCH_DOCS)
set(_INSTALL_QCH_DOCS false)
endif()
- get_target_property(_QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
+ get_target_property(_QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
get_update_path_command(UPDATE_PATH_COMMAND)
add_custom_target(
BuildQbsDocumentation ALL
diff --git a/doc/qbs-hugo.qdocconf b/doc/qbs-hugo.qdocconf
new file mode 100644
index 000000000..cc8cdb532
--- /dev/null
+++ b/doc/qbs-hugo.qdocconf
@@ -0,0 +1,3 @@
+include(config/qbs-project.qdocconf)
+
+syntaxhighlighting = true
diff --git a/doc/reference/cli/cli-options.qdocinc b/doc/reference/cli/cli-options.qdocinc
index b02ce68ea..a993f6d12 100644
--- a/doc/reference/cli/cli-options.qdocinc
+++ b/doc/reference/cli/cli-options.qdocinc
@@ -499,6 +499,8 @@
\li \c iar
\li \c keil
\li \c sdcc
+ \li \c cosmic
+ \li \c dmc
\endlist
//! [type]
diff --git a/doc/reference/items/language/export.qdoc b/doc/reference/items/language/export.qdoc
index 056233193..96abde2ed 100644
--- a/doc/reference/items/language/export.qdoc
+++ b/doc/reference/items/language/export.qdoc
@@ -44,8 +44,8 @@
name: "A"
Export {
Depends { name: "cpp" }
- cpp.includePaths: product.sourceDirectory
- cpp.defines: ["USING_" + product.name.toUpperCase()]
+ cpp.includePaths: exportingProduct.sourceDirectory
+ cpp.defines: ["USING_" + exportingProduct.name.toUpperCase()]
}
}
diff --git a/doc/reference/items/probe/dmc-probe.qdoc b/doc/reference/items/probe/dmc-probe.qdoc
new file mode 100644
index 000000000..1cd8707bb
--- /dev/null
+++ b/doc/reference/items/probe/dmc-probe.qdoc
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmltype DmcProbe
+ \inqmlmodule QbsProbes
+ \ingroup list-of-items
+ \keyword QML.DmcProbe
+ \inherits PathProbe
+ \brief Collects Digital Mars toolchain compiler information.
+ \since Qbs 1.13
+ \internal
+
+ Detects the version, supported architecture, the platform
+ endianness, and other stuff for the specified compiler executable
+ from the \l{https://www.digitalmars.com/}{Digital Mars} toolchain.
+*/
+
+/*!
+ \qmlproperty string DmcProbe::compilerFilePath
+
+ An input property which is a full path to the Digital Mars compiler
+ executable.
+
+ \nodefaultvalue
+*/
+
+/*!
+ \qmlproperty string DmcProbe::architecture
+
+ Detected architecture of the target platform's processor.
+
+ The only possible value is \c "x86".
+
+ \nodefaultvalue
+*/
+
+/*!
+ \qmlproperty string DmcProbe::endianness
+
+ Detected endianness of the target platform's processor architecture.
+
+ The possible value is \c "little".
+
+ \nodefaultvalue
+*/
+
+/*!
+ \qmlproperty string DmcProbe::targetPlatform
+
+ Detected target platform.
+
+ The possible value is \c "windows".
+
+ \nodefaultvalue
+*/
+
+/*!
+ \qmlproperty int DmcProbe::versionMajor
+
+ Detected major compiler version.
+
+ \nodefaultvalue
+*/
+
+/*!
+ \qmlproperty int DmcProbe::versionMinor
+
+ Detected minor compiler version.
+
+ \nodefaultvalue
+*/
+
+/*!
+ \qmlproperty int DmcProbe::versionPatch
+
+ Detected patch compiler version.
+
+ \nodefaultvalue
+*/
diff --git a/doc/reference/modules/qbs-module.qdoc b/doc/reference/modules/qbs-module.qdoc
index 3866f56fb..82a9120cc 100644
--- a/doc/reference/modules/qbs-module.qdoc
+++ b/doc/reference/modules/qbs-module.qdoc
@@ -502,6 +502,12 @@
\li \c{"clang-cl"}
\li \c{["clang-cl", "msvc"]}
\row
+ \li \c{"cosmic"}
+ \li \c{["cosmic"]}
+ \row
+ \li \c{"dmc"}
+ \li \c{["dmc"]}
+ \row
\li \c{"gcc"}
\li \c{["gcc"]}
\row
diff --git a/doc/reference/modules/qt-android_support-module.qdoc b/doc/reference/modules/qt-android_support-module.qdoc
index 67348ebc0..f8f8368c5 100644
--- a/doc/reference/modules/qt-android_support-module.qdoc
+++ b/doc/reference/modules/qt-android_support-module.qdoc
@@ -38,17 +38,6 @@
*/
/*!
- \qmlproperty bool Qt.android_support::useMinistro
-
- Whether or not to use the Ministro service. If this property is enabled, then
- the Qt libraries required by your application as well as some other resources
- will not be packaged into the APK file, but are expected to be present on the
- device at run time.
-
- \defaultvalue \c false
-*/
-
-/*!
\qmlproperty string Qt.android_support::qmlRootDir
The root directory of the product's QML files. This information is passed to
diff --git a/docker-compose.yml b/docker-compose.yml
index 2df603fc5..13b4f6a2f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -21,24 +21,24 @@ services:
focal:
<< : *linux
hostname: focal
- image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-5.15.2_1.17.1-1
+ image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-5.15.2_1.18.2-0
build:
dockerfile: docker/focal/Dockerfile
context: .
args:
QT_VERSION: 5.15.2
- QTCREATOR_VERSION: 4.13.3
+ QTCREATOR_VERSION: 4.14.2
focal-qt6:
<< : *linux
hostname: focal-qt6
- image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-qt6-6.0.2_1.18.1-0
+ image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-qt6-6.0.2_1.18.2-0
build:
dockerfile: docker/focal/Dockerfile
context: .
args:
QT_VERSION: 6.0.2
- QTCREATOR_VERSION: 4.14.1
+ QTCREATOR_VERSION: 4.14.2
focal-android-513:
<< : *linux
@@ -73,7 +73,7 @@ services:
focal-android-600:
<< : *linux
hostname: focal-android
- image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-android-6.0.0-1
+ image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-android-6.0.0-2
build:
dockerfile: docker/focal/test-android.Dockerfile
context: .
@@ -97,13 +97,13 @@ services:
context: .
windows:
- image: ${DOCKER_USER:-qbsbuild}/qbsdev:windowsservercore-5.15.0_1.16.0-0
+ image: ${DOCKER_USER:-qbsbuild}/qbsdev:windowsservercore-5.15.0_1.18.2-0
build:
dockerfile: docker/windowsservercore/Dockerfile
context: .
args:
QT_VERSION: 5.15.0
- QBS_VERSION: 1.16.0
+ QBS_VERSION: 1.18.2
working_dir: 'C:/qbs'
environment:
- BUILD_OPTIONS
diff --git a/docker/focal/test-android.Dockerfile b/docker/focal/test-android.Dockerfile
index 72c84ca0c..11c4a5757 100644
--- a/docker/focal/test-android.Dockerfile
+++ b/docker/focal/test-android.Dockerfile
@@ -72,8 +72,14 @@ ARG ANDROID_PLATFORM="android-29"
ARG BUILD_TOOLS="29.0.2"
RUN yes | sdkmanager "--sdk_root=${ANDROID_HOME}" --verbose --licenses && \
sdkmanager "--sdk_root=${ANDROID_HOME}" --update && \
- sdkmanager "--sdk_root=${ANDROID_HOME}" "platforms;${ANDROID_PLATFORM}" "build-tools;${BUILD_TOOLS}" "platform-tools" "tools" "ndk-bundle" && \
- /usr/lib/jvm/java-8-openjdk-amd64/bin/keytool -genkey -keystore /home/${USER_NAME}/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname 'CN=Android Debug,O=Android,C=US'
+ sdkmanager "--sdk_root=${ANDROID_HOME}" "platforms;${ANDROID_PLATFORM}"
+
+RUN yes | sdkmanager "--sdk_root=${ANDROID_HOME}" "build-tools;${BUILD_TOOLS}"
+RUN yes | sdkmanager "--sdk_root=${ANDROID_HOME}" "platform-tools"
+RUN yes | sdkmanager "--sdk_root=${ANDROID_HOME}" "tools"
+RUN yes | sdkmanager "--sdk_root=${ANDROID_HOME}" "ndk-bundle"
+
+RUN /usr/lib/jvm/java-8-openjdk-amd64/bin/keytool -genkey -keystore /home/${USER_NAME}/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname 'CN=Android Debug,O=Android,C=US'
# Install ndk samples in ${ANDROID_NDK_ROOT}/samples
RUN cd ${ANDROID_NDK_ROOT} && \
diff --git a/examples/app-and-lib/lib/lib.qbs b/examples/app-and-lib/lib/lib.qbs
index 66ec4eccd..b67ba9ba6 100644
--- a/examples/app-and-lib/lib/lib.qbs
+++ b/examples/app-and-lib/lib/lib.qbs
@@ -61,7 +61,7 @@ StaticLibrary {
Export {
Depends { name: "cpp" }
- cpp.includePaths: [product.sourceDirectory]
+ cpp.includePaths: [exportingProduct.sourceDirectory]
}
}
diff --git a/qbs-resources/imports/QbsApp.qbs b/qbs-resources/imports/QbsApp.qbs
index 5fe32046b..2ddb3cb38 100644
--- a/qbs-resources/imports/QbsApp.qbs
+++ b/qbs-resources/imports/QbsApp.qbs
@@ -10,7 +10,7 @@ QbsProduct {
consoleApplication: true
Group {
fileTagsFilter: product.type
- .concat(qbs.buildVariant === "debug" ? ["debuginfo_app"] : [])
+ .concat(qbs.debugInformation ? ["debuginfo_app"] : [])
qbs.install: true
qbs.installDir: targetInstallDir
qbs.installSourceBase: buildDirectory
diff --git a/qbs-resources/imports/QbsLibrary.qbs b/qbs-resources/imports/QbsLibrary.qbs
index 6fc6c7791..f0769dd6c 100644
--- a/qbs-resources/imports/QbsLibrary.qbs
+++ b/qbs-resources/imports/QbsLibrary.qbs
@@ -28,7 +28,7 @@ QbsProduct {
Group {
fileTagsFilter: libType.concat("dynamiclibrary_symlink")
- .concat(qbs.buildVariant === "debug" ? ["debuginfo_dll"] : [])
+ .concat(qbs.debugInformation ? ["debuginfo_dll"] : [])
qbs.install: install
qbs.installDir: targetInstallDir
qbs.installSourceBase: buildDirectory
@@ -61,15 +61,15 @@ QbsProduct {
Depends { name: "Qt"; submodules: ["core"] }
Properties {
- condition: product.hasExporter
+ condition: exportingProduct.hasExporter
prefixMapping: [{
- prefix: product.sourceDirectory,
- replacement: FileInfo.joinPaths(product.qbs.installPrefix,
- product.headerInstallPrefix)
+ prefix: exportingProduct.sourceDirectory,
+ replacement: FileInfo.joinPaths(exportingProduct.qbs.installPrefix,
+ exportingProduct.headerInstallPrefix)
}]
}
- cpp.includePaths: [product.sourceDirectory]
- cpp.defines: product.visibilityType === "static" ? ["QBS_STATIC_LIB"] : []
+ cpp.includePaths: [exportingProduct.sourceDirectory]
+ cpp.defines: exportingProduct.visibilityType === "static" ? ["QBS_STATIC_LIB"] : []
}
}
diff --git a/qbs-resources/imports/QbsStaticLibrary.qbs b/qbs-resources/imports/QbsStaticLibrary.qbs
index 299ca3948..6fa9fde31 100644
--- a/qbs-resources/imports/QbsStaticLibrary.qbs
+++ b/qbs-resources/imports/QbsStaticLibrary.qbs
@@ -4,6 +4,6 @@ QbsProduct {
Depends { name: "cpp" }
Depends { name: "Qt"; submodules: ["core"] }
- cpp.includePaths: [product.sourceDirectory]
+ cpp.includePaths: [exportingProduct.sourceDirectory]
}
}
diff --git a/scripts/install-qt.sh b/scripts/install-qt.sh
index 9a3595062..3105c99e4 100755
--- a/scripts/install-qt.sh
+++ b/scripts/install-qt.sh
@@ -223,10 +223,10 @@ if ${INSTALLATION_IS_VALID}; then
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 \
+ http://download.qt.io \
"
for MIRROR in ${MIRRORS}; do
@@ -251,12 +251,24 @@ function compute_url(){
if [[ "${COMPONENT}" =~ "qtcreator" ]]; then
+ if [[ "${HOST_OS}" == "windows_x86" ]]; then
+ # newer QtC versions do not supported x86 version anymore
+ HOST_OS="windows_x64"
+ fi
+
SHORT_VERSION=${VERSION%??}
BASE_URL="${MIRROR}/official_releases/qtcreator"
REMOTE_PATH="${SHORT_VERSION}/${VERSION}/installer_source/${HOST_OS}/qtcreator.7z"
echo "${BASE_URL}/${REMOTE_PATH}"
return 0
+ elif [[ "${COMPONENT}" =~ "mingw" ]]; then
+ REMOTE_BASE="tools_mingw/qt.tools.${TOOLCHAIN}${VERSION//./}"
+ REMOTE_PATH="$(${CURL} ${BASE_URL}/${REMOTE_BASE}/ | grep -o -E "[[:alnum:]_.\-]*7z" | grep -v "meta" | head -1)"
+ if [ ! -z "${REMOTE_PATH}" ]; then
+ echo "${BASE_URL}/${REMOTE_BASE}/${REMOTE_PATH}"
+ return 0
+ fi
else
REMOTE_BASES=(
# New repository format (>=6.0.0)
@@ -364,6 +376,12 @@ for COMPONENT in ${COMPONENTS}; do
# Print the directory so that the caller can
# adjust the PATH variable.
echo $(dirname "${CONF_FILE}")
+ elif [[ "${COMPONENT}" =~ "mingw" ]]; then
+ if [[ "${TOOLCHAIN}" =~ "win64_mingw" ]]; then
+ echo "${UNPACK_DIR}/Tools/mingw${VERSION//./}_64/bin"
+ elif [[ "${TOOLCHAIN}" =~ "win32_mingw" ]]; then
+ echo "${UNPACK_DIR}/Tools/mingw${VERSION//./}/bin"
+ fi
elif [[ "${COMPONENT}" =~ "qtcreator" ]]; then
if [ "${HOST_OS}" == "mac_x64" ]; then
echo "${UNPACK_DIR}/Qt Creator.app/Contents/MacOS"
diff --git a/share/qbs/imports/qbs/ModUtils/utils.js b/share/qbs/imports/qbs/ModUtils/utils.js
index 0433fa46e..33360a175 100644
--- a/share/qbs/imports/qbs/ModUtils/utils.js
+++ b/share/qbs/imports/qbs/ModUtils/utils.js
@@ -636,16 +636,3 @@ function toJSLiteral(v) {
return "undefined";
return JSON.stringify(v);
}
-
-function extractMacros(output) {
- var m = {};
- output.trim().split(/\r?\n/g).map(function (line) {
- var prefix = "#define ";
- if (!line.startsWith(prefix))
- return;
- var index = line.indexOf(" ", prefix.length);
- if (index !== -1)
- m[line.substr(prefix.length, index - prefix.length)] = line.substr(index + 1);
- });
- return m;
-}
diff --git a/share/qbs/imports/qbs/Probes/CosmicProbe.qbs b/share/qbs/imports/qbs/Probes/CosmicProbe.qbs
new file mode 100644
index 000000000..7de781e6e
--- /dev/null
+++ b/share/qbs/imports/qbs/Probes/CosmicProbe.qbs
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs.File
+import "../../../modules/cpp/cosmic.js" as COSMIC
+
+PathProbe {
+ // Inputs
+ property string compilerFilePath
+ property stringList enableDefinesByLanguage
+
+ // Outputs
+ property string architecture
+ property string endianness
+ property int versionMajor
+ property int versionMinor
+ property int versionPatch
+ property stringList includePaths
+ property var compilerDefinesByLanguage
+
+ configure: {
+ compilerDefinesByLanguage = {};
+
+ if (!File.exists(compilerFilePath)) {
+ found = false;
+ return;
+ }
+
+ var languages = enableDefinesByLanguage;
+ if (!languages || languages.length === 0)
+ languages = ["c"];
+
+ // COSMIC compiler support only the C-language.
+ if (!languages.contains("c")) {
+ found = false;
+ return;
+ }
+
+ var macros = COSMIC.dumpMacros(compilerFilePath);
+ if (!macros) {
+ found = false;
+ return;
+ }
+
+ compilerDefinesByLanguage["c"] = macros;
+
+ architecture = COSMIC.guessArchitecture(compilerFilePath);
+ endianness = COSMIC.guessEndianness(architecture);
+ var defaultPaths = COSMIC.dumpDefaultPaths(compilerFilePath, architecture);
+ includePaths = defaultPaths.includePaths;
+
+ var version = COSMIC.dumpVersion(compilerFilePath);
+ if (version) {
+ versionMajor = version.major;
+ versionMinor = version.minor;
+ versionPatch = version.patch;
+ found = !!architecture && !!endianness;
+ }
+ }
+}
diff --git a/share/qbs/imports/qbs/Probes/DmcProbe.qbs b/share/qbs/imports/qbs/Probes/DmcProbe.qbs
new file mode 100644
index 000000000..0375805b5
--- /dev/null
+++ b/share/qbs/imports/qbs/Probes/DmcProbe.qbs
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs.File
+import qbs.ModUtils
+import "../../../modules/cpp/dmc.js" as DMC
+
+PathProbe {
+ // Inputs
+ property string compilerFilePath
+ property stringList enableDefinesByLanguage
+
+ // Outputs
+ property string architecture
+ property string targetPlatform
+ property int versionMajor
+ property int versionMinor
+ property int versionPatch
+ property stringList includePaths
+ property var compilerDefinesByLanguage
+
+ configure: {
+ compilerDefinesByLanguage = {};
+
+ if (!File.exists(compilerFilePath)) {
+ found = false;
+ return;
+ }
+
+ var languages = enableDefinesByLanguage;
+ if (!languages || languages.length === 0)
+ languages = ["c"];
+
+ var defaultPathsByLanguage = {};
+ for (var i = 0; i < languages.length; ++i) {
+ var tag = languages[i];
+ compilerDefinesByLanguage[tag] = DMC.dumpMacros(
+ compilerFilePath, tag);
+ var paths = DMC.dumpDefaultPaths(compilerFilePath, tag);
+ defaultPathsByLanguage[tag] = paths;
+ }
+
+ var macros = compilerDefinesByLanguage["c"]
+ || compilerDefinesByLanguage["cpp"];
+
+ architecture = ModUtils.guessArchitecture(macros);
+ targetPlatform = ModUtils.guessTargetPlatform(macros);
+
+ var defaultPaths = defaultPathsByLanguage["cpp"]
+ || defaultPathsByLanguage["c"];
+
+ includePaths = defaultPaths.includePaths;
+
+ var version = DMC.guessVersion(macros);
+ if (version) {
+ versionMajor = version.major;
+ versionMinor = version.minor;
+ versionPatch = version.patch;
+ found = !!architecture && !!endianness;
+ }
+ }
+}
diff --git a/share/qbs/module-providers/Qt/setup-qt.js b/share/qbs/module-providers/Qt/setup-qt.js
index 5cf1bcb44..060ea7a0a 100644
--- a/share/qbs/module-providers/Qt/setup-qt.js
+++ b/share/qbs/module-providers/Qt/setup-qt.js
@@ -268,8 +268,14 @@ function getQtProperties(qmakeFilePath, qbs) {
(pathQueryValue(queryResult, "QT_INSTALL_DATA"), "mkspecs");
}
- if (Utilities.versionCompare(qtProps.qtVersion, "6") >= 0)
- qtProps.libExecPath = pathQueryValue(queryResult, "QT_INSTALL_LIBEXECS");
+ if (Utilities.versionCompare(qtProps.qtVersion, "6") >= 0) {
+ qtProps.libExecPath = pathQueryValue(queryResult, "QT_HOST_LIBEXECS")
+ || pathQueryValue(queryResult, "QT_INSTALL_LIBEXECS");
+ }
+
+ // QML tools were only moved in Qt 6.2.
+ qtProps.qmlLibExecPath = Utilities.versionCompare(qtProps.qtVersion, "6.2") >= 0
+ ? qtProps.libExecPath : qtProps.binaryPath
if (!File.exists(qtProps.mkspecBasePath))
throw "Cannot extract the mkspecs directory.";
@@ -567,11 +573,15 @@ function libraryBaseName(modInfo, qtProps, debugBuild) {
|| modInfo.name === "DataVisualization"
|| modInfo.name === "Phonon";
- var libName = !modInfo.modulePrefix && !libNameBroken ? "Qt" : modInfo.modulePrefix;
- if (qtProps.qtMajorVersion >= 5 && !isFramework(modInfo, qtProps) && !libNameBroken)
- libName += qtProps.qtMajorVersion;
+ var libName = "";
+ if (!modInfo.isExternal) {
+ libName += !modInfo.modulePrefix && !libNameBroken ? "Qt" : modInfo.modulePrefix;
+ if (qtProps.qtMajorVersion >= 5 && !isFramework(modInfo, qtProps) && !libNameBroken)
+ libName += qtProps.qtMajorVersion;
+ }
libName += moduleNameWithoutPrefix(modInfo);
- libName += qtProps.qtLibInfix;
+ if (!modInfo.isExternal)
+ libName += qtProps.qtLibInfix;
return libBaseName(modInfo, libName, debugBuild, qtProps);
}
@@ -967,7 +977,8 @@ function extractPaths(rhs, filePath) {
if (endIndex === -1)
endIndex = rhs.length;
}
- paths.push(FileInfo.cleanPath(rhs.slice(startIndex, endIndex)));
+ paths.push(FileInfo.cleanPath(rhs.slice(startIndex, endIndex)
+ .replace("$$PWD", FileInfo.path(filePath))));
startIndex = endIndex + 1;
}
return paths;
@@ -1061,17 +1072,21 @@ function allQt5Modules(qtProps, androidAbi) {
for (var i = 0; i < modulePriFiles.length; ++i) {
var priFileName = modulePriFiles[i];
var priFilePath = FileInfo.joinPaths(modulesDir, priFileName);
+ var genericFileNamePrefix = "qt_";
var moduleFileNamePrefix = "qt_lib_";
var pluginFileNamePrefix = "qt_plugin_";
var moduleFileNameSuffix = ".pri";
var fileHasPluginPrefix = priFileName.startsWith(pluginFileNamePrefix);
- if (!fileHasPluginPrefix && (!priFileName.startsWith(moduleFileNamePrefix))
+ if (!fileHasPluginPrefix && !priFileName.startsWith(genericFileNamePrefix)
|| !priFileName.endsWith(moduleFileNameSuffix)) {
continue;
}
var moduleInfo = makeQtModuleInfo();
moduleInfo.isPlugin = fileHasPluginPrefix;
- var fileNamePrefix = moduleInfo.isPlugin ? pluginFileNamePrefix : moduleFileNamePrefix;
+ moduleInfo.isExternal = !moduleInfo.isPlugin
+ && !priFileName.startsWith(moduleFileNamePrefix);
+ var fileNamePrefix = moduleInfo.isPlugin ? pluginFileNamePrefix : moduleInfo.isExternal
+ ? genericFileNamePrefix : moduleFileNamePrefix;
moduleInfo.qbsName = priFileName.slice(fileNamePrefix.length, -moduleFileNameSuffix.length);
if (moduleInfo.isPlugin) {
moduleInfo.name = moduleInfo.qbsName;
@@ -1344,6 +1359,7 @@ function replaceSpecialValues(content, module, qtProps, abi) {
installPath: ModUtils.toJSLiteral(qtProps.installPath),
libPath: ModUtils.toJSLiteral(qtProps.libraryPath),
libExecPath: ModUtils.toJSLiteral(qtProps.libExecPath),
+ qmlLibExecPath: ModUtils.toJSLiteral(qtProps.qmlLibExecPath),
pluginPath: ModUtils.toJSLiteral(qtProps.pluginPath),
incPath: ModUtils.toJSLiteral(qtProps.includePath),
docPath: ModUtils.toJSLiteral(qtProps.documentationPath),
@@ -1561,7 +1577,7 @@ function setupOneQt(qmakeFilePath, outputBaseDir, uniquify, location, qbs) {
copyTemplateFile("qml.js", qbsQtModuleDir, qtProps, androidAbis[a], location,
allFiles);
var qmlcacheStr = "qmlcache";
- if (File.exists(FileInfo.joinPaths(qtProps.binaryPath,
+ if (File.exists(FileInfo.joinPaths(qtProps.qmlLibExecPath,
"qmlcachegen" + exeSuffix(qbs)))) {
copyTemplateFile(qmlcacheStr + ".qbs",
FileInfo.joinPaths(qbsQtModuleBaseDir, qmlcacheStr), qtProps,
diff --git a/share/qbs/module-providers/Qt/templates/android_support.qbs b/share/qbs/module-providers/Qt/templates/android_support.qbs
index 68a29bb95..a1975b890 100644
--- a/share/qbs/module-providers/Qt/templates/android_support.qbs
+++ b/share/qbs/module-providers/Qt/templates/android_support.qbs
@@ -8,20 +8,18 @@ import qbs.Xml
Module {
version: @version@
- property bool useMinistro: false
property string qmlRootDir: product.sourceDirectory
property stringList extraPrefixDirs
property stringList deploymentDependencies // qmake: ANDROID_DEPLOYMENT_DEPENDENCIES
property stringList extraPlugins // qmake: ANDROID_EXTRA_PLUGINS
property stringList extraLibs // qmake: ANDROID_EXTRA_LIBS
property bool verboseAndroidDeployQt: false
-
property string _androidDeployQtFilePath: FileInfo.joinPaths(_qtBinaryDir, "bin",
"androiddeployqt")
property string _qtBinaryDir
property string _qtInstallDir
- // TODO: Remove in 1.20
- // From 1.20 product property used from an export item will point to the
+ // TODO: Remove in 1.21
+ // From 1.21 product property used from an export item will point to the
// importingProduct property. So using the importingProduct property will be useless
// and the change will be reverted
property var _importingProduct: (typeof importingProduct !== "undefined") ? importingProduct :
@@ -58,6 +56,8 @@ Module {
Android.sdk.customManifestProcessing: true
java._tagJniHeaders: false // prevent rule cycle
}
+ readonly property string _qtAndroidJarFileName: Utilities.versionCompare(version, "6.0") >= 0 ?
+ "Qt6Android.jar" : "QtAndroid.jar"
Properties {
condition: _enableSdkSupport && Utilities.versionCompare(version, "5.15") >= 0
&& Utilities.versionCompare(version, "6.0") < 0
@@ -280,39 +280,36 @@ Module {
"android.manifest_final", "android.resources", "android.assets", "bundled_jar",
"android.deployqt_list",
]
- outputArtifacts: {
- var artifacts = [
- {
- filePath: "AndroidManifest.xml",
- fileTags: "android.manifest_final"
- },
- {
- filePath: product.Qt.android_support._deployQtOutDir + "/res/values/libs.xml",
- fileTags: "android.resources"
- },
- {
- filePath: product.Qt.android_support._deployQtOutDir
- + "/res/values/strings.xml",
- fileTags: "android.resources"
- },
- {
- filePath: product.Qt.android_support._deployQtOutDir + "/assets/.dummy",
- fileTags: "android.assets"
- },
- {
- filePath: "deployqt.list",
- fileTags: "android.deployqt_list"
- },
-
- ];
- if (!product.Qt.android_support.useMinistro) {
- artifacts.push({
- filePath: FileInfo.joinPaths(product.java.classFilesDir, "QtAndroid.jar"),
- fileTags: ["bundled_jar"]
- });
+ outputArtifacts: [
+ {
+ filePath: "AndroidManifest.xml",
+ fileTags: "android.manifest_final"
+ },
+ {
+ filePath: product.Qt.android_support._deployQtOutDir + "/res/values/libs.xml",
+ fileTags: "android.resources"
+ },
+ {
+ filePath: product.Qt.android_support._deployQtOutDir
+ + "/res/values/strings.xml",
+ fileTags: "android.resources"
+ },
+ {
+ filePath: product.Qt.android_support._deployQtOutDir + "/assets/.dummy",
+ fileTags: "android.assets"
+ },
+ {
+ filePath: "deployqt.list",
+ fileTags: "android.deployqt_list"
+ },
+ // androiddeployqt potentially copies more jar files but this one will always be there
+ // since it comes with Qt.core
+ {
+ filePath: FileInfo.joinPaths(product.java.classFilesDir,
+ product.Qt.android_support._qtAndroidJarFileName),
+ fileTags: "bundled_jar"
}
- return artifacts;
- }
+ ]
prepare: {
var copyCmd = new JavaScriptCommand();
copyCmd.description = "copying Qt resource templates";
@@ -343,7 +340,7 @@ Module {
var androidDeployQtArgs = [
"--output", product.Qt.android_support._deployQtOutDir,
"--input", inputs["qt_androiddeployqt_input"][0].filePath, "--aux-mode",
- "--deployment", product.Qt.android_support.useMinistro ? "ministro" : "bundled",
+ "--deployment", "bundled",
"--android-platform", product.Android.sdk.platform,
];
if (product.Qt.android_support.verboseAndroidDeployQt)
@@ -360,6 +357,7 @@ Module {
var moveCmd = new JavaScriptCommand();
moveCmd.description = "processing androiddeployqt outout";
moveCmd.sourceCode = function() {
+ File.makePath(product.java.classFilesDir);
var libsDir = product.Qt.android_support._deployQtOutDir + "/libs";
var libDir = product.Android.sdk.packageContentsDir + "/lib";
var listFilePath = outputs["android.deployqt_list"][0].filePath;
diff --git a/share/qbs/module-providers/Qt/templates/core.qbs b/share/qbs/module-providers/Qt/templates/core.qbs
index 2e810eeed..e34274cfd 100644
--- a/share/qbs/module-providers/Qt/templates/core.qbs
+++ b/share/qbs/module-providers/Qt/templates/core.qbs
@@ -30,7 +30,7 @@ Module {
// depend on qml. That's why the scannerName must be defined here and not in the
// qml module
property string qmlImportScannerName: "qmlimportscanner"
- property string qmlImportScannerFilePath: binPath + '/' + qmlImportScannerName
+ property string qmlImportScannerFilePath: qmlLibExecPath + '/' + qmlImportScannerName
version: @version@
property stringList architectures: @archs@
@@ -43,6 +43,7 @@ Module {
property path incPath: @incPath@
property path libPath: @libPath@
property path libExecPath: @libExecPath@
+ property path qmlLibExecPath: @qmlLibExecPath@
property path pluginPath: @pluginPath@
property string mkspecName: @mkspecName@
property path mkspecPath: @mkspecPath@
diff --git a/share/qbs/module-providers/Qt/templates/qml.qbs b/share/qbs/module-providers/Qt/templates/qml.qbs
index 104e6848f..9b4dfa36c 100644
--- a/share/qbs/module-providers/Qt/templates/qml.qbs
+++ b/share/qbs/module-providers/Qt/templates/qml.qbs
@@ -107,7 +107,7 @@ QtModule {
args.push("--foreign-types=" + foreignTypes.join(","));
args.push("-o", outputs.cpp[0].filePath);
args = args.concat(inputs["qt.core.metatypes"].map(filePathFromArtifact));
- var cmd = new Command(product.Qt.core.binPath + "/qmltyperegistrar", args);
+ var cmd = new Command(product.Qt.core.qmlLibExecPath + "/qmltyperegistrar", args);
cmd.description = "running qmltyperegistrar";
cmd.highlight = "codegen";
return cmd;
diff --git a/share/qbs/module-providers/Qt/templates/qmlcache.qbs b/share/qbs/module-providers/Qt/templates/qmlcache.qbs
index 9111eb500..38338d106 100644
--- a/share/qbs/module-providers/Qt/templates/qmlcache.qbs
+++ b/share/qbs/module-providers/Qt/templates/qmlcache.qbs
@@ -9,7 +9,7 @@ Module {
if (!qmlcachegenProbe.found)
throw "qmlcachegen unsupported for this target";
}
- property string qmlCacheGenPath: FileInfo.joinPaths(Qt.core.binPath, "qmlcachegen")
+ property string qmlCacheGenPath: FileInfo.joinPaths(Qt.core.qmlLibExecPath, "qmlcachegen")
+ (qbs.hostOS.contains("windows") ? ".exe" : "")
property bool supportsAllArchitectures: Utilities.versionCompare(Qt.core.version, "5.11") >= 0
property string installDir
diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs
index cae5fc2e5..b284c1f8f 100644
--- a/share/qbs/modules/Android/sdk/sdk.qbs
+++ b/share/qbs/modules/Android/sdk/sdk.qbs
@@ -150,7 +150,7 @@ Module {
}
property path buildToolsDir: FileInfo.joinPaths(sdkDir, "build-tools", buildToolsVersion)
- property string aaptName: "aapt"
+ property string aaptName: "aapt2"
PropertyOptions {
name: "aaptName"
allowedValues: ["aapt", "aapt2"]
@@ -167,6 +167,13 @@ Module {
property path apksignerFilePath: FileInfo.joinPaths(buildToolsDir, "apksigner")
property path aidlFilePath: FileInfo.joinPaths(buildToolsDir, "aidl")
property path dxFilePath: FileInfo.joinPaths(buildToolsDir, "dx")
+ property path d8FilePath: FileInfo.joinPaths(buildToolsDir, "d8")
+ property string dexCompilerName: "d8"
+ PropertyOptions {
+ name: "dexCompilerName"
+ allowedValues: ["dx", "d8"]
+ }
+ readonly property bool _useD8: dexCompilerName === "d8"
property path zipalignFilePath: FileInfo.joinPaths(buildToolsDir, "zipalign")
property path androidJarFilePath: FileInfo.joinPaths(sdkDir, "platforms", platform,
"android.jar")
@@ -430,7 +437,7 @@ Module {
condition: _enableRules
multiplex: true
inputs: ["java.class"]
- inputsFromDependencies: ["java.jar"]
+ inputsFromDependencies: ["java.jar", "bundled_jar"]
Artifact {
filePath: product.Android.sdk._generateAab ?
FileInfo.joinPaths(product.Android.sdk.packageContentsDir, "dex",
diff --git a/share/qbs/modules/Android/sdk/utils.js b/share/qbs/modules/Android/sdk/utils.js
index 264ad2da7..a10ca69fc 100644
--- a/share/qbs/modules/Android/sdk/utils.js
+++ b/share/qbs/modules/Android/sdk/utils.js
@@ -57,8 +57,21 @@ function availableBuildToolsVersions(sdkDir) {
}
function prepareDex(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
- var dxFilePath = product.Android.sdk.dxFilePath;
- var args = ["--dex", "--output", output.filePath, product.java.classFilesDir];
+ var dexCompilerFilePath = product.Android.sdk._useD8 ? product.Android.sdk.d8FilePath
+ : product.Android.sdk.dxFilePath;
+ var args = ["--output", FileInfo.path(output.filePath)];
+
+ if (product.Android.sdk._useD8) {
+ args.push("--no-desugaring", "--release");
+ var classes = inputs["java.class"];
+ if (classes) {
+ args = args.concat(classes.map(function(javaClass) {
+ return FileInfo.relativePath(product.java.classFilesDir, javaClass.filePath) }));
+ }
+ } else {
+ args.unshift("--dex");
+ args.push(product.java.classFilesDir);
+ }
var jarFiles = [];
function traverseJarDeps(dep) {
@@ -80,8 +93,42 @@ function prepareDex(project, product, inputs, outputs, input, output, explicitly
args = args.concat(jarFiles);
- var cmd = new Command(dxFilePath, args);
- cmd.description = "creating " + output.fileName;
+ var cmd;
+ if (product.Android.sdk._useD8) {
+ cmd = new JavaScriptCommand();
+ cmd.args = args;
+ cmd.dexCompilerFilePath = dexCompilerFilePath;
+ cmd.description = "creating " + output.fileName;
+ cmd.workingDirectory = product.java.classFilesDir;
+ cmd.extendedDescription = dexCompilerFilePath + " " + args.join(' ');
+ cmd.highlight = "compiler";
+ cmd.sourceCode = function() {
+ // androiddeployqt copied jar files in product.java.classFilesDir
+ // but the rule only tags one jar file ("QtAndroid.jar"/"Qt6Android.jar")
+ // So to pass all files to d8, Qbs needs to read the directory
+ var bundledJarFilesDir = product.java.classFilesDir;
+ var bundledJarFiles = File.directoryEntries(bundledJarFilesDir, File.Files
+ | File.NoDotAndDotDot);
+ args = args.concat(bundledJarFiles.map(function(jarFile) {
+ return FileInfo.joinPaths(bundledJarFilesDir, jarFile) }));
+ var process = new Process();
+ var exitCode;
+ process.setWorkingDirectory(workingDirectory);
+ process.exec(dexCompilerFilePath, args, true);
+ try {
+ process.exec(dexCompilerFilePath, args, true);
+ } catch (e) {
+ throw new Error("Error while running dex compiler command: '"
+ + Process.shellQuote(dexCompilerFilePath, args) + "': " + e.toString());
+ } finally {
+ process.close();
+ }
+ }
+ } else {
+ cmd = new Command(dexCompilerFilePath, args);
+ cmd.description = "creating " + output.fileName;
+ cmd.workingDirectory = product.java.classFilesDir;
+ }
return [cmd];
}
diff --git a/share/qbs/modules/bundle/MacOSX-Package-Types.xcspec b/share/qbs/modules/bundle/MacOSX-Package-Types.xcspec
index b36353fc7..23f094641 100644
--- a/share/qbs/modules/bundle/MacOSX-Package-Types.xcspec
+++ b/share/qbs/modules/bundle/MacOSX-Package-Types.xcspec
@@ -1,462 +1,533 @@
-[
- {
- "DefaultBuildSettings" : {
- "EXECUTABLE_PATH" : "$(EXECUTABLE_NAME)",
- "EXECUTABLE_PREFIX" : "",
- "EXECUTABLE_SUFFIX" : "",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)"
- },
- "Identifier" : "com.apple.package-type.mach-o-executable",
- "Type" : "PackageType",
- "Name" : "Mach-O Executable",
- "Description" : "Mach-O executable",
- "ProductReference" : {
- "FileType" : "compiled.mach-o.executable",
- "Name" : "$(EXECUTABLE_NAME)",
- "IsLaunchable" : "YES"
- }
- },
- {
- "DefaultBuildSettings" : {
- "EXECUTABLE_PATH" : "$(EXECUTABLE_NAME)",
- "EXECUTABLE_PREFIX" : "",
- "EXECUTABLE_SUFFIX" : "",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)"
- },
- "Identifier" : "com.apple.package-type.mach-o-objfile",
- "Type" : "PackageType",
- "Name" : "Mach-O Object File",
- "Description" : "Mach-O Object File",
- "ProductReference" : {
- "FileType" : "compiled.mach-o.objfile",
- "Name" : "$(EXECUTABLE_NAME)",
- "IsLaunchable" : "NO"
- }
- },
- {
- "DefaultBuildSettings" : {
- "EXECUTABLE_PATH" : "$(EXECUTABLE_NAME)",
- "EXECUTABLE_PREFIX" : "",
- "EXECUTABLE_SUFFIX" : "",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)"
- },
- "Identifier" : "com.apple.package-type.mach-o-dylib",
- "Type" : "PackageType",
- "Name" : "Mach-O Dynamic Library",
- "Description" : "Mach-O dynamic library",
- "ProductReference" : {
- "FileType" : "compiled.mach-o.dylib",
- "Name" : "$(EXECUTABLE_NAME)",
- "IsLaunchable" : "NO"
- }
- },
- {
- "DefaultBuildSettings" : {
- "EXECUTABLE_PATH" : "$(EXECUTABLE_NAME)",
- "EXECUTABLE_PREFIX" : "lib",
- "EXECUTABLE_SUFFIX" : ".a",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)"
- },
- "Identifier" : "com.apple.package-type.static-library",
- "Type" : "PackageType",
- "Name" : "Mach-O Static Library",
- "Description" : "Mach-O static library",
- "ProductReference" : {
- "FileType" : "archive.ar",
- "Name" : "$(EXECUTABLE_NAME)",
- "IsLaunchable" : "NO"
- }
- },
- {
- "DefaultBuildSettings" : {
- "EXECUTABLE_PATH" : "$(EXECUTABLE_NAME)",
- "EXECUTABLE_PREFIX" : "",
- "EXECUTABLE_SUFFIX" : ".dylib",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)"
- },
- "Identifier" : "com.apple.package-type.mach-o-bundle",
- "Type" : "PackageType",
- "Name" : "Mach-O Loadable",
- "Description" : "Mach-O loadable",
- "ProductReference" : {
- "FileType" : "compiled.mach-o.bundle",
- "Name" : "$(EXECUTABLE_NAME)",
- "IsLaunchable" : "NO"
- }
- },
- {
- "DefaultBuildSettings" : {
- "PUBLIC_HEADERS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/Headers",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)",
- "EXECUTABLE_PREFIX" : "",
- "PLUGINS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/PlugIns",
- "DOCUMENTATION_FOLDER_PATH" : "$(LOCALIZED_RESOURCES_FOLDER_PATH)\/Documentation",
- "EXECUTABLES_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/Executables",
- "INFOSTRINGS_PATH" : "$(LOCALIZED_RESOURCES_FOLDER_PATH)\/InfoPlist.strings",
- "INFOPLIST_PATH" : "$(CONTENTS_FOLDER_PATH)\/Info.plist",
- "EXECUTABLE_SUFFIX" : "",
- "VERSIONPLIST_PATH" : "$(CONTENTS_FOLDER_PATH)\/version.plist",
- "SHARED_SUPPORT_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/SharedSupport",
- "EXECUTABLE_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/MacOS",
- "PBDEVELOPMENTPLIST_PATH" : "$(CONTENTS_FOLDER_PATH)\/pbdevelopment.plist",
- "FRAMEWORKS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/Frameworks",
- "LOCALIZED_RESOURCES_FOLDER_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)\/$(DEVELOPMENT_LANGUAGE).lproj",
- "SCRIPTS_FOLDER_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)\/Scripts",
- "WRAPPER_PREFIX" : "",
- "PRIVATE_HEADERS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/PrivateHeaders",
- "CONTENTS_FOLDER_PATH" : "$(WRAPPER_NAME)\/Contents",
- "WRAPPER_NAME" : "$(WRAPPER_PREFIX)$(PRODUCT_NAME)$(WRAPPER_SUFFIX)",
- "PKGINFO_PATH" : "$(CONTENTS_FOLDER_PATH)\/PkgInfo",
- "EXECUTABLE_PATH" : "$(EXECUTABLE_FOLDER_PATH)\/$(EXECUTABLE_NAME)",
- "UNLOCALIZED_RESOURCES_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/Resources",
- "JAVA_FOLDER_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)\/Java",
- "SHARED_FRAMEWORKS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/SharedFrameworks",
- "WRAPPER_SUFFIX" : ".bundle"
- },
- "Identifier" : "com.apple.package-type.wrapper",
- "Type" : "PackageType",
- "Name" : "Wrapper",
- "Description" : "Wrapper",
- "ProductReference" : {
- "FileType" : "wrapper.cfbundle",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
- }
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.cfbundle",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
- },
- "DefaultBuildSettings" : {
- "CONTENTS_FOLDER_PATH" : "$(WRAPPER_NAME)",
- "UNLOCALIZED_RESOURCES_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "SHALLOW_BUNDLE" : "YES",
- "EXECUTABLE_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)"
- },
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper",
- "Name" : "Wrapper (Shallow)",
- "Identifier" : "com.apple.package-type.wrapper.shallow",
- "Description" : "Shallow Wrapper"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.application",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "YES"
- },
- "DefaultBuildSettings" : {
- "GENERATE_PKGINFO_FILE" : "YES"
- },
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper",
- "Name" : "Application Wrapper",
- "Identifier" : "com.apple.package-type.wrapper.application",
- "Description" : "Application Wrapper"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.application",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "YES"
- },
- "DefaultBuildSettings" : {
- "UNLOCALIZED_RESOURCES_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "SHALLOW_BUNDLE" : "YES",
- "GENERATE_PKGINFO_FILE" : "YES"
- },
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper.shallow",
- "Name" : "Application Wrapper (Shallow)",
- "Identifier" : "com.apple.package-type.wrapper.application.shallow",
- "Description" : "Shallow Application Wrapper"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.cfbundle",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
- },
- "DefaultBuildSettings" : {
- "PRIVATE_HEADERS_FOLDER_PATH" : "$(KEXT_FRAMEWORK)\/Contents\/PrivateHeaders\/$(KEXT_FAMILY_NAME)",
- "PUBLIC_HEADERS_FOLDER_PATH" : "$(KEXT_FRAMEWORK)\/Contents\/Headers\/$(KEXT_FAMILY_NAME)"
+/**
+ MacOSX Package Types.xcspec
+
+ Copyright (c) 1999-2015 Apple Inc. All rights reserved.
+
+ Package type specifications in the Mac OS X platform.
+*/
+(
+ // Mach-O executable
+ { Type = PackageType;
+ Identifier = com.apple.package-type.mach-o-executable;
+ Name = "Mach-O Executable";
+ Description = "Mach-O executable";
+ DefaultBuildSettings = {
+ EXECUTABLE_PREFIX = "";
+ EXECUTABLE_SUFFIX = "";
+ EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)";
+ EXECUTABLE_PATH = "$(EXECUTABLE_NAME)";
+ };
+ ProductReference = {
+ FileType = compiled.mach-o.executable;
+ Name = "$(EXECUTABLE_NAME)";
+ IsLaunchable = YES;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper",
- "Name" : "Kernel Extension Wrapper",
- "Identifier" : "com.apple.package-type.wrapper.kernel-extension",
- "Description" : "Kernel Extension Wrapper"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.cfbundle",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
+
+ // Mach-O object file
+ { Type = PackageType;
+ Identifier = com.apple.package-type.mach-o-objfile;
+ Name = "Mach-O Object File";
+ Description = "Mach-O Object File";
+ DefaultBuildSettings = {
+ EXECUTABLE_PREFIX = "";
+ EXECUTABLE_SUFFIX = "";
+ EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)";
+ EXECUTABLE_PATH = "$(EXECUTABLE_NAME)";
+ };
+ ProductReference = {
+ FileType = compiled.mach-o.objfile;
+ Name = "$(EXECUTABLE_NAME)";
+ IsLaunchable = NO;
+ };
},
- "DefaultBuildSettings" : {
- "PRIVATE_HEADERS_FOLDER_PATH" : "$(KEXT_FRAMEWORK)\/Contents\/PrivateHeaders\/$(KEXT_FAMILY_NAME)",
- "PUBLIC_HEADERS_FOLDER_PATH" : "$(KEXT_FRAMEWORK)\/Contents\/Headers\/$(KEXT_FAMILY_NAME)",
- "SHALLOW_BUNDLE" : "YES"
+
+ // Mach-O dynamic library
+ { Type = PackageType;
+ Identifier = com.apple.package-type.mach-o-dylib;
+ Name = "Mach-O Dynamic Library";
+ Description = "Mach-O dynamic library";
+ DefaultBuildSettings = {
+ EXECUTABLE_PREFIX = "";
+ EXECUTABLE_SUFFIX = "";
+ EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)";
+ EXECUTABLE_PATH = "$(EXECUTABLE_NAME)";
+ };
+ ProductReference = {
+ FileType = compiled.mach-o.dylib;
+ Name = "$(EXECUTABLE_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper.shallow",
- "Name" : "Kernel Extension Wrapper (Shallow)",
- "Identifier" : "com.apple.package-type.wrapper.kernel-extension.shallow",
- "Description" : "Shallow Kernel Extension Wrapper"
- },
- {
- "DefaultBuildSettings" : {
- "PUBLIC_HEADERS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/Headers",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)",
- "EXECUTABLE_PREFIX" : "",
- "PLUGINS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/PlugIns",
- "DOCUMENTATION_FOLDER_PATH" : "$(LOCALIZED_RESOURCES_FOLDER_PATH)\/Documentation",
- "EXECUTABLES_FOLDER_PATH" : "$(LOCALIZED_RESOURCES_FOLDER_PATH)",
- "INFOPLIST_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)\/Info.plist",
- "EXECUTABLE_SUFFIX" : "",
- "INFOPLISTSTRINGS_PATH" : "$(LOCALIZED_RESOURCES_FOLDER_PATH)\/InfoPlist.strings",
- "VERSIONPLIST_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)\/version.plist",
- "SHARED_SUPPORT_FOLDER_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)",
- "EXECUTABLE_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "PBDEVELOPMENTPLIST_PATH" : "$(CONTENTS_FOLDER_PATH)\/pbdevelopment.plist",
- "VERSIONS_FOLDER_PATH" : "$(WRAPPER_NAME)\/Versions",
- "FRAMEWORKS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/Frameworks",
- "CODESIGNING_FOLDER_PATH" : "$(TARGET_BUILD_DIR)\/$(CONTENTS_FOLDER_PATH)",
- "LOCALIZED_RESOURCES_FOLDER_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)\/$(DEVELOPMENT_LANGUAGE).lproj",
- "SCRIPTS_FOLDER_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)\/Scripts",
- "WRAPPER_PREFIX" : "",
- "PRIVATE_HEADERS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/PrivateHeaders",
- "CURRENT_VERSION" : "Current",
- "PKGINFO_PATH" : "$(WRAPPER_NAME)\/PkgInfo",
- "WRAPPER_NAME" : "$(WRAPPER_PREFIX)$(PRODUCT_NAME)$(WRAPPER_SUFFIX)",
- "CONTENTS_FOLDER_PATH" : "$(VERSIONS_FOLDER_PATH)\/$(FRAMEWORK_VERSION)",
- "EXECUTABLE_PATH" : "$(EXECUTABLE_FOLDER_PATH)\/$(EXECUTABLE_NAME)",
- "UNLOCALIZED_RESOURCES_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/Resources",
- "JAVA_FOLDER_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)\/Java",
- "SHARED_FRAMEWORKS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)\/SharedFrameworks",
- "WRAPPER_SUFFIX" : ".framework"
+
+ // Static library ('ar' archive containing .o files)
+ { Type = PackageType;
+ Identifier = com.apple.package-type.static-library;
+ Name = "Mach-O Static Library";
+ Description = "Mach-O static library";
+ DefaultBuildSettings = {
+ EXECUTABLE_PREFIX = "lib";
+ EXECUTABLE_SUFFIX = ".a";
+ EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)";
+ EXECUTABLE_PATH = "$(EXECUTABLE_NAME)";
+ };
+ ProductReference = {
+ FileType = archive.ar;
+ Name = "$(EXECUTABLE_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Identifier" : "com.apple.package-type.wrapper.framework",
- "Type" : "PackageType",
- "Name" : "Framework Wrapper",
- "Description" : "Framework wrapper",
- "ProductReference" : {
- "FileType" : "wrapper.framework",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
- }
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.framework.static",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
+
+ // Mach-O bundle (not related to a CFBundle)
+ { Type = PackageType;
+ Identifier = com.apple.package-type.mach-o-bundle;
+ Name = "Mach-O Loadable";
+ Description = "Mach-O loadable";
+ DefaultBuildSettings = {
+ EXECUTABLE_PREFIX = "";
+ EXECUTABLE_SUFFIX = ".dylib";
+ EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)";
+ EXECUTABLE_PATH = "$(EXECUTABLE_NAME)";
+ };
+ ProductReference = {
+ FileType = compiled.mach-o.bundle;
+ Name = "$(EXECUTABLE_NAME)";
+ IsLaunchable = NO;
+ };
},
- "DefaultBuildSettings" : {
- "EXECUTABLE_SUFFIX" : "",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)",
- "EXECUTABLE_PREFIX" : ""
+
+ // CFBundle wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.wrapper;
+ Name = "Wrapper";
+ Description = "Wrapper";
+ DefaultBuildSettings = {
+ PRODUCT_BUNDLE_PACKAGE_TYPE = "BNDL";
+ WRAPPER_PREFIX = "";
+ WRAPPER_SUFFIX = ".bundle";
+ WRAPPER_NAME = "$(WRAPPER_PREFIX)$(PRODUCT_NAME)$(WRAPPER_SUFFIX)";
+ CONTENTS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH_SHALLOW_BUNDLE_$(SHALLOW_BUNDLE))";
+ EXECUTABLE_PREFIX = "";
+ EXECUTABLE_SUFFIX = "";
+ EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)";
+ EXECUTABLE_FOLDER_PATH = "$(EXECUTABLE_FOLDER_PATH_SHALLOW_BUNDLE_$(SHALLOW_BUNDLE))";
+ EXECUTABLE_PATH = "$(EXECUTABLE_FOLDER_PATH)/$(EXECUTABLE_NAME)";
+ INFOPLIST_PATH = "$(CONTENTS_FOLDER_PATH)/Info.plist";
+ INFOSTRINGS_PATH = "$(LOCALIZED_RESOURCES_FOLDER_PATH)/InfoPlist.strings";
+ PKGINFO_PATH = "$(CONTENTS_FOLDER_PATH)/PkgInfo";
+ PBDEVELOPMENTPLIST_PATH = "$(CONTENTS_FOLDER_PATH)/pbdevelopment.plist";
+ VERSIONPLIST_PATH = "$(CONTENTS_FOLDER_PATH)/version.plist";
+ PUBLIC_HEADERS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/Headers";
+ PRIVATE_HEADERS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/PrivateHeaders";
+ EXECUTABLES_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/Executables"; // Not the same as EXECUTABLE_FOLDER_PATH
+ FRAMEWORKS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/Frameworks";
+ SHARED_FRAMEWORKS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/SharedFrameworks";
+ SHARED_SUPPORT_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/SharedSupport";
+ UNLOCALIZED_RESOURCES_FOLDER_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH_SHALLOW_BUNDLE_$(SHALLOW_BUNDLE))";
+ LOCALIZED_RESOURCES_FOLDER_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/$(DEVELOPMENT_LANGUAGE).lproj";
+ DOCUMENTATION_FOLDER_PATH = "$(LOCALIZED_RESOURCES_FOLDER_PATH)/Documentation";
+ MODULES_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/Modules";
+ PLUGINS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/PlugIns";
+ SCRIPTS_FOLDER_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/Scripts";
+ JAVA_FOLDER_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/Java";
+ SYSTEM_EXTENSIONS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/Library/SystemExtensions";
+
+ // Settings specific to deep bundles (macOS)
+ CONTENTS_FOLDER_PATH_SHALLOW_BUNDLE_NO = "$(WRAPPER_NAME)/Contents";
+ EXECUTABLE_FOLDER_PATH_SHALLOW_BUNDLE_NO = "$(CONTENTS_FOLDER_PATH)/MacOS";
+ UNLOCALIZED_RESOURCES_FOLDER_PATH_SHALLOW_BUNDLE_NO = "$(CONTENTS_FOLDER_PATH)/Resources";
+
+ // Settings specific to shallow bundles (iOS, DriverKit on any OS)
+ CONTENTS_FOLDER_PATH_SHALLOW_BUNDLE_YES = "$(WRAPPER_NAME)";
+ EXECUTABLE_FOLDER_PATH_SHALLOW_BUNDLE_YES = "$(CONTENTS_FOLDER_PATH)";
+ UNLOCALIZED_RESOURCES_FOLDER_PATH_SHALLOW_BUNDLE_YES = "$(CONTENTS_FOLDER_PATH)";
+
+ // DriverKit should always use shallow bundles
+ SHALLOW_BUNDLE = "$(SHALLOW_BUNDLE_$(SWIFT_PLATFORM_TARGET_PREFIX))";
+ SHALLOW_BUNDLE_ = YES;
+ SHALLOW_BUNDLE_macos = NO;
+ SHALLOW_BUNDLE_ios = NO; // for macCatalyst
+ SHALLOW_BUNDLE_driverkit = YES;
+ };
+ ProductReference = {
+ FileType = wrapper.cfbundle;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper.framework",
- "Name" : "Mach-O Static Framework",
- "Identifier" : "com.apple.package-type.wrapper.framework.static",
- "Description" : "Mach-O static framework"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.framework",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
+
+ // Shallow CFBundle wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.wrapper.shallow;
+ BasedOn = com.apple.package-type.wrapper;
+ Name = "Wrapper (Shallow)";
+ Description = "Shallow Wrapper";
+ DefaultBuildSettings = {
+ SHALLOW_BUNDLE = YES;
+ };
+ ProductReference = {
+ FileType = wrapper.cfbundle;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "DefaultBuildSettings" : {
- "UNLOCALIZED_RESOURCES_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "CONTENTS_FOLDER_PATH" : "$(WRAPPER_NAME)",
- "SHALLOW_BUNDLE" : "YES",
- "VERSIONS_FOLDER_PATH" : "$(WRAPPER_NAME)"
+
+ // Application wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.wrapper.application;
+ BasedOn = com.apple.package-type.wrapper;
+ Name = "Application Wrapper";
+ Description = "Application Wrapper";
+ DefaultBuildSettings = {
+ PRODUCT_BUNDLE_PACKAGE_TYPE = "APPL";
+ GENERATE_PKGINFO_FILE = YES;
+ };
+ ProductReference = {
+ FileType = wrapper.application;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = YES;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper.framework",
- "Name" : "Shallow Framework Wrapper",
- "Identifier" : "com.apple.package-type.wrapper.framework.shallow",
- "Description" : "Shallow framework wrapper"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.cfbundle",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
+
+ // Shallow Application wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.wrapper.application.shallow;
+ BasedOn = com.apple.package-type.wrapper.shallow;
+ Name = "Application Wrapper (Shallow)";
+ Description = "Shallow Application Wrapper";
+ DefaultBuildSettings = {
+ PRODUCT_BUNDLE_PACKAGE_TYPE = "APPL";
+ GENERATE_PKGINFO_FILE = YES;
+ SHALLOW_BUNDLE = YES;
+ };
+ ProductReference = {
+ FileType = wrapper.application;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = YES;
+ };
},
- "DefaultBuildSettings" : {
- "WRAPPER_SUFFIX" : "xctest"
+
+ // System extension wrapper
+ {
+ Type = PackageType;
+ Identifier = com.apple.package-type.wrapper.system-extension;
+ BasedOn = com.apple.package-type.wrapper;
+ Name = "System Extension Wrapper";
+ Description = "System Extension Wrapper";
+ DefaultBuildSettings = {
+ PRODUCT_BUNDLE_PACKAGE_TYPE = "SYSX";
+ };
+ ProductReference = {
+ FileType = wrapper.system-extension;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper",
- "Name" : "Unit Test Bundle",
- "Identifier" : "com.apple.package-type.bundle.unit-test",
- "Description" : "Unit Test Bundle"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.cfbundle",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
+
+ // Driver extension wrapper
+ {
+ Type = PackageType;
+ Identifier = com.apple.package-type.wrapper.driver-extension;
+ BasedOn = com.apple.package-type.wrapper.system-extension;
+ Name = "Driver Extension Wrapper";
+ Description = "Driver Extension Wrapper";
+ DefaultBuildSettings = {
+ PRODUCT_BUNDLE_PACKAGE_TYPE = "DEXT";
+ };
+ ProductReference = {
+ FileType = wrapper.driver-extension;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "DefaultBuildSettings" : {
- "WRAPPER_SUFFIX" : "octest"
+
+ // Kernel extension wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.wrapper.kernel-extension;
+ BasedOn = com.apple.package-type.wrapper;
+ Name = "Kernel Extension Wrapper";
+ Description = "Kernel Extension Wrapper";
+ DefaultBuildSettings = {
+ PRODUCT_BUNDLE_PACKAGE_TYPE = "KEXT";
+ PUBLIC_HEADERS_FOLDER_PATH = "$(KEXT_FRAMEWORK)/Contents/Headers/$(KEXT_FAMILY_NAME)";
+ PRIVATE_HEADERS_FOLDER_PATH = "$(KEXT_FRAMEWORK)/Contents/PrivateHeaders/$(KEXT_FAMILY_NAME)";
+ };
+ ProductReference = {
+ FileType = wrapper.cfbundle;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper",
- "Name" : "OCUnit Test Bundle",
- "Identifier" : "com.apple.package-type.bundle.ocunit-test",
- "Description" : "OCUnit Test Bundle"
- },
- {
- "ProductReference" : {
- "FileType" : "folder",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
+
+ // Shallow Kernel extension wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.wrapper.kernel-extension.shallow;
+ BasedOn = com.apple.package-type.wrapper.shallow;
+ Name = "Kernel Extension Wrapper (Shallow)";
+ Description = "Shallow Kernel Extension Wrapper";
+ DefaultBuildSettings = {
+ PRODUCT_BUNDLE_PACKAGE_TYPE = "KEXT";
+ PUBLIC_HEADERS_FOLDER_PATH = "$(KEXT_FRAMEWORK)/Contents/Headers/$(KEXT_FAMILY_NAME)";
+ PRIVATE_HEADERS_FOLDER_PATH = "$(KEXT_FRAMEWORK)/Contents/PrivateHeaders/$(KEXT_FAMILY_NAME)";
+ SHALLOW_BUNDLE = YES;
+ };
+ ProductReference = {
+ FileType = wrapper.cfbundle;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "DefaultBuildSettings" : {
- "EXECUTABLE_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "JAVA_FOLDER_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)",
- "INFOSTRINGS_PATH" : "$(LOCALIZED_RESOURCES_FOLDER_PATH)\/ContentInfo.strings",
- "INFOPLIST_PATH" : "$(WRAPPER_NAME)\/ContentInfo.plist",
- "WRAPPER_SUFFIX" : "",
- "UNLOCALIZED_RESOURCES_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "DOCUMENTATION_FOLDER_PATH" : "$(LOCALIZED_RESOURCES_FOLDER_PATH)",
- "EXECUTABLES_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "LOCALIZED_RESOURCES_FOLDER_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)\/$(DEVELOPMENT_LANGUAGE).lproj",
- "PLUGINS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "PUBLIC_HEADERS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "SHARED_SUPPORT_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "SHARED_FRAMEWORKS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "PRIVATE_HEADERS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)",
- "SCRIPTS_FOLDER_PATH" : "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)",
- "FRAMEWORKS_FOLDER_PATH" : "$(CONTENTS_FOLDER_PATH)"
+
+ // Framework wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.wrapper.framework;
+ BasedOn = com.apple.package-type.wrapper;
+ Name = "Framework Wrapper";
+ Description = "Framework wrapper";
+ DefaultBuildSettings = {
+ PRODUCT_BUNDLE_PACKAGE_TYPE = "FMWK";
+ WRAPPER_SUFFIX = ".framework";
+ VERSIONS_FOLDER_PATH = "$(VERSIONS_FOLDER_PATH_SHALLOW_BUNDLE_$(SHALLOW_BUNDLE))";
+ CURRENT_VERSION = "Current";
+ INFOPLIST_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/Info.plist";
+ PKGINFO_PATH = "$(WRAPPER_NAME)/PkgInfo";
+ VERSIONPLIST_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/version.plist";
+ EXECUTABLES_FOLDER_PATH = "$(LOCALIZED_RESOURCES_FOLDER_PATH)"; // Not the same as EXECUTABLE_FOLDER_PATH
+ SHARED_SUPPORT_FOLDER_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)";
+ CODESIGNING_FOLDER_PATH = "$(TARGET_BUILD_DIR)/$(CONTENTS_FOLDER_PATH)";
+
+ // Settings specific to deep bundles (macOS)
+ VERSIONS_FOLDER_PATH_SHALLOW_BUNDLE_NO = "$(WRAPPER_NAME)/Versions";
+ CONTENTS_FOLDER_PATH_SHALLOW_BUNDLE_NO = "$(VERSIONS_FOLDER_PATH)/$(FRAMEWORK_VERSION)";
+ EXECUTABLE_FOLDER_PATH_SHALLOW_BUNDLE_NO = "$(CONTENTS_FOLDER_PATH)";
+
+ // Settings specific to shallow bundles (iOS, DriverKit on any OS)
+ VERSIONS_FOLDER_PATH_SHALLOW_BUNDLE_YES = "$(WRAPPER_NAME)";
+ };
+ ProductReference = {
+ FileType = wrapper.framework;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper",
- "Name" : "In-App Purchase Content",
- "Identifier" : "com.apple.package-type.in-app-purchase-content",
- "Description" : "In-App Purchase Content"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.xpc-service",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
+
+ // Static framework wrapper (like a framework, except that it contains a libX.a instead of a dylib)
+ { Type = PackageType;
+ Identifier = com.apple.package-type.wrapper.framework.static;
+ Name = "Mach-O Static Framework";
+ Description = "Mach-O static framework";
+ BasedOn = com.apple.package-type.wrapper.framework;
+ DefaultBuildSettings = {
+ };
+ ProductReference = {
+ FileType = wrapper.framework.static;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "DefaultBuildSettings" : {
- "WRAPPER_SUFFIX" : ".xpc"
+
+ // Shallow Framework Package
+ { Type = PackageType;
+ Identifier = com.apple.package-type.wrapper.framework.shallow;
+ Name = "Shallow Framework Wrapper";
+ Description = "Shallow framework wrapper";
+ BasedOn = com.apple.package-type.wrapper.framework;
+ DefaultBuildSettings = {
+ SHALLOW_BUNDLE = YES;
+ };
+ ProductReference = {
+ FileType = wrapper.framework;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper",
- "Name" : "XPC Service",
- "Identifier" : "com.apple.package-type.xpc-service",
- "Description" : "XPC Service"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.app-extension",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
+
+ // Unit Test Bundle wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.bundle.unit-test;
+ BasedOn = com.apple.package-type.wrapper;
+ Name = "Unit Test Bundle";
+ Description = "Unit Test Bundle";
+ DefaultBuildSettings = {
+ WRAPPER_SUFFIX = "xctest";
+ };
+ ProductReference = {
+ FileType = wrapper.cfbundle;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "DefaultBuildSettings" : {
- "WRAPPER_SUFFIX" : ".pluginkit"
+
+ // Legacy OCUnit Test Bundle wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.bundle.ocunit-test;
+ BasedOn = com.apple.package-type.wrapper;
+ Name = "OCUnit Test Bundle";
+ Description = "OCUnit Test Bundle";
+ DefaultBuildSettings = {
+ WRAPPER_SUFFIX = "octest";
+ };
+ ProductReference = {
+ FileType = wrapper.cfbundle;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.xpc-service",
- "Name" : "PlugInKit PlugIn",
- "Identifier" : "com.apple.package-type.pluginkit-plugin",
- "Description" : "PlugInKit PlugIn"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.app-extension",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
+
+ // In-app Purchase Content wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.in-app-purchase-content;
+ BasedOn = com.apple.package-type.wrapper;
+ Name = "In-App Purchase Content";
+ Description = "In-App Purchase Content";
+ DefaultBuildSettings = {
+ PRODUCT_BUNDLE_PACKAGE_TYPE = "";
+ WRAPPER_SUFFIX = "";
+ EXECUTABLE_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)";
+ INFOPLIST_PATH = "$(WRAPPER_NAME)/ContentInfo.plist";
+ INFOSTRINGS_PATH = "$(LOCALIZED_RESOURCES_FOLDER_PATH)/ContentInfo.strings";
+ PUBLIC_HEADERS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)";
+ PRIVATE_HEADERS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)";
+ EXECUTABLES_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)";
+ FRAMEWORKS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)";
+ SHARED_FRAMEWORKS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)";
+ SHARED_SUPPORT_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)";
+ UNLOCALIZED_RESOURCES_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)";
+ LOCALIZED_RESOURCES_FOLDER_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/$(DEVELOPMENT_LANGUAGE).lproj";
+ DOCUMENTATION_FOLDER_PATH = "$(LOCALIZED_RESOURCES_FOLDER_PATH)";
+ MODULES_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)";
+ PLUGINS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)";
+ SCRIPTS_FOLDER_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)";
+ JAVA_FOLDER_PATH = "$(UNLOCALIZED_RESOURCES_FOLDER_PATH)";
+ };
+ ProductReference = {
+ FileType = folder;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "DefaultBuildSettings" : {
- "WRAPPER_SUFFIX" : ".appex"
+
+ // XPC Service wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.xpc-service;
+ BasedOn = com.apple.package-type.wrapper;
+ Name = "XPC Service";
+ Description = "XPC Service";
+ DefaultBuildSettings = {
+ PRODUCT_BUNDLE_PACKAGE_TYPE = "XPC!";
+ WRAPPER_SUFFIX = ".xpc";
+ };
+ ProductReference = {
+ FileType = wrapper.xpc-service;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.pluginkit-plugin",
- "Name" : "App Extension",
- "Identifier" : "com.apple.package-type.app-extension",
- "Description" : "App Extension"
- },
- {
- "ProductReference" : {
- "FileType" : "wrapper.spotlight-importer",
- "Name" : "$(WRAPPER_NAME)",
- "IsLaunchable" : "NO"
+
+ // PlugInKit PlugIn wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.pluginkit-plugin;
+ BasedOn = com.apple.package-type.xpc-service;
+ Name = "PlugInKit PlugIn";
+ Description = "PlugInKit PlugIn";
+ DefaultBuildSettings = {
+ WRAPPER_SUFFIX = ".pluginkit";
+ };
+ ProductReference = {
+ FileType = wrapper.app-extension;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "DefaultBuildSettings" : {
+
+ // App Extension wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.app-extension;
+ BasedOn = com.apple.package-type.pluginkit-plugin;
+ Name = "App Extension";
+ Description = "App Extension";
+ DefaultBuildSettings = {
+ WRAPPER_SUFFIX = ".appex";
+ };
+ ProductReference = {
+ FileType = wrapper.app-extension;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Type" : "PackageType",
- "BasedOn" : "com.apple.package-type.wrapper",
- "Name" : "Spotlight Importer",
- "Identifier" : "com.apple.package-type.spotlight-importer",
- "Description" : "Spotlight Importer"
- },
- {
- "DefaultBuildSettings" : {
- "EXECUTABLE_PATH" : "$(EXECUTABLE_NAME)",
- "JAVA_MAKE_ZIPFILE" : "NO",
- "JAVA_ARCHIVE_CLASSES" : "YES",
- "EXECUTABLE_PREFIX" : "",
- "EXECUTABLE_SUFFIX" : ".jar",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_SUFFIX)"
+
+ // Spotlight Importer wrapper
+ { Type = PackageType;
+ Identifier = com.apple.package-type.spotlight-importer;
+ BasedOn = com.apple.package-type.wrapper;
+ Name = "Spotlight Importer";
+ Description = "Spotlight Importer";
+ DefaultBuildSettings = {
+ };
+ ProductReference = {
+ FileType = wrapper.spotlight-importer;
+ Name = "$(WRAPPER_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Identifier" : "com.apple.package-type.jarfile",
- "Type" : "PackageType",
- "Name" : "Jar File",
- "Description" : "Jar file",
- "ProductReference" : {
- "FileType" : "archive.jar",
- "Name" : "$(EXECUTABLE_NAME)",
- "IsLaunchable" : "NO"
- }
- },
- {
- "DefaultBuildSettings" : {
- "EXECUTABLE_PATH" : "$(EXECUTABLE_NAME)",
- "JAVA_MAKE_ZIPFILE" : "YES",
- "JAVA_ARCHIVE_CLASSES" : "YES",
- "EXECUTABLE_PREFIX" : "",
- "EXECUTABLE_SUFFIX" : ".zip",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_SUFFIX)"
+
+ // Jar file
+ { Type = PackageType;
+ Identifier = com.apple.package-type.jarfile;
+ Name = "Jar File";
+ Description = "Jar file";
+ DefaultBuildSettings = {
+ EXECUTABLE_PREFIX = "";
+ EXECUTABLE_SUFFIX = ".jar";
+ EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_SUFFIX)";
+ EXECUTABLE_PATH = "$(EXECUTABLE_NAME)";
+ JAVA_ARCHIVE_CLASSES = YES;
+ JAVA_MAKE_ZIPFILE = NO;
+ };
+ ProductReference = {
+ FileType = archive.jar;
+ Name = "$(EXECUTABLE_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Identifier" : "com.apple.package-type.zipfile",
- "Type" : "PackageType",
- "Name" : "Zip File",
- "Description" : "Zip file",
- "ProductReference" : {
- "FileType" : "archive.zip",
- "Name" : "$(EXECUTABLE_NAME)",
- "IsLaunchable" : "NO"
- }
- },
- {
- "DefaultBuildSettings" : {
- "EXECUTABLE_PATH" : "$(EXECUTABLE_NAME)",
- "JAVA_ARCHIVE_CLASSES" : "NO",
- "EXECUTABLE_PREFIX" : "",
- "EXECUTABLE_SUFFIX" : "",
- "EXECUTABLE_NAME" : "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_SUFFIX)"
+
+ // Zip file
+ { Type = PackageType;
+ Identifier = com.apple.package-type.zipfile;
+ Name = "Zip File";
+ Description = "Zip file";
+ DefaultBuildSettings = {
+ EXECUTABLE_PREFIX = "";
+ EXECUTABLE_SUFFIX = ".zip";
+ EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_SUFFIX)";
+ EXECUTABLE_PATH = "$(EXECUTABLE_NAME)";
+ JAVA_ARCHIVE_CLASSES = YES;
+ JAVA_MAKE_ZIPFILE = YES;
+ };
+ ProductReference = {
+ FileType = archive.zip;
+ Name = "$(EXECUTABLE_NAME)";
+ IsLaunchable = NO;
+ };
},
- "Identifier" : "com.apple.package-type.javaclassfolder",
- "Type" : "PackageType",
- "Name" : "Class Folder",
- "Description" : "Class folder",
- "ProductReference" : {
- "FileType" : "wrapper.java-classfolder",
- "Name" : "$(EXECUTABLE_NAME)",
- "IsLaunchable" : "NO"
- }
- }
-]
+
+ // Java class folder
+ { Type = PackageType;
+ Identifier = com.apple.package-type.javaclassfolder;
+ Name = "Class Folder";
+ Description = "Class folder";
+ DefaultBuildSettings = {
+ EXECUTABLE_PREFIX = "";
+ EXECUTABLE_SUFFIX = "";
+ EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_SUFFIX)";
+ EXECUTABLE_PATH = "$(EXECUTABLE_NAME)";
+ JAVA_ARCHIVE_CLASSES = NO;
+ };
+ ProductReference = {
+ FileType = wrapper.java-classfolder;
+ Name = "$(EXECUTABLE_NAME)";
+ IsLaunchable = NO;
+ };
+ },
+)
diff --git a/share/qbs/modules/bundle/MacOSX-Product-Types.xcspec b/share/qbs/modules/bundle/MacOSX-Product-Types.xcspec
index 8d8450869..bc1d087d6 100644
--- a/share/qbs/modules/bundle/MacOSX-Product-Types.xcspec
+++ b/share/qbs/modules/bundle/MacOSX-Product-Types.xcspec
@@ -1,590 +1,803 @@
-[
- {
- "IconNamePrefix" : "TargetExecutable",
- "DefaultBuildProperties" : {
- "REZ_EXECUTABLE" : "YES",
- "FULL_PRODUCT_NAME" : "$(EXECUTABLE_NAME)",
- "LIBRARY_FLAG_NOSPACE" : "YES",
- "FRAMEWORK_FLAG_PREFIX" : "-framework",
- "INSTALL_PATH" : "\/usr\/local\/bin",
- "GCC_INLINES_ARE_PRIVATE_EXTERN" : "YES",
- "GCC_DYNAMIC_NO_PIC" : "NO",
- "GCC_SYMBOLS_PRIVATE_EXTERN" : "YES",
- "CODE_SIGNING_ALLOWED" : "YES",
- "STRIP_STYLE" : "all",
- "EXECUTABLE_PREFIX" : "",
- "MACH_O_TYPE" : "mh_execute",
- "EXECUTABLE_SUFFIX" : "",
- "LIBRARY_FLAG_PREFIX" : "-l"
+//
+// MacOSX Product Types.xcspec
+//
+// Copyright © 1999-2020 Apple Inc. All rights reserved.
+//
+// Product type specifications in the macOS platform.
+//
+(
+ //
+ // Single-file product types
+ //
+
+ // Tool (normal Unix command-line executable)
+ { Type = ProductType;
+ Identifier = com.apple.product-type.tool;
+ Class = PBXToolProductType;
+ Name = "Command-line Tool";
+ Description = "Standalone command-line tool";
+ IconNamePrefix = "TargetExecutable";
+ DefaultTargetName = "Command-line Tool";
+ DefaultBuildProperties = {
+ FULL_PRODUCT_NAME = "$(EXECUTABLE_NAME)";
+ MACH_O_TYPE = "mh_execute";
+ EXECUTABLE_PREFIX = "";
+ EXECUTABLE_SUFFIX = "";
+ REZ_EXECUTABLE = YES;
+ INSTALL_PATH = "/usr/local/bin";
+ FRAMEWORK_FLAG_PREFIX = "-framework";
+ LIBRARY_FLAG_PREFIX = "-l";
+ LIBRARY_FLAG_NOSPACE = YES;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+ GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+ STRIP_STYLE = "all";
+ CODE_SIGNING_ALLOWED = YES;
+ };
+ PackageTypes = (
+ com.apple.package-type.mach-o-executable // default
+ );
+ WantsSigningEditing = YES;
+ WantsBundleIdentifierEditing = YES;
},
- "PackageTypes" : [
- "com.apple.package-type.mach-o-executable"
- ],
- "Type" : "ProductType",
- "DefaultTargetName" : "Command-line Tool",
- "Name" : "Command-line Tool",
- "Identifier" : "com.apple.product-type.tool",
- "Description" : "Standalone command-line tool",
- "Class" : "PBXToolProductType"
- },
- {
- "IconNamePrefix" : "TargetExecutable",
- "IsJava" : "YES",
- "PackageTypes" : [
- "com.apple.package-type.jarfile",
- "com.apple.package-type.zipfile",
- "com.apple.package-type.javaclassfolder"
- ],
- "Type" : "ProductType",
- "DefaultTargetName" : "Java Command-line Tool",
- "Name" : "Java Command-line Tool",
- "Identifier" : "com.apple.product-type.tool.java",
- "Description" : "Java Command-line tool",
- "DefaultBuildProperties" : {
- "REZ_EXECUTABLE" : "YES",
- "INSTALL_PATH" : "\/usr\/local\/bin",
- "FULL_PRODUCT_NAME" : "$(EXECUTABLE_NAME)"
- }
- },
- {
- "IconNamePrefix" : "TargetPlugin",
- "DefaultBuildProperties" : {
- "DEAD_CODE_STRIPPING" : "NO",
- "REZ_EXECUTABLE" : "YES",
- "LINK_WITH_STANDARD_LIBRARIES" : "NO",
- "FULL_PRODUCT_NAME" : "$(EXECUTABLE_NAME)",
- "LIBRARY_FLAG_NOSPACE" : "YES",
- "FRAMEWORK_FLAG_PREFIX" : "-framework",
- "INSTALL_PATH" : "$(HOME)\/Objects",
- "SKIP_INSTALL" : "YES",
- "GCC_INLINES_ARE_PRIVATE_EXTERN" : "YES",
- "KEEP_PRIVATE_EXTERNS" : "YES",
- "EXECUTABLE_EXTENSION" : "o",
- "PUBLIC_HEADERS_FOLDER_PATH" : "\/usr\/local\/include",
- "MACH_O_TYPE" : "mh_object",
- "EXECUTABLE_SUFFIX" : ".$(EXECUTABLE_EXTENSION)",
- "LIBRARY_FLAG_PREFIX" : "-l",
- "PRIVATE_HEADERS_FOLDER_PATH" : "\/usr\/local\/include",
- "STRIP_STYLE" : "debugging"
+
+ // Java tool
+ { Type = ProductType;
+ Identifier = com.apple.product-type.tool.java;
+ Name = "Java Command-line Tool";
+ Description = "Java Command-line tool";
+ IconNamePrefix = "TargetExecutable";
+ DefaultTargetName = "Java Command-line Tool";
+ DefaultBuildProperties = {
+ FULL_PRODUCT_NAME = "$(EXECUTABLE_NAME)";
+ REZ_EXECUTABLE = YES;
+ INSTALL_PATH = "/usr/local/bin";
+ };
+ IsJava = YES;
+ PackageTypes = (
+ com.apple.package-type.jarfile, // default
+ com.apple.package-type.zipfile,
+ com.apple.package-type.javaclassfolder
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.mach-o-objfile"
- ],
- "Type" : "ProductType",
- "DefaultTargetName" : "Object File",
- "Name" : "Object File",
- "Identifier" : "com.apple.product-type.objfile",
- "Description" : "Object File",
- "Class" : "XCStandaloneExecutableProductType"
- },
- {
- "IconNamePrefix" : "TargetLibrary",
- "DefaultBuildProperties" : {
- "LIBRARY_FLAG_PREFIX" : "-l",
- "STRIP_STYLE" : "debugging",
- "REZ_EXECUTABLE" : "YES",
- "FULL_PRODUCT_NAME" : "$(EXECUTABLE_NAME)",
- "LD_DYLIB_INSTALL_NAME" : "$(DYLIB_INSTALL_NAME_BASE:standardizepath)\/$(EXECUTABLE_PATH)",
- "DYLIB_COMPATIBILITY_VERSION" : "1",
- "INSTALL_PATH" : "\/usr\/local\/lib",
- "FRAMEWORK_FLAG_PREFIX" : "-framework",
- "LIBRARY_FLAG_NOSPACE" : "YES",
- "GCC_INLINES_ARE_PRIVATE_EXTERN" : "YES",
- "CODE_SIGNING_ALLOWED" : "YES",
- "CODE_SIGNING_REQUIRED" : "NO",
- "EXECUTABLE_EXTENSION" : "dylib",
- "PUBLIC_HEADERS_FOLDER_PATH" : "\/usr\/local\/include",
- "DYLIB_INSTALL_NAME_BASE" : "$(INSTALL_PATH)",
- "EXECUTABLE_SUFFIX" : ".$(EXECUTABLE_EXTENSION)",
- "PRIVATE_HEADERS_FOLDER_PATH" : "\/usr\/local\/include",
- "MACH_O_TYPE" : "mh_dylib",
- "DYLIB_CURRENT_VERSION" : "1"
+
+ // Object file
+ { Type = ProductType;
+ Identifier = com.apple.product-type.objfile;
+ Class = XCStandaloneExecutableProductType;
+ Name = "Object File";
+ Description = "Object File";
+ IconNamePrefix = "TargetPlugin";
+ DefaultTargetName = "Object File";
+ DefaultBuildProperties = {
+ FULL_PRODUCT_NAME = "$(EXECUTABLE_NAME)";
+ MACH_O_TYPE = "mh_object";
+ LINK_WITH_STANDARD_LIBRARIES = NO;
+ REZ_EXECUTABLE = YES;
+ EXECUTABLE_SUFFIX = ".$(EXECUTABLE_EXTENSION)";
+ EXECUTABLE_EXTENSION = "o";
+ PUBLIC_HEADERS_FOLDER_PATH = "/usr/local/include";
+ PRIVATE_HEADERS_FOLDER_PATH = "/usr/local/include";
+ INSTALL_PATH = "$(HOME)/Objects";
+ FRAMEWORK_FLAG_PREFIX = "-framework";
+ LIBRARY_FLAG_PREFIX = "-l";
+ LIBRARY_FLAG_NOSPACE = YES;
+ SKIP_INSTALL = YES;
+ STRIP_STYLE = "debugging";
+ GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+ KEEP_PRIVATE_EXTERNS = YES;
+ DEAD_CODE_STRIPPING = NO;
+ };
+ PackageTypes = (
+ com.apple.package-type.mach-o-objfile // default
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.mach-o-dylib"
- ],
- "Type" : "ProductType",
- "DefaultTargetName" : "Dynamic Library",
- "Name" : "Dynamic Library",
- "Identifier" : "com.apple.product-type.library.dynamic",
- "Description" : "Dynamic library",
- "Class" : "PBXDynamicLibraryProductType"
- },
- {
- "IconNamePrefix" : "TargetLibrary",
- "DefaultBuildProperties" : {
- "STRIP_STYLE" : "debugging",
- "CLANG_ENABLE_MODULE_DEBUGGING" : "NO",
- "REZ_EXECUTABLE" : "YES",
- "FULL_PRODUCT_NAME" : "$(EXECUTABLE_NAME)",
- "LIBRARY_FLAG_NOSPACE" : "YES",
- "FRAMEWORK_FLAG_PREFIX" : "-framework",
- "INSTALL_PATH" : "\/usr\/local\/lib",
- "EXECUTABLE_EXTENSION" : "a",
- "EXECUTABLE_PREFIX" : "lib",
- "PUBLIC_HEADERS_FOLDER_PATH" : "\/usr\/local\/include",
- "EXECUTABLE_SUFFIX" : ".$(EXECUTABLE_EXTENSION)",
- "LIBRARY_FLAG_PREFIX" : "-l",
- "PRIVATE_HEADERS_FOLDER_PATH" : "\/usr\/local\/include",
- "MACH_O_TYPE" : "staticlib"
+
+ // Dynamic library
+ { Type = ProductType;
+ Identifier = com.apple.product-type.library.dynamic;
+ Class = PBXDynamicLibraryProductType;
+ Name = "Dynamic Library";
+ Description = "Dynamic library";
+ IconNamePrefix = "TargetLibrary";
+ DefaultTargetName = "Dynamic Library";
+ DefaultBuildProperties = {
+ FULL_PRODUCT_NAME = "$(EXECUTABLE_NAME)";
+ MACH_O_TYPE = "mh_dylib";
+ REZ_EXECUTABLE = YES;
+ EXECUTABLE_SUFFIX = ".$(EXECUTABLE_EXTENSION)";
+ EXECUTABLE_EXTENSION = "dylib";
+ PUBLIC_HEADERS_FOLDER_PATH = "/usr/local/include";
+ PRIVATE_HEADERS_FOLDER_PATH = "/usr/local/include";
+ INSTALL_PATH = "/usr/local/lib";
+ DYLIB_INSTALL_NAME_BASE = "$(INSTALL_PATH)";
+ LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
+ DYLIB_COMPATIBILITY_VERSION = "1";
+ DYLIB_CURRENT_VERSION = "1";
+ FRAMEWORK_FLAG_PREFIX = "-framework";
+ LIBRARY_FLAG_PREFIX = "-l";
+ LIBRARY_FLAG_NOSPACE = YES;
+ STRIP_STYLE = "debugging";
+ GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+ CODE_SIGNING_ALLOWED = YES;
+ CODE_SIGNING_REQUIRED = NO;
+ };
+ PackageTypes = (
+ com.apple.package-type.mach-o-dylib // default
+ );
},
- "AlwaysPerformSeparateStrip" : "YES",
- "PackageTypes" : [
- "com.apple.package-type.static-library"
- ],
- "Type" : "ProductType",
- "DefaultTargetName" : "Static Library",
- "Name" : "Static Library",
- "Identifier" : "com.apple.product-type.library.static",
- "Description" : "Static library",
- "Class" : "PBXStaticLibraryProductType"
- },
- {
- "IconNamePrefix" : "TargetPlugin",
- "IsJava" : "YES",
- "PackageTypes" : [
- "com.apple.package-type.jarfile",
- "com.apple.package-type.zipfile",
- "com.apple.package-type.javaclassfolder"
- ],
- "Type" : "ProductType",
- "DefaultTargetName" : "Java Library",
- "Name" : "Java Library",
- "Identifier" : "com.apple.product-type.library.java.archive",
- "Description" : "Java library packaged as a Jar file, Zip file, or class folder",
- "DefaultBuildProperties" : {
- "INSTALL_PATH" : "\/usr\/local\/lib",
- "FULL_PRODUCT_NAME" : "$(PRODUCT_NAME)"
- }
- },
- {
- "HasInfoPlistStrings" : "YES",
- "Description" : "Generic bundle",
- "HasInfoPlist" : "YES",
- "Name" : "Bundle",
- "Class" : "PBXBundleProductType",
- "DefaultTargetName" : "Bundle",
- "DefaultBuildProperties" : {
- "LIBRARY_FLAG_NOSPACE" : "YES",
- "WRAPPER_NAME" : "$(WRAPPER_PREFIX)$(PRODUCT_NAME)$(WRAPPER_SUFFIX)",
- "FRAMEWORK_FLAG_PREFIX" : "-framework",
- "GCC_INLINES_ARE_PRIVATE_EXTERN" : "YES",
- "WRAPPER_SUFFIX" : ".$(WRAPPER_EXTENSION)",
- "FULL_PRODUCT_NAME" : "$(WRAPPER_NAME)",
- "WRAPPER_EXTENSION" : "bundle",
- "CODE_SIGNING_ALLOWED" : "YES",
- "WRAPPER_PREFIX" : "",
- "STRIP_STYLE" : "non-global",
- "MACH_O_TYPE" : "mh_bundle",
- "LIBRARY_FLAG_PREFIX" : "-l"
+
+ // Static library
+ { Type = ProductType;
+ Identifier = com.apple.product-type.library.static;
+ Class = PBXStaticLibraryProductType;
+ Name = "Static Library";
+ Description = "Static library";
+ IconNamePrefix = "TargetLibrary";
+ DefaultTargetName = "Static Library";
+ DefaultBuildProperties = {
+ FULL_PRODUCT_NAME = "$(EXECUTABLE_NAME)";
+ MACH_O_TYPE = "staticlib";
+ REZ_EXECUTABLE = YES;
+ EXECUTABLE_PREFIX = "lib";
+ EXECUTABLE_SUFFIX = ".$(EXECUTABLE_EXTENSION)";
+ EXECUTABLE_EXTENSION = "a";
+ PUBLIC_HEADERS_FOLDER_PATH = "/usr/local/include";
+ PRIVATE_HEADERS_FOLDER_PATH = "/usr/local/include";
+ INSTALL_PATH = "/usr/local/lib";
+ FRAMEWORK_FLAG_PREFIX = "-framework";
+ LIBRARY_FLAG_PREFIX = "-l";
+ LIBRARY_FLAG_NOSPACE = YES;
+ STRIP_STYLE = "debugging";
+ CLANG_ENABLE_MODULE_DEBUGGING = NO;
+ CODE_SIGNING_ALLOWED = NO;
+ };
+ AlwaysPerformSeparateStrip = YES;
+ PackageTypes = (
+ com.apple.package-type.static-library // default
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.wrapper",
- "com.apple.package-type.wrapper.shallow"
- ],
- "IsWrapper" : "YES",
- "Type" : "ProductType",
- "Identifier" : "com.apple.product-type.bundle",
- "IconNamePrefix" : "TargetPlugin"
- },
- {
- "PackageTypes" : [
- "com.apple.package-type.wrapper.shallow"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.bundle",
- "Name" : "Bundle (Shallow)",
- "Identifier" : "com.apple.product-type.bundle.shallow",
- "Description" : "Bundle (Shallow)",
- "Class" : "PBXBundleProductType"
- },
- {
- "Description" : "Application",
- "Class" : "PBXApplicationProductType",
- "Name" : "Application",
- "RunpathSearchPathForEmbeddedFrameworks" : "@executable_path\/..\/Frameworks",
- "ValidateEmbeddedBinaries" : "YES",
- "ProvisioningProfileSupported" : "YES",
- "DefaultTargetName" : "Application",
- "DefaultBuildProperties" : {
- "INSTALL_PATH" : "$(LOCAL_APPS_DIR)",
- "WRAPPER_EXTENSION" : "app",
- "GCC_DYNAMIC_NO_PIC" : "NO",
- "STRIP_STYLE" : "all",
- "CODE_SIGNING_ALLOWED" : "YES",
- "GCC_INLINES_ARE_PRIVATE_EXTERN" : "YES",
- "WRAPPER_SUFFIX" : ".$(WRAPPER_EXTENSION)",
- "GCC_SYMBOLS_PRIVATE_EXTERN" : "YES",
- "MACH_O_TYPE" : "mh_execute"
+
+ // Java library (jar or zip file)
+ { Type = ProductType;
+ Identifier = com.apple.product-type.library.java.archive;
+ Name = "Java Library";
+ Description = "Java library packaged as a Jar file, Zip file, or class folder";
+ IconNamePrefix = "TargetPlugin";
+ DefaultTargetName = "Java Library";
+ DefaultBuildProperties = {
+ FULL_PRODUCT_NAME = "$(PRODUCT_NAME)";
+ INSTALL_PATH = "/usr/local/lib";
+ };
+ IsJava = YES;
+ PackageTypes = (
+ com.apple.package-type.jarfile, // default
+ com.apple.package-type.zipfile,
+ com.apple.package-type.javaclassfolder
+ );
},
- "BasedOn" : "com.apple.product-type.bundle",
- "ProvisioningProfileRequired" : "NO",
- "PackageTypes" : [
- "com.apple.package-type.wrapper.application"
- ],
- "Type" : "ProductType",
- "CanEmbedCompilerSanitizerLibraries" : "YES",
- "Identifier" : "com.apple.product-type.application",
- "IconNamePrefix" : "TargetApp"
- },
- {
- "PackageTypes" : [
- "com.apple.package-type.wrapper.application.shallow"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.application",
- "Name" : "Application (Shallow Bundle)",
- "Identifier" : "com.apple.product-type.application.shallow",
- "Description" : "Application (Shallow Bundle)",
- "Class" : "PBXApplicationProductType"
- },
- {
- "DefaultBuildProperties" : {
- "PKGINFO_PATH" : "",
- "INFOPLIST_PATH" : ""
+
+
+ //
+ // Wrapper product types
+ //
+
+ // Bundle
+ { Type = ProductType;
+ Identifier = com.apple.product-type.bundle;
+ Class = PBXBundleProductType;
+ Name = "Bundle";
+ Description = "Generic bundle";
+ IconNamePrefix = "TargetPlugin";
+ DefaultTargetName = "Bundle";
+ DefaultBuildProperties = {
+ FULL_PRODUCT_NAME = "$(WRAPPER_NAME)";
+ MACH_O_TYPE = "mh_bundle";
+ WRAPPER_PREFIX = "";
+ WRAPPER_SUFFIX = ".$(WRAPPER_EXTENSION)";
+ WRAPPER_EXTENSION = "bundle";
+ WRAPPER_NAME = "$(WRAPPER_PREFIX)$(PRODUCT_NAME)$(WRAPPER_SUFFIX)";
+ FRAMEWORK_FLAG_PREFIX = "-framework";
+ LIBRARY_FLAG_PREFIX = "-l";
+ LIBRARY_FLAG_NOSPACE = YES;
+ STRIP_STYLE = "non-global";
+ GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+ CODE_SIGNING_ALLOWED = YES;
+ };
+ PackageTypes = (
+ com.apple.package-type.wrapper, // default
+ com.apple.package-type.wrapper.shallow // Not clear if this is needed in the presence of the Shallow Bundle product type below.
+ );
+ IsWrapper = YES;
+ HasInfoPlist = YES;
+ HasInfoPlistStrings = YES;
+ WantsBundleIdentifierEditing = YES;
+ WantsSigningEditing = YES;
},
- "IsJava" : "YES",
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.application",
- "Name" : "Java Application",
- "Identifier" : "com.apple.product-type.application.java",
- "Description" : "Java Application",
- "DefaultTargetName" : "Java Application"
- },
- {
- "IconNamePrefix" : "TargetFramework",
- "DefaultTargetName" : "Framework",
- "DefaultBuildProperties" : {
- "CODE_SIGNING_REQUIRES_TEAM" : "YES",
- "LD_DYLIB_INSTALL_NAME" : "$(DYLIB_INSTALL_NAME_BASE:standardizepath)\/$(EXECUTABLE_PATH)",
- "CODE_SIGNING_REQUIRED" : "NO",
- "CODE_SIGNING_ALLOWED" : "YES",
- "INSTALL_PATH" : "$(LOCAL_LIBRARY_DIR)\/Frameworks",
- "WRAPPER_SUFFIX" : ".$(WRAPPER_EXTENSION)",
- "WRAPPER_EXTENSION" : "framework",
- "FRAMEWORK_VERSION" : "A",
- "ENTITLEMENTS_REQUIRED" : "NO",
- "STRIP_STYLE" : "debugging",
- "DYLIB_INSTALL_NAME_BASE" : "$(INSTALL_PATH)",
- "MACH_O_TYPE" : "mh_dylib"
+
+ // Shallow Bundle Product
+ { Type = ProductType;
+ Identifier = com.apple.product-type.bundle.shallow;
+ BasedOn = com.apple.product-type.bundle;
+ Class = PBXBundleProductType;
+ Name = "Bundle (Shallow)";
+ Description = "Bundle (Shallow)";
+ PackageTypes = (
+ com.apple.package-type.wrapper.shallow
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.wrapper.framework"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.bundle",
- "Name" : "Framework",
- "Identifier" : "com.apple.product-type.framework",
- "Description" : "Framework",
- "Class" : "PBXFrameworkProductType"
- },
- {
- "PackageTypes" : [
- "com.apple.package-type.wrapper.framework.shallow"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.framework",
- "Name" : "Framework (Shallow Bundle)",
- "Identifier" : "com.apple.product-type.framework.shallow",
- "Description" : "Framework (Shallow Bundle)",
- "Class" : "PBXFrameworkProductType"
- },
- {
- "IconNamePrefix" : "TargetFramework",
- "DefaultTargetName" : "Static Framework",
- "DefaultBuildProperties" : {
- "WRAPPER_EXTENSION" : "framework",
- "DYLIB_INSTALL_NAME_BASE" : "",
- "CODE_SIGNING_ALLOWED" : "NO",
- "FRAMEWORK_VERSION" : "A",
- "LD_DYLIB_INSTALL_NAME" : "",
- "GCC_INLINES_ARE_PRIVATE_EXTERN" : "NO",
- "INSTALL_PATH" : "$(LOCAL_LIBRARY_DIR)\/Frameworks",
- "WRAPPER_SUFFIX" : ".$(WRAPPER_EXTENSION)",
- "MACH_O_TYPE" : "staticlib"
+
+ // Application
+ { Type = ProductType;
+ Identifier = com.apple.product-type.application;
+ BasedOn = com.apple.product-type.bundle;
+ Class = PBXApplicationProductType;
+ Name = "Application";
+ Description = "Application";
+ IconNamePrefix = "TargetApp";
+ DefaultTargetName = "Application";
+ DefaultBuildProperties = {
+ MACH_O_TYPE = "mh_execute";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+ GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+ WRAPPER_SUFFIX = ".$(WRAPPER_EXTENSION)";
+ WRAPPER_EXTENSION = "app";
+ INSTALL_PATH = "$(LOCAL_APPS_DIR)";
+ STRIP_STYLE = "all";
+ CODE_SIGNING_ALLOWED = YES;
+ LD_RUNPATH_SEARCH_PATHS = "$(LD_RUNPATH_SEARCH_PATHS_$(IS_MACCATALYST))";
+ LD_RUNPATH_SEARCH_PATHS_YES = ( "@loader_path/../Frameworks", );
+ };
+ PackageTypes = (
+ com.apple.package-type.wrapper.application // default
+ );
+
+ /** Product type validation hooks */
+ Validation = {
+
+ // Checks - a dictionary of checks that are perform just prior to building the product
+ // Each dictionary key is the "XCPropertyMacroExpression" to evaluate
+ // The dictionary value contains the error message to display if the condition evaluates to false.
+ Checks = {
+ // This is intentially empty as currently all of the checks are done in-code for this particular application type. However, we enable the plubmbing for the validation tool spec infrastructure to be called to avoid any further hacks in pbxbuild or xcbuild. This is to enable rdar://problem/45590882.
+ };
+
+ // Determines if the legacy build system has support for this validation hook. This is a workaround for enabling additional validation in xcbuild (specifically for rdar://problem/45590882), which does not have the same plugin restriction that is imposed on pbxbuild's implementation of the validation hooks.
+ EnabledForLegacyBuildSystem = NO;
+
+ // ValidationToolSpec - the identifier of the tool (script) to run after a target is constructed.
+ ValidationToolSpec = "com.apple.build-tools.platform.validate";
+ };
+ CanEmbedCompilerSanitizerLibraries = YES;
+ RunpathSearchPathForEmbeddedFrameworks = "@executable_path/../Frameworks";
+ ValidateEmbeddedBinaries = YES;
+ ProvisioningProfileSupported = YES;
+ ProvisioningProfileRequired = NO;
+ WantsBundleIdentifierEditing = YES;
+ WantsSigningEditing = YES;
},
- "AlwaysPerformSeparateStrip" : "YES",
- "PackageTypes" : [
- "com.apple.package-type.wrapper.framework.static"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.framework",
- "Name" : "Static Framework",
- "Identifier" : "com.apple.product-type.framework.static",
- "Description" : "Static Framework",
- "Class" : "XCStaticFrameworkProductType"
- },
- {
- "DefaultTargetName" : "Kernel Extension",
- "DefaultBuildProperties" : {
- "GCC_ENABLE_BUILTIN_FUNCTIONS" : "NO",
- "MODULE_START" : "0",
- "PRIVATE_HEADERS_FOLDER_PATH" : "$(KEXT_FRAMEWORK)\/Contents\/PrivateHeaders\/$(KEXT_FAMILY_NAME)",
- "WRAPPER_SUFFIX" : ".$(WRAPPER_EXTENSION)",
- "MACH_O_TYPE" : "mh_execute",
- "GCC_ENABLE_KERNEL_DEVELOPMENT" : "YES",
- "PRODUCT_TYPE_CPLUSPLUSFLAGS" : "$(inherited) $(KEXT_CPLUSPLUSFLAGS)",
- "MODULE_STOP" : "0",
- "GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS" : "YES",
- "GCC_PRODUCT_TYPE_PREPROCESSOR_DEFINITIONS" : "$(inherited) KERNEL KERNEL_PRIVATE DRIVER_PRIVATE APPLE NeXT",
- "GCC_DISABLE_STATIC_FUNCTION_INLINING" : "YES",
- "ENABLE_APPLE_KEXT_CODE_GENERATION" : "YES",
- "CODE_SIGNING_ALLOWED" : "YES",
- "GCC_FORCE_CPU_SUBTYPE_ALL" : "YES",
- "PRODUCT_SPECIFIC_LDFLAGS" : "$(inherited) $(KEXT_LDFLAGS)",
- "WRAPPER_EXTENSION" : "kext",
- "KERNEL_EXTENSION_HEADER_SEARCH_PATHS" : "$(KERNEL_FRAMEWORK)\/PrivateHeaders $(KERNEL_FRAMEWORK_HEADERS)",
- "GCC_INLINES_ARE_PRIVATE_EXTERN" : "NO",
- "PRODUCT_TYPE_CFLAGS" : "$(inherited) $(KEXT_CFLAGS)",
- "KEXT_FRAMEWORK_NAME" : "Kernel",
- "GCC_NO_COMMON_BLOCKS" : "YES",
- "GCC_ENABLE_PASCAL_STRINGS" : "NO",
- "PUBLIC_HEADERS_FOLDER_PATH" : "$(KEXT_FRAMEWORK)\/Contents\/Headers\/$(KEXT_FAMILY_NAME)",
- "GCC_ENABLE_FUNCTION_INLINING" : "YES",
- "KERNEL_FRAMEWORK_HEADERS" : "$(KERNEL_FRAMEWORK)\/Headers",
- "KEXT_FAMILY_NAME" : "family",
- "KEXT_FRAMEWORK" : "$(SYSTEM_LIBRARY_DIR)\/Frameworks\/$(KEXT_FRAMEWORK_NAME).framework",
- "GCC_ENABLE_CPP_EXCEPTIONS" : "NO",
- "GCC_ENABLE_CPP_RTTI" : "NO",
- "MODULE_NAME" : "com.company.driver.modulename",
- "GCC_USE_STANDARD_INCLUDE_SEARCHING" : "NO",
- "KERNEL_FRAMEWORK" : "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)\/Frameworks\/Kernel.framework",
- "MODULE_VERSION" : "1.0",
- "INSTALL_PATH" : "$(DEFAULT_KEXT_INSTALL_PATH)",
- "PRODUCT_TYPE_HEADER_SEARCH_PATHS" : "$(inherited) $(KERNEL_EXTENSION_HEADER_SEARCH_PATHS)",
- "GCC_CHECK_RETURN_VALUE_OF_OPERATOR_NEW" : "YES",
- "STRIP_STYLE" : "debugging"
+
+ // Shallow Application Product
+ { Type = ProductType;
+ Identifier = com.apple.product-type.application.shallow;
+ BasedOn = com.apple.product-type.application;
+ Class = PBXApplicationProductType; // see radar 5604879, this shouldn't be necesary
+ Name = "Application (Shallow Bundle)";
+ Description = "Application (Shallow Bundle)";
+ PackageTypes = (
+ com.apple.package-type.wrapper.application.shallow
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.wrapper.kernel-extension",
- "com.apple.package-type.wrapper.kernel-extension.shallow"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.bundle",
- "Name" : "Kernel Extension",
- "Identifier" : "com.apple.product-type.kernel-extension",
- "Description" : "Kernel extension",
- "Class" : "XCKernelExtensionProductType"
- },
- {
- "DefaultBuildProperties" : {
+ // Java Application
+ { Type = ProductType;
+ Identifier = com.apple.product-type.application.java;
+ BasedOn = com.apple.product-type.application;
+ Name = "Java Application";
+ Description = "Java Application";
+ DefaultTargetName = "Java Application";
+ DefaultBuildProperties = {
+ INFOPLIST_PATH = "";
+ PKGINFO_PATH = "";
+ };
+ IsJava = YES;
},
- "PackageTypes" : [
- "com.apple.package-type.wrapper.kernel-extension.shallow"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.kernel-extension",
- "Name" : "Kernel Extension (Shallow)",
- "Identifier" : "com.apple.product-type.kernel-extension.shallow",
- "Description" : "Kernel extension (shallow)",
- "Class" : "XCKernelExtensionProductType"
- },
- {
- "DefaultTargetName" : "IOKit Kernel Extension",
- "DefaultBuildProperties" : {
- "CODE_SIGNING_ALLOWED" : "YES"
+
+ // Framework
+ { Type = ProductType;
+ Identifier = com.apple.product-type.framework;
+ BasedOn = com.apple.product-type.bundle;
+ Class = PBXFrameworkProductType;
+ Name = "Framework";
+ Description = "Framework";
+ IconNamePrefix = "TargetFramework";
+ DefaultTargetName = "Framework";
+ DefaultBuildProperties = {
+ MACH_O_TYPE = "mh_dylib";
+ FRAMEWORK_VERSION = "A";
+ WRAPPER_SUFFIX = ".$(WRAPPER_EXTENSION)";
+ WRAPPER_EXTENSION = "framework";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ DYLIB_INSTALL_NAME_BASE = "$(INSTALL_PATH)";
+ LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
+ STRIP_STYLE = "debugging";
+ CODE_SIGNING_ALLOWED = YES;
+ CODE_SIGNING_REQUIRED = NO;
+ ENTITLEMENTS_REQUIRED = NO;
+ CODE_SIGNING_REQUIRES_TEAM = YES;
+ };
+ PackageTypes = (
+ com.apple.package-type.wrapper.framework // default
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.wrapper.kernel-extension",
- "com.apple.package-type.wrapper.kernel-extension.shallow"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.kernel-extension",
- "Name" : "IOKit Kernel Extension",
- "Identifier" : "com.apple.product-type.kernel-extension.iokit",
- "Description" : "IOKit Kernel extension",
- "Class" : "XCKernelExtensionProductType"
- },
- {
- "DefaultTargetName" : "IOKit Kernel Extension (Shallow)",
- "DefaultBuildProperties" : {
+ // Shallow Framework Product
+ { Type = ProductType;
+ Identifier = com.apple.product-type.framework.shallow;
+ BasedOn = com.apple.product-type.framework;
+ Class = PBXFrameworkProductType;
+ Name = "Framework (Shallow Bundle)";
+ Description = "Framework (Shallow Bundle)";
+ PackageTypes = (
+ com.apple.package-type.wrapper.framework.shallow
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.wrapper.kernel-extension.shallow"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.kernel-extension",
- "Name" : "IOKit Kernel Extension (Shallow)",
- "Identifier" : "com.apple.product-type.kernel-extension.iokit.shallow",
- "Description" : "IOKit Kernel extension (Shallow)",
- "Class" : "XCKernelExtensionProductType"
- },
- {
- "DefaultBuildProperties" : {
- "TEST_FRAMEWORK_SEARCH_PATHS" : [
- "$(inherited)",
- "$(PLATFORM_DIR)\/Developer\/Library\/Frameworks"
- ],
- "PRODUCT_SPECIFIC_LDFLAGS" : "-framework XCTest",
- "WRAPPER_EXTENSION" : "xctest",
- "PRODUCT_TYPE_FRAMEWORK_SEARCH_PATHS" : "$(TEST_FRAMEWORK_SEARCH_PATHS)"
+
+ // Static framework
+ { Type = ProductType;
+ Identifier = com.apple.product-type.framework.static;
+ BasedOn = com.apple.product-type.framework;
+ Class = XCStaticFrameworkProductType;
+ Name = "Static Framework";
+ Description = "Static Framework";
+ IconNamePrefix = "TargetFramework";
+ DefaultTargetName = "Static Framework";
+ DefaultBuildProperties = {
+ MACH_O_TYPE = "staticlib";
+ FRAMEWORK_VERSION = "A";
+ WRAPPER_SUFFIX = ".$(WRAPPER_EXTENSION)";
+ WRAPPER_EXTENSION = "framework";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ DYLIB_INSTALL_NAME_BASE = "";
+ LD_DYLIB_INSTALL_NAME = "";
+ GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
+ CODE_SIGNING_ALLOWED = NO;
+ };
+ AlwaysPerformSeparateStrip = YES;
+ PackageTypes = (
+ com.apple.package-type.wrapper.framework.static // default
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.bundle.unit-test"
- ],
- "CanEmbedCompilerSanitizerLibraries" : "YES",
- "IsUnitTest" : "YES",
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.bundle",
- "Name" : "Unit Test Bundle",
- "Identifier" : "com.apple.product-type.bundle.unit-test",
- "Description" : "Unit Test Bundle",
- "Class" : "PBXXCTestBundleProductType"
- },
- {
- "DefaultBuildProperties" : {
- "TEST_FRAMEWORK_SEARCH_PATHS" : [
- "$(inherited)",
- "$(PLATFORM_DIR)\/Developer\/Library\/Frameworks"
- ],
- "PRODUCT_SPECIFIC_LDFLAGS" : "-framework XCTest",
- "WRAPPER_EXTENSION" : "xctest",
- "USES_XCTRUNNER" : "YES",
- "PRODUCT_TYPE_FRAMEWORK_SEARCH_PATHS" : "$(TEST_FRAMEWORK_SEARCH_PATHS)"
+
+ // System extension
+ { Type = ProductType;
+ Identifier = com.apple.product-type.system-extension;
+ BasedOn = com.apple.product-type.bundle;
+ Name = "DriverKit Driver";
+ Description = "DriverKit driver";
+ DefaultTargetName = "DriverKit Driver";
+ DefaultBuildProperties = {
+ MACH_O_TYPE = "mh_execute";
+ WRAPPER_SUFFIX = ".$(WRAPPER_EXTENSION)";
+ WRAPPER_EXTENSION = "systemextension";
+
+ PRODUCT_NAME = "$(PRODUCT_BUNDLE_IDENTIFIER)";
+ };
+ PackageTypes = (
+ com.apple.package-type.wrapper.system-extension,
+ );
+ ProvisioningProfileSupported = YES;
+ ProvisioningProfileRequired = NO;
},
- "PackageTypes" : [
- "com.apple.package-type.bundle.unit-test"
- ],
- "ProvisioningProfileSupported" : "YES",
- "IsUITest" : "YES",
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.bundle.unit-test",
- "Name" : "UI Testing Bundle",
- "Identifier" : "com.apple.product-type.bundle.ui-testing",
- "Description" : "UI Testing Bundle",
- "Class" : "PBXXCTestBundleProductType"
- },
- {
- "DefaultBuildProperties" : {
- "WRAPPER_EXTENSION" : "octest"
+
+ // DriverKit driver
+ { Type = ProductType;
+ Identifier = com.apple.product-type.driver-extension;
+ BasedOn = com.apple.product-type.system-extension;
+ Name = "DriverKit Driver";
+ Description = "DriverKit driver";
+ DefaultTargetName = "DriverKit Driver";
+ DefaultBuildProperties = {
+ SDKROOT = "driverkit";
+ MACH_O_TYPE = "mh_execute";
+ WRAPPER_SUFFIX = ".$(WRAPPER_EXTENSION)";
+ WRAPPER_EXTENSION = "dext";
+ INSTALL_PATH = "$(DEFAULT_DEXT_INSTALL_PATH)";
+ STRIP_STYLE = "debugging";
+
+ DEXT_FRAMEWORK_NAME = "DriverKit";
+ DEXT_FRAMEWORK = "$(SYSTEM_LIBRARY_DIR)/Frameworks/$(DEXT_FRAMEWORK_NAME).framework";
+
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+
+ PRODUCT_NAME = "$(PRODUCT_BUNDLE_IDENTIFIER)";
+ PRODUCT_TYPE_HEADER_SEARCH_PATHS = "$(inherited) $(IIG_HEADERS_DIR)";
+ };
+ DefaultEntitlements = {
+ "com.apple.developer.driverkit" = YES;
+ };
+ PackageTypes = (
+ com.apple.package-type.wrapper.driver-extension,
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.bundle.ocunit-test"
- ],
- "IsUnitTest" : "YES",
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.bundle",
- "Name" : "OCUnit Test Bundle",
- "Identifier" : "com.apple.product-type.bundle.ocunit-test",
- "Description" : "OCUnit Test Bundle",
- "Class" : "PBXBundleProductType"
- },
- {
- "HasInfoPlistStrings" : "NO",
- "PackageTypes" : [
- "com.apple.package-type.in-app-purchase-content"
- ],
- "HasInfoPlist" : "YES",
- "IsWrapper" : "YES",
- "Type" : "ProductType",
- "DefaultBuildProperties" : {
- "FULL_PRODUCT_NAME" : "$(WRAPPER_NAME)"
+
+ // Kernel Extension
+ { Type = ProductType;
+ Identifier = com.apple.product-type.kernel-extension;
+ BasedOn = com.apple.product-type.bundle;
+ Class = XCKernelExtensionProductType;
+ Name = "Kernel Extension";
+ Description = "Kernel extension";
+ DefaultTargetName = "Kernel Extension";
+ DefaultBuildProperties = {
+ MACH_O_TYPE = "mh_execute";
+ WRAPPER_SUFFIX = ".$(WRAPPER_EXTENSION)";
+ WRAPPER_EXTENSION = "kext";
+ INSTALL_PATH = "$(DEFAULT_KEXT_INSTALL_PATH)";
+ STRIP_STYLE = "debugging";
+
+ KEXT_FRAMEWORK_NAME = "Kernel";
+ KEXT_FRAMEWORK = "$(SYSTEM_LIBRARY_DIR)/Frameworks/$(KEXT_FRAMEWORK_NAME).framework";
+ KEXT_FAMILY_NAME = "family";
+ PUBLIC_HEADERS_FOLDER_PATH = "$(KEXT_FRAMEWORK)/Contents/Headers/$(KEXT_FAMILY_NAME)";
+ PRIVATE_HEADERS_FOLDER_PATH = "$(KEXT_FRAMEWORK)/Contents/PrivateHeaders/$(KEXT_FAMILY_NAME)";
+ MODULE_NAME = "com.company.driver.modulename";
+ MODULE_VERSION = "1.0";
+ MODULE_START = "0";
+ MODULE_STOP = "0";
+
+ ENABLE_APPLE_KEXT_CODE_GENERATION = YES; // -fapple-kext
+ GCC_ENABLE_KERNEL_DEVELOPMENT = YES; // -mkernel
+
+ GCC_USE_STANDARD_INCLUDE_SEARCHING = NO; // -nostdinc
+ GCC_ENABLE_PASCAL_STRINGS = NO; // Disables -fpascal-strings
+ GCC_FORCE_CPU_SUBTYPE_ALL = YES; // -force_cpusubtype_ALL
+ GCC_CHECK_RETURN_VALUE_OF_OPERATOR_NEW = YES; // -fcheck-new
+ GCC_INLINES_ARE_PRIVATE_EXTERN = NO; // -fvisibility-inlines-hidden
+ GCC_ENABLE_BUILTIN_FUNCTIONS = NO; // -fno-builtin
+ GCC_NO_COMMON_BLOCKS = YES; // -fno-common
+ GCC_ENABLE_CPP_EXCEPTIONS = NO; // -fno-exceptions
+ GCC_ENABLE_CPP_RTTI = NO; // -fno-rtti
+
+ // Supposedly these two flags are the default in GCC, but they're provided here for compatibility with older Xcode versions.
+ GCC_ENABLE_FUNCTION_INLINING = YES; // -finline
+ GCC_DISABLE_STATIC_FUNCTION_INLINING = YES; // -fno-keep-inline-functions
+
+ // Per-product-type settings.
+ // The KERNEL_*** settings are defined differently for some SDKs, so we continue to use them for compatibility reasons.
+ KERNEL_FRAMEWORK = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework";
+ KERNEL_FRAMEWORK_HEADERS = "$(KERNEL_FRAMEWORK)/Headers";
+ KERNEL_EXTENSION_HEADER_SEARCH_PATHS = "$(KERNEL_FRAMEWORK)/PrivateHeaders $(KERNEL_FRAMEWORK_HEADERS)";
+ // These settings are reserved for use by product types.
+ GCC_PRODUCT_TYPE_PREPROCESSOR_DEFINITIONS = "$(inherited) KERNEL KERNEL_PRIVATE DRIVER_PRIVATE APPLE NeXT";
+ PRODUCT_TYPE_CFLAGS = "$(inherited) $(KEXT_CFLAGS)";
+ PRODUCT_TYPE_CPLUSPLUSFLAGS = "$(inherited) $(KEXT_CPLUSPLUSFLAGS)";
+ PRODUCT_SPECIFIC_LDFLAGS = "$(inherited) $(KEXT_LDFLAGS)";
+ PRODUCT_TYPE_HEADER_SEARCH_PATHS = "$(inherited) $(KERNEL_EXTENSION_HEADER_SEARCH_PATHS)";
+
+ CODE_SIGNING_ALLOWED = YES;
+
+ ARCHS_STANDARD = "arm64e x86_64";
+ ARCHS_STANDARD_64_BIT = "$(ARCHS_STANDARD)";
+ ARCHS_STANDARD_INCLUDING_64_BIT = "$(ARCHS_STANDARD)";
+ };
+ PackageTypes = (
+ com.apple.package-type.wrapper.kernel-extension, // Default
+ com.apple.package-type.wrapper.kernel-extension.shallow,
+ );
+ },
+
+ // Shallow Kernel Extension
+ {
+ Type = ProductType;
+ Identifier = com.apple.product-type.kernel-extension.shallow;
+ BasedOn = com.apple.product-type.kernel-extension;
+ Class = XCKernelExtensionProductType;
+ Name = "Kernel Extension (Shallow)";
+ Description = "Kernel extension (shallow)";
+ DefaultBuildProperties = {
+ // None yet
+ };
+ PackageTypes = (
+ com.apple.package-type.wrapper.kernel-extension.shallow,
+ );
+ },
+
+ // IOKit Kernel Extension
+ { Type = ProductType;
+ Identifier = com.apple.product-type.kernel-extension.iokit;
+ BasedOn = com.apple.product-type.kernel-extension;
+ Class = XCKernelExtensionProductType;
+ Name = "IOKit Kernel Extension";
+ Description = "IOKit Kernel extension";
+ DefaultTargetName = "IOKit Kernel Extension";
+ DefaultBuildProperties = {
+ CODE_SIGNING_ALLOWED = YES;
+ };
+ PackageTypes = (
+ com.apple.package-type.wrapper.kernel-extension, // Default
+ com.apple.package-type.wrapper.kernel-extension.shallow,
+ );
+ },
+
+ // Shallow IOKit Kernel Extension
+ { Type = ProductType;
+ Identifier = com.apple.product-type.kernel-extension.iokit.shallow;
+ BasedOn = com.apple.product-type.kernel-extension;
+ Class = XCKernelExtensionProductType;
+ Name = "IOKit Kernel Extension (Shallow)";
+ Description = "IOKit Kernel extension (Shallow)";
+ DefaultTargetName = "IOKit Kernel Extension (Shallow)";
+ DefaultBuildProperties = {
+ // None yet
+ };
+ PackageTypes = (
+ com.apple.package-type.wrapper.kernel-extension.shallow,
+ );
+ },
+
+ // Unit Test Bundle
+ { Type = ProductType;
+ Identifier = com.apple.product-type.bundle.unit-test;
+ BasedOn = com.apple.product-type.bundle;
+ Class = PBXXCTestBundleProductType;
+ Name = "Unit Test Bundle";
+ Description = "Unit Test Bundle";
+ DefaultBuildProperties = {
+ WRAPPER_EXTENSION = "xctest";
+ ENABLE_TESTING_SEARCH_PATHS = YES;
+ PRODUCT_SPECIFIC_LDFLAGS = "-framework XCTest";
+ XCTRUNNER_PATH = "$(XCTRUNNER_PATH$(TEST_BUILD_STYLE))";
+ LD_RUNPATH_SEARCH_PATHS = "$(LD_RUNPATH_SEARCH_PATHS_$(IS_MACCATALYST))";
+ LD_RUNPATH_SEARCH_PATHS_YES = (
+ "@loader_path/../Frameworks",
+ "@executable_path/../Frameworks",
+ );
+ };
+ PackageTypes = (
+ com.apple.package-type.bundle.unit-test
+ );
+ CanEmbedCompilerSanitizerLibraries = YES;
+ IsUnitTest = YES;
+ WantsBundleIdentifierEditing = NO;
+ },
+
+ // UI Testing Bundle
+ { Type = ProductType;
+ Identifier = com.apple.product-type.bundle.ui-testing;
+ BasedOn = com.apple.product-type.bundle.unit-test;
+ Class = PBXXCTestBundleProductType;
+ Name = "UI Testing Bundle";
+ Description = "UI Testing Bundle";
+ DefaultBuildProperties = {
+ USES_XCTRUNNER = "YES";
+ };
+ PackageTypes = (
+ com.apple.package-type.bundle.unit-test
+ );
+ ProvisioningProfileSupported = YES;
+ IsUITest = YES;
+ InfoPlistAdditions = {
+ XCTContainsUITests = YES;
+ };
+ WantsBundleIdentifierEditing = NO;
},
- "Name" : "In-App Purchase Content",
- "Identifier" : "com.apple.product-type.in-app-purchase-content",
- "Description" : "In-App Purchase Content",
- "Class" : "PBXBundleProductType"
- },
- {
- "IconNamePrefix" : "XPCService",
- "DefaultTargetName" : "XPC Service",
- "CanEmbedCompilerSanitizerLibraries" : "YES",
- "DefaultBuildProperties" : {
- "MACH_O_TYPE" : "mh_execute",
- "WRAPPER_EXTENSION" : "xpc"
+
+ // Legacy OCUnit Test Bundle
+ { Type = ProductType;
+ Identifier = com.apple.product-type.bundle.ocunit-test;
+ BasedOn = com.apple.product-type.bundle;
+ Class = PBXBundleProductType;
+ Name = "OCUnit Test Bundle";
+ Description = "OCUnit Test Bundle";
+ DefaultBuildProperties = {
+ WRAPPER_EXTENSION = "octest";
+ };
+ PackageTypes = (
+ com.apple.package-type.bundle.ocunit-test
+ );
+ IsUnitTest = YES;
+ },
+
+ // In-App Purchase Content
+ { Type = ProductType;
+ Identifier = com.apple.product-type.in-app-purchase-content;
+ Class = PBXBundleProductType;
+ Name = "In-App Purchase Content";
+ Description = "In-App Purchase Content";
+ DefaultBuildProperties = {
+ CODE_SIGNING_ALLOWED = NO;
+ FULL_PRODUCT_NAME = "$(WRAPPER_NAME)";
+ };
+ PackageTypes = (
+ com.apple.package-type.in-app-purchase-content, // default
+ );
+ IsWrapper = YES;
+ HasInfoPlist = YES;
+ HasInfoPlistStrings = NO;
+ },
+
+ // XPC Service
+ {
+ Type = ProductType;
+ Identifier = "com.apple.product-type.xpc-service";
+ BasedOn = "com.apple.product-type.bundle";
+ Class = PBXBundleProductType;
+ Name = "XPC Service";
+ Description = "XPC Service";
+ IconNamePrefix = XPCService;
+ DefaultTargetName = "XPC Service";
+ CanEmbedCompilerSanitizerLibraries = YES;
+ "DefaultBuildProperties" = {
+ "MACH_O_TYPE" = "mh_execute";
+ WRAPPER_EXTENSION = "xpc";
+ LD_RUNPATH_SEARCH_PATHS = "$(LD_RUNPATH_SEARCH_PATHS_$(IS_MACCATALYST)_$(_BOOL_$(SKIP_INSTALL)))";
+ LD_RUNPATH_SEARCH_PATHS_YES_YES = (
+ "@loader_path/../Frameworks",
+ "@loader_path/../../../../Frameworks",
+ );
+ LD_RUNPATH_SEARCH_PATHS_YES_NO = ( "@loader_path/../Frameworks", );
+ };
+ PackageTypes = (
+ "com.apple.package-type.xpc-service",
+ );
+ ProvisioningProfileSupported = YES;
+ ProvisioningProfileRequired = NO;
+ WantsBundleIdentifierEditing = YES;
+ WantsSigningEditing = YES;
+ },
+
+ // PlugIn-Kit PlugIn
+ {
+ Type = ProductType;
+ Identifier = "com.apple.product-type.pluginkit-plugin";
+ BasedOn = "com.apple.product-type.xpc-service";
+ Class = PBXBundleProductType;
+ Name = "PlugInKit PlugIn";
+ Description = "PlugInKit PlugIn";
+ IconNamePrefix = XPCService;
+ DefaultTargetName = "PlugInKit PlugIn";
+ "DefaultBuildProperties" = {
+ "PRODUCT_SPECIFIC_LDFLAGS" = "$(SDKROOT)/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit";
+ WRAPPER_EXTENSION = "pluginkit";
+ };
+ PackageTypes = (
+ "com.apple.package-type.pluginkit-plugin",
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.xpc-service"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.bundle",
- "Name" : "XPC Service",
- "Identifier" : "com.apple.product-type.xpc-service",
- "Description" : "XPC Service",
- "Class" : "PBXBundleProductType"
- },
- {
- "IconNamePrefix" : "XPCService",
- "DefaultTargetName" : "PlugInKit PlugIn",
- "DefaultBuildProperties" : {
- "WRAPPER_EXTENSION" : "pluginkit",
- "PRODUCT_SPECIFIC_LDFLAGS" : "$(SDKROOT)\/System\/Library\/PrivateFrameworks\/PlugInKit.framework\/PlugInKit"
+
+ // App Extension
+ {
+ Type = ProductType;
+ Identifier = "com.apple.product-type.app-extension";
+ BasedOn = "com.apple.product-type.pluginkit-plugin";
+ Class = PBXBundleProductType;
+ Name = "App Extension";
+ Description = "App Extension";
+ IconNamePrefix = AppExtension;
+ DefaultTargetName = "App Extension";
+ "DefaultBuildProperties" = {
+ "CODE_SIGNING_ALLOWED" = YES;
+ "APPLICATION_EXTENSION_API_ONLY" = YES;
+ "PRODUCT_SPECIFIC_LDFLAGS" = "-e _NSExtensionMain";
+ WRAPPER_EXTENSION = "appex";
+ };
+ PackageTypes = (
+ "com.apple.package-type.app-extension",
+ );
+ ProvisioningProfileSupported = YES;
+ ProvisioningProfileRequired = NO;
+ WantsBundleIdentifierEditing = YES;
+ WantsSigningEditing = YES;
},
- "PackageTypes" : [
- "com.apple.package-type.pluginkit-plugin"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.xpc-service",
- "Name" : "PlugInKit PlugIn",
- "Identifier" : "com.apple.product-type.pluginkit-plugin",
- "Description" : "PlugInKit PlugIn",
- "Class" : "PBXBundleProductType"
- },
- {
- "Description" : "App Extension",
- "Class" : "PBXBundleProductType",
- "Name" : "App Extension",
- "ProvisioningProfileSupported" : "YES",
- "DefaultTargetName" : "App Extension",
- "DefaultBuildProperties" : {
- "APPLICATION_EXTENSION_API_ONLY" : "YES",
- "PRODUCT_SPECIFIC_LDFLAGS" : "-e _NSExtensionMain",
- "WRAPPER_EXTENSION" : "appex",
- "CODE_SIGNING_ALLOWED" : "YES"
+
+ // Xcode Extension
+ {
+ Type = ProductType;
+ Identifier = "com.apple.product-type.xcode-extension";
+ BasedOn = "com.apple.product-type.app-extension";
+ Name = "Xcode Extension";
+ Description = "Xcode Extension";
+ IconNamePrefix = XcodeExtension;
+ DefaultTargetName = "Xcode Extension";
+ "DefaultBuildProperties" = {
+ "CODE_SIGNING_ALLOWED" = YES;
+ "APPLICATION_EXTENSION_API_ONLY" = YES;
+ "PRODUCT_SPECIFIC_LDFLAGS" = "-e _XCExtensionMain -lXcodeExtension";
+ "PRODUCT_TYPE_FRAMEWORK_SEARCH_PATHS" = (
+ "$(inherited)",
+ "$(DEVELOPER_FRAMEWORKS_DIR)",
+ );
+ "PRODUCT_TYPE_LIBRARY_SEARCH_PATHS" = (
+ "$(inherited)",
+ "$(DEVELOPER_USR_DIR)/lib",
+ );
+ LD_RUNPATH_SEARCH_PATHS = (
+ "@loader_path/../Frameworks",
+ );
+ WRAPPER_EXTENSION = "appex";
+ };
+ PackageTypes = (
+ "com.apple.package-type.app-extension",
+ );
+ ProvisioningProfileSupported = YES;
+ ProvisioningProfileRequired = NO;
+ WantsBundleIdentifierEditing = YES;
+ WantsSigningEditing = YES;
},
- "BasedOn" : "com.apple.product-type.pluginkit-plugin",
- "ProvisioningProfileRequired" : "NO",
- "PackageTypes" : [
- "com.apple.package-type.app-extension"
- ],
- "Type" : "ProductType",
- "Identifier" : "com.apple.product-type.app-extension",
- "IconNamePrefix" : "AppExtension"
- },
- {
- "Description" : "Xcode Extension",
- "Class" : "PBXBundleProductType",
- "Name" : "Xcode Extension",
- "ProvisioningProfileSupported" : "YES",
- "DefaultTargetName" : "Xcode Extension",
- "DefaultBuildProperties" : {
- "APPLICATION_EXTENSION_API_ONLY" : "YES",
- "PRODUCT_SPECIFIC_LDFLAGS" : "-e _XCExtensionMain -lXcodeExtension -weak_framework XcodeKit",
- "PRODUCT_TYPE_LIBRARY_SEARCH_PATHS" : [
- "$(inherited)",
- "$(DEVELOPER_USR_DIR)\/lib"
- ],
- "CODE_SIGNING_ALLOWED" : "YES",
- "WRAPPER_EXTENSION" : "appex",
- "PRODUCT_TYPE_FRAMEWORK_SEARCH_PATHS" : [
- "$(inherited)",
- "$(DEVELOPER_FRAMEWORKS_DIR)"
- ]
+
+ // Spotlight Importer
+ {
+ Type = ProductType;
+ Identifier = "com.apple.product-type.spotlight-importer";
+ BasedOn = "com.apple.product-type.bundle";
+ Class = PBXBundleProductType;
+ Name = "Spotlight Importer";
+ Description = "Spotlight Importer";
+ DefaultTargetName = "Spotlight";
+ "DefaultBuildProperties" = {
+ "CODE_SIGNING_ALLOWED" = YES;
+ };
+ PackageTypes = (
+ "com.apple.package-type.spotlight-importer",
+ );
},
- "BasedOn" : "com.apple.product-type.app-extension",
- "ProvisioningProfileRequired" : "NO",
- "PackageTypes" : [
- "com.apple.package-type.app-extension"
- ],
- "Type" : "ProductType",
- "Identifier" : "com.apple.product-type.xcode-extension",
- "IconNamePrefix" : "XcodeExtension"
- },
- {
- "DefaultTargetName" : "Spotlight",
- "DefaultBuildProperties" : {
- "CODE_SIGNING_ALLOWED" : "YES"
+
+ // Copied from iOS specs to aid in build system diagnostic support.
+ // Later, we should put these in some central place.
+ {
+ Type = ProductType;
+ Identifier = "com.apple.product-type.app-extension.messages";
+ BasedOn = "com.apple.product-type.app-extension";
+ },
+
+ {
+ Type = ProductType;
+ Identifier = "com.apple.product-type.app-extension.messages-sticker-pack";
+ BasedOn = "com.apple.product-type.app-extension";
+ IsCapabilitiesUnsupported = YES;
+ WantsSimpleTargetEditing = YES;
+ DefaultBuildProperties = {
+ MESSAGES_APPLICATION_EXTENSION_PRODUCT_BINARY_SOURCE_PATH = "$(PLATFORM_DIR)/Library/Application Support/MessagesApplicationExtensionStub/MessagesApplicationExtensionStub";
+ ASSETCATALOG_COMPILER_INCLUDE_STICKER_CONTENT = YES;
+ ASSETCATALOG_COMPILER_TARGET_STICKERS_ICON_ROLE = "extension";
+ ASSETCATALOG_COMPILER_STICKER_PACK_IDENTIFIER_PREFIX = "$(PRODUCT_BUNDLE_IDENTIFIER).sticker-pack.";
+ };
+ AllowedBuildPhases = (
+ "com.apple.buildphase.resources",
+ "com.apple.buildphase.shell-script",
+ );
+ InfoPlistAdditions = {
+ LSApplicationIsStickerProvider = YES;
+ };
+ },
+
+ {
+ Type = ProductType;
+ Identifier = "com.apple.product-type.application.on-demand-install-capable";
+ BasedOn = "com.apple.product-type.application";
+ Name = "App Clip";
+ Description = "App Clip";
+ DefaultBuildProperties = {
+ ENABLE_ON_DEMAND_RESOURCES = NO;
+ ASSETCATALOG_COMPILER_STANDALONE_ICON_BEHAVIOR = none; // Don't include standalone icons to keep size down
+ PRODUCT_SPECIFIC_LDFLAGS = "$(inherited) -framework AppClip";
+ SKIP_INSTALL = YES;
+ };
+ DefaultEntitlements = {
+ "com.apple.developer.on-demand-install-capable" = YES;
+ };
+ SupportsOnDemandResources = NO;
+ IsEmbeddable = YES;
+ BuildPhaseInjectionsWhenEmbedding = (
+ {
+ BuildPhase = "CopyFiles";
+ Name = "Embed App Clips";
+ RunOnlyForDeploymentPostprocessing = NO;
+ DstSubFolderSpec = 16;
+ DstPath = "$(CONTENTS_FOLDER_PATH)/AppClips";
+ }
+ );
},
- "PackageTypes" : [
- "com.apple.package-type.spotlight-importer"
- ],
- "Type" : "ProductType",
- "BasedOn" : "com.apple.product-type.bundle",
- "Name" : "Spotlight Importer",
- "Identifier" : "com.apple.product-type.spotlight-importer",
- "Description" : "Spotlight Importer",
- "Class" : "PBXBundleProductType"
- }
-]
+)
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index 39077bec8..0a959ea8e 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -32,7 +32,7 @@
import qbs.ModUtils
import qbs.Utilities
import qbs.WindowsUtils
-
+import "cpp.js" as Cpp
import "setuprunenv.js" as SetupRunEnv
Module {
@@ -190,6 +190,7 @@ Module {
property string linkerMapSuffix: ".map"
property string compilerListingSuffix: ".lst"
property string assemblerListingSuffix: ".lst"
+ property string resourceSuffix: ".res"
property bool createSymlinks: true
property stringList dynamicLibraries // list of names, will be linked with -lname
property stringList staticLibraries // list of static library files
@@ -204,6 +205,18 @@ Module {
property bool discardUnusedData
property bool removeDuplicateLibraries: true
+ property string defineFlag
+ property string includeFlag
+ property string systemIncludeFlag
+ property string preincludeFlag
+ property string libraryDependencyFlag
+ property string libraryPathFlag
+ property string linkerScriptFlag
+
+ property stringList knownArchitectures: []
+ property var toolchainDetails
+ property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
+
property string linkerMode: "automatic"
PropertyOptions {
name: "linkerMode"
@@ -533,6 +546,13 @@ Module {
return '"' + a + '"'; }).join(", ")
+ ". See https://docs.microsoft.com/en-us/windows/desktop/SysInfo/operating-system-version");
}
+
+ if (knownArchitectures && knownArchitectures.length > 0) {
+ var isSupported = Cpp.supportsArchitecture(qbs.architecture, knownArchitectures);
+ if (!isSupported) {
+ throw ModUtils.ModuleError("Unsupported architecture: '" + qbs.architecture + "'");
+ }
+ }
}
}
diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index 934636849..6f22ef3e2 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -178,7 +178,6 @@ CppModule {
property string toolchainPathPrefix: Gcc.pathPrefix(toolchainInstallPath, toolchainPrefix)
property string binutilsPathPrefix: Gcc.pathPrefix(binutilsPath, toolchainPrefix)
- property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
property string cCompilerName: (qbs.toolchain.contains("clang") ? "clang" : "gcc")
+ compilerExtension
property string cxxCompilerName: (qbs.toolchain.contains("clang") ? "clang++" : "g++")
@@ -205,8 +204,12 @@ CppModule {
property stringList dsymutilFlags
property bool alwaysUseLipo: false
- property string includeFlag: "-I"
- property string systemIncludeFlag: "-isystem"
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-isystem"
+ preincludeFlag: "-include"
+ libraryPathFlag: "-L"
+ linkerScriptFlag: "-T"
readonly property bool shouldCreateSymlinks: {
return createSymlinks && internalVersion && ["macho", "elf"].contains(cpp.imageFormat);
@@ -403,12 +406,14 @@ CppModule {
}
inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary", "dynamiclibrary_import"]
- outputFileTags: [
- "bundle.input",
- "dynamiclibrary", "dynamiclibrary_symlink", "dynamiclibrary_symbols", "debuginfo_dll",
- "debuginfo_bundle","dynamiclibrary_import", "debuginfo_plist",
- "codesign.signed_artifact",
- ]
+ outputFileTags: {
+ var tags = ["bundle.input", "dynamiclibrary", "dynamiclibrary_symlink",
+ "dynamiclibrary_symbols", "debuginfo_dll", "debuginfo_bundle",
+ "dynamiclibrary_import", "debuginfo_plist"];
+ if (shouldSignArtifacts)
+ tags.push("codesign.signed_artifact");
+ return tags;
+ }
outputArtifacts: {
var artifacts = [{
filePath: product.destinationDirectory + "/"
@@ -519,8 +524,13 @@ CppModule {
}
inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"]
- outputFileTags: ["bundle.input", "loadablemodule", "debuginfo_loadablemodule",
- "debuginfo_bundle", "debuginfo_plist", "codesign.signed_artifact"]
+ outputFileTags: {
+ var tags = ["bundle.input", "loadablemodule", "debuginfo_loadablemodule",
+ "debuginfo_bundle", "debuginfo_plist"];
+ if (shouldSignArtifacts)
+ tags.push("codesign.signed_artifact");
+ return tags;
+ }
outputArtifacts: {
var app = {
filePath: FileInfo.joinPaths(product.destinationDirectory,
@@ -559,8 +569,15 @@ CppModule {
}
inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"]
- outputFileTags: ["bundle.input", "application", "debuginfo_app", "debuginfo_bundle",
- "debuginfo_plist", "mem_map", "codesign.signed_artifact"]
+ outputFileTags: {
+ var tags = ["bundle.input", "application", "debuginfo_app", "debuginfo_bundle",
+ "debuginfo_plist"];
+ if (shouldSignArtifacts)
+ tags.push("codesign.signed_artifact");
+ if (generateLinkerMapFile)
+ tags.push("mem_map");
+ return tags;
+ }
outputArtifacts: {
var app = {
filePath: FileInfo.joinPaths(product.destinationDirectory,
diff --git a/share/qbs/modules/cpp/cosmic.js b/share/qbs/modules/cpp/cosmic.js
new file mode 100644
index 000000000..08abe7b6b
--- /dev/null
+++ b/share/qbs/modules/cpp/cosmic.js
@@ -0,0 +1,460 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+var Cpp = require("cpp.js");
+var Environment = require("qbs.Environment");
+var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+var ModUtils = require("qbs.ModUtils");
+var Process = require("qbs.Process");
+var TemporaryDir = require("qbs.TemporaryDir");
+var TextFile = require("qbs.TextFile");
+
+function toolchainDetails(qbs) {
+ var architecture = qbs.architecture;
+ if (architecture.startsWith("arm")) {
+ return {
+ "executableSuffix": ".cxm",
+ "staticLibrarySuffix": ".cxm",
+ "assemblerName": "cacorm",
+ "compilerName": "cxcorm"
+ };
+ } else if (architecture === "stm8") {
+ return {
+ "executableSuffix": ".sm8",
+ "staticLibrarySuffix": ".sm8",
+ "assemblerName": "castm8",
+ "compilerName": "cxstm8"
+ };
+ } else if (architecture === "hcs8") {
+ return {
+ "executableSuffix": ".h08",
+ "staticLibrarySuffix": ".h08",
+ "assemblerName": "ca6808",
+ "compilerName": "cx6808"
+ };
+ } else if (architecture === "hcs12") {
+ return {
+ "executableSuffix": ".h12",
+ "staticLibrarySuffix": ".h12",
+ "assemblerName": "ca6812",
+ "compilerName": "cx6812"
+ };
+ } else if (architecture === "m68k") {
+ return {
+ "executableSuffix": ".332",
+ "staticLibrarySuffix": ".332",
+ "assemblerName": "ca332",
+ "compilerName": "cx332"
+ };
+ }
+}
+
+function guessArchitecture(compilerFilePath) {
+ var baseName = FileInfo.baseName(compilerFilePath);
+ if (baseName === "cxcorm")
+ return "arm";
+ else if (baseName === "cxstm8")
+ return "stm8";
+ else if (baseName === "cx6808")
+ return "hcs8";
+ else if (baseName === "cx6812")
+ return "hcs12";
+ else if (baseName === "cx332")
+ return "m68k";
+}
+
+function dumpMacros(compilerFilePath) {
+ // Note: The COSMIC compiler does not support the predefined
+ // macros dumping. So, we do it with the following trick, where we try
+ // to create and compile a special temporary file and to parse the console
+ // output with the own magic pattern: (""|"key"|"value"|"").
+
+ var outputDirectory = new TemporaryDir();
+ var outputFilePath = FileInfo.fromNativeSeparators(FileInfo.joinPaths(outputDirectory.path(),
+ "dump-macros.c"));
+ var outputFile = new TextFile(outputFilePath, TextFile.WriteOnly);
+ outputFile.writeLine("#define VALUE_TO_STRING(x) #x");
+ outputFile.writeLine("#define VALUE(x) VALUE_TO_STRING(x)");
+ outputFile.writeLine("#define VAR_NAME_VALUE(var) #var VALUE(var)");
+ // The COSMIC compiler defines only one pre-defined macro
+ // (at least nothing is said about other macros in the documentation).
+ var keys = ["__CSMC__"];
+ for (var i in keys) {
+ var key = keys[i];
+ outputFile.writeLine("#if defined (" + key + ")");
+ outputFile.writeLine("#pragma message (VAR_NAME_VALUE(" + key + "))");
+ outputFile.writeLine("#endif");
+ }
+ outputFile.close();
+
+ var process = new Process();
+ process.exec(compilerFilePath, [outputFilePath], false);
+ File.remove(outputFilePath);
+
+ var map = {};
+ // COSMIC compiler use the errors output!
+ process.readStdErr().trim().split(/\r?\n/g).map(function(line) {
+ var match = line.match(/^#message \("(.+)" "(.+)"\)$/);
+ if (match)
+ map[match[1]] = match[2];
+ });
+ return map;
+}
+
+function dumpVersion(compilerFilePath) {
+ var p = new Process();
+ p.exec(compilerFilePath, ["-vers"]);
+ // COSMIC compiler use the errors output!
+ var output = p.readStdErr();
+ var match = output.match(/^COSMIC.+V(\d+)\.?(\d+)\.?(\*|\d+)?/);
+ if (match) {
+ var major = match[1] ? parseInt(match[1], 10) : 0;
+ var minor = match[2] ? parseInt(match[2], 10) : 0;
+ var patch = match[3] ? parseInt(match[3], 10) : 0;
+ return { major: major, minor: minor, patch: patch };
+ }
+}
+
+function guessEndianness(architecture) {
+ // There is no mention of supported endianness in the cosmic compiler.
+ return "big";
+}
+
+function dumpDefaultPaths(compilerFilePath, architecture) {
+ var rootPath = FileInfo.path(compilerFilePath);
+ var includePath;
+ var includePaths = [];
+ if (architecture.startsWith("arm")) {
+ includePath = FileInfo.joinPaths(rootPath, "hcorm");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
+ } else if (architecture === "stm8") {
+ includePath = FileInfo.joinPaths(rootPath, "hstm8");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
+ } else if (architecture === "hcs8") {
+ includePath = FileInfo.joinPaths(rootPath, "h6808");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
+ } else if (architecture === "hcs12") {
+ includePath = FileInfo.joinPaths(rootPath, "h6812");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
+ } else if (architecture === "m68k") {
+ includePath = FileInfo.joinPaths(rootPath, "h332");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
+ }
+
+ var libraryPaths = [];
+ var libraryPath = FileInfo.joinPaths(rootPath, "lib");
+ if (File.exists(libraryPath))
+ libraryPaths.push(libraryPath);
+
+ return {
+ "includePaths": includePaths,
+ "libraryPaths": libraryPaths,
+ }
+}
+
+function detectRelativePath(baseDirectory, filePath) {
+ if (FileInfo.isAbsolutePath(filePath))
+ return FileInfo.relativePath(baseDirectory, filePath);
+ return filePath;
+}
+
+function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = [];
+
+ // Up to 128 include files.
+ args = args.concat(Cpp.collectPreincludePaths(input).map(function(path) {
+ return input.cpp.preincludeFlag + detectRelativePath(product.buildDirectory, path);
+ }));
+
+ // Defines.
+ args = args.concat(Cpp.collectDefines(input).map(function(define) {
+ return input.cpp.defineFlag + detectRelativePath(product.buildDirectory, define);
+ }));
+
+ // Up to 128 include paths.
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + detectRelativePath(product.buildDirectory, path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.systemIncludeFlag + detectRelativePath(product.buildDirectory, path);
+ }));
+
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("+debug");
+
+ var architecture = input.qbs.architecture;
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
+
+ // Warning level flags.
+ switch (input.cpp.warningLevel) {
+ case "none":
+ // Disabled by default.
+ break;
+ case "all":
+ // Highest warning level.
+ args.push("-pw7");
+ break;
+ }
+
+ // C language version flags.
+ if (tag === "c") {
+ var knownValues = ["c99"];
+ var cLanguageVersion = Cpp.languageVersion(
+ input.cpp.cLanguageVersion, knownValues, "C");
+ switch (cLanguageVersion) {
+ case "c99":
+ args.push("-p", "c99");
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Objects output directory.
+ args.push("-co", detectRelativePath(product.buildDirectory,
+ FileInfo.path(outputs.obj[0].filePath)));
+
+ // Listing files generation flag.
+ if (input.cpp.generateCompilerListingFiles) {
+ // Enable listings.
+ args.push("-l");
+ // Listings output directory.
+ args.push("-cl", detectRelativePath(product.buildDirectory,
+ FileInfo.path(outputs.lst[0].filePath)));
+ }
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(product));
+
+ // Input.
+ args.push(detectRelativePath(product.buildDirectory, input.filePath));
+ return args;
+}
+
+function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = [];
+
+ // Up to 128 include paths.
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + detectRelativePath(product.buildDirectory, path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.systemIncludeFlag + detectRelativePath(product.buildDirectory, path);
+ }));
+
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("-xx");
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
+
+ // Listing files generation flag.
+ if (input.cpp.generateAssemblerListingFiles) {
+ args.push("-l");
+ args.push("+l", detectRelativePath(product.buildDirectory, outputs.lst[0].filePath));
+ }
+
+ // Objects output file path.
+ args.push("-o", detectRelativePath(product.buildDirectory, outputs.obj[0].filePath));
+
+ // Input.
+ args.push(detectRelativePath(product.buildDirectory, input.filePath));
+ return args;
+}
+
+function linkerFlags(project, product, inputs, outputs) {
+ var args = [];
+
+ // Library paths.
+ args = args.concat(Cpp.collectLibraryPaths(product).map(function(path) {
+ return product.cpp.libraryPathFlag + detectRelativePath(product.buildDirectory, path);
+ }));
+
+ // Output.
+ args.push("-o", detectRelativePath(product.buildDirectory, outputs.application[0].filePath));
+
+ // Map file generation flag.
+ if (product.cpp.generateLinkerMapFile)
+ args.push("-m", detectRelativePath(product.buildDirectory, outputs.mem_map[0].filePath));
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscEscapableLinkerArguments(product),
+ Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
+
+ // Linker scripts.
+ args = args.concat(Cpp.collectLinkerScriptPaths(inputs).map(function(path) {
+ return product.cpp.linkerScriptFlag + detectRelativePath(product.buildDirectory, path);
+ }));
+
+ // Input objects.
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
+ return detectRelativePath(product.buildDirectory, path);
+ }));
+
+ // Library dependencies (order has matters).
+ args = args.concat(Cpp.collectLibraryDependencies(product).map(function(dep) {
+ return detectRelativePath(product.buildDirectory, dep.filePath);
+ }));
+
+ return args;
+}
+
+function archiverFlags(project, product, inputs, outputs) {
+ var args = ["-cl"];
+
+ // Output.
+ args.push(detectRelativePath(product.buildDirectory, outputs.staticlibrary[0].filePath));
+
+ // Input objects.
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
+ return detectRelativePath(product.buildDirectory, path);
+ }));
+
+ return args;
+}
+
+function createPath(fullPath) {
+ var cmd = new JavaScriptCommand();
+ cmd.fullPath = fullPath;
+ cmd.silent = true;
+ cmd.sourceCode = function() {
+ File.makePath(fullPath);
+ };
+ return cmd;
+}
+
+// It is a workaround to rename the generated object file to the desired name.
+// Reason is that the Cosmic compiler always generates the object files in the
+// format of 'module.o', but we expect it in flexible format, e.g. 'module.c.obj'
+// or 'module.c.o' depending on the cpp.objectSuffix property.
+function renameObjectFile(project, product, inputs, outputs, input, output) {
+ var object = outputs.obj[0];
+ var cmd = new JavaScriptCommand();
+ cmd.newObject = object.filePath;
+ cmd.oldObject = FileInfo.joinPaths(FileInfo.path(object.filePath),
+ object.baseName + ".o");
+ cmd.silent = true;
+ cmd.sourceCode = function() { File.move(oldObject, newObject); };
+ return cmd;
+}
+
+// It is a workaround to rename the generated listing file to the desired name.
+// Reason is that the Cosmic compiler always generates the listing files in the
+// format of 'module.ls', but we expect it in flexible format, e.g. 'module.c.lst'
+// or 'module.c.ls' depending on the cpp.compilerListingSuffix property.
+function renameListingFile(project, product, inputs, outputs, input, output) {
+ var listing = outputs.lst[0];
+ var cmd = new JavaScriptCommand();
+ cmd.newListing = listing.filePath;
+ cmd.oldListing = FileInfo.joinPaths(FileInfo.path(listing.filePath),
+ listing.baseName + ".ls");
+ cmd.silent = true;
+ cmd.sourceCode = function() { File.move(oldListing, newListing); };
+ return cmd;
+}
+
+function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
+
+ // Create output objects path, because the Cosmic doesn't do it.
+ var cmd = createPath(FileInfo.path(outputs.obj[0].filePath));
+ cmds.push(cmd);
+
+ // Create output listing path, because the Cosmic doesn't do it.
+ if (input.cpp.generateCompilerListingFiles) {
+ cmd = createPath(FileInfo.path(outputs.lst[0].filePath));
+ cmds.push(cmd);
+ }
+
+ var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn);
+ cmd = new Command(input.cpp.compilerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmds.push(cmd);
+
+ cmds.push(renameObjectFile(project, product, inputs, outputs, input, output));
+
+ if (input.cpp.generateCompilerListingFiles)
+ cmds.push(renameListingFile(project, product, inputs, outputs, input, output));
+
+ return cmds;
+}
+
+function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
+
+ // Create output objects path, because the Cosmic doesn't do it.
+ var cmd = createPath(FileInfo.path(outputs.obj[0].filePath));
+ cmds.push(cmd);
+
+ // Create output listing path, because the Cosmic doesn't do it.
+ if (input.cpp.generateCompilerListingFiles) {
+ cmd = createPath(FileInfo.path(outputs.lst[0].filePath));
+ cmds.push(cmd);
+ }
+
+ var args = assemblerFlags(project, product, input, outputs, explicitlyDependsOn);
+ cmd = new Command(input.cpp.assemblerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "assembling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmds.push(cmd);
+ return cmds;
+}
+
+function prepareLinker(project, product, inputs, outputs, input, output) {
+ var primaryOutput = outputs.application[0];
+ var args = linkerFlags(project, product, inputs, outputs);
+ var cmd = new Command(product.cpp.linkerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "linking " + primaryOutput.fileName;
+ cmd.highlight = "linker";
+ return [cmd];
+}
+
+function prepareArchiver(project, product, inputs, outputs, input, output) {
+ var args = archiverFlags(project, product, inputs, outputs);
+ var cmd = new Command(product.cpp.archiverPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "linking " + output.fileName;
+ cmd.highlight = "linker";
+ return [cmd];
+}
diff --git a/share/qbs/modules/cpp/cosmic.qbs b/share/qbs/modules/cpp/cosmic.qbs
new file mode 100644
index 000000000..acc744a5b
--- /dev/null
+++ b/share/qbs/modules/cpp/cosmic.qbs
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs 1.0
+import qbs.File
+import qbs.FileInfo
+import qbs.PathTools
+import qbs.Probes
+import qbs.Utilities
+import "cosmic.js" as COSMIC
+import "cpp.js" as Cpp
+
+CppModule {
+ condition: qbs.toolchain && qbs.toolchain.contains("cosmic")
+
+ Probes.BinaryProbe {
+ id: compilerPathProbe
+ condition: !toolchainInstallPath && !_skipAllChecks
+ names: ["cxcorm"]
+ }
+
+ Probes.CosmicProbe {
+ id: cosmicProbe
+ condition: !_skipAllChecks
+ compilerFilePath: compilerPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
+ }
+
+ qbs.architecture: cosmicProbe.found ? cosmicProbe.architecture : original
+ qbs.targetPlatform: "none"
+
+ compilerVersionMajor: cosmicProbe.versionMajor
+ compilerVersionMinor: cosmicProbe.versionMinor
+ compilerVersionPatch: cosmicProbe.versionPatch
+ endianness: cosmicProbe.endianness
+
+ compilerDefinesByLanguage: cosmicProbe.compilerDefinesByLanguage
+ compilerIncludePaths: cosmicProbe.includePaths
+
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
+
+ /* Work-around for QtCreator which expects these properties to exist. */
+ property string cCompilerName: compilerName
+ property string cxxCompilerName: compilerName
+
+ compilerName: toolchainDetails.compilerName + compilerExtension
+ compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
+
+ assemblerName: toolchainDetails.assemblerName + compilerExtension
+ assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
+
+ linkerName: "clnk" + compilerExtension
+ linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+
+ property string archiverName: "clib" + compilerExtension
+ property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
+
+ runtimeLibrary: "static"
+
+ staticLibrarySuffix: toolchainDetails.staticLibrarySuffix
+ executableSuffix: toolchainDetails.executableSuffix
+
+ property string objectSuffix: ".o"
+
+ imageFormat: "cosmic"
+
+ enableExceptions: false
+ enableRtti: false
+
+ defineFlag: "-d"
+ includeFlag: "-i"
+ systemIncludeFlag: "-i"
+ preincludeFlag: "-ph"
+ libraryDependencyFlag: ""
+ libraryPathFlag: "-l"
+ linkerScriptFlag: ""
+
+ toolchainDetails: COSMIC.toolchainDetails(qbs)
+
+ knownArchitectures: ["arm", "hcs12", "hcs8", "m68k", "stm8"]
+
+ Rule {
+ id: assembler
+ inputs: ["asm"]
+ outputFileTags: Cpp.assemblerOutputTags(generateAssemblerListingFiles)
+ outputArtifacts: Cpp.assemblerOutputArtifacts(input)
+ prepare: COSMIC.prepareAssembler.apply(COSMIC, arguments)
+ }
+
+ FileTagger {
+ patterns: ["*.s"]
+ fileTags: ["asm"]
+ }
+
+ Rule {
+ id: compiler
+ inputs: ["cpp", "c"]
+ auxiliaryInputs: ["hpp"]
+ outputFileTags: Cpp.compilerOutputTags(generateCompilerListingFiles)
+ outputArtifacts: Cpp.compilerOutputArtifacts(input)
+ prepare: COSMIC.prepareCompiler.apply(COSMIC, arguments)
+ }
+
+ Rule {
+ id: applicationLinker
+ multiplex: true
+ inputs: ["obj", "linkerscript"]
+ inputsFromDependencies: ["staticlibrary"]
+ outputFileTags: Cpp.applicationLinkerOutputTags(generateLinkerMapFile)
+ outputArtifacts: Cpp.applicationLinkerOutputArtifacts(product)
+ prepare: COSMIC.prepareLinker.apply(COSMIC, arguments)
+ }
+
+ Rule {
+ id: staticLibraryLinker
+ multiplex: true
+ inputs: ["obj"]
+ inputsFromDependencies: ["staticlibrary"]
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
+ prepare: COSMIC.prepareArchiver.apply(COSMIC, arguments)
+ }
+}
diff --git a/share/qbs/modules/cpp/cpp.js b/share/qbs/modules/cpp/cpp.js
index 0e440bdb0..9563a5c84 100644
--- a/share/qbs/modules/cpp/cpp.js
+++ b/share/qbs/modules/cpp/cpp.js
@@ -28,6 +28,12 @@
**
****************************************************************************/
+var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+var ModUtils = require("qbs.ModUtils");
+var PathTools = require("qbs.PathTools");
+var Utilities = require("qbs.Utilities");
+
function languageVersion(versionArray, knownValues, lang) {
if (!versionArray)
return undefined;
@@ -44,3 +50,375 @@ function languageVersion(versionArray, knownValues, lang) {
+ "' from list of unknown " + lang + " version strings (" + versions + ")");
return version;
}
+
+function extractMacros(output) {
+ var m = {};
+ output.trim().split(/\r?\n/g).map(function (line) {
+ var prefix = "#define ";
+ if (!line.startsWith(prefix))
+ return;
+ var index = line.indexOf(" ", prefix.length);
+ if (index !== -1)
+ m[line.substr(prefix.length, index - prefix.length)] = line.substr(index + 1);
+ });
+ return m;
+}
+
+function relativePath(baseDirectory, filePath) {
+ if (FileInfo.isAbsolutePath(filePath))
+ return FileInfo.relativePath(baseDirectory, filePath);
+ return filePath;
+}
+
+function assemblerOutputTags(needsListingFiles) {
+ var tags = ["obj"];
+ if (needsListingFiles)
+ tags.push("lst");
+ return tags;
+}
+
+function compilerOutputTags(needsListingFiles) {
+ var tags = ["obj"];
+ if (needsListingFiles)
+ tags.push("lst");
+ return tags;
+}
+
+function applicationLinkerOutputTags(needsLinkerMapFile) {
+ var tags = ["application"];
+ if (needsLinkerMapFile)
+ tags.push("mem_map");
+ return tags;
+}
+
+function dynamicLibraryLinkerOutputTags() {
+ return ["dynamiclibrary", "dynamiclibrary_import"];
+}
+
+function staticLibraryLinkerOutputTags() {
+ return ["staticlibrary"];
+}
+
+function resourceCompilerOutputTags() {
+ return ["res"];
+}
+
+function assemblerOutputArtifacts(input) {
+ var artifacts = [];
+ artifacts.push({
+ fileTags: ["obj"],
+ filePath: Utilities.getHash(input.baseDir) + "/"
+ + input.fileName + input.cpp.objectSuffix
+ });
+ if (input.cpp.generateAssemblerListingFiles) {
+ artifacts.push({
+ fileTags: ["lst"],
+ filePath: Utilities.getHash(input.baseDir) + "/"
+ + input.fileName + input.cpp.assemblerListingSuffix
+ });
+ }
+ return artifacts;
+}
+
+function compilerOutputArtifacts(input) {
+ var artifacts = [];
+ artifacts.push({
+ fileTags: ["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 + input.cpp.compilerListingSuffix
+ });
+ }
+ return artifacts;
+}
+
+function applicationLinkerOutputArtifacts(product) {
+ var artifacts = [{
+ fileTags: ["application"],
+ filePath: FileInfo.joinPaths(
+ product.destinationDirectory,
+ PathTools.applicationFilePath(product))
+ }];
+ if (product.cpp.generateLinkerMapFile) {
+ artifacts.push({
+ fileTags: ["mem_map"],
+ filePath: FileInfo.joinPaths(
+ product.destinationDirectory,
+ product.targetName + product.cpp.linkerMapSuffix)
+ });
+ }
+ return artifacts;
+}
+
+function dynamicLibraryLinkerOutputArtifacts(product) {
+ return [{
+ fileTags: ["dynamiclibrary"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.dynamicLibraryFilePath(product))
+ }, {
+ fileTags: ["dynamiclibrary_import"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.importLibraryFilePath(product)),
+ alwaysUpdated: false
+ }];
+}
+
+function staticLibraryLinkerOutputArtifacts(product) {
+ return [{
+ fileTags: ["staticlibrary"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.staticLibraryFilePath(product))
+ }];
+}
+
+function resourceCompilerOutputArtifacts(input) {
+ return [{
+ fileTags: ["res"],
+ filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir),
+ input.completeBaseName + input.cpp.resourceSuffix)
+ }];
+}
+
+function collectLibraryDependencies(product) {
+ var seen = {};
+ var result = [];
+
+ function addFilePath(filePath, wholeArchive, productName) {
+ result.push({ filePath: filePath, wholeArchive: wholeArchive, productName: productName });
+ }
+
+ function addArtifactFilePaths(dep, artifacts) {
+ if (!artifacts)
+ return;
+ var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
+ var wholeArchive = dep.parameters.cpp && dep.parameters.cpp.linkWholeArchive;
+ var artifactsAreImportLibs = artifacts.length > 0
+ && artifacts[0].fileTags.contains("dynamiclibrary_import");
+ for (var i = 0; i < artifactFilePaths.length; ++i) {
+ addFilePath(artifactFilePaths[i], wholeArchive,
+ artifactsAreImportLibs ? dep.name : undefined);
+ }
+ }
+
+ function addExternalLibs(obj) {
+ if (!obj.cpp)
+ return;
+ function ensureArray(a) {
+ return (a instanceof Array) ? a : [];
+ }
+ function sanitizedModuleListProperty(obj, moduleName, propertyName) {
+ return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
+ }
+ var externalLibs = [].concat(
+ sanitizedModuleListProperty(obj, "cpp", "staticLibraries"),
+ sanitizedModuleListProperty(obj, "cpp", "dynamicLibraries"));
+ var libSuffix = obj.moduleProperty("cpp", "staticLibrarySuffix");
+ externalLibs.forEach(function(libName) {
+ if (!libName.endsWith(libSuffix) && !libName.startsWith('@'))
+ libName += libSuffix;
+ addFilePath(libName);
+ });
+ }
+
+ function traverse(dep) {
+ if (seen.hasOwnProperty(dep.name))
+ return;
+ if (dep.parameters.cpp && dep.parameters.cpp.link === false)
+ return;
+
+ var staticLibraryArtifacts = dep.artifacts["staticlibrary"];
+ var dynamicLibraryArtifacts = staticLibraryArtifacts
+ ? null : dep.artifacts["dynamiclibrary_import"];
+ if (staticLibraryArtifacts) {
+ seen[dep.name] = true;
+ dep.dependencies.forEach(traverse);
+ addArtifactFilePaths(dep, staticLibraryArtifacts);
+ addExternalLibs(dep);
+ } else if (dynamicLibraryArtifacts) {
+ seen[dep.name] = true;
+ addArtifactFilePaths(dep, dynamicLibraryArtifacts);
+ }
+ }
+
+ product.dependencies.forEach(traverse);
+ addExternalLibs(product);
+ return result;
+}
+
+function collectAbsoluteLibraryDependencyPaths(product) {
+ var paths = collectLibraryPaths(product);
+ var deps = collectLibraryDependencies(product);
+ return deps.map(function(dep) {
+ var filePath = dep.filePath;
+ if (FileInfo.isAbsolutePath(filePath))
+ return filePath;
+ for (var i = 0; i < paths.length; ++i) {
+ var fullPath = FileInfo.joinPaths(paths[i], filePath);
+ if (File.exists(fullPath))
+ return fullPath;
+ }
+ return filePath;
+ });
+}
+
+function collectDefines(input) {
+ var allDefines = [];
+ var platformDefines = input.cpp.platformDefines;
+ if (platformDefines)
+ allDefines = allDefines.uniqueConcat(platformDefines);
+ var defines = input.cpp.defines;
+ if (defines)
+ allDefines = allDefines.uniqueConcat(defines);
+ return allDefines;
+}
+
+function collectIncludePaths(input) {
+ var allIncludePaths = [];
+ var includePaths = input.cpp.includePaths;
+ if (includePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
+ return allIncludePaths;
+}
+
+function collectSystemIncludePaths(input) {
+ var allIncludePaths = [];
+ var systemIncludePaths = input.cpp.systemIncludePaths;
+ if (systemIncludePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
+ var distributionIncludePaths = input.cpp.distributionIncludePaths;
+ if (distributionIncludePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(distributionIncludePaths);
+ return allIncludePaths;
+}
+
+function collectPreincludePaths(input) {
+ return input.cpp.prefixHeaders;
+}
+
+function collectLibraryPaths(product) {
+ var allLibraryPaths = [];
+ var libraryPaths = product.cpp.libraryPaths;
+ if (libraryPaths)
+ allLibraryPaths = allLibraryPaths.uniqueConcat(libraryPaths);
+ var distributionLibraryPaths = product.cpp.distributionLibraryPaths;
+ if (distributionLibraryPaths)
+ allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths);
+ return allLibraryPaths;
+}
+
+function collectLinkerScriptPaths(inputs) {
+ return inputs.linkerscript
+ ? inputs.linkerscript.map(function(script) { return script.filePath; })
+ : [];
+}
+
+function collectLinkerObjectPaths(inputs) {
+ return inputs.obj ? inputs.obj.map(function(obj) { return obj.filePath; }) : [];
+}
+
+function collectResourceObjectPaths(inputs) {
+ return inputs.res ? inputs.res.map(function(res) { return res.filePath; }) : [];
+}
+
+function collectLibraryDependenciesArguments(product) {
+ var deps = collectLibraryDependencies(product);
+ return deps.map(function(dep) { return product.cpp.libraryDependencyFlag + dep.filePath })
+}
+
+function collectDefinesArguments(input) {
+ var defines = collectDefines(input);
+ return defines.map(function(define) { return input.cpp.defineFlag + define });
+}
+
+function collectIncludePathsArguments(input) {
+ var paths = collectIncludePaths(input);
+ return paths.map(function(path) { return input.cpp.includeFlag + path });
+}
+
+function collectSystemIncludePathsArguments(input, flag) {
+ flag = (flag === undefined) ? input.cpp.systemIncludeFlag : flag;
+ var paths = collectSystemIncludePaths(input);
+ return paths.map(function(path) { return flag + path });
+}
+
+function collectPreincludePathsArguments(input, split) {
+ var paths = collectPreincludePaths(input);
+ if (split) {
+ var args = [];
+ for (var i = 0; i < paths.length; ++i)
+ args.push(input.cpp.preincludeFlag, paths[i]);
+ return args;
+ } else {
+ return paths.map(function(path) { return input.cpp.preincludeFlag + path });
+ }
+}
+
+function collectLibraryPathsArguments(product, flag) {
+ flag = (flag === undefined) ? product.cpp.libraryPathFlag : flag;
+ var paths = collectLibraryPaths(product);
+ return paths.map(function(path) { return flag + path });
+}
+
+function collectLinkerScriptPathsArguments(product, inputs, split, flag) {
+ flag = (flag === undefined) ? product.cpp.linkerScriptFlag : flag;
+ var paths = collectLinkerScriptPaths(inputs);
+ if (split) {
+ var args = [];
+ for (var i = 0; i < paths.length; ++i)
+ args.push(flag, paths[i]);
+ return args;
+ } else {
+ return paths.map(function(path) { return flag + path });
+ }
+}
+
+function collectLinkerObjectPathsArguments(product, inputs, flag) {
+ flag = (flag === undefined) ? "" : flag;
+ var paths = collectLinkerObjectPaths(product);
+ return paths.map(function(path) { return flag + path });
+}
+
+function collectMiscCompilerArguments(input, tag) {
+ return [].concat(ModUtils.moduleProperty(input, "platformFlags"),
+ ModUtils.moduleProperty(input, "flags"),
+ ModUtils.moduleProperty(input, "platformFlags", tag),
+ ModUtils.moduleProperty(input, "flags", tag));
+}
+
+function collectMiscAssemblerArguments(input, tag) {
+ return [].concat(ModUtils.moduleProperty(input, "platformFlags", tag),
+ ModUtils.moduleProperty(input, "flags", tag));
+}
+
+function collectMiscDriverArguments(config) {
+ return [].concat(ModUtils.moduleProperty(config, "platformDriverFlags"),
+ ModUtils.moduleProperty(config, "driverFlags"),
+ ModUtils.moduleProperty(config, "targetDriverFlags"));
+}
+
+function collectMiscLinkerArguments(product) {
+ return [].concat(ModUtils.moduleProperty(product, "driverLinkerFlags"));
+}
+
+function collectMiscEscapableLinkerArguments(product) {
+ return [].concat(ModUtils.moduleProperty(product, "platformLinkerFlags"),
+ ModUtils.moduleProperty(product, "linkerFlags"));
+}
+
+function supportsArchitecture(architecture, knownArchitectures) {
+ for (var i = 0; i < knownArchitectures.length; ++i) {
+ if (architecture.startsWith("arm")) {
+ if (architecture.startsWith(knownArchitectures[i]))
+ return true;
+ } else {
+ if (architecture === knownArchitectures[i])
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/share/qbs/modules/cpp/darwin.js b/share/qbs/modules/cpp/darwin.js
index 98497a050..e4f740dbe 100644
--- a/share/qbs/modules/cpp/darwin.js
+++ b/share/qbs/modules/cpp/darwin.js
@@ -172,25 +172,8 @@ function prepareLipo(project, product, inputs, outputs, input, output) {
commands.push(cmd);
}
- var debugInfo = outputs.debuginfo_app || outputs.debuginfo_dll
- || outputs.debuginfo_loadablemodule;
- if (debugInfo) {
- var dsymPath = debugInfo[0].filePath;
- if (outputs.debuginfo_bundle && outputs.debuginfo_bundle[0])
- dsymPath = outputs.debuginfo_bundle[0].filePath;
- var flags = ModUtils.moduleProperty(product, "dsymutilFlags") || [];
- var files = outputs.primary.map(function (f) { return f.filePath; });
- cmd = new Command(ModUtils.moduleProperty(product, "dsymutilPath"), flags.concat([
- "-o", dsymPath
- ]).concat(files));
- cmd.description = "generating dSYM for " + product.name;
- commands.push(cmd);
-
- // strip debug info
- cmd = new Command(ModUtils.moduleProperty(product, "stripPath"), ["-S"].concat(files));
- cmd.silent = true;
- commands.push(cmd);
- }
+ commands = commands.concat(
+ Gcc.separateDebugInfoCommandsDarwin(product, outputs, outputs.primary));
if (outputs.dynamiclibrary_symbols)
Array.prototype.push.apply(commands, Gcc.createSymbolCheckingCommands(product, outputs));
diff --git a/share/qbs/modules/cpp/dmc.js b/share/qbs/modules/cpp/dmc.js
new file mode 100644
index 000000000..7303c67fc
--- /dev/null
+++ b/share/qbs/modules/cpp/dmc.js
@@ -0,0 +1,462 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+var Cpp = require("cpp.js");
+var Environment = require("qbs.Environment");
+var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+var ModUtils = require("qbs.ModUtils");
+var Process = require("qbs.Process");
+var TemporaryDir = require("qbs.TemporaryDir");
+var TextFile = require("qbs.TextFile");
+var Utilities = require("qbs.Utilities");
+
+function dumpMacros(compilerFilePath, tag) {
+ // Note: The DMC compiler does not support the predefined/ macros dumping. So, we do it
+ // with the following trick, where we try to create and compile a special temporary file
+ // and to parse the console output with the own magic pattern: #define <key> <value>.
+
+ var outputDirectory = new TemporaryDir();
+ var outputFilePath = FileInfo.joinPaths(outputDirectory.path(), "dump-macros.c");
+ var outputFile = new TextFile(outputFilePath, TextFile.WriteOnly);
+ outputFile.writeLine("#define VALUE_TO_STRING(x) #x");
+ outputFile.writeLine("#define VALUE(x) VALUE_TO_STRING(x)");
+ outputFile.writeLine("#define VAR_NAME_VALUE(var) \"#define \" #var\" \"VALUE(var)");
+ // Declare all available pre-defined macros of DMC compiler.
+ var keys = [
+ // Prepare the DOS target macros.
+ "_MSDOS", "MSDOS",
+ // Prepare the OS/2 target macros.
+ "__OS2__",
+ "WIN32", "_WIN32",
+ // Prepare extended the 32 and 16 bit DOS target macros.
+ "DOS386", "DOS16RM",
+ // Prepare the memory model macros.
+ "M_I86", "_M_I86",
+ "_M_I86TM", "M_I86TM",
+ "_M_I86SM", "M_I86SM",
+ "_M_I86MM", "M_I86MM",
+ "_M_I86CM", "M_I86CM",
+ "_M_I86LM", "M_I86LM",
+ "_M_I86VM", "M_I86VM",
+ // Prepare 8086 macros.
+ "_M_I8086", "M_I8086",
+ // Prepare 286 macros.
+ "_M_I286", "M_I286",
+ // Prepare 32 bit macros.
+ "_M_IX86",
+ // Prepare compiler identification macros.
+ "__DMC__", "__DMC_VERSION_STRING__",
+ // Prepare common compiler macros.
+ "_CHAR_UNSIGNED", "_CHAR_EQ_UCHAR", "_DEBUG_TRACE", "_DLL",
+ "_ENABLE_ARRAYNEW", "_BOOL_DEFINED", "_WCHAR_T_DEFINED",
+ "_CPPRTTI", "_CPPUNWIND", "_MD", "_PUSHPOP_SUPPORTED",
+ "_STDCALL_SUPPORTED", "__INTSIZE", "__DEFALIGN", "_INTEGRAL_MAX_BITS",
+ "_WINDOWS", "_WINDLL", "__INLINE_8087", "__I86__", "__SMALL__",
+ "__MEDIUM__", "__COMPACT__", "__LARGE__", "__VCM__", "__FPCE__",
+ "__FPCE__IEEE__", "DEBUG",
+ // Prepare C99 and C++98 macros.
+ "__STDC__", "__STDC_HOSTED__", "__STDC_VERSION__", "__STDC_IEC_559__",
+ "__STDC_IEC_559_COMPLEX__", "__STDC_ISO_10646__", "__cplusplus"
+ ];
+ for (var i = 0; i < keys.length; ++i) {
+ var key = keys[i];
+ outputFile.writeLine("#if defined (" + key + ")");
+ outputFile.writeLine("#pragma message (VAR_NAME_VALUE(" + key + "))");
+ outputFile.writeLine("#endif");
+ }
+ outputFile.close();
+
+ var process = new Process();
+ process.setWorkingDirectory(outputDirectory.path());
+ var args = ["-c"].concat((tag === "cpp") ? ["-cpp"] : [],
+ FileInfo.toWindowsSeparators(outputFilePath));
+ process.exec(compilerFilePath, args, false);
+ File.remove(outputFilePath);
+ var out = process.readStdOut();
+ return Cpp.extractMacros(out);
+}
+
+function dumpDefaultPaths(compilerFilePath, tag) {
+ var binPath = FileInfo.path(compilerFilePath);
+ var rootPath = FileInfo.path(binPath);
+ var includePaths = [];
+ var cppIncludePath = FileInfo.joinPaths(rootPath, "stlport/stlport");
+ if (File.exists(cppIncludePath))
+ includePaths.push(cppIncludePath);
+ var cIncludePath = FileInfo.joinPaths(rootPath, "include");
+ if (File.exists(cIncludePath))
+ includePaths.push(cIncludePath);
+
+ var libraryPaths = [];
+ var libraryPath = FileInfo.joinPaths(rootPath, "lib");
+ if (File.exists(libraryPath))
+ libraryPaths.push(libraryPath);
+
+ return {
+ "includePaths": includePaths,
+ "libraryPaths": libraryPaths,
+ }
+}
+
+function guessVersion(macros) {
+ var version = macros["__DMC__"];
+ return { major: parseInt(version / 100),
+ minor: parseInt(version % 100),
+ patch: 0 };
+}
+
+function effectiveLinkerPath(product) {
+ if (product.cpp.linkerMode === "automatic") {
+ var compilerPath = product.cpp.compilerPath;
+ if (compilerPath)
+ return compilerPath;
+ console.log("Found no C-language objects, choosing system linker for " + product.name);
+ }
+ return product.cpp.linkerPath;
+}
+
+function useCompilerDriverLinker(product) {
+ var linker = effectiveLinkerPath(product);
+ var compilers = product.cpp.compilerPathByLanguage;
+ if (compilers)
+ return linker === compilers["cpp"] || linker === compilers["c"];
+ return linker === product.cpp.compilerPath;
+}
+
+function depsOutputTags() {
+ return ["dep"];
+}
+
+function depsOutputArtifacts(input, product) {
+ return [{
+ fileTags: depsOutputTags(),
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ input.baseName + ".dep")
+ }];
+}
+
+function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = ["-c"];
+
+ // Input.
+ args.push(FileInfo.toWindowsSeparators(input.filePath));
+ // Output.
+ args.push("-o" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath));
+ // Preinclude headers.
+ args = args.concat(Cpp.collectPreincludePaths(input).map(function(path) {
+ return input.cpp.preincludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Defines.
+ args = args.concat(Cpp.collectDefinesArguments(input));
+
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
+ if (tag === "cpp") {
+ // We need to add the paths to the STL includes, because the DMC compiler does
+ // not handle it by default (because the STL libraries is a separate port).
+ var compilerIncludePaths = input.cpp.compilerIncludePaths || [];
+ args = args.concat(compilerIncludePaths.map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+ }
+
+ // Other includes.
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.systemIncludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("-d");
+
+ // Optimization flags.
+ switch (input.cpp.optimization) {
+ case "small":
+ args.push("-o+space");
+ break;
+ case "fast":
+ args.push("-o+speed");
+ break;
+ case "none":
+ args.push("-o+none");
+ break;
+ }
+
+ // Warning level flags.
+ switch (input.cpp.warningLevel) {
+ case "none":
+ args.push("-w");
+ break;
+ case "all":
+ args.push("-w-");
+ break;
+ }
+ if (input.cpp.treatWarningsAsErrors)
+ args.push("-wx");
+
+ if (tag === "cpp") {
+ args.push("-cpp");
+
+ // Exceptions flag.
+ if (input.cpp.enableExceptions)
+ args.push("-Ae");
+
+ // RTTI flag.
+ var enableRtti = input.cpp.enableRtti;
+ if (input.cpp.enableRtti)
+ args.push("-Ar");
+ }
+
+ // Listing files generation flag.
+ if (input.cpp.generateCompilerListingFiles) {
+ // We need to use the relative path here, because the DMC compiler does not handle
+ // a long file path for this option.
+ var listingPath = Cpp.relativePath(product.buildDirectory, outputs.lst[0].filePath);
+ args.push("-l" + FileInfo.toWindowsSeparators(listingPath));
+ }
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(product));
+ return args;
+}
+
+function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = ["-c"];
+
+ // Input.
+ args.push(FileInfo.toWindowsSeparators(input.filePath));
+ // Output.
+ args.push("-o" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath));
+ // Preinclude headers.
+ args = args.concat(Cpp.collectPreincludePaths(input).map(function(path) {
+ return input.cpp.preincludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Defines.
+ args = args.concat(Cpp.collectDefinesArguments(input));
+
+ // Other includes.
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.systemIncludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
+ return args;
+}
+
+function linkerFlags(project, product, inputs, outputs) {
+ var args = [];
+
+ var useCompilerDriver = useCompilerDriverLinker(product);
+ if (useCompilerDriver) {
+ // Input objects.
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
+ return FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Input resources.
+ args = args.concat(Cpp.collectResourceObjectPaths(inputs).map(function(path) {
+ return FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Input libraries.
+ args = args.concat(Cpp.collectAbsoluteLibraryDependencyPaths(product).map(function(path) {
+ return FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Output.
+ if (product.type.contains("application")) {
+ args.push("-o" + FileInfo.toWindowsSeparators(outputs.application[0].filePath));
+ args.push("-WA");
+ args.push("/SUBSYSTEM:" + (product.consoleApplication ? "CONSOLE" : "WINDOWS"));
+ } else if (product.type.contains("dynamiclibrary")) {
+ args.push("-o" + FileInfo.toWindowsSeparators(outputs.dynamiclibrary[0].filePath));
+ args.push("-WD");
+ }
+
+ if (product.cpp.debugInformation)
+ args.push("/DEBUG");
+
+ args.push("/NOLOGO", "/SILENT");
+ }
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscEscapableLinkerArguments(product),
+ Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
+ return args;
+}
+
+function archiverFlags(project, product, inputs, outputs) {
+ var args = ["-c"];
+ // Output.
+ args.push(FileInfo.toWindowsSeparators(outputs.staticlibrary[0].filePath));
+ // Input objects.
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
+ return FileInfo.toWindowsSeparators(path);
+ }));
+ return args;
+}
+
+function rccCompilerFlags(project, product, input, outputs) {
+ // Input.
+ var args = [FileInfo.toWindowsSeparators(input.filePath)];
+ // Output.
+ args.push("-o" + FileInfo.toWindowsSeparators(outputs.res[0].filePath));
+ // Bitness.
+ args.push("-32");
+
+ // Defines
+ args = args.concat(Cpp.collectDefinesArguments(input));
+
+ // Other includes.
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.systemIncludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+ return args;
+}
+
+function buildLinkerMapFilePath(target, suffix) {
+ return FileInfo.joinPaths(FileInfo.path(target.filePath),
+ FileInfo.completeBaseName(target.fileName) + suffix);
+}
+
+// It is a workaround which removes the generated linker map file if it is disabled
+// by cpp.generateLinkerMapFile property. Reason is that the DMC 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) {
+ var target = outputs.dynamiclibrary ? outputs.dynamiclibrary[0]
+ : outputs.application[0];
+ var cmd = new JavaScriptCommand();
+ cmd.mapFilePath = buildLinkerMapFilePath(target, ".map")
+ 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) {
+ var target = outputs.dynamiclibrary ? outputs.dynamiclibrary[0]
+ : 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 to generate the import library file from the dynamic library.
+// Because the DMC compiler use the separate `implib.exe` tool for that.
+function createImportLib(project, product, inputs, outputs, input, output) {
+ var args = [
+ FileInfo.toWindowsSeparators(outputs.dynamiclibrary_import[0].filePath),
+ FileInfo.toWindowsSeparators(outputs.dynamiclibrary[0].filePath)
+ ];
+ var cmd = new Command(input.cpp.implibPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.silent = true;
+ return cmd;
+}
+
+function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn);
+ var cmd = new Command(input.cpp.compilerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ return [cmd];
+}
+
+function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var args = assemblerFlags(project, product, input, outputs, explicitlyDependsOn);
+ var cmd = new Command(input.cpp.assemblerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ return [cmd];
+}
+
+function prepareLinker(project, product, inputs, outputs, input, output) {
+ var cmds = [];
+ var primaryOutput = outputs.dynamiclibrary ? outputs.dynamiclibrary[0]
+ : outputs.application[0];
+ var args = linkerFlags(project, product, inputs, outputs);
+ var linkerPath = effectiveLinkerPath(product);
+ var cmd = new Command(linkerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "linking " + primaryOutput.fileName;
+ cmd.highlight = "linker";
+ cmds.push(cmd);
+
+ if (outputs.dynamiclibrary
+ || (outputs.application && !product.cpp.generateLinkerMapFile)) {
+ if (outputs.dynamiclibrary)
+ cmds.push(createImportLib(project, product, inputs, outputs, input, output));
+ cmds.push(removeLinkerMapFile(project, product, inputs, outputs, input, output));
+ } else if (outputs.application
+ && product.cpp.generateLinkerMapFile
+ && (product.cpp.linkerMapSuffix !== ".map")) {
+ cmds.push(renameLinkerMapFile(project, product, inputs, outputs, input, output));
+ }
+ return cmds;
+}
+
+function prepareArchiver(project, product, inputs, outputs, input, output) {
+ var args = archiverFlags(project, product, inputs, outputs);
+ var cmd = new Command(product.cpp.archiverPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "linking " + output.fileName;
+ cmd.highlight = "linker";
+ return [cmd];
+}
+
+function prepareRccCompiler(project, product, inputs, outputs, input, output) {
+ var args = rccCompilerFlags(project, product, input, outputs);
+ var cmd = new Command(input.cpp.rccCompilerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ return [cmd];
+}
diff --git a/share/qbs/modules/cpp/dmc.qbs b/share/qbs/modules/cpp/dmc.qbs
new file mode 100644
index 000000000..5369e84a7
--- /dev/null
+++ b/share/qbs/modules/cpp/dmc.qbs
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs.File
+import qbs.FileInfo
+import qbs.PathTools
+import qbs.Probes
+import qbs.Utilities
+import "dmc.js" as DMC
+import "cpp.js" as Cpp
+
+CppModule {
+ condition: qbs.hostOS.contains("windows") && qbs.toolchain && qbs.toolchain.contains("dmc")
+
+ Probes.BinaryProbe {
+ id: compilerPathProbe
+ condition: !toolchainInstallPath && !_skipAllChecks
+ names: ["cxcorm"]
+ }
+
+ Probes.DmcProbe {
+ id: dmcProbe
+ condition: !_skipAllChecks
+ compilerFilePath: compilerPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
+ }
+
+ qbs.architecture: dmcProbe.found ? dmcProbe.architecture : original
+ qbs.targetPlatform: dmcProbe.targetPlatform
+
+ compilerVersionMajor: dmcProbe.versionMajor
+ compilerVersionMinor: dmcProbe.versionMinor
+ compilerVersionPatch: dmcProbe.versionPatch
+ endianness: "little"
+
+ compilerDefinesByLanguage: dmcProbe.compilerDefinesByLanguage
+ compilerIncludePaths: dmcProbe.includePaths
+
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
+
+ /* Work-around for QtCreator which expects these properties to exist. */
+ property string cCompilerName: compilerName
+ property string cxxCompilerName: compilerName
+
+ compilerName: "dmc.exe"
+ compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
+
+ assemblerName: "dmc.exe"
+ assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
+
+ linkerName: "link.exe"
+ linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+
+ property string archiverName: "lib.exe"
+ property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
+ property string implibName: "implib.exe"
+ property string implibPath: FileInfo.joinPaths(toolchainInstallPath, implibName)
+ property string rccCompilerName: "rcc.exe"
+ property string rccCompilerPath: FileInfo.joinPaths(toolchainInstallPath, rccCompilerName)
+
+ runtimeLibrary: "dynamic"
+
+ staticLibrarySuffix: ".lib"
+ dynamicLibraryImportSuffix: ".lib"
+ dynamicLibrarySuffix: ".dll"
+ executableSuffix: ".exe"
+ objectSuffix: ".obj"
+ resourceSuffix: ".res"
+
+ imageFormat: "pe"
+
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-I"
+ preincludeFlag: "-HI"
+ libraryPathFlag: "-L/packcode"
+
+ knownArchitectures: ["x86"]
+
+ Rule {
+ id: assembler
+ inputs: ["asm"]
+ outputFileTags: DMC.depsOutputTags().concat(
+ Cpp.assemblerOutputTags(generateAssemblerListingFiles))
+ outputArtifacts: DMC.depsOutputArtifacts(input, product).concat(
+ Cpp.assemblerOutputArtifacts(input))
+ prepare: DMC.prepareAssembler.apply(DMC, arguments)
+ }
+
+ FileTagger {
+ patterns: ["*.s", "*.asm"]
+ fileTags: ["asm"]
+ }
+
+ Rule {
+ id: compiler
+ inputs: ["cpp", "c"]
+ auxiliaryInputs: ["hpp"]
+ outputFileTags: DMC.depsOutputTags().concat(
+ Cpp.compilerOutputTags(generateCompilerListingFiles))
+ outputArtifacts: DMC.depsOutputArtifacts(input, product).concat(
+ Cpp.compilerOutputArtifacts(input))
+ prepare: DMC.prepareCompiler.apply(DMC, arguments)
+ }
+
+
+ Rule {
+ id: rccCompiler
+ inputs: ["rc"]
+ auxiliaryInputs: ["hpp"]
+ outputFileTags: Cpp.resourceCompilerOutputTags()
+ outputArtifacts: Cpp.resourceCompilerOutputArtifacts(input)
+ prepare: DMC.prepareRccCompiler.apply(DMC, arguments)
+ }
+
+ FileTagger {
+ patterns: ["*.rc"]
+ fileTags: ["rc"]
+ }
+
+ Rule {
+ id: applicationLinker
+ multiplex: true
+ inputs: ["obj", "res", "linkerscript"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.applicationLinkerOutputTags(generateLinkerMapFile)
+ outputArtifacts: Cpp.applicationLinkerOutputArtifacts(product)
+ prepare: DMC.prepareLinker.apply(DMC, arguments)
+ }
+
+ Rule {
+ id: dynamicLibraryLinker
+ multiplex: true
+ inputs: ["obj", "res"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.dynamicLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.dynamicLibraryLinkerOutputArtifacts(product)
+ prepare: DMC.prepareLinker.apply(DMC, arguments)
+ }
+
+ Rule {
+ id: staticLibraryLinker
+ multiplex: true
+ inputs: ["obj"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
+ prepare: DMC.prepareArchiver.apply(DMC, arguments)
+ }
+}
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index aecb69a57..5fce2bbe4 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -261,8 +261,6 @@ function escapeLinkerFlags(product, inputs, linkerFlags) {
}
function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPath) {
- var libraryPaths = product.cpp.libraryPaths;
- var distributionLibraryPaths = product.cpp.distributionLibraryPaths;
var isDarwin = product.qbs.targetOS.contains("darwin");
var libraryDependencies = collectLibraryDependencies(product, isDarwin);
var frameworks = product.cpp.frameworks;
@@ -403,19 +401,12 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
args.push("-stdlib=" + stdlib);
// Flags for library search paths
- var allLibraryPaths = [];
- if (libraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(libraryPaths);
- if (distributionLibraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths);
+ var allLibraryPaths = Cpp.collectLibraryPaths(product);
if (systemRunPaths.length > 0)
allLibraryPaths = allLibraryPaths.filter(isNotSystemRunPath);
- args = args.concat(allLibraryPaths.map(function(path) { return '-L' + path }));
+ args = args.concat(allLibraryPaths.map(function(path) { return product.cpp.libraryPathFlag + path }));
- var linkerScripts = inputs.linkerscript
- ? inputs.linkerscript.map(function(a) { return a.filePath; }) : [];
- Array.prototype.push.apply(escapableLinkerFlags, [].uniqueConcat(linkerScripts)
- .map(function(path) { return '-T' + path }));
+ escapableLinkerFlags = escapableLinkerFlags.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs));
var versionScripts = inputs.versionscript
? inputs.versionscript.map(function(a) { return a.filePath; }) : [];
@@ -427,16 +418,14 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var useCompilerDriver = useCompilerDriverLinker(product, inputs);
args = args.concat(configFlags(product, useCompilerDriver));
- Array.prototype.push.apply(escapableLinkerFlags, product.cpp.platformLinkerFlags);
- Array.prototype.push.apply(escapableLinkerFlags, product.cpp.linkerFlags);
+ escapableLinkerFlags = escapableLinkerFlags.concat(Cpp.collectMiscEscapableLinkerArguments(product));
// Note: due to the QCC response files hack in prepareLinker(), at least one object file or
// library file must follow the output file path so that QCC has something to process before
// sending the rest of the arguments through the response file.
args.push("-o", primaryOutput.filePath);
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function (obj) { return obj.filePath }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
for (i in frameworks) {
frameworkExecutablePath = PathTools.frameworkExecutablePath(frameworks[i]);
@@ -537,9 +526,8 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var escapedLinkerFlags = escapeLinkerFlags(product, inputs, escapableLinkerFlags);
Array.prototype.push.apply(escapedLinkerFlags, args);
- var driverLinkerFlags = useCompilerDriver ? product.cpp.driverLinkerFlags : undefined;
- if (driverLinkerFlags)
- Array.prototype.push.apply(escapedLinkerFlags, driverLinkerFlags);
+ if (useCompilerDriver)
+ escapedLinkerFlags = escapedLinkerFlags.concat(Cpp.collectMiscLinkerArguments(product));
return escapedLinkerFlags;
}
@@ -547,11 +535,8 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
function configFlags(config, isDriver) {
var args = [];
- if (isDriver !== false) {
- args = args.concat(config.cpp.platformDriverFlags);
- args = args.concat(config.cpp.driverFlags);
- args = args.concat(config.cpp.targetDriverFlags);
- }
+ if (isDriver !== false)
+ args = args.concat(Cpp.collectMiscDriverArguments(config));
var frameworkPaths = config.cpp.frameworkPaths;
if (frameworkPaths)
@@ -756,13 +741,6 @@ function standardFallbackValueOrDefault(toolchain, compilerVersion, languageVers
function compilerFlags(project, product, input, output, explicitlyDependsOn) {
var i;
- var includePaths = input.cpp.includePaths;
- var systemIncludePaths = input.cpp.systemIncludePaths;
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
-
- var platformDefines = input.cpp.platformDefines;
- var defines = input.cpp.defines;
-
// Determine which C-language we're compiling
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
if (!["c", "cpp", "objc", "objcpp", "asm_cpp"].contains(tag))
@@ -853,10 +831,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
// Only push language arguments if we have to.
Array.prototype.push.apply(args, compilerInfo.language);
- args = args.concat(ModUtils.moduleProperty(input, 'platformFlags'),
- ModUtils.moduleProperty(input, 'flags'),
- ModUtils.moduleProperty(input, 'platformFlags', tag),
- ModUtils.moduleProperty(input, 'flags', tag));
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag));
var pchTag = compilerInfo.tag + "_pch";
var pchOutput = output.fileTags.contains(pchTag);
@@ -866,14 +841,10 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
var pchInput = pchInputs[0];
var pchFilePath = FileInfo.joinPaths(FileInfo.path(pchInput.filePath),
pchInput.completeBaseName);
- args.push('-include', pchFilePath);
+ args.push(input.cpp.preincludeFlag, pchFilePath);
}
- var prefixHeaders = input.cpp.prefixHeaders;
- for (i in prefixHeaders) {
- args.push('-include');
- args.push(prefixHeaders[i]);
- }
+ args = args.concat(Cpp.collectPreincludePathsArguments(input));
var positionIndependentCode = input.cpp.positionIndependentCode;
if (positionIndependentCode && !product.qbs.targetOS.contains("windows"))
@@ -883,24 +854,9 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
for (i in cppFlags)
args.push('-Wp,' + cppFlags[i])
- var allDefines = [];
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
- args = args.concat(allDefines.map(function(define) { return '-D' + define }));
- if (includePaths) {
- args = args.concat([].uniqueConcat(includePaths).map(function(path) {
- return input.cpp.includeFlag + path;
- }));
- }
-
- var allSystemIncludePaths = [];
- if (systemIncludePaths)
- allSystemIncludePaths = allSystemIncludePaths.uniqueConcat(systemIncludePaths);
- if (distributionIncludePaths)
- allSystemIncludePaths = allSystemIncludePaths.uniqueConcat(distributionIncludePaths);
- allSystemIncludePaths.forEach(function(v) { args.push(input.cpp.systemIncludeFlag, v); });
+ args = args.concat(Cpp.collectDefinesArguments(input));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
var minimumWindowsVersion = input.cpp.minimumWindowsVersion;
if (minimumWindowsVersion && product.qbs.targetOS.contains("windows")) {
@@ -908,7 +864,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
if (hexVersion) {
var versionDefs = [ 'WINVER', '_WIN32_WINNT', '_WIN32_WINDOWS' ];
for (i in versionDefs)
- args.push('-D' + versionDefs[i] + '=' + hexVersion);
+ args.push(input.cpp.defineFlag + versionDefs[i] + '=' + hexVersion);
}
}
@@ -978,10 +934,6 @@ function languageName(fileTag) {
function prepareAssembler(project, product, inputs, outputs, input, output) {
var assemblerPath = product.cpp.assemblerPath;
- var includePaths = input.cpp.includePaths;
- var systemIncludePaths = input.cpp.systemIncludePaths;
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
-
var args = product.cpp.targetAssemblerFlags;
if (input.cpp.debugInformation)
@@ -991,18 +943,9 @@ function prepareAssembler(project, product, inputs, outputs, input, output) {
if (warnings === 'none')
args.push('-W');
- var tag = "asm";
- args = args.concat(ModUtils.moduleProperty(input, 'platformFlags', tag),
- ModUtils.moduleProperty(input, 'flags', tag));
-
- var allIncludePaths = [];
- if (includePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
- if (systemIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
- if (distributionIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(distributionIncludePaths);
- args = args.concat(allIncludePaths.map(function(path) { return input.cpp.includeFlag + path }));
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
args.push("-o", output.filePath);
args.push(input.filePath);
@@ -1283,6 +1226,59 @@ function createSymbolCheckingCommands(product, outputs) {
return commands;
}
+function separateDebugInfoCommands(product, outputs, primaryOutput) {
+ var commands = [];
+
+ var debugInfo = outputs.debuginfo_app || outputs.debuginfo_dll
+ || outputs.debuginfo_loadablemodule;
+
+ if (debugInfo) {
+ var objcopy = product.cpp.objcopyPath;
+
+ var cmd = new Command(objcopy, ["--only-keep-debug", primaryOutput.filePath,
+ debugInfo[0].filePath]);
+ cmd.silent = true;
+ commands.push(cmd);
+
+ cmd = new Command(objcopy, ["--strip-debug", primaryOutput.filePath]);
+ cmd.silent = true;
+ commands.push(cmd);
+
+ cmd = new Command(objcopy, ["--add-gnu-debuglink=" + debugInfo[0].filePath,
+ primaryOutput.filePath]);
+ cmd.silent = true;
+ commands.push(cmd);
+ }
+
+ return commands;
+}
+
+function separateDebugInfoCommandsDarwin(product, outputs, primaryOutputs) {
+ var commands = [];
+
+ var debugInfo = outputs.debuginfo_app || outputs.debuginfo_dll
+ || outputs.debuginfo_loadablemodule;
+ if (debugInfo) {
+ var dsymPath = debugInfo[0].filePath;
+ if (outputs.debuginfo_bundle && outputs.debuginfo_bundle[0])
+ dsymPath = outputs.debuginfo_bundle[0].filePath;
+
+ var flags = product.cpp.dsymutilFlags || [];
+ var files = primaryOutputs.map(function (f) { return f.filePath; });
+ var cmd = new Command(product.cpp.dsymutilPath,
+ flags.concat(["-o", dsymPath].concat(files)));
+ cmd.description = "generating dSYM for " + product.name;
+ commands.push(cmd);
+
+ // strip debug info
+ cmd = new Command(product.cpp.stripPath, ["-S"].concat(files));
+ cmd.silent = true;
+ commands.push(cmd);
+ }
+
+ return commands;
+}
+
function prepareLinker(project, product, inputs, outputs, input, output) {
var i, primaryOutput, cmd, commands = [];
@@ -1329,44 +1325,13 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
setResponseFileThreshold(cmd, product);
commands.push(cmd);
- var debugInfo = outputs.debuginfo_app || outputs.debuginfo_dll
- || outputs.debuginfo_loadablemodule;
- if (debugInfo) {
- if (product.qbs.targetOS.contains("darwin")) {
- if (!product.aggregate) {
- var dsymPath = debugInfo[0].filePath;
- if (outputs.debuginfo_bundle && outputs.debuginfo_bundle[0])
- dsymPath = outputs.debuginfo_bundle[0].filePath;
- var flags = product.cpp.dsymutilFlags || [];
- cmd = new Command(product.cpp.dsymutilPath, flags.concat([
- "-o", dsymPath, primaryOutput.filePath
- ]));
- cmd.description = "generating dSYM for " + product.name;
- commands.push(cmd);
-
- // strip debug info
- cmd = new Command(product.cpp.stripPath,
- ["-S", primaryOutput.filePath]);
- cmd.silent = true;
- commands.push(cmd);
- }
- } else {
- var objcopy = product.cpp.objcopyPath;
-
- cmd = new Command(objcopy, ["--only-keep-debug", primaryOutput.filePath,
- debugInfo[0].filePath]);
- cmd.silent = true;
- commands.push(cmd);
-
- cmd = new Command(objcopy, ["--strip-debug", primaryOutput.filePath]);
- cmd.silent = true;
- commands.push(cmd);
-
- cmd = new Command(objcopy, ["--add-gnu-debuglink=" + debugInfo[0].filePath,
- primaryOutput.filePath]);
- cmd.silent = true;
- commands.push(cmd);
+ if (product.qbs.targetOS.contains("darwin")) {
+ if (!product.aggregate) {
+ commands = commands.concat(separateDebugInfoCommandsDarwin(
+ product, outputs, [primaryOutput]));
}
+ } else {
+ commands = commands.concat(separateDebugInfoCommands(product, outputs, primaryOutput));
}
if (outputs.dynamiclibrary) {
@@ -1447,7 +1412,7 @@ function dumpMacros(env, compilerFilePath, args, nullDevice, tag) {
p.exec(compilerFilePath,
(args || []).concat(["-Wp,-dM", "-E", "-x", languageName(tag || "c") , nullDevice]),
true);
- return ModUtils.extractMacros(p.readStdOut());
+ return Cpp.extractMacros(p.readStdOut());
} finally {
p.close();
}
diff --git a/share/qbs/modules/cpp/iar.js b/share/qbs/modules/cpp/iar.js
index 416de7ee2..3848761f5 100644
--- a/share/qbs/modules/cpp/iar.js
+++ b/share/qbs/modules/cpp/iar.js
@@ -210,156 +210,103 @@ function architectureCode(architecture) {
}
}
-function compilerName(qbs) {
+function toolchainDetails(qbs) {
var architecture = qbs.architecture;
- if (architecture.startsWith("arm"))
- return "iccarm";
- else if (architecture === "78k")
- return "icc78k";
- else if (architecture === "avr")
- return "iccavr";
- 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 === "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 === "sh")
- return "iccsh";
- else if (architecture === "stm8")
- return "iccstm8";
- else if (architecture === "v850")
- return "iccv850";
- throw "Unable to deduce compiler name for unsupported architecture: '"
- + architecture + "'";
-}
-
-function assemblerName(qbs) {
- var architecture = qbs.architecture;
- if (architecture.startsWith("arm"))
- return "iasmarm";
- else if (architecture === "78k")
- return "a78k";
- else if (architecture === "avr")
- return "aavr";
- else if (architecture === "avr32")
- return "aavr32";
- 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 === "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 + "'";
-}
-
-function linkerName(qbs) {
- var architecture = qbs.architecture;
- if (supportXLinker(architecture))
- return "xlink";
- else if (supportILinker(architecture))
- return architecture.startsWith("arm") ? "ilinkarm" : ("ilink" + architecture);
- throw "Unable to deduce linker name for unsupported architecture: '"
- + architecture + "'";
-}
+ var code = architectureCode(architecture);
+ var details = {};
+
+ if (supportXLinker(architecture)) {
+ details.libraryPathFlag = "-I";
+ details.linkerScriptFlag = "-f";
+ details.linkerName = "xlink";
+ details.linkerSilentFlag = "-S";
+ details.linkerMapFileFlag = "-l";
+ details.linkerEntryPointFlag = "-s";
+ } else if (supportILinker(architecture)) {
+ details.libraryPathFlag = "-L";
+ details.linkerScriptFlag = "--config";
+ details.linkerSilentFlag = "--silent";
+ details.linkerMapFileFlag = "--map";
+ details.linkerEntryPointFlag = "--entry";
+ details.linkerName = architecture.startsWith("arm")
+ ? "ilinkarm" : ("ilink" + architecture);
+ }
-function archiverName(qbs) {
- var architecture = qbs.architecture;
if (supportXArchiver(architecture))
- return "xar";
+ details.archiverName = "xar";
else if (supportIArchiver(architecture))
- return "iarchive";
- throw "Unable to deduce archiver name for unsupported architecture: '"
- + architecture + "'";
-}
-
-function staticLibrarySuffix(qbs) {
- var architecture = qbs.architecture;
- var code = architectureCode(architecture);
- if (code === undefined) {
- throw "Unable to deduce static library suffix for unsupported architecture: '"
- + architecture + "'";
- }
- return (code !== "") ? (".r" + code) : ".a";
-}
+ details.archiverName = "iarchive";
-function executableSuffix(qbs) {
- var architecture = qbs.architecture;
- var code = architectureCode(architecture);
- if (code === undefined) {
- throw "Unable to deduce executable suffix for unsupported architecture: '"
- + architecture + "'";
- }
- return (code !== "") ? ((qbs.debugInformation) ? (".d" + code) : (".a" + code)) : ".out";
-}
+ var hasCode = (code !== "");
+ details.staticLibrarySuffix = hasCode ? (".r" + code) : ".a";
+ details.executableSuffix = hasCode
+ ? ((qbs.debugInformation) ? (".d" + code) : (".a" + code)) : ".out";
+ details.objectSuffix = hasCode ? (".r" + code) : ".o";
+ details.imageFormat = hasCode ? "ubrof" : "elf";
-function objectSuffix(qbs) {
- var architecture = qbs.architecture;
- var code = architectureCode(architecture);
- if (code === undefined) {
- throw "Unable to deduce object file suffix for unsupported architecture: '"
- + architecture + "'";
+ if (architecture.startsWith("arm")) {
+ details.compilerName = "iccarm";
+ details.assemblerName = "iasmarm";
+ } else if (architecture === "78k") {
+ details.compilerName = "icc78k";
+ details.assemblerName = "a78k";
+ } else if (architecture === "avr") {
+ details.compilerName = "iccavr";
+ details.assemblerName = "aavr";
+ } else if (architecture === "avr32") {
+ details.compilerName = "iccavr32";
+ details.assemblerName = "aavr32";
+ } else if (architecture === "cr16") {
+ details.compilerName = "icccr16c";
+ details.assemblerName = "acr16c";
+ } else if (architecture === "hcs12") {
+ details.compilerName = "icchcs12";
+ details.assemblerName = "ahcs12";
+ } else if (architecture === "hcs8") {
+ details.compilerName = "iccs08";
+ details.assemblerName = "as08";
+ } else if (architecture === "m16c") {
+ details.compilerName = "iccm16c";
+ details.assemblerName = "am16c";
+ } else if (architecture === "m32c") {
+ details.compilerName = "iccm32c";
+ details.assemblerName = "am32c";
+ } else if (architecture === "m68k") {
+ details.compilerName = "icccf";
+ details.assemblerName = "acf";
+ } else if (architecture === "mcs51") {
+ details.compilerName = "icc8051";
+ details.assemblerName = "a8051";
+ } else if (architecture === "msp430") {
+ details.compilerName = "icc430";
+ details.assemblerName = "a430";
+ } else if (architecture === "r32c") {
+ details.compilerName = "iccr32c";
+ details.assemblerName = "ar32c";
+ } else if (architecture === "rh850") {
+ details.compilerName = "iccrh850";
+ details.assemblerName = "iasmrh850";
+ } else if (architecture === "riscv") {
+ details.compilerName = "iccriscv";
+ details.assemblerName = "iasmriscv";
+ } else if (architecture === "rl78") {
+ details.compilerName = "iccrl78";
+ details.assemblerName = "iasmrl78";
+ } else if (architecture === "rx") {
+ details.compilerName = "iccrx";
+ details.assemblerName = "iasmrx";
+ } else if (architecture === "sh") {
+ details.compilerName = "iccsh";
+ details.assemblerName = "iasmsh";
+ } else if (architecture === "stm8") {
+ details.compilerName = "iccstm8";
+ details.assemblerName = "iasmstm8";
+ } else if (architecture === "v850") {
+ details.compilerName = "iccv850";
+ details.assemblerName = "av850";
}
- return (code !== "") ? (".r" + code) : ".o";
-}
-function imageFormat(qbs) {
- var architecture = qbs.architecture;
- var code = architectureCode(architecture);
- if (code === undefined) {
- throw "Unable to deduce image format for unsupported architecture: '"
- + architecture + "'";
- }
- return (code !== "") ? "ubrof" : "elf";
+ return details;
}
function guessArmArchitecture(core) {
@@ -490,8 +437,6 @@ function cppLanguageOption(compilerFilePath) {
case "iccv850":
return "--ec++";
}
- throw "Unable to deduce C++ language option for unsupported compiler: '"
- + FileInfo.toNativeSeparators(compilerFilePath) + "'";
}
function dumpMacros(compilerFilePath, tag) {
@@ -507,7 +452,7 @@ function dumpMacros(compilerFilePath, tag) {
var p = new Process();
p.exec(compilerFilePath, args, true);
var outFile = new TextFile(outFilePath, TextFile.ReadOnly);
- return ModUtils.extractMacros(outFile.readAll());
+ return Cpp.extractMacros(outFile.readAll());
}
function dumpCompilerIncludePaths(compilerFilePath, tag) {
@@ -557,110 +502,6 @@ function dumpDefaultPaths(compilerFilePath, tag) {
};
}
-function collectLibraryDependencies(product) {
- var seen = {};
- var result = [];
-
- function addFilePath(filePath) {
- result.push({ filePath: filePath });
- }
-
- function addArtifactFilePaths(dep, artifacts) {
- if (!artifacts)
- return;
- var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
- artifactFilePaths.forEach(addFilePath);
- }
-
- function addExternalStaticLibs(obj) {
- if (!obj.cpp)
- return;
- function ensureArray(a) {
- return (a instanceof Array) ? a : [];
- }
- function sanitizedModuleListProperty(obj, moduleName, propertyName) {
- return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
- }
- var externalLibs = [].concat(
- sanitizedModuleListProperty(obj, "cpp", "staticLibraries"));
- var staticLibrarySuffix = obj.moduleProperty("cpp", "staticLibrarySuffix");
- externalLibs.forEach(function(staticLibraryName) {
- if (!staticLibraryName.endsWith(staticLibrarySuffix))
- staticLibraryName += staticLibrarySuffix;
- addFilePath(staticLibraryName);
- });
- }
-
- function traverse(dep) {
- if (seen.hasOwnProperty(dep.name))
- return;
- seen[dep.name] = true;
-
- if (dep.parameters.cpp && dep.parameters.cpp.link === false)
- return;
-
- var staticLibraryArtifacts = dep.artifacts["staticlibrary"];
- if (staticLibraryArtifacts) {
- dep.dependencies.forEach(traverse);
- addArtifactFilePaths(dep, staticLibraryArtifacts);
- addExternalStaticLibs(dep);
- }
- }
-
- product.dependencies.forEach(traverse);
- addExternalStaticLibs(product);
- return result;
-}
-
-function compilerOutputArtifacts(input, isCompilerArtifacts) {
- var artifacts = [];
- artifacts.push({
- fileTags: ["obj"],
- filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + input.cpp.objectSuffix
- });
- 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 + input.cpp.assemblerListingSuffix
- });
- }
- return artifacts;
-}
-
-function applicationLinkerOutputArtifacts(product) {
- var app = {
- fileTags: ["application"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.applicationFilePath(product))
- };
- var mem_map = {
- fileTags: ["mem_map"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- product.targetName + product.cpp.linkerMapSuffix)
- };
- return [app, mem_map]
-}
-
-function staticLibraryLinkerOutputArtifacts(product) {
- var staticLib = {
- fileTags: ["staticlibrary"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.staticLibraryFilePath(product))
- };
- return [staticLib]
-}
-
function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
var args = [];
@@ -670,32 +511,15 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
// Output.
args.push("-o", outputs.obj[0].filePath);
- var prefixHeaders = input.cpp.prefixHeaders;
- for (var i in prefixHeaders)
- args.push("--preinclude", prefixHeaders[i]);
+ // Preinclude headers.
+ args = args.concat(Cpp.collectPreincludePathsArguments(input, true));
// Defines.
- var allDefines = [];
- var platformDefines = input.cpp.platformDefines;
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- var defines = input.cpp.defines;
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
- args = args.concat(allDefines.map(function(define) { return "-D" + define }));
+ args = args.concat(Cpp.collectDefinesArguments(input));
// Includes.
- var allIncludePaths = [];
- var includePaths = input.cpp.includePaths;
- if (includePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
- var systemIncludePaths = input.cpp.systemIncludePaths;
- if (systemIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
- if (distributionIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(distributionIncludePaths);
- args = args.concat(allIncludePaths.map(function(include) { return "-I" + include }));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
// Silent output generation flag.
args.push("--silent");
@@ -783,18 +607,12 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("-l", outputs.lst[0].filePath);
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags"),
- ModUtils.moduleProperty(input, "flags"),
- ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag),
- ModUtils.moduleProperty(input, "driverFlags", tag));
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(product));
return args;
}
function assemblerFlags(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.
@@ -807,21 +625,12 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
// 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]);
- }
+ if (supportIAssembler(architecture))
+ args = args.concat(Cpp.collectPreincludePathsArguments(input));
// Includes.
- var allIncludePaths = [];
- var systemIncludePaths = input.cpp.systemIncludePaths;
- if (systemIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
- if (distributionIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(distributionIncludePaths);
- args = args.concat(allIncludePaths.map(function(include) { return "-I" + include }));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
// Debug information flags.
if (input.cpp.debugInformation)
@@ -853,8 +662,7 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("-l", outputs.lst[0].filePath);
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag));
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
return args;
}
@@ -862,63 +670,41 @@ function linkerFlags(project, product, inputs, outputs) {
var args = [];
// Inputs.
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
// Output.
args.push("-o", outputs.application[0].filePath);
// Library paths.
- var allLibraryPaths = [];
- var libraryPaths = product.cpp.libraryPaths;
- if (libraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(libraryPaths);
- var distributionLibraryPaths = product.cpp.distributionLibraryPaths;
- if (distributionLibraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths);
+ args = args.concat(Cpp.collectLibraryPathsArguments(product));
// Library dependencies.
- var libraryDependencies = collectLibraryDependencies(product);
- if (libraryDependencies)
- args = args.concat(libraryDependencies.map(function(dep) { return dep.filePath }));
+ args = args.concat(Cpp.collectLibraryDependenciesArguments(product));
// Linker scripts.
- var linkerScripts = inputs.linkerscript
- ? inputs.linkerscript.map(function(a) { return a.filePath; }) : [];
+ args = args.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs));
- // Architecture specific flags.
- var architecture = product.qbs.architecture;
- if (supportILinker(architecture)) {
- args = args.concat(allLibraryPaths.map(function(path) { return '-L' + path }));
- // Silent output generation flag.
- args.push("--silent");
- // Map file generation flag.
- if (product.cpp.generateLinkerMapFile)
- args.push("--map", outputs.mem_map[0].filePath);
- // Entry point flag.
- if (product.cpp.entryPoint)
- args.push("--entry", product.cpp.entryPoint);
- // Linker scripts flags.
- linkerScripts.forEach(function(script) { args.push("--config", script); });
- } else if (supportXLinker(architecture)) {
- args = args.concat(allLibraryPaths.map(function(path) { return '-I' + path }));
- // Silent output generation flag.
- args.push("-S");
- // Debug information flag.
+ // Silent output generation flag.
+ args.push(product.cpp.linkerSilentFlag);
+
+ // Map file generation flag.
+ if (product.cpp.generateLinkerMapFile)
+ args.push(product.cpp.linkerMapFileFlag, outputs.mem_map[0].filePath);
+
+ // Entry point flag.
+ if (product.cpp.entryPoint)
+ args.push(product.cpp.linkerEntryPointFlag, product.cpp.entryPoint);
+
+ // Debug information flag.
+ if (supportXLinker(product.qbs.architecture)) {
if (product.cpp.debugInformation)
args.push("-rt");
- // Map file generation flag.
- if (product.cpp.generateLinkerMapFile)
- args.push("-l", outputs.mem_map[0].filePath);
- // Entry point flag.
- if (product.cpp.entryPoint)
- args.push("-s", product.cpp.entryPoint);
- // Linker scripts flags.
- linkerScripts.forEach(function(script) { args.push("-f", script); });
}
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(product, "driverLinkerFlags"));
+ args = args.concat(Cpp.collectMiscEscapableLinkerArguments(product),
+ Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
return args;
}
@@ -926,8 +712,7 @@ function archiverFlags(project, product, inputs, outputs) {
var args = [];
// Inputs.
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
// Output.
var architecture = product.qbs.architecture;
diff --git a/share/qbs/modules/cpp/iar.qbs b/share/qbs/modules/cpp/iar.qbs
index 9709695c1..79d4a0720 100644
--- a/share/qbs/modules/cpp/iar.qbs
+++ b/share/qbs/modules/cpp/iar.qbs
@@ -31,10 +31,10 @@
import qbs 1.0
import qbs.File
import qbs.FileInfo
-import qbs.ModUtils
import qbs.PathTools
import qbs.Probes
import qbs.Utilities
+import "cpp.js" as Cpp
import "iar.js" as IAR
CppModule {
@@ -66,40 +66,56 @@ CppModule {
toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
- property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
-
/* Work-around for QtCreator which expects these properties to exist. */
property string cCompilerName: compilerName
property string cxxCompilerName: compilerName
- compilerName: IAR.compilerName(qbs) + compilerExtension
+ compilerName: toolchainDetails.compilerName + compilerExtension
compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: IAR.assemblerName(qbs) + compilerExtension
+ assemblerName: toolchainDetails.assemblerName + compilerExtension
assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
- linkerName: IAR.linkerName(qbs) + compilerExtension
+ linkerName: toolchainDetails.linkerName + compilerExtension
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
- property string archiverName: IAR.archiverName(qbs) + compilerExtension
+ property string archiverName: toolchainDetails.archiverName + compilerExtension
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
runtimeLibrary: "static"
- staticLibrarySuffix: IAR.staticLibrarySuffix(qbs)
- executableSuffix: IAR.executableSuffix(qbs)
- objectSuffix: IAR.objectSuffix(qbs)
+ staticLibrarySuffix: toolchainDetails.staticLibrarySuffix
+ executableSuffix: toolchainDetails.executableSuffix
+ objectSuffix: toolchainDetails.objectSuffix
- imageFormat: IAR.imageFormat(qbs)
+ imageFormat: toolchainDetails.imageFormat
enableExceptions: false
enableRtti: false
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-I"
+ preincludeFlag: "--preinclude"
+ libraryDependencyFlag: ""
+ libraryPathFlag: toolchainDetails.libraryPathFlag
+ linkerScriptFlag: toolchainDetails.linkerScriptFlag
+
+ property string linkerSilentFlag: toolchainDetails.linkerSilentFlag
+ property string linkerMapFileFlag: toolchainDetails.linkerMapFileFlag
+ property string linkerEntryPointFlag: toolchainDetails.linkerEntryPointFlag
+
+ toolchainDetails: IAR.toolchainDetails(qbs)
+
+ knownArchitectures: ["78k", "arm", "avr", "avr32", "cr16",
+ "hcs12", "hcs8", "m16c", "m32c", "m68k", "mcs51", "msp430",
+ "r32c", "rh850", "riscv", "rl78", "rx", "sh", "stm8", "v850"]
+
Rule {
id: assembler
inputs: ["asm"]
- outputFileTags: ["obj", "lst"]
- outputArtifacts: IAR.compilerOutputArtifacts(input, false)
+ outputFileTags: Cpp.assemblerOutputTags(generateAssemblerListingFiles)
+ outputArtifacts: Cpp.assemblerOutputArtifacts(input)
prepare: IAR.prepareAssembler.apply(IAR, arguments)
}
@@ -112,8 +128,8 @@ CppModule {
id: compiler
inputs: ["cpp", "c"]
auxiliaryInputs: ["hpp"]
- outputFileTags: ["obj", "lst"]
- outputArtifacts: IAR.compilerOutputArtifacts(input, true)
+ outputFileTags: Cpp.compilerOutputTags(generateCompilerListingFiles)
+ outputArtifacts: Cpp.compilerOutputArtifacts(input)
prepare: IAR.prepareCompiler.apply(IAR, arguments)
}
@@ -122,8 +138,8 @@ CppModule {
multiplex: true
inputs: ["obj", "linkerscript"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["application", "mem_map"]
- outputArtifacts: IAR.applicationLinkerOutputArtifacts(product)
+ outputFileTags: Cpp.applicationLinkerOutputTags(generateLinkerMapFile)
+ outputArtifacts: Cpp.applicationLinkerOutputArtifacts(product)
prepare: IAR.prepareLinker.apply(IAR, arguments)
}
@@ -132,8 +148,8 @@ CppModule {
multiplex: true
inputs: ["obj"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["staticlibrary"]
- outputArtifacts: IAR.staticLibraryLinkerOutputArtifacts(product)
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
prepare: IAR.prepareArchiver.apply(IAR, arguments)
}
}
diff --git a/share/qbs/modules/cpp/keil.js b/share/qbs/modules/cpp/keil.js
index 67b07dfe5..5a5e165c8 100644
--- a/share/qbs/modules/cpp/keil.js
+++ b/share/qbs/modules/cpp/keil.js
@@ -77,118 +77,6 @@ function isArmClangCompiler(compilerPath) {
return FileInfo.baseName(compilerPath).toLowerCase() === "armclang";
}
-function compilerName(qbs) {
- var architecture = qbs.architecture;
- if (architecture === "mcs51")
- return "c51";
- if (architecture === "mcs251")
- return "c251";
- if (isC166Architecture(architecture))
- return "c166";
- if (isArmArchitecture(architecture))
- return "armcc";
- throw "Unable to deduce compiler name for unsupported architecture: '"
- + architecture + "'";
-}
-
-function assemblerName(qbs) {
- var architecture = qbs.architecture;
- if (architecture === "mcs51")
- return "a51";
- if (architecture === "mcs251")
- return "a251";
- if (isC166Architecture(architecture))
- return "a166";
- if (isArmArchitecture(architecture))
- return "armasm";
- throw "Unable to deduce assembler name for unsupported architecture: '"
- + architecture + "'";
-}
-
-function linkerName(qbs) {
- var architecture = qbs.architecture;
- if (architecture === "mcs51")
- return "bl51";
- if (architecture === "mcs251")
- return "l251";
- if (isC166Architecture(architecture))
- return "l166";
- if (isArmArchitecture(architecture))
- return "armlink";
- throw "Unable to deduce linker name for unsupported architecture: '"
- + architecture + "'";
-}
-
-function archiverName(qbs) {
- var architecture = qbs.architecture;
- if (architecture === "mcs51")
- return "lib51";
- if (architecture === "mcs251")
- return "lib251";
- if (isC166Architecture(architecture))
- return "lib166";
- if (isArmArchitecture(architecture))
- return "armar";
- throw "Unable to deduce archiver name for unsupported architecture: '"
- + architecture + "'";
-}
-
-function disassemblerName(qbs) {
- var architecture = qbs.architecture;
- return isArmArchitecture(architecture) ? "fromelf" : undefined;
-}
-
-function staticLibrarySuffix(qbs) {
- var architecture = qbs.architecture;
- if (isMcsArchitecture(architecture) || isC166Architecture(architecture)
- || isArmArchitecture(architecture)) {
- return ".lib";
- }
- throw "Unable to deduce static library suffix for unsupported architecture: '"
- + architecture + "'";
-}
-
-function executableSuffix(qbs) {
- var architecture = qbs.architecture;
- if (isMcsArchitecture(architecture) || isC166Architecture(architecture))
- return ".abs";
- if (isArmArchitecture(architecture))
- return ".axf";
- throw "Unable to deduce executable suffix for unsupported architecture: '"
- + architecture + "'";
-}
-
-function objectSuffix(qbs) {
- var architecture = qbs.architecture;
- if (isMcsArchitecture(architecture) || isC166Architecture(architecture))
- return ".obj";
- if (isArmArchitecture(architecture))
- return ".o";
- throw "Unable to deduce object file suffix for unsupported architecture: '"
- + architecture + "'";
-}
-
-function linkerMapSuffix(qbs) {
- var architecture = qbs.architecture;
- if (isMcs51Architecture(architecture))
- return ".m51";
- if (isC166Architecture(architecture))
- return ".m66";
- return ".map";
-}
-
-function imageFormat(qbs) {
- var architecture = qbs.architecture;
- if (isMcsArchitecture(architecture) || isC166Architecture(architecture))
- // Keil OMF51 or OMF2 Object Module Format (which is an
- // extension of the original Intel OMF51).
- return "omf";
- if (isArmArchitecture(architecture))
- return "elf";
- throw "Unable to deduce image format for unsupported architecture: '"
- + architecture + "'";
-}
-
function preincludeFlag(compilerPath) {
if (isArmCCCompiler(compilerPath))
return "--preinclude";
@@ -196,6 +84,56 @@ function preincludeFlag(compilerPath) {
return "-include";
}
+function toolchainDetails(qbs) {
+ var architecture = qbs.architecture;
+ if (isMcs51Architecture(architecture)) {
+ return {
+ "imageFormat": "omf",
+ "linkerMapSuffix":".m51",
+ "objectSuffix": ".obj",
+ "executableSuffix": ".abs",
+ "compilerName": "c51",
+ "assemblerName": "a51",
+ "linkerName": "bl51",
+ "archiverName": "lib51"
+ };
+ } else if (isMcs251Architecture(architecture)) {
+ return {
+ "imageFormat": "omf",
+ "linkerMapSuffix":".m51",
+ "objectSuffix": ".obj",
+ "executableSuffix": ".abs",
+ "compilerName": "c251",
+ "assemblerName": "a251",
+ "linkerName": "l251",
+ "archiverName": "lib251"
+ };
+ } else if (isC166Architecture(architecture)) {
+ return {
+ "imageFormat": "omf",
+ "linkerMapSuffix":".m66",
+ "objectSuffix": ".obj",
+ "executableSuffix": ".abs",
+ "compilerName": "c166",
+ "assemblerName": "a166",
+ "linkerName": "l166",
+ "archiverName": "lib166"
+ };
+ } else if (isArmArchitecture(architecture)) {
+ return {
+ "imageFormat": "elf",
+ "linkerMapSuffix":".map",
+ "objectSuffix": ".o",
+ "executableSuffix": ".axf",
+ "disassemblerName": "fromelf",
+ "compilerName": "armcc",
+ "assemblerName": "armasm",
+ "linkerName": "armlink",
+ "archiverName": "armar"
+ };
+ }
+}
+
function guessArmCCArchitecture(targetArchArm, targetArchThumb) {
var arch = "arm";
if (targetArchArm === "4" && targetArchThumb === "0")
@@ -436,7 +374,7 @@ function dumpArmCCCompilerMacros(compilerFilePath, tag, nullDevice) {
var p = new Process();
p.exec(compilerFilePath, args, false);
- return ModUtils.extractMacros(p.readStdOut());
+ return Cpp.extractMacros(p.readStdOut());
}
function dumpArmClangCompilerMacros(compilerFilePath, tag, nullDevice) {
@@ -444,7 +382,7 @@ function dumpArmClangCompilerMacros(compilerFilePath, tag, nullDevice) {
"-x", ((tag === "cpp") ? "c++" : "c"), nullDevice ];
var p = new Process();
p.exec(compilerFilePath, args, false);
- return ModUtils.extractMacros(p.readStdOut());
+ return Cpp.extractMacros(p.readStdOut());
}
function dumpMacros(compilerFilePath, tag, nullDevice) {
@@ -507,61 +445,6 @@ function dumpDefaultPaths(compilerFilePath, nullDevice) {
return { "includePaths": includePaths };
}
-function collectLibraryDependencies(product) {
- var seen = {};
- var result = [];
-
- function addFilePath(filePath) {
- result.push({ filePath: filePath });
- }
-
- function addArtifactFilePaths(dep, artifacts) {
- if (!artifacts)
- return;
- var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
- artifactFilePaths.forEach(addFilePath);
- }
-
- function addExternalStaticLibs(obj) {
- if (!obj.cpp)
- return;
- function ensureArray(a) {
- return (a instanceof Array) ? a : [];
- }
- function sanitizedModuleListProperty(obj, moduleName, propertyName) {
- return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
- }
- var externalLibs = [].concat(
- sanitizedModuleListProperty(obj, "cpp", "staticLibraries"));
- var staticLibrarySuffix = obj.moduleProperty("cpp", "staticLibrarySuffix");
- externalLibs.forEach(function(staticLibraryName) {
- if (!staticLibraryName.endsWith(staticLibrarySuffix))
- staticLibraryName += staticLibrarySuffix;
- addFilePath(staticLibraryName);
- });
- }
-
- function traverse(dep) {
- if (seen.hasOwnProperty(dep.name))
- return;
- seen[dep.name] = true;
-
- if (dep.parameters.cpp && dep.parameters.cpp.link === false)
- return;
-
- var staticLibraryArtifacts = dep.artifacts["staticlibrary"];
- if (staticLibraryArtifacts) {
- dep.dependencies.forEach(traverse);
- addArtifactFilePaths(dep, staticLibraryArtifacts);
- addExternalStaticLibs(dep);
- }
- }
-
- product.dependencies.forEach(traverse);
- addExternalStaticLibs(product);
- return result;
-}
-
function filterMcsOutput(output) {
var filteredLines = [];
output.split(/\r\n|\r|\n/).forEach(function(line) {
@@ -582,79 +465,11 @@ function filterC166Output(output) {
return filteredLines.join('\n');
};
-function compilerOutputArtifacts(input, isCompilerArtifacts) {
- var artifacts = [];
- artifacts.push({
- fileTags: ["obj"],
- filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + input.cpp.objectSuffix
- });
- 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 + input.cpp.assemblerListingSuffix
- });
- }
- return artifacts;
-}
-
-function applicationLinkerOutputArtifacts(product) {
- var app = {
- fileTags: ["application"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.applicationFilePath(product))
- };
- var mem_map = {
- fileTags: ["mem_map"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- product.targetName + product.cpp.linkerMapSuffix)
- };
- return [app, mem_map];
-}
-
-function staticLibraryLinkerOutputArtifacts(product) {
- var staticLib = {
- fileTags: ["staticlibrary"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.staticLibraryFilePath(product))
- };
- return [staticLib]
-}
-
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 = [];
- var allDefines = [];
- var platformDefines = input.cpp.platformDefines;
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- var defines = input.cpp.defines;
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
-
- var allIncludePaths = [];
- var includePaths = input.cpp.includePaths;
- if (includePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
- var systemIncludePaths = input.cpp.systemIncludePaths;
- if (systemIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
- if (distributionIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(distributionIncludePaths);
-
var architecture = input.qbs.architecture;
if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) {
// Input.
@@ -664,10 +479,13 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("OBJECT(" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath) + ")");
// Defines.
- if (allDefines.length > 0)
- args = args.concat("DEFINE(" + allDefines.join(",") + ")");
+ var defines = Cpp.collectDefines(input);
+ if (defines.length > 0)
+ args = args.concat("DEFINE (" + defines.join(",") + ")");
// Includes.
+ var allIncludePaths = [].concat(Cpp.collectIncludePaths(input),
+ Cpp.collectSystemIncludePaths(input));
if (allIncludePaths.length > 0)
args = args.concat("INCDIR(" + allIncludePaths.map(function(path) {
return FileInfo.toWindowsSeparators(path); }).join(";") + ")");
@@ -696,7 +514,7 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
break;
case "all":
args.push("WARNINGLEVEL (2)");
- if (architecture === "mcs51")
+ if (isMcs51Architecture(architecture))
args.push("FARWARNING");
break;
}
@@ -709,17 +527,19 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
} else if (isArmArchitecture(architecture)) {
// Input.
args.push("-c", input.filePath);
+
// Output.
args.push("-o", outputs.obj[0].filePath);
+ // Preinclude headers.
+ args = args.concat(Cpp.collectPreincludePathsArguments(input, true));
+
// Defines.
- args = args.concat(allDefines.map(function(define) { return '-D' + define }));
- // Includes.
- args = args.concat(allIncludePaths.map(function(include) { return '-I' + include }));
+ args = args.concat(Cpp.collectDefinesArguments(input));
- var prefixHeaders = input.cpp.prefixHeaders;
- for (var i in prefixHeaders)
- args.push(input.cpp.preincludeFlag, prefixHeaders[i]);
+ // Includes.
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
var compilerPath = input.cpp.compilerPath;
if (isArmCCCompiler(compilerPath)) {
@@ -858,38 +678,13 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
}
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags"),
- ModUtils.moduleProperty(input, "flags"),
- ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag),
- ModUtils.moduleProperty(input, "driverFlags", tag));
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(input));
return args;
}
function assemblerFlags(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 = [];
-
- var allDefines = [];
- var platformDefines = input.cpp.platformDefines;
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- var defines = input.cpp.defines;
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
-
- var allIncludePaths = [];
- var includePaths = input.cpp.includePaths;
- if (includePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
- var systemIncludePaths = input.cpp.systemIncludePaths;
- if (systemIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
- if (distributionIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(distributionIncludePaths);
-
var architecture = input.qbs.architecture;
if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) {
// Input.
@@ -898,11 +693,9 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
// Output.
args.push("OBJECT(" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath) + ")");
- // Defines.
- if (allDefines.length > 0)
- args = args.concat("DEFINE(" + allDefines.join(",") + ")");
-
// Includes.
+ var allIncludePaths = [].concat(Cpp.collectIncludePaths(input),
+ Cpp.collectSystemIncludePaths(input));
if (allIncludePaths.length > 0)
args = args.concat("INCDIR(" + allIncludePaths.map(function(path) {
return FileInfo.toWindowsSeparators(path); }).join(";") + ")");
@@ -926,20 +719,9 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
// Output.
args.push("-o", outputs.obj[0].filePath);
- // Defines.
- allDefines.forEach(function(define) {
- var parts = define.split("=");
- args.push("--pd");
- if (parts[1] === undefined)
- args.push(parts[0] + " SETA " + 1);
- else if (parts[1].contains("\""))
- args.push(parts[0] + " SETS " + parts[1]);
- else
- args.push(parts[0] + " SETA " + parts[1]);
- });
-
// Includes.
- args = args.concat(allIncludePaths.map(function(include) { return '-I' + include }));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
// Debug information flags.
if (input.cpp.debugInformation) {
@@ -962,8 +744,7 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
}
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag));
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
return args;
}
@@ -977,39 +758,39 @@ function disassemblerFlags(project, product, input, outputs, explicitlyDependsOn
function linkerFlags(project, product, inputs, outputs) {
var args = [];
- // Library paths.
- var libraryPaths = product.cpp.libraryPaths;
+ var libraryPaths = Cpp.collectLibraryPaths(product);
var architecture = product.qbs.architecture;
if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) {
+ // 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.
+ function collectLibraryObjectPaths(product) {
+ var libraryObjects = Cpp.collectLibraryDependencies(product);
+ return libraryObjects.map(function(dep) {
+ var filePath = dep.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;
+ });
+ }
+
// 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 = [];
-
- // Inputs.
- if (inputs.obj)
- inputs.obj.map(function(obj) { allObjectPaths.push(obj.filePath) });
-
- // Library dependencies.
- var libraryObjects = collectLibraryDependencies(product);
- 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;
- }));
+ function collectAllObjectPathsArguments(product, inputs) {
+ return [].concat(Cpp.collectLinkerObjectPaths(inputs),
+ collectLibraryObjectPaths(product));
+ }
// Add all input objects as arguments (application and library object files).
+ var allObjectPaths = collectAllObjectPathsArguments(product, inputs);
if (allObjectPaths.length > 0)
args = args.concat(allObjectPaths.map(function(path) {
return FileInfo.toWindowsSeparators(path); }).join(","));
@@ -1024,23 +805,20 @@ function linkerFlags(project, product, inputs, outputs) {
args.push("PRINT(" + FileInfo.toWindowsSeparators(outputs.mem_map[0].filePath) + ")");
} else if (isArmArchitecture(architecture)) {
// Inputs.
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
// Output.
args.push("--output", outputs.application[0].filePath);
- if (libraryPaths)
- args.push("--userlibpath=" + libraryPaths.join(","));
+ // Library paths.
+ if (libraryPaths.length > 0)
+ args.push(product.cpp.libraryPathFlag + libraryPaths.join(","));
// Library dependencies.
- var libraryDependencies = collectLibraryDependencies(product);
- args = args.concat(libraryDependencies.map(function(dep) { return dep.filePath; }));
+ args = args.concat(Cpp.collectLibraryDependenciesArguments(product));
- // Debug information flag.
- var debugInformation = product.cpp.debugInformation;
- if (debugInformation !== undefined)
- args.push(debugInformation ? "--debug" : "--no_debug");
+ // Linker scripts.
+ args = args.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs));
// Map file generation flag.
if (product.cpp.generateLinkerMapFile)
@@ -1050,37 +828,33 @@ function linkerFlags(project, product, inputs, outputs) {
if (product.cpp.entryPoint)
args.push("--entry", product.cpp.entryPoint);
- // Linker scripts flags.
- var linkerScripts = inputs.linkerscript
- ? inputs.linkerscript.map(function(a) { return a.filePath; }) : [];
- linkerScripts.forEach(function(script) { args.push("--scatter", script); });
+ // Debug information flag.
+ var debugInformation = product.cpp.debugInformation;
+ if (debugInformation !== undefined)
+ args.push(debugInformation ? "--debug" : "--no_debug");
}
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(product, "driverLinkerFlags"));
+ args = args.concat(Cpp.collectMiscEscapableLinkerArguments(product),
+ Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
return args;
}
function archiverFlags(project, product, inputs, outputs) {
var args = [];
+ // Inputs.
+ var objectPaths = Cpp.collectLinkerObjectPaths(inputs);
+
var architecture = product.qbs.architecture;
if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) {
// Library creation command.
args.push("TRANSFER");
- var allObjectPaths = [];
- function addObjectPath(obj) {
- allObjectPaths.push(obj.filePath);
- }
-
// Inputs.
- if (inputs.obj)
- inputs.obj.map(function(obj) { addObjectPath(obj) });
-
- // Add all input objects as arguments.
- if (allObjectPaths.length > 0)
- args = args.concat(allObjectPaths.map(function(path) {
+ if (objectPaths.length > 0)
+ args = args.concat(objectPaths.map(function(path) {
return FileInfo.toWindowsSeparators(path); }).join(","));
// Output.
@@ -1093,8 +867,7 @@ function archiverFlags(project, product, inputs, outputs) {
args.push("--create", outputs.staticlibrary[0].filePath);
// Inputs.
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ args = args.concat(objectPaths);
// Debug information flag.
if (product.cpp.debugInformation)
diff --git a/share/qbs/modules/cpp/keil.qbs b/share/qbs/modules/cpp/keil.qbs
index ea99b589c..8e4d98402 100644
--- a/share/qbs/modules/cpp/keil.qbs
+++ b/share/qbs/modules/cpp/keil.qbs
@@ -31,8 +31,8 @@
import qbs 1.0
import qbs.File
import qbs.FileInfo
-import qbs.ModUtils
import qbs.Probes
+import "cpp.js" as Cpp
import "keil.js" as KEIL
CppModule {
@@ -64,46 +64,54 @@ CppModule {
toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
- property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
-
/* Work-around for QtCreator which expects these properties to exist. */
property string cCompilerName: compilerName
property string cxxCompilerName: compilerName
- compilerName: KEIL.compilerName(qbs) + compilerExtension
+ compilerName: toolchainDetails.compilerName + compilerExtension
compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: KEIL.assemblerName(qbs) + compilerExtension
+ assemblerName: toolchainDetails.assemblerName + compilerExtension
assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
- linkerName: KEIL.linkerName(qbs) + compilerExtension
+ linkerName: toolchainDetails.linkerName + compilerExtension
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
- property string archiverName: KEIL.archiverName(qbs) + compilerExtension
+ property string archiverName: toolchainDetails.archiverName + compilerExtension
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
- property string disassemblerName: KEIL.disassemblerName(qbs) + compilerExtension
+ property string disassemblerName: toolchainDetails.disassemblerName + compilerExtension
property string disassemblerPath: FileInfo.joinPaths(toolchainInstallPath, disassemblerName)
runtimeLibrary: "static"
- staticLibrarySuffix: KEIL.staticLibrarySuffix(qbs)
- executableSuffix: KEIL.executableSuffix(qbs)
- objectSuffix: KEIL.objectSuffix(qbs)
- linkerMapSuffix: KEIL.linkerMapSuffix(qbs)
+ staticLibrarySuffix: ".lib"
+ executableSuffix: toolchainDetails.executableSuffix
+ objectSuffix: toolchainDetails.objectSuffix
+ linkerMapSuffix: toolchainDetails.linkerMapSuffix
- imageFormat: KEIL.imageFormat(qbs)
+ imageFormat: toolchainDetails.imageFormat
enableExceptions: false
enableRtti: false
- property string preincludeFlag: KEIL.preincludeFlag(compilerPath)
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-I"
+ preincludeFlag: KEIL.preincludeFlag(compilerPath)
+ libraryDependencyFlag: ""
+ libraryPathFlag: "--userlibpath="
+ linkerScriptFlag: "--scatter"
+
+ toolchainDetails: KEIL.toolchainDetails(qbs)
+
+ knownArchitectures: ["arm", "c166", "mcs251", "mcs51"]
Rule {
id: assembler
inputs: ["asm"]
- outputFileTags: ["obj", "lst"]
- outputArtifacts: KEIL.compilerOutputArtifacts(input, false)
+ outputFileTags: Cpp.assemblerOutputTags(generateAssemblerListingFiles)
+ outputArtifacts: Cpp.assemblerOutputArtifacts(input)
prepare: KEIL.prepareAssembler.apply(KEIL, arguments)
}
@@ -116,8 +124,8 @@ CppModule {
id: compiler
inputs: ["cpp", "c"]
auxiliaryInputs: ["hpp"]
- outputFileTags: ["obj", "lst"]
- outputArtifacts: KEIL.compilerOutputArtifacts(input, true)
+ outputFileTags: Cpp.compilerOutputTags(generateCompilerListingFiles)
+ outputArtifacts: Cpp.compilerOutputArtifacts(input)
prepare: KEIL.prepareCompiler.apply(KEIL, arguments)
}
@@ -126,8 +134,8 @@ CppModule {
multiplex: true
inputs: ["obj", "linkerscript"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["application", "mem_map"]
- outputArtifacts: KEIL.applicationLinkerOutputArtifacts(product)
+ outputFileTags: Cpp.applicationLinkerOutputTags(generateLinkerMapFile)
+ outputArtifacts: Cpp.applicationLinkerOutputArtifacts(product)
prepare: KEIL.prepareLinker.apply(KEIL, arguments)
}
@@ -136,8 +144,8 @@ CppModule {
multiplex: true
inputs: ["obj"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["staticlibrary"]
- outputArtifacts: KEIL.staticLibraryLinkerOutputArtifacts(product)
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
prepare: KEIL.prepareArchiver.apply(KEIL, arguments)
}
}
diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js
index b22ebdbd0..b27bb23c9 100644
--- a/share/qbs/modules/cpp/msvc.js
+++ b/share/qbs/modules/cpp/msvc.js
@@ -188,9 +188,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
args.push(rtl);
}
- var driverFlags = product.cpp.driverFlags;
- if (driverFlags)
- args = args.concat(driverFlags);
+ args = args.concat(Cpp.collectMiscDriverArguments(product));
// warnings:
var warningLevel = input.cpp.warningLevel;
@@ -200,41 +198,30 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
args.push('/Wall')
if (input.cpp.treatWarningsAsErrors)
args.push('/WX')
- var includePaths = input.cpp.includePaths;
- if (includePaths) {
- args = args.concat([].uniqueConcat(includePaths).map(function(path) {
- return '/I' + FileInfo.toWindowsSeparators(path);
- }));
- }
- var allSystemIncludePaths = [];
- var systemIncludePaths = input.cpp.systemIncludePaths;
- if (systemIncludePaths)
- allSystemIncludePaths = allSystemIncludePaths.uniqueConcat(systemIncludePaths);
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
- if (distributionIncludePaths)
- allSystemIncludePaths = allSystemIncludePaths.uniqueConcat(distributionIncludePaths);
- var includeFlag = "/I";
+ var includePaths = Cpp.collectIncludePaths(input);
+ args = args.concat([].uniqueConcat(includePaths).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ var includeFlag = input.cpp.includeFlag;
if (supportsExternalIncludesOption(input)) {
args.push("/experimental:external");
var enforcesSlashW =
Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30037") >= 0
if (enforcesSlashW)
args.push("/external:W0")
- includeFlag = "/external:I"
+ includeFlag = input.cpp.systemIncludeFlag;
}
- allSystemIncludePaths.forEach(function(path) {
- args.push(includeFlag, FileInfo.toWindowsSeparators(path)); });
+ var systemIncludePaths = Cpp.collectSystemIncludePaths(input);
+ args = args.concat([].uniqueConcat(systemIncludePaths).map(function(path) {
+ return includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
- var allDefines = [];
- var platformDefines = input.cpp.platformDefines;
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- var defines = input.cpp.defines;
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
- for (i in allDefines)
- args.push('/D' + allDefines[i].replace(/%/g, "%%"));
+ var defines = Cpp.collectDefines(input);
+ args = args.concat([].uniqueConcat(defines).map(function(define) {
+ return input.cpp.defineFlag + define.replace(/%/g, "%%");
+ }));
var minimumWindowsVersion = product.cpp.minimumWindowsVersion;
if (minimumWindowsVersion) {
@@ -242,7 +229,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
if (hexVersion) {
var versionDefs = [ 'WINVER', '_WIN32_WINNT', '_WIN32_WINDOWS' ];
for (i in versionDefs) {
- args.push('/D' + versionDefs[i] + '=' + hexVersion);
+ args.push(input.cpp.defineFlag + versionDefs[i] + '=' + hexVersion);
}
}
}
@@ -258,9 +245,10 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
args.push('/Fo' + FileInfo.toWindowsSeparators(objOutput.filePath))
args.push(FileInfo.toWindowsSeparators(input.filePath))
- var prefixHeaders = product.cpp.prefixHeaders;
- for (i in prefixHeaders)
- args.push("/FI" + FileInfo.toWindowsSeparators(prefixHeaders[i]));
+ var preincludePaths = Cpp.collectPreincludePaths(input);
+ args = args.concat([].uniqueConcat(preincludePaths).map(function(path) {
+ return input.cpp.preincludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
// Language
if (tag === "cpp") {
@@ -305,10 +293,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
}
}
- args = args.concat(ModUtils.moduleProperty(input, 'platformFlags'),
- ModUtils.moduleProperty(input, 'flags'),
- ModUtils.moduleProperty(input, 'platformFlags', tag),
- ModUtils.moduleProperty(input, 'flags', tag));
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag));
var compilerPath = product.cpp.compilerPath;
var wrapperArgs = product.cpp.compilerWrapper;
@@ -439,19 +424,14 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
if (useCompilerDriver) {
args.push('/nologo');
- var driverFlags = product.cpp.driverFlags;
- if (driverFlags)
- args = args.concat(driverFlags);
- var driverLinkerFlags = product.cpp.driverLinkerFlags;
- if (driverLinkerFlags)
- args = args.concat(driverLinkerFlags);
+ args = args.concat(Cpp.collectMiscDriverArguments(product),
+ Cpp.collectMiscLinkerArguments(product));
}
- var allInputs = inputs.obj || [];
- for (i in allInputs) {
- var fileName = FileInfo.toWindowsSeparators(allInputs[i].filePath)
- args.push(fileName)
- }
+ var allInputs = Cpp.collectLinkerObjectPaths(inputs);
+ args = args.concat([].uniqueConcat(allInputs).map(function(path) {
+ return FileInfo.toWindowsSeparators(path);
+ }));
var linkerArgs = ['/nologo']
if (linkDLL) {
@@ -585,12 +565,12 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
args.push('/Fe' + linkerOutputNativeFilePath);
else
linkerArgs.push('/OUT:' + linkerOutputNativeFilePath);
- var libraryPaths = product.cpp.libraryPaths;
- if (libraryPaths)
- libraryPaths = [].uniqueConcat(libraryPaths);
- for (i in libraryPaths) {
- linkerArgs.push('/LIBPATH:' + FileInfo.toWindowsSeparators(libraryPaths[i]))
- }
+
+ var libraryPaths = Cpp.collectLibraryPaths(product);
+ linkerArgs = linkerArgs.concat([].uniqueConcat(libraryPaths).map(function(path) {
+ return product.cpp.libraryPathFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
handleDiscardProperty(product, linkerArgs);
var linkerFlags = product.cpp.platformLinkerFlags.concat(product.cpp.linkerFlags);
linkerArgs = linkerArgs.concat(linkerFlags);
diff --git a/share/qbs/modules/cpp/sdcc.js b/share/qbs/modules/cpp/sdcc.js
index 1904f59fc..b3dfd92b4 100644
--- a/share/qbs/modules/cpp/sdcc.js
+++ b/share/qbs/modules/cpp/sdcc.js
@@ -41,38 +41,24 @@ var TextFile = require("qbs.TextFile");
var Utilities = require("qbs.Utilities");
var WindowsUtils = require("qbs.WindowsUtils");
-function compilerName(qbs) {
- return "sdcc";
-}
-
-function assemblerName(qbs) {
- switch (qbs.architecture) {
- case "mcs51":
- return "sdas8051";
- case "stm8":
- return "sdasstm8";
- case "hcs8":
- return "sdas6808";
- }
- throw "Unable to deduce assembler name for unsupported architecture: '"
- + qbs.architecture + "'";
-}
-
-function linkerName(qbs) {
- switch (qbs.architecture) {
- case "mcs51":
- return "sdld";
- case "stm8":
- return "sdldstm8";
- case "hcs8":
- return "sdld6808";
+function toolchainDetails(qbs) {
+ var architecture = qbs.architecture;
+ if (architecture === "mcs51") {
+ return {
+ "assemblerName": "sdas8051",
+ "linkerName": "sdld"
+ }
+ } else if (architecture === "stm8") {
+ return {
+ "assemblerName": "sdasstm8",
+ "linkerName": "sdldstm8"
+ }
+ } else if (architecture === "hcs8") {
+ return {
+ "assemblerName": "sdas6808",
+ "linkerName": "sdld6808"
+ }
}
- throw "Unable to deduce linker name for unsupported architecture: '"
- + qbs.architecture + "'";
-}
-
-function archiverName(qbs) {
- return "sdar";
}
function targetArchitectureFlag(architecture) {
@@ -126,7 +112,7 @@ function dumpMacros(compilerFilePath, architecture) {
var p = new Process();
p.exec(compilerFilePath, args, true);
- return ModUtils.extractMacros(p.readStdOut());
+ return Cpp.extractMacros(p.readStdOut());
}
function dumpDefaultPaths(compilerFilePath, architecture) {
@@ -184,150 +170,61 @@ function escapePreprocessorFlags(preprocessorFlags) {
return ["-Wp " + preprocessorFlags.join(",")];
}
-function collectLibraryDependencies(product) {
- var seen = {};
- var result = [];
-
- function addFilePath(filePath) {
- result.push({ filePath: filePath });
- }
-
- function addArtifactFilePaths(dep, artifacts) {
- if (!artifacts)
- return;
- var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
- artifactFilePaths.forEach(addFilePath);
- }
-
- function addExternalStaticLibs(obj) {
- if (!obj.cpp)
- return;
- function ensureArray(a) {
- return (a instanceof Array) ? a : [];
- }
- function sanitizedModuleListProperty(obj, moduleName, propertyName) {
- return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
- }
- var externalLibs = [].concat(
- sanitizedModuleListProperty(obj, "cpp", "staticLibraries"));
- var staticLibrarySuffix = obj.moduleProperty("cpp", "staticLibrarySuffix");
- externalLibs.forEach(function(staticLibraryName) {
- if (!staticLibraryName.endsWith(staticLibrarySuffix))
- staticLibraryName += staticLibrarySuffix;
- addFilePath(staticLibraryName);
- });
- }
-
- function traverse(dep) {
- if (seen.hasOwnProperty(dep.name))
- return;
- seen[dep.name] = true;
-
- if (dep.parameters.cpp && dep.parameters.cpp.link === false)
- return;
-
- var staticLibraryArtifacts = dep.artifacts["staticlibrary"];
- if (staticLibraryArtifacts) {
- dep.dependencies.forEach(traverse);
- addArtifactFilePaths(dep, staticLibraryArtifacts);
- addExternalStaticLibs(dep);
- }
- }
-
- product.dependencies.forEach(traverse);
- addExternalStaticLibs(product);
- return result;
+// We need to use the asm_adb, asm_src, asm_sym and rst_data
+// artifacts without of any conditions. Because SDCC always generates
+// it (and seems, this behavior can not be disabled for SDCC).
+function extraCompilerOutputTags() {
+ return ["asm_adb", "asm_src", "asm_sym", "rst_data"];
}
-function compilerOutputArtifacts(input, isCompilerArtifacts) {
- var obj = {
- fileTags: ["obj"],
- filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + input.cpp.objectSuffix
- };
+// We need to use the lk_cmd, and mem_summary artifacts without
+// of any conditions. Because SDCC always generates
+// it (and seems, this behavior can not be disabled for SDCC).
+function extraApplicationLinkerOutputTags() {
+ return ["lk_cmd", "mem_summary"];
+}
- // We need to use the asm_adb, asm_src, asm_sym and rst_data
- // artifacts without of any conditions. Because SDCC always generates
- // it (and seems, this behavior can not be disabled for SDCC).
- var asm_adb = {
+// We need to use the asm_adb, asm_src, asm_sym and rst_data
+// artifacts without of any conditions. Because SDCC always generates
+// it (and seems, this behavior can not be disabled for SDCC).
+function extraCompilerOutputArtifacts(input) {
+ return [{
fileTags: ["asm_adb"],
filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + ".adb"
- };
- var asm_src = {
+ + input.fileName + ".adb"
+ }, {
fileTags: ["asm_src"],
filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + ".asm"
- };
- var asm_sym = {
+ + input.fileName + ".asm"
+ }, {
fileTags: ["asm_sym"],
filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + ".sym"
- };
- var rst_data = {
+ + input.fileName + ".sym"
+ }, {
fileTags: ["rst_data"],
filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + ".rst"
- };
- var artifacts = [obj, asm_adb, asm_src, asm_sym, rst_data];
- 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 + input.cpp.assemblerListingSuffix
- });
- }
- return artifacts;
+ + input.fileName + ".rst"
+ }];
}
-function applicationLinkerOutputArtifacts(product) {
- var app = {
- fileTags: ["application"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.applicationFilePath(product))
- };
- var lk_cmd = {
+// We need to use the lk_cmd, and mem_summary artifacts without
+// of any conditions. Because SDCC always generates
+// it (and seems, this behavior can not be disabled for SDCC).
+function extraApplicationLinkerOutputArtifacts(product) {
+ return [{
fileTags: ["lk_cmd"],
filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- product.targetName + ".lk")
- };
- var mem_summary = {
+ product.destinationDirectory,
+ product.targetName + ".lk")
+ }, {
fileTags: ["mem_summary"],
filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- product.targetName + ".mem")
- };
- var mem_map = {
- fileTags: ["mem_map"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- product.targetName + product.cpp.linkerMapSuffix)
- };
- return [app, lk_cmd, mem_summary, mem_map]
-}
-
-function staticLibraryLinkerOutputArtifacts(product) {
- var staticLib = {
- fileTags: ["staticlibrary"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.staticLibraryFilePath(product))
- };
- return [staticLib]
+ product.destinationDirectory,
+ product.targetName + ".mem")
+ }];
}
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 = [];
var escapablePreprocessorFlags = [];
@@ -338,37 +235,19 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("-c");
args.push("-o", outputs.obj[0].filePath);
- var prefixHeaders = input.cpp.prefixHeaders;
- for (var i in prefixHeaders)
- escapablePreprocessorFlags.push("-include " + prefixHeaders[i]);
+ // Prefix headers.
+ escapablePreprocessorFlags = escapablePreprocessorFlags.concat(
+ Cpp.collectPreincludePathsArguments(input));
// Defines.
- var allDefines = [];
- var platformDefines = input.cpp.platformDefines;
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- var defines = input.cpp.defines;
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
- args = args.concat(allDefines.map(function(define) { return "-D" + define }));
+ args = args.concat(Cpp.collectDefinesArguments(input));
// Includes.
- var includePaths = input.cpp.includePaths;
- if (includePaths) {
- args = args.concat([].uniqueConcat(includePaths).map(function(path) {
- return "-I" + path; }));
- }
-
- var allSystemIncludePaths = [];
- var systemIncludePaths = input.cpp.systemIncludePaths;
- if (systemIncludePaths)
- allSystemIncludePaths = allSystemIncludePaths.uniqueConcat(systemIncludePaths);
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
- if (distributionIncludePaths)
- allSystemIncludePaths = allSystemIncludePaths.uniqueConcat(distributionIncludePaths);
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
escapablePreprocessorFlags = escapablePreprocessorFlags.concat(
- allSystemIncludePaths.map(function(include) { return "-isystem " + include }));
+ Cpp.collectSystemIncludePathsArguments(input));
+ // Target MCU flag.
var targetFlag = targetArchitectureFlag(input.cpp.architecture);
if (targetFlag)
args.push(targetFlag);
@@ -401,6 +280,9 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
if (input.cpp.treatWarningsAsErrors)
args.push("--Werror");
+ // Determine which C-language we"re compiling.
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
+
// C language version flags.
if (tag === "c") {
var knownValues = ["c11", "c99", "c89"];
@@ -419,46 +301,25 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
}
}
- // Misc flags.
- escapablePreprocessorFlags = escapablePreprocessorFlags.uniqueConcat(input.cpp.cppFlags);
var escapedPreprocessorFlags = escapePreprocessorFlags(escapablePreprocessorFlags);
if (escapedPreprocessorFlags)
Array.prototype.push.apply(args, escapedPreprocessorFlags);
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags"),
- ModUtils.moduleProperty(input, "flags"),
- ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag),
- ModUtils.moduleProperty(input, "driverFlags", tag));
-
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(input));
return args;
}
function assemblerFlags(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 = [];
// Includes.
- var includePaths = input.cpp.includePaths;
- if (includePaths) {
- args = args.concat([].uniqueConcat(includePaths).map(function(path) {
- return "-I" + path; }));
- }
-
- var allSystemIncludePaths = [];
- var systemIncludePaths = input.cpp.systemIncludePaths;
- if (systemIncludePaths)
- allSystemIncludePaths = allSystemIncludePaths.uniqueConcat(systemIncludePaths);
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
- if (distributionIncludePaths)
- allSystemIncludePaths = allSystemIncludePaths.uniqueConcat(distributionIncludePaths);
- args = args.concat(allSystemIncludePaths.map(function(include) { return "-I" + include }));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input, input.cpp.includeFlag));
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag));
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
args.push("-ol");
args.push(outputs.obj[0].filePath);
@@ -474,82 +335,53 @@ function linkerFlags(project, product, inputs, outputs) {
if (targetFlag)
args.push(targetFlag);
- var allLibraryPaths = [];
- var libraryPaths = product.cpp.libraryPaths;
- if (libraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(libraryPaths);
- var distributionLibraryPaths = product.cpp.distributionLibraryPaths;
- if (distributionLibraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths);
-
- var libraryDependencies = collectLibraryDependencies(product);
-
var escapableLinkerFlags = [];
// Map file generation flag.
if (product.cpp.generateLinkerMapFile)
escapableLinkerFlags.push("-m");
- if (product.cpp.platformLinkerFlags)
- Array.prototype.push.apply(escapableLinkerFlags, product.cpp.platformLinkerFlags);
- if (product.cpp.linkerFlags)
- Array.prototype.push.apply(escapableLinkerFlags, product.cpp.linkerFlags);
+ escapableLinkerFlags = escapableLinkerFlags.concat(Cpp.collectMiscEscapableLinkerArguments(product));
var useCompilerDriver = useCompilerDriverLinker(product);
- if (useCompilerDriver) {
- // Output.
- args.push("-o", outputs.application[0].filePath);
-
- // Inputs.
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
-
- // Library paths.
- args = args.concat(allLibraryPaths.map(function(path) { return "-L" + path }));
-
- // Linker scripts.
- var scripts = inputs.linkerscript
- ? inputs.linkerscript.map(function(scr) { return "-f" + scr.filePath; }) : [];
- if (scripts)
- Array.prototype.push.apply(escapableLinkerFlags, scripts);
- } else {
- // Output.
- args.push(outputs.application[0].filePath);
-
- // Inputs.
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
-
- // Library paths.
- args = args.concat(allLibraryPaths.map(function(path) { return "-k" + path }));
-
- // Linker scripts.
- // Note: We need to split the '-f' and the file path to separate
- // lines; otherwise the linking fails.
- inputs.linkerscript.forEach(function(scr) {
- escapableLinkerFlags.push("-f", scr.filePath);
- });
- }
+
+ // Output.
+ if (useCompilerDriver)
+ args.push("-o");
+ args.push(outputs.application[0].filePath);
+
+ // Inputs.
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
+
+ // Library paths.
+ var libraryPathFlag = useCompilerDriver ? "-L" : "-k";
+ args = args.concat(Cpp.collectLibraryPathsArguments(product, libraryPathFlag));
+
+ // Linker scripts.
+ // Note: We need to split the '-f' flag and the file path to separate
+ // lines when we don't use the compiler driver mode.
+ escapableLinkerFlags = escapableLinkerFlags.concat(
+ Cpp.collectLinkerScriptPathsArguments(product, inputs, !useCompilerDriver));
// Library dependencies.
- if (libraryDependencies)
- args = args.concat(libraryDependencies.map(function(dep) { return "-l" + dep.filePath }));
+ args = args.concat(Cpp.collectLibraryDependenciesArguments(product));
- // Misc flags.
var escapedLinkerFlags = escapeLinkerFlags(product, escapableLinkerFlags);
if (escapedLinkerFlags)
Array.prototype.push.apply(args, escapedLinkerFlags);
- var driverLinkerFlags = useCompilerDriver ? product.cpp.driverLinkerFlags : undefined;
- if (driverLinkerFlags)
- Array.prototype.push.apply(args, driverLinkerFlags);
+
+ // Misc flags.
+ if (useCompilerDriver) {
+ args = args.concat(Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
+ }
return args;
}
function archiverFlags(project, product, inputs, outputs) {
var args = ["-rc"];
args.push(outputs.staticlibrary[0].filePath);
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
return args;
}
diff --git a/share/qbs/modules/cpp/sdcc.qbs b/share/qbs/modules/cpp/sdcc.qbs
index c5a0893d4..0f33e9f02 100644
--- a/share/qbs/modules/cpp/sdcc.qbs
+++ b/share/qbs/modules/cpp/sdcc.qbs
@@ -31,8 +31,8 @@
import qbs 1.0
import qbs.File
import qbs.FileInfo
-import qbs.ModUtils
import qbs.Probes
+import "cpp.js" as Cpp
import "sdcc.js" as SDCC
CppModule {
@@ -65,24 +65,22 @@ CppModule {
toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
- property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
-
/* Work-around for QtCreator which expects these properties to exist. */
property string cCompilerName: compilerName
property string cxxCompilerName: compilerName
property string linkerMode: "automatic"
- compilerName: SDCC.compilerName(qbs) + compilerExtension
+ compilerName: "sdcc" + compilerExtension
compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: SDCC.assemblerName(qbs) + compilerExtension
+ assemblerName: toolchainDetails.assemblerName + compilerExtension
assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
- linkerName: SDCC.linkerName(qbs) + compilerExtension
+ linkerName: toolchainDetails.linkerName + compilerExtension
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
- property string archiverName: SDCC.archiverName(qbs) + compilerExtension
+ property string archiverName: "sdar" + compilerExtension
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
runtimeLibrary: "static"
@@ -96,11 +94,25 @@ CppModule {
enableExceptions: false
enableRtti: false
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-isystem"
+ preincludeFlag: "-include"
+ libraryDependencyFlag: "-l"
+ libraryPathFlag: "-L"
+ linkerScriptFlag: "-f"
+
+ toolchainDetails: SDCC.toolchainDetails(qbs)
+
+ knownArchitectures: ["hcs8", "mcs51", "stm8"]
+
Rule {
id: assembler
inputs: ["asm"]
- outputFileTags: ["obj", "asm_adb", "lst", "asm_src", "asm_sym", "rst_data"]
- outputArtifacts: SDCC.compilerOutputArtifacts(input, false)
+ outputFileTags: SDCC.extraCompilerOutputTags().concat(
+ Cpp.assemblerOutputTags(generateAssemblerListingFiles))
+ outputArtifacts: SDCC.extraCompilerOutputArtifacts(input).concat(
+ Cpp.assemblerOutputArtifacts(input))
prepare: SDCC.prepareAssembler.apply(SDCC, arguments)
}
@@ -113,8 +125,10 @@ CppModule {
id: compiler
inputs: ["cpp", "c"]
auxiliaryInputs: ["hpp"]
- outputFileTags: ["obj", "asm_adb", "lst", "asm_src", "asm_sym", "rst_data"]
- outputArtifacts: SDCC.compilerOutputArtifacts(input, true)
+ outputFileTags: SDCC.extraCompilerOutputTags().concat(
+ Cpp.compilerOutputTags(generateCompilerListingFiles))
+ outputArtifacts: SDCC.extraCompilerOutputArtifacts(input).concat(
+ Cpp.compilerOutputArtifacts(input))
prepare: SDCC.prepareCompiler.apply(SDCC, arguments)
}
@@ -123,8 +137,10 @@ CppModule {
multiplex: true
inputs: ["obj", "linkerscript"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["application", "lk_cmd", "mem_summary", "mem_map"]
- outputArtifacts: SDCC.applicationLinkerOutputArtifacts(product)
+ outputFileTags: SDCC.extraApplicationLinkerOutputTags().concat(
+ Cpp.applicationLinkerOutputTags(generateLinkerMapFile))
+ outputArtifacts: SDCC.extraApplicationLinkerOutputArtifacts(product).concat(
+ Cpp.applicationLinkerOutputArtifacts(product))
prepare: SDCC.prepareLinker.apply(SDCC, arguments)
}
@@ -133,8 +149,8 @@ CppModule {
multiplex: true
inputs: ["obj"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["staticlibrary"]
- outputArtifacts: SDCC.staticLibraryLinkerOutputArtifacts(product)
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
prepare: SDCC.prepareArchiver.apply(SDCC, arguments)
}
}
diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs
index c45ec5ec3..4efd20668 100644
--- a/share/qbs/modules/cpp/windows-msvc-base.qbs
+++ b/share/qbs/modules/cpp/windows-msvc-base.qbs
@@ -35,6 +35,7 @@ import qbs.PathTools
import qbs.Probes
import qbs.Utilities
import qbs.WindowsUtils
+import 'cpp.js' as Cpp
import 'msvc.js' as MSVC
CppModule {
@@ -114,6 +115,12 @@ CppModule {
property string windowsSdkVersion
+ defineFlag: "/D"
+ includeFlag: "/I"
+ systemIncludeFlag: "/external:I"
+ preincludeFlag: "/FI"
+ libraryPathFlag: "/LIBPATH:"
+
Rule {
condition: useCPrecompiledHeader
inputs: ["c_pch_src"]
@@ -155,7 +162,12 @@ CppModule {
auxiliaryInputs: ["hpp"]
explicitlyDependsOn: ["c_pch", "cpp_pch"]
- outputFileTags: ["obj", "intermediate_obj", "lst"]
+ outputFileTags: {
+ var tags = ["obj", "intermediate_obj"];
+ if (generateCompilerListingFiles)
+ tags.push("lst");
+ return tags;
+ }
outputArtifacts: {
var tags = input.fileTags.contains("cpp_intermediate_object")
? ["intermediate_obj"]
@@ -197,7 +209,9 @@ CppModule {
inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"]
outputFileTags: {
- var tags = ["application", "debuginfo_app", "mem_map"];
+ var tags = ["application", "debuginfo_app"];
+ if (generateLinkerMapFile)
+ tags.push("mem_map");
if (shouldSignArtifacts)
tags.push("codesign.signed_artifact");
return tags;
@@ -355,8 +369,7 @@ CppModule {
FileInfo.toWindowsSeparators(input.filePath)];
if (product.cpp.debugInformation)
args.push("/Zi");
- args = args.concat(ModUtils.moduleProperty(input, 'platformFlags', 'asm'),
- ModUtils.moduleProperty(input, 'flags', 'asm'));
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
var cmd = new Command(product.cpp.assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.jobPool = "assembler";
diff --git a/src/app/config-ui/CMakeLists.txt b/src/app/config-ui/CMakeLists.txt
index 47b9c1905..f3375d5ea 100644
--- a/src/app/config-ui/CMakeLists.txt
+++ b/src/app/config-ui/CMakeLists.txt
@@ -14,6 +14,6 @@ if(APPLE)
endif()
add_qbs_app(qbs-config-ui
- DEPENDS qbscore qbsconsolelogger Qt5::Widgets ${MACOS_FRAMEWORKS}
+ DEPENDS qbscore qbsconsolelogger Qt${QT_VERSION_MAJOR}::Widgets ${MACOS_FRAMEWORKS}
SOURCES ${SOURCES} ${MACOS_SOURCES}
)
diff --git a/src/app/config/configcommand.h b/src/app/config/configcommand.h
index 1574e3745..f8e2a8ae9 100644
--- a/src/app/config/configcommand.h
+++ b/src/app/config/configcommand.h
@@ -47,7 +47,7 @@
class ConfigCommand
{
public:
- enum Command { CfgSet, CfgUnset, CfgList, CfgExport, CfgImport, CfgNone };
+ enum Command { CfgSet, CfgUnset, CfgList, CfgExport, CfgImport, CfgAddProfile, CfgNone };
ConfigCommand() : command(CfgNone) {}
diff --git a/src/app/config/configcommandexecutor.cpp b/src/app/config/configcommandexecutor.cpp
index 0a6883aa7..a01058b11 100644
--- a/src/app/config/configcommandexecutor.cpp
+++ b/src/app/config/configcommandexecutor.cpp
@@ -42,6 +42,7 @@
#include "../shared/logging/consolelogger.h"
#include <tools/error.h>
+#include <tools/profile.h>
#include <tools/qttools.h>
#include <tools/settingsrepresentation.h>
@@ -73,6 +74,17 @@ void ConfigCommandExecutor::execute(const ConfigCommand &command)
for (const QString &varName : command.varNames)
m_settings->remove(varName);
break;
+ case ConfigCommand::CfgAddProfile: {
+ Profile profile(command.varValue, m_settings);
+ profile.removeProfile();
+ Q_ASSERT(command.varNames.size() % 2 == 0);
+ for (int i = 0; i < command.varNames.size(); i += 2) {
+ const QString &key = command.varNames.at(i);
+ const QString &rawValue = command.varNames.at(i + 1);
+ profile.setValue(key, representationToSettingsValue(rawValue));
+ }
+ break;
+ }
case ConfigCommand::CfgExport:
exportSettings(command.fileName);
break;
diff --git a/src/app/config/configcommandlineparser.cpp b/src/app/config/configcommandlineparser.cpp
index 2f2d1610e..8652a58bc 100644
--- a/src/app/config/configcommandlineparser.cpp
+++ b/src/app/config/configcommandlineparser.cpp
@@ -71,6 +71,8 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine)
setCommand(ConfigCommand::CfgExport);
else if (arg == QLatin1String("import"))
setCommand(ConfigCommand::CfgImport);
+ else if (arg == QLatin1String("add-profile"))
+ setCommand(ConfigCommand::CfgAddProfile);
else if (arg == QLatin1String("settings-dir"))
assignOptionArgument(arg, m_settingsDir);
else if (arg == QLatin1String("user"))
@@ -113,6 +115,22 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine)
case ConfigCommand::CfgList:
m_command.varNames = m_commandLine;
break;
+ case ConfigCommand::CfgAddProfile:
+ if (m_commandLine.empty())
+ throw Error(Tr::tr("Profile name missing."));
+ m_command.varValue = m_commandLine.takeFirst();
+ if (m_command.varValue.isEmpty())
+ throw Error(Tr::tr("Profile name must not be empty."));
+ m_command.varNames = m_commandLine;
+ if (m_command.varNames.isEmpty())
+ throw Error(Tr::tr("Profile properties must be provided."));
+ if (m_command.varNames.size() % 2 != 0)
+ throw Error(Tr::tr("Profile properties must be key/value pairs."));
+ for (int i = 0; i < m_command.varNames.size(); ++i) {
+ if (m_command.varNames.at(i).isEmpty())
+ throw Error(Tr::tr("Property names must not be empty."));
+ }
+ break;
default:
break;
}
@@ -140,12 +158,13 @@ void ConfigCommandLineParser::printUsage() const
" qbs config [--settings-dir <settings directory] <key> <value>"
"\n"
"Options:\n"
- " --list [<root> ...] list keys under key <root> or all keys\n"
- " --user consider only user-level settings\n"
- " --system consider only system-level settings\n"
- " --unset <name> remove key with given name\n"
- " --import <file> import settings from given file\n"
- " --export <file> export settings to given file\n");
+ " --list [<root> ...] list keys under key <root> or all keys\n"
+ " --user consider only user-level settings\n"
+ " --system consider only system-level settings\n"
+ " --unset <name> remove key with given name\n"
+ " --add-profile <name> <key> <value> ... add profile with the given name and properties\n"
+ " --import <file> import settings from given file\n"
+ " --export <file> export settings to given file\n");
}
void ConfigCommandLineParser::assignOptionArgument(const QString &option, QString &argument)
diff --git a/src/app/qbs-setup-toolchains/CMakeLists.txt b/src/app/qbs-setup-toolchains/CMakeLists.txt
index d23221c73..bb287be52 100644
--- a/src/app/qbs-setup-toolchains/CMakeLists.txt
+++ b/src/app/qbs-setup-toolchains/CMakeLists.txt
@@ -3,6 +3,10 @@ set(SOURCES
clangclprobe.h
commandlineparser.cpp
commandlineparser.h
+ cosmicprobe.cpp
+ cosmicprobe.h
+ dmcprobe.cpp
+ dmcprobe.h
gccprobe.cpp
gccprobe.h
iarewprobe.cpp
diff --git a/src/app/qbs-setup-toolchains/cosmicprobe.cpp b/src/app/qbs-setup-toolchains/cosmicprobe.cpp
new file mode 100644
index 000000000..a41b21ee8
--- /dev/null
+++ b/src/app/qbs-setup-toolchains/cosmicprobe.cpp
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "probe.h"
+#include "cosmicprobe.h"
+
+#include "../shared/logging/consolelogger.h"
+
+#include <logging/translator.h>
+
+#include <tools/hostosinfo.h>
+#include <tools/profile.h>
+
+#include <QtCore/qprocess.h>
+#include <QtCore/qregularexpression.h>
+#include <QtCore/qsettings.h>
+#include <QtCore/qstandardpaths.h>
+
+using namespace qbs;
+using Internal::Tr;
+using Internal::HostOsInfo;
+
+static QStringList knownCosmicCompilerNames()
+{
+ return {QStringLiteral("cxcorm"), QStringLiteral("cxstm8"),
+ QStringLiteral("cx6808"), QStringLiteral("cx6812"),
+ QStringLiteral("cx332")};
+}
+
+static QString guessCosmicArchitecture(const QFileInfo &compiler)
+{
+ const auto baseName = compiler.baseName();
+ if (baseName == QLatin1String("cxcorm"))
+ return QStringLiteral("arm");
+ if (baseName == QLatin1String("cxstm8"))
+ return QStringLiteral("stm8");
+ if (baseName == QLatin1String("cx6808"))
+ return QStringLiteral("hcs8");
+ if (baseName == QLatin1String("cx6812"))
+ return QStringLiteral("hcs12");
+ if (baseName == QLatin1String("cx332"))
+ return QStringLiteral("m68k");
+ return {};
+}
+
+static Profile createCosmicProfileHelper(const ToolchainInstallInfo &info,
+ Settings *settings,
+ QString profileName = QString())
+{
+ const QFileInfo compiler = info.compilerPath;
+ const QString architecture = guessCosmicArchitecture(compiler);
+
+ // In case the profile is auto-detected.
+ if (profileName.isEmpty()) {
+ if (!info.compilerVersion.isValid()) {
+ profileName = QStringLiteral("cosmic-unknown-%1").arg(architecture);
+ } else {
+ const QString version = info.compilerVersion.toString(QLatin1Char('_'),
+ QLatin1Char('_'));
+ profileName = QStringLiteral("cosmic-%1-%2").arg(
+ version, architecture);
+ }
+ }
+
+ Profile profile(profileName, settings);
+ profile.setValue(QLatin1String("cpp.toolchainInstallPath"), compiler.absolutePath());
+ profile.setValue(QLatin1String("qbs.toolchainType"), QLatin1String("cosmic"));
+ if (!architecture.isEmpty())
+ profile.setValue(QLatin1String("qbs.architecture"), architecture);
+
+ qbsInfo() << Tr::tr("Profile '%1' created for '%2'.").arg(
+ profile.name(), compiler.absoluteFilePath());
+ return profile;
+}
+
+static Version dumpCosmicCompilerVersion(const QFileInfo &compiler)
+{
+ QProcess p;
+ QStringList args;
+ p.start(compiler.absoluteFilePath(), args);
+ p.waitForFinished(3000);
+ const auto es = p.exitStatus();
+ if (es != QProcess::NormalExit) {
+ const QByteArray out = p.readAll();
+ qbsWarning() << Tr::tr("Compiler dumping failed:\n%1")
+ .arg(QString::fromUtf8(out));
+ return Version{};
+ }
+
+ const QByteArray output = p.readAllStandardError();
+ const QRegularExpression re(QLatin1String("^COSMIC.+V(\\d+)\\.?(\\d+)\\.?(\\*|\\d+)?"));
+ const QRegularExpressionMatch match = re.match(QString::fromLatin1(output));
+ if (!match.hasMatch())
+ return Version{};
+
+ const auto major = match.captured(1).toInt();
+ const auto minor = match.captured(2).toInt();
+ const auto patch = match.captured(3).toInt();
+ return Version{major, minor, patch};
+}
+
+static std::vector<ToolchainInstallInfo> installedCosmicsFromPath()
+{
+ std::vector<ToolchainInstallInfo> infos;
+ const auto compilerNames = knownCosmicCompilerNames();
+ for (const QString &compilerName : compilerNames) {
+ const QFileInfo cosmicPath(
+ findExecutable(
+ HostOsInfo::appendExecutableSuffix(compilerName)));
+ if (!cosmicPath.exists())
+ continue;
+ const Version version = dumpCosmicCompilerVersion(cosmicPath);
+ infos.push_back({cosmicPath, version});
+ }
+ std::sort(infos.begin(), infos.end());
+ return infos;
+}
+
+bool isCosmicCompiler(const QString &compilerName)
+{
+ return Internal::any_of(knownCosmicCompilerNames(), [compilerName](const QString &knownName) {
+ return compilerName.contains(knownName);
+ });
+}
+
+void createCosmicProfile(const QFileInfo &compiler, Settings *settings,
+ QString profileName)
+{
+ const ToolchainInstallInfo info = {compiler, Version{}};
+ createCosmicProfileHelper(info, settings, std::move(profileName));
+}
+
+void cosmicProbe(Settings *settings, std::vector<Profile> &profiles)
+{
+ qbsInfo() << Tr::tr("Trying to detect COSMIC toolchains...");
+
+ const std::vector<ToolchainInstallInfo> allInfos = installedCosmicsFromPath();
+ for (const ToolchainInstallInfo &info : allInfos) {
+ const auto profile = createCosmicProfileHelper(info, settings);
+ profiles.push_back(profile);
+ }
+
+ if (allInfos.empty())
+ qbsInfo() << Tr::tr("No COSMIC toolchains found.");
+}
diff --git a/src/app/qbs-setup-toolchains/cosmicprobe.h b/src/app/qbs-setup-toolchains/cosmicprobe.h
new file mode 100644
index 000000000..9b7b4bb10
--- /dev/null
+++ b/src/app/qbs-setup-toolchains/cosmicprobe.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBS_SETUPTOOLCHAINS_COSMICPROBE_H
+#define QBS_SETUPTOOLCHAINS_COSMICPROBE_H
+
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+class QFileInfo;
+QT_END_NAMESPACE
+
+namespace qbs {
+class Profile;
+class Settings;
+}
+
+bool isCosmicCompiler(const QString &compilerName);
+
+void createCosmicProfile(const QFileInfo &compiler, qbs::Settings *settings,
+ QString profileName);
+
+void cosmicProbe(qbs::Settings *settings, std::vector<qbs::Profile> &profiles);
+
+#endif // Header guard
diff --git a/src/app/qbs-setup-toolchains/dmcprobe.cpp b/src/app/qbs-setup-toolchains/dmcprobe.cpp
new file mode 100644
index 000000000..3ac12eba5
--- /dev/null
+++ b/src/app/qbs-setup-toolchains/dmcprobe.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "probe.h"
+#include "dmcprobe.h"
+
+#include "../shared/logging/consolelogger.h"
+
+#include <logging/translator.h>
+
+#include <tools/hostosinfo.h>
+#include <tools/profile.h>
+
+#include <QtCore/qdir.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qprocess.h>
+#include <QtCore/qregularexpression.h>
+#include <QtCore/qsettings.h>
+#include <QtCore/qstandardpaths.h>
+
+using namespace qbs;
+using Internal::Tr;
+using Internal::HostOsInfo;
+
+static QStringList knownDmcCompilerNames()
+{
+ return {QStringLiteral("dmc")};
+}
+
+static QString guessDmcArchitecture(const QFileInfo &compiler)
+{
+ const QStringList keys = {QStringLiteral("__I86__")};
+ const auto macros = dumpMacros([&compiler, &keys]() {
+ const QString filePath = QDir(QDir::tempPath())
+ .absoluteFilePath(QLatin1String("dmc-dump.c"));
+ QFile fakeIn(filePath);
+ if (!fakeIn.open(QIODevice::Truncate | QIODevice::WriteOnly | QIODevice::Text)) {
+ qbsWarning() << Tr::tr("Unable to open temporary file %1 for output: %2")
+ .arg(fakeIn.fileName(), fakeIn.errorString());
+ return QStringList{};
+ }
+ fakeIn.write("#define VALUE_TO_STRING(x) #x\n");
+ fakeIn.write("#define VALUE(x) VALUE_TO_STRING(x)\n");
+ fakeIn.write("#define VAR_NAME_VALUE(var) \"#define \" #var\" \"VALUE(var)\n");
+ for (const QString &key : keys) {
+ fakeIn.write("#if defined(" + key.toLatin1() + ")\n");
+ fakeIn.write("#pragma message (VAR_NAME_VALUE(" + key.toLatin1() + "))\n");
+ fakeIn.write("#endif\n");
+ }
+ fakeIn.close();
+ QProcess p;
+ p.start(compiler.absoluteFilePath(), {QStringLiteral("-e"), filePath});
+ p.waitForFinished(3000);
+ fakeIn.remove();
+ const QStringList lines = QString::fromUtf8(p.readAllStandardOutput())
+ .split(QRegularExpression(QLatin1String("\\r?\\n")));
+ return lines;
+ });
+
+ for (const QString &key : keys) {
+ if (macros.contains(key)) {
+ bool ok = false;
+ const auto value = macros.value(key).toInt(&ok);
+ if (ok) {
+ switch (value) {
+ case 0: // 8088
+ case 2: // 286
+ case 3: // 386
+ case 4: // 486
+ break;
+ case 5: // P5
+ case 6: // P6
+ return QLatin1String("x86");
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return QLatin1String("unknown");
+}
+
+static Profile createDmcProfileHelper(const ToolchainInstallInfo &info,
+ Settings *settings,
+ QString profileName = QString())
+{
+ const QFileInfo compiler = info.compilerPath;
+ const QString architecture = guessDmcArchitecture(compiler);
+
+ // In case the profile is auto-detected.
+ if (profileName.isEmpty()) {
+ if (!info.compilerVersion.isValid()) {
+ profileName = QStringLiteral("dmc-unknown-%1").arg(architecture);
+ } else {
+ const QString version = info.compilerVersion.toString(QLatin1Char('_'),
+ QLatin1Char('_'));
+ profileName = QStringLiteral("dmc-%1-%2").arg(
+ version, architecture);
+ }
+ }
+
+ Profile profile(profileName, settings);
+ profile.setValue(QLatin1String("cpp.toolchainInstallPath"), compiler.absolutePath());
+ profile.setValue(QLatin1String("qbs.toolchainType"), QLatin1String("dmc"));
+ if (!architecture.isEmpty())
+ profile.setValue(QLatin1String("qbs.architecture"), architecture);
+
+ qbsInfo() << Tr::tr("Profile '%1' created for '%2'.").arg(
+ profile.name(), compiler.absoluteFilePath());
+ return profile;
+}
+
+static Version dumpDmcCompilerVersion(const QFileInfo &compiler)
+{
+ QProcess p;
+ QStringList args;
+ p.start(compiler.absoluteFilePath(), args);
+ p.waitForFinished(3000);
+ const auto es = p.exitStatus();
+ if (es != QProcess::NormalExit) {
+ const QByteArray out = p.readAll();
+ qbsWarning() << Tr::tr("Compiler dumping failed:\n%1")
+ .arg(QString::fromUtf8(out));
+ return Version{};
+ }
+
+ const QByteArray output = p.readAllStandardOutput();
+ const QRegularExpression re(QLatin1String(
+ "^Digital Mars Compiler Version (\\d+)\\.?(\\d+)\\.?(\\*|\\d+)?"));
+ const QRegularExpressionMatch match = re.match(QString::fromLatin1(output));
+ if (!match.hasMatch())
+ return Version{};
+
+ const auto major = match.captured(1).toInt();
+ const auto minor = match.captured(2).toInt();
+ const auto patch = match.captured(3).toInt();
+ return Version{major, minor, patch};
+}
+
+static std::vector<ToolchainInstallInfo> installedDmcsFromPath()
+{
+ std::vector<ToolchainInstallInfo> infos;
+ const auto compilerNames = knownDmcCompilerNames();
+ for (const QString &compilerName : compilerNames) {
+ const QFileInfo dmcPath(
+ findExecutable(
+ HostOsInfo::appendExecutableSuffix(compilerName)));
+ if (!dmcPath.exists())
+ continue;
+ const Version version = dumpDmcCompilerVersion(dmcPath);
+ infos.push_back({dmcPath, version});
+ }
+ std::sort(infos.begin(), infos.end());
+ return infos;
+}
+
+bool isDmcCompiler(const QString &compilerName)
+{
+ return Internal::any_of(knownDmcCompilerNames(),
+ [compilerName](const QString &knownName) {
+ return compilerName.contains(knownName);
+ });
+}
+
+void createDmcProfile(const QFileInfo &compiler, Settings *settings,
+ QString profileName)
+{
+ const ToolchainInstallInfo info = {compiler, Version{}};
+ createDmcProfileHelper(info, settings, std::move(profileName));
+}
+
+void dmcProbe(Settings *settings, std::vector<Profile> &profiles)
+{
+ qbsInfo() << Tr::tr("Trying to detect DMC toolchains...");
+
+ const std::vector<ToolchainInstallInfo> allInfos = installedDmcsFromPath();
+ for (const ToolchainInstallInfo &info : allInfos) {
+ const auto profile = createDmcProfileHelper(info, settings);
+ profiles.push_back(profile);
+ }
+
+ if (allInfos.empty())
+ qbsInfo() << Tr::tr("No DMC toolchains found.");
+}
diff --git a/src/app/qbs-setup-toolchains/dmcprobe.h b/src/app/qbs-setup-toolchains/dmcprobe.h
new file mode 100644
index 000000000..a2fbc74cb
--- /dev/null
+++ b/src/app/qbs-setup-toolchains/dmcprobe.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBS_SETUPTOOLCHAINS_DMCPROBE_H
+#define QBS_SETUPTOOLCHAINS_DMCPROBE_H
+
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+class QFileInfo;
+QT_END_NAMESPACE
+
+namespace qbs {
+class Profile;
+class Settings;
+}
+
+bool isDmcCompiler(const QString &compilerName);
+
+void createDmcProfile(const QFileInfo &compiler, qbs::Settings *settings,
+ QString profileName);
+
+void dmcProbe(qbs::Settings *settings, std::vector<qbs::Profile> &profiles);
+
+#endif // Header guard
diff --git a/src/app/qbs-setup-toolchains/probe.cpp b/src/app/qbs-setup-toolchains/probe.cpp
index efa5d9b78..5a04232e1 100644
--- a/src/app/qbs-setup-toolchains/probe.cpp
+++ b/src/app/qbs-setup-toolchains/probe.cpp
@@ -39,6 +39,8 @@
#include "probe.h"
#include "clangclprobe.h"
+#include "cosmicprobe.h"
+#include "dmcprobe.h"
#include "gccprobe.h"
#include "iarewprobe.h"
#include "keilprobe.h"
@@ -117,6 +119,10 @@ QString toolchainTypeFromCompilerName(const QString &compilerName)
return QStringLiteral("keil");
if (isSdccCompiler(compilerName))
return QStringLiteral("sdcc");
+ if (isCosmicCompiler(compilerName))
+ return QStringLiteral("cosmic");
+ if (isDmcCompiler(compilerName))
+ return QStringLiteral("dmc");
return {};
}
@@ -136,6 +142,8 @@ void probe(Settings *settings)
iarProbe(settings, profiles);
keilProbe(settings, profiles);
sdccProbe(settings, profiles);
+ cosmicProbe(settings, profiles);
+ dmcProbe(settings, profiles);
if (profiles.empty()) {
qStderr << Tr::tr("Could not detect any toolchains. No profile created.") << Qt::endl;
@@ -175,6 +183,10 @@ void createProfile(const QString &profileName, const QString &toolchainType,
createKeilProfile(compiler, settings, profileName);
else if (toolchain.contains(QLatin1String("sdcc")))
createSdccProfile(compiler, settings, profileName);
+ else if (toolchain.contains(QLatin1String("cosmic")))
+ createCosmicProfile(compiler, settings, profileName);
+ else if (toolchain.contains(QLatin1String("dmc")))
+ createDmcProfile(compiler, settings, profileName);
else
throw qbs::ErrorInfo(Tr::tr("Cannot create profile: Unknown toolchain type."));
}
@@ -301,3 +313,21 @@ bool isSameExecutable(const QString &filePath1, const QString &filePath2)
return false;
}
+
+MacrosMap dumpMacros(const std::function<QStringList()> &func)
+{
+ MacrosMap macros;
+ const QStringList lines = func();
+ for (const QString &line : lines) {
+ const QString prefix = QLatin1String("#define ");
+ if (!line.startsWith(prefix))
+ return macros;
+ const auto index = line.indexOf(QLatin1String(" "), prefix.length());
+ if (index != -1) {
+ const auto key = line.mid(prefix.length(), index - prefix.length());
+ const auto value = line.mid(index + 1);
+ macros.insert(key, value);
+ }
+ }
+ return macros;
+}
diff --git a/src/app/qbs-setup-toolchains/probe.h b/src/app/qbs-setup-toolchains/probe.h
index 63b4c6555..e97530285 100644
--- a/src/app/qbs-setup-toolchains/probe.h
+++ b/src/app/qbs-setup-toolchains/probe.h
@@ -46,6 +46,7 @@
#include <QtCore/qstring.h>
#include <QtCore/qstringlist.h>
+#include <functional> // for std::function
#include <tuple> // for std::tie
namespace qbs { class Settings; }
@@ -78,4 +79,9 @@ int extractVersion(const QByteArray &macroDump, const QByteArray &keyToken);
bool isSameExecutable(const QString &exe1, const QString &exe2);
+using MacrosMap = QMap<QString, QString>;
+using DefinesList = QVector<QByteArray>;
+
+MacrosMap dumpMacros(const std::function<QStringList()> &func);
+
#endif // Header guard
diff --git a/src/app/qbs-setup-toolchains/qbs-setup-toolchains.pro b/src/app/qbs-setup-toolchains/qbs-setup-toolchains.pro
index 6581bec63..1ae1c710d 100644
--- a/src/app/qbs-setup-toolchains/qbs-setup-toolchains.pro
+++ b/src/app/qbs-setup-toolchains/qbs-setup-toolchains.pro
@@ -5,6 +5,8 @@ TARGET = qbs-setup-toolchains
HEADERS += \
clangclprobe.h \
commandlineparser.h \
+ cosmicprobe.h \
+ dmcprobe.h \
gccprobe.h \
iarewprobe.h \
keilprobe.h \
@@ -16,6 +18,8 @@ HEADERS += \
SOURCES += \
clangclprobe.cpp \
commandlineparser.cpp \
+ cosmicprobe.cpp \
+ dmcprobe.cpp \
gccprobe.cpp \
iarewprobe.cpp \
keilprobe.cpp \
diff --git a/src/app/qbs-setup-toolchains/qbs-setup-toolchains.qbs b/src/app/qbs-setup-toolchains/qbs-setup-toolchains.qbs
index 3bc72700f..d33b4c8fb 100644
--- a/src/app/qbs-setup-toolchains/qbs-setup-toolchains.qbs
+++ b/src/app/qbs-setup-toolchains/qbs-setup-toolchains.qbs
@@ -8,6 +8,10 @@ QbsApp {
"clangclprobe.h",
"commandlineparser.cpp",
"commandlineparser.h",
+ "cosmicprobe.cpp",
+ "cosmicprobe.h",
+ "dmcprobe.cpp",
+ "dmcprobe.h",
"gccprobe.cpp",
"gccprobe.h",
"iarewprobe.cpp",
diff --git a/src/app/qbs/parser/commandlineparser.cpp b/src/app/qbs/parser/commandlineparser.cpp
index 052f6b92f..5d3c14ebb 100644
--- a/src/app/qbs/parser/commandlineparser.cpp
+++ b/src/app/qbs/parser/commandlineparser.cpp
@@ -111,14 +111,9 @@ public:
bool logTime;
};
-CommandLineParser::CommandLineParser() : d(nullptr)
-{
-}
+CommandLineParser::CommandLineParser() = default;
-CommandLineParser::~CommandLineParser()
-{
- delete d;
-}
+CommandLineParser::~CommandLineParser() = default;
void CommandLineParser::printHelp() const
{
@@ -309,8 +304,7 @@ QList<QVariantMap> CommandLineParser::buildConfigurations() const
bool CommandLineParser::parseCommandLine(const QStringList &args)
{
- delete d;
- d = new CommandLineParserPrivate;
+ d = std::make_unique<CommandLineParserPrivate>();
d->commandLine = args;
try {
d->doParse();
diff --git a/src/app/qbs/parser/commandlineparser.h b/src/app/qbs/parser/commandlineparser.h
index d47657b16..70586b2d4 100644
--- a/src/app/qbs/parser/commandlineparser.h
+++ b/src/app/qbs/parser/commandlineparser.h
@@ -44,6 +44,8 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qvariant.h>
+#include <memory>
+
namespace qbs {
class BuildOptions;
class CleanOptions;
@@ -90,7 +92,7 @@ public:
private:
class CommandLineParserPrivate;
- CommandLineParserPrivate *d;
+ std::unique_ptr<CommandLineParserPrivate> d;
};
} // namespace qbs
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index f029edd1f..8356cd6a1 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -1,2 +1,8 @@
+if (QBS_USE_BUNDLED_QT_SCRIPT OR NOT Qt5Script_FOUND)
+ add_subdirectory(scriptengine)
+else()
+ add_library(qbsscriptengine ALIAS Qt5::Script)
+endif()
+
add_subdirectory(corelib)
add_subdirectory(msbuild)
diff --git a/src/lib/corelib/CMakeLists.txt b/src/lib/corelib/CMakeLists.txt
index 224754a30..06e725ab4 100644
--- a/src/lib/corelib/CMakeLists.txt
+++ b/src/lib/corelib/CMakeLists.txt
@@ -228,6 +228,8 @@ set(LANGUAGE_SOURCES
modulemerger.cpp
modulemerger.h
moduleproviderinfo.h
+ moduleproviderloader.cpp
+ moduleproviderloader.h
preparescriptobserver.cpp
preparescriptobserver.h
projectresolver.cpp
@@ -422,9 +424,14 @@ add_qbs_library(qbscore
PUBLIC_DEFINES
${QBS_PROJECT_FILE_UPDATES_DEFINES}
DEPENDS
- Qt5::CorePrivate Qt5::Network Qt5::Script Qt5::Xml ${EXTERNAL_DEPENDS}
+ Qt${QT_VERSION_MAJOR}::CorePrivate
+ Qt${QT_VERSION_MAJOR}::Network
+ Qt${QT_VERSION_MAJOR}::Xml
+ Qt6Core5Compat
+ qbsscriptengine
PUBLIC_DEPENDS
- Qt5::Core
+ Qt${QT_VERSION_MAJOR}::Core
+ ${EXTERNAL_DEPENDS}
INCLUDES
"${CMAKE_CURRENT_SOURCE_DIR}/../.."
SOURCES
diff --git a/src/lib/corelib/api/runenvironment.cpp b/src/lib/corelib/api/runenvironment.cpp
index 8cea759a8..f54914964 100644
--- a/src/lib/corelib/api/runenvironment.cpp
+++ b/src/lib/corelib/api/runenvironment.cpp
@@ -109,15 +109,12 @@ RunEnvironment::RunEnvironment(const ResolvedProductPtr &product,
const TopLevelProjectConstPtr &project, const InstallOptions &installOptions,
const QProcessEnvironment &environment, const QStringList &setupRunEnvConfig,
Settings *settings, const Logger &logger)
- : d(new RunEnvironmentPrivate(product, project, installOptions, environment, setupRunEnvConfig,
- settings, logger))
+ : d(std::make_unique<RunEnvironmentPrivate>(product, project, installOptions, environment,
+ setupRunEnvConfig, settings, logger))
{
}
-RunEnvironment::~RunEnvironment()
-{
- delete d;
-}
+RunEnvironment::~RunEnvironment() = default;
int RunEnvironment::runShell(ErrorInfo *error)
{
diff --git a/src/lib/corelib/api/runenvironment.h b/src/lib/corelib/api/runenvironment.h
index b95bfbf85..4a967ba63 100644
--- a/src/lib/corelib/api/runenvironment.h
+++ b/src/lib/corelib/api/runenvironment.h
@@ -46,6 +46,8 @@
#include <QtCore/qglobal.h>
#include <QtCore/qstringlist.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QProcess;
class QProcessEnvironment;
@@ -95,7 +97,7 @@ private:
const QProcessEnvironment getBuildEnvironment() const;
class RunEnvironmentPrivate;
- RunEnvironmentPrivate * const d;
+ const std::unique_ptr<RunEnvironmentPrivate> d;
};
} // namespace qbs
diff --git a/src/lib/corelib/buildgraph/buildgraphloader.cpp b/src/lib/corelib/buildgraph/buildgraphloader.cpp
index 58a34b616..c5a377550 100644
--- a/src/lib/corelib/buildgraph/buildgraphloader.cpp
+++ b/src/lib/corelib/buildgraph/buildgraphloader.cpp
@@ -58,6 +58,7 @@
#include <logging/translator.h>
#include <tools/buildgraphlocker.h>
#include <tools/fileinfo.h>
+#include <tools/jsliterals.h>
#include <tools/persistence.h>
#include <tools/profile.h>
#include <tools/profiling.h>
@@ -868,9 +869,23 @@ bool BuildGraphLoader::checkConfigCompatibility()
if (!m_parameters.overrideBuildGraphData()) {
if (!m_parameters.overriddenValues().empty()
&& m_parameters.overriddenValues() != restoredProject->overriddenValues) {
+ const auto toUserOutput = [](const QVariantMap &propMap) {
+ QString o;
+ for (auto it = propMap.begin(); it != propMap.end(); ++it) {
+ if (!o.isEmpty())
+ o += QLatin1Char(' ');
+ o.append(it.key()).append(QLatin1Char(':')).append(toJSLiteral(it.value()));
+ }
+ return o;
+ };
throw ErrorInfo(Tr::tr("Property values set on the command line differ from the "
- "ones used for the previous build. Use the 'resolve' command if "
- "you really want to rebuild with the new properties."));
+ "ones used for the previous build.\n"
+ "Old property values: %1\n"
+ "New property values: %2\n"
+ "Use the 'resolve' command if "
+ "you really want to rebuild with the new properties.")
+ .arg(toUserOutput(restoredProject->overriddenValues))
+ .arg(toUserOutput(m_parameters.overriddenValues())));
}
m_parameters.setOverriddenValues(restoredProject->overriddenValues);
if (m_parameters.topLevelProfile() != restoredProject->profile()) {
diff --git a/src/lib/corelib/corelib.qbs b/src/lib/corelib/corelib.qbs
index 6a5b33f98..65644ea32 100644
--- a/src/lib/corelib/corelib.qbs
+++ b/src/lib/corelib/corelib.qbs
@@ -321,6 +321,8 @@ QbsLibrary {
"modulemerger.cpp",
"modulemerger.h",
"moduleproviderinfo.h",
+ "moduleproviderloader.cpp",
+ "moduleproviderloader.h",
"preparescriptobserver.cpp",
"preparescriptobserver.h",
"projectresolver.cpp",
@@ -530,6 +532,6 @@ QbsLibrary {
}
Export {
Depends { name: "cpp" }
- cpp.defines: base.concat(product.projectFileUpdateDefines)
+ cpp.defines: base.concat(exportingProduct.projectFileUpdateDefines)
}
}
diff --git a/src/lib/corelib/generators/generator.cpp b/src/lib/corelib/generators/generator.cpp
index 90bebdcaa..d3cdce412 100644
--- a/src/lib/corelib/generators/generator.cpp
+++ b/src/lib/corelib/generators/generator.cpp
@@ -58,14 +58,11 @@ public:
};
ProjectGenerator::ProjectGenerator()
- : d(new ProjectGeneratorPrivate)
+ : d(std::make_unique<ProjectGeneratorPrivate>())
{
}
-ProjectGenerator::~ProjectGenerator()
-{
- delete d;
-}
+ProjectGenerator::~ProjectGenerator() = default;
static QString _configurationName(const Project &project)
{
diff --git a/src/lib/corelib/generators/generator.h b/src/lib/corelib/generators/generator.h
index 775469f18..a7cc56b51 100644
--- a/src/lib/corelib/generators/generator.h
+++ b/src/lib/corelib/generators/generator.h
@@ -45,6 +45,8 @@
#include <QtCore/qlist.h>
#include <QtCore/qstring.h>
+#include <memory>
+
namespace qbs {
class ProjectGeneratorPrivate;
@@ -89,7 +91,7 @@ private:
QVariantMap buildConfiguration(const Project &project) const;
QStringList buildConfigurationCommandLine(const Project &project) const;
- ProjectGeneratorPrivate *d;
+ const std::unique_ptr<ProjectGeneratorPrivate> d;
};
} // namespace qbs
diff --git a/src/lib/corelib/jsextensions/binaryfile.cpp b/src/lib/corelib/jsextensions/binaryfile.cpp
index f02f0bff6..bb35235b1 100644
--- a/src/lib/corelib/jsextensions/binaryfile.cpp
+++ b/src/lib/corelib/jsextensions/binaryfile.cpp
@@ -67,7 +67,6 @@ public:
};
static QScriptValue ctor(QScriptContext *context, QScriptEngine *engine);
- ~BinaryFile() override;
Q_INVOKABLE void close();
Q_INVOKABLE QString filePath();
@@ -87,7 +86,7 @@ private:
// ResourceAcquiringScriptObject implementation
void releaseResources() override;
- QFile *m_file = nullptr;
+ std::unique_ptr<QFile> m_file;
};
QScriptValue BinaryFile::ctor(QScriptContext *context, QScriptEngine *engine)
@@ -120,11 +119,6 @@ QScriptValue BinaryFile::ctor(QScriptContext *context, QScriptEngine *engine)
return engine->newQObject(t, QScriptEngine::QtOwnership);
}
-BinaryFile::~BinaryFile()
-{
- delete m_file;
-}
-
BinaryFile::BinaryFile(QScriptContext *context, const QString &filePath, OpenMode mode)
{
Q_ASSERT(thisObject().engine() == engine());
@@ -146,12 +140,11 @@ BinaryFile::BinaryFile(QScriptContext *context, const QString &filePath, OpenMod
return;
}
- m_file = new QFile(filePath);
+ m_file = std::make_unique<QFile>(filePath);
if (Q_UNLIKELY(!m_file->open(m))) {
context->throwError(Tr::tr("Unable to open file '%1': %2")
.arg(filePath, m_file->errorString()));
- delete m_file;
- m_file = nullptr;
+ m_file.reset();
}
}
@@ -160,8 +153,7 @@ void BinaryFile::close()
if (checkForClosed())
return;
m_file->close();
- delete m_file;
- m_file = nullptr;
+ m_file.reset();
}
QString BinaryFile::filePath()
diff --git a/src/lib/corelib/jsextensions/process.cpp b/src/lib/corelib/jsextensions/process.cpp
index 8ddb48acd..8257be6dc 100644
--- a/src/lib/corelib/jsextensions/process.cpp
+++ b/src/lib/corelib/jsextensions/process.cpp
@@ -66,7 +66,6 @@ class Process : public QObject, public QScriptable, public ResourceAcquiringScri
public:
static QScriptValue ctor(QScriptContext *context, QScriptEngine *engine);
Process(QScriptContext *context);
- ~Process() override;
Q_INVOKABLE QString getEnv(const QString &name);
Q_INVOKABLE void setEnv(const QString &name, const QString &value);
@@ -103,7 +102,7 @@ private:
// ResourceAcquiringScriptObject implementation
void releaseResources() override;
- QProcess *m_qProcess = nullptr;
+ std::unique_ptr<QProcess> m_qProcess;
QProcessEnvironment m_environment;
QString m_workingDirectory;
QTextCodec *m_codec = nullptr;
@@ -144,17 +143,12 @@ QScriptValue Process::ctor(QScriptContext *context, QScriptEngine *engine)
return obj;
}
-Process::~Process()
-{
- delete m_qProcess;
-}
-
Process::Process(QScriptContext *context)
{
Q_UNUSED(context);
Q_ASSERT(thisObject().engine() == engine());
- m_qProcess = new QProcess;
+ m_qProcess = std::make_unique<QProcess>();
m_codec = QTextCodec::codecForName("UTF-8");
}
@@ -236,8 +230,7 @@ void Process::close()
if (!m_qProcess)
return;
Q_ASSERT(thisObject().engine() == engine());
- delete m_qProcess;
- m_qProcess = nullptr;
+ m_qProcess.reset();
}
bool Process::waitForFinished(int msecs)
diff --git a/src/lib/corelib/jsextensions/propertylist_darwin.h b/src/lib/corelib/jsextensions/propertylist_darwin.h
index 75900b144..279309681 100644
--- a/src/lib/corelib/jsextensions/propertylist_darwin.h
+++ b/src/lib/corelib/jsextensions/propertylist_darwin.h
@@ -50,6 +50,8 @@
#include <QtScript/qscriptable.h>
#include <QtScript/qscriptvalue.h>
+#include <memory>
+
namespace qbs {
namespace Internal {
@@ -78,7 +80,7 @@ public:
Q_INVOKABLE QString toXMLString() const;
Q_INVOKABLE QString toJSON(const QString &style = QString()) const;
private:
- PropertyListPrivate *d;
+ const std::unique_ptr<PropertyListPrivate> d;
};
} // namespace Internal
diff --git a/src/lib/corelib/jsextensions/propertylist_darwin.mm b/src/lib/corelib/jsextensions/propertylist_darwin.mm
index 7a08b5e9f..caf9feb3e 100644
--- a/src/lib/corelib/jsextensions/propertylist_darwin.mm
+++ b/src/lib/corelib/jsextensions/propertylist_darwin.mm
@@ -94,13 +94,10 @@ PropertyListPrivate::PropertyListPrivate()
{
}
-PropertyList::~PropertyList()
-{
- delete d;
-}
+PropertyList::~PropertyList() = default;
PropertyList::PropertyList(QScriptContext *context)
-: d(new PropertyListPrivate)
+ : d(std::make_unique<PropertyListPrivate>())
{
Q_UNUSED(context);
Q_ASSERT(thisObject().engine() == engine());
diff --git a/src/lib/corelib/jsextensions/textfile.cpp b/src/lib/corelib/jsextensions/textfile.cpp
index 3c7f2d316..f4171b117 100644
--- a/src/lib/corelib/jsextensions/textfile.cpp
+++ b/src/lib/corelib/jsextensions/textfile.cpp
@@ -74,7 +74,6 @@ public:
};
static QScriptValue ctor(QScriptContext *context, QScriptEngine *engine);
- ~TextFile() override;
Q_INVOKABLE void close();
Q_INVOKABLE QString filePath();
@@ -95,7 +94,7 @@ private:
// ResourceAcquiringScriptObject implementation
void releaseResources() override;
- QFile *m_file = nullptr;
+ std::unique_ptr<QFile> m_file;
QTextCodec *m_codec = nullptr;
};
@@ -136,18 +135,13 @@ QScriptValue TextFile::ctor(QScriptContext *context, QScriptEngine *engine)
return engine->newQObject(t, QScriptEngine::QtOwnership);
}
-TextFile::~TextFile()
-{
- delete m_file;
-}
-
TextFile::TextFile(QScriptContext *context, const QString &filePath, OpenMode mode,
const QString &codec)
{
Q_UNUSED(codec)
Q_ASSERT(thisObject().engine() == engine());
- m_file = new QFile(filePath);
+ m_file = std::make_unique<QFile>(filePath);
const auto newCodec = QTextCodec::codecForName(qPrintable(codec));
m_codec = newCodec ? newCodec : QTextCodec::codecForName("UTF-8");
QIODevice::OpenMode m = QIODevice::NotOpen;
@@ -161,8 +155,7 @@ TextFile::TextFile(QScriptContext *context, const QString &filePath, OpenMode mo
if (Q_UNLIKELY(!m_file->open(m))) {
context->throwError(Tr::tr("Unable to open file '%1': %2")
.arg(filePath, m_file->errorString()));
- delete m_file;
- m_file = nullptr;
+ m_file.reset();
}
}
@@ -171,8 +164,7 @@ void TextFile::close()
if (checkForClosed())
return;
m_file->close();
- delete m_file;
- m_file = nullptr;
+ m_file.reset();
}
QString TextFile::filePath()
diff --git a/src/lib/corelib/language/itemreader.cpp b/src/lib/corelib/language/itemreader.cpp
index bdc5570a0..afa768a06 100644
--- a/src/lib/corelib/language/itemreader.cpp
+++ b/src/lib/corelib/language/itemreader.cpp
@@ -88,7 +88,7 @@ void ItemReader::popExtraSearchPaths()
m_allSearchPaths.clear();
}
-std::vector<QStringList> ItemReader::extraSearchPathsStack() const
+const std::vector<QStringList> &ItemReader::extraSearchPathsStack() const
{
return m_extraSearchPaths;
}
@@ -124,6 +124,17 @@ Item *ItemReader::readFile(const QString &filePath)
return m_visitorState->readFile(filePath, allSearchPaths(), m_pool);
}
+Item *ItemReader::readFile(const QString &filePath, const CodeLocation &referencingLocation)
+{
+ try {
+ return readFile(filePath);
+ } catch (const ErrorInfo &e) {
+ if (e.hasLocation())
+ throw;
+ throw ErrorInfo(e.toString(), referencingLocation);
+ }
+}
+
Set<QString> ItemReader::filesRead() const
{
return m_visitorState->filesRead();
diff --git a/src/lib/corelib/language/itemreader.h b/src/lib/corelib/language/itemreader.h
index 2a01d7640..3dc5329d2 100644
--- a/src/lib/corelib/language/itemreader.h
+++ b/src/lib/corelib/language/itemreader.h
@@ -74,12 +74,13 @@ public:
void setSearchPaths(const QStringList &searchPaths);
void pushExtraSearchPaths(const QStringList &extraSearchPaths);
void popExtraSearchPaths();
- std::vector<QStringList> extraSearchPathsStack() const;
+ const std::vector<QStringList> &extraSearchPathsStack() const;
void setExtraSearchPathsStack(const std::vector<QStringList> &s);
void clearExtraSearchPathsStack();
const QStringList &allSearchPaths() const;
Item *readFile(const QString &filePath);
+ Item *readFile(const QString &filePath, const CodeLocation &referencingLocation);
Set<QString> filesRead() const;
diff --git a/src/lib/corelib/language/language.pri b/src/lib/corelib/language/language.pri
index e07a671b9..249093e61 100644
--- a/src/lib/corelib/language/language.pri
+++ b/src/lib/corelib/language/language.pri
@@ -29,6 +29,7 @@ HEADERS += \
$$PWD/moduleloader.h \
$$PWD/modulemerger.h \
$$PWD/moduleproviderinfo.h \
+ $$PWD/moduleproviderloader.h \
$$PWD/preparescriptobserver.h \
$$PWD/projectresolver.h \
$$PWD/property.h \
@@ -63,6 +64,7 @@ SOURCES += \
$$PWD/loader.cpp \
$$PWD/moduleloader.cpp \
$$PWD/modulemerger.cpp \
+ $$PWD/moduleproviderloader.cpp \
$$PWD/preparescriptobserver.cpp \
$$PWD/scriptpropertyobserver.cpp \
$$PWD/projectresolver.cpp \
diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp
index f65421a35..3d059b4a8 100644
--- a/src/lib/corelib/language/moduleloader.cpp
+++ b/src/lib/corelib/language/moduleloader.cpp
@@ -46,6 +46,7 @@
#include "itemreader.h"
#include "language.h"
#include "modulemerger.h"
+#include "moduleproviderloader.h"
#include "qualifiedid.h"
#include "scriptengine.h"
#include "value.h"
@@ -57,7 +58,6 @@
#include <logging/translator.h>
#include <tools/error.h>
#include <tools/fileinfo.h>
-#include <tools/jsliterals.h>
#include <tools/preferences.h>
#include <tools/profile.h>
#include <tools/profiling.h>
@@ -75,7 +75,6 @@
#include <QtCore/qdiriterator.h>
#include <QtCore/qjsondocument.h>
#include <QtCore/qjsonobject.h>
-#include <QtCore/qtemporaryfile.h>
#include <QtCore/qtextstream.h>
#include <QtCore/qthreadstorage.h>
#include <QtScript/qscriptvalueiterator.h>
@@ -227,15 +226,25 @@ private:
class SearchPathsManager {
public:
- SearchPathsManager(ItemReader *itemReader, const QStringList &extraSearchPaths)
+ explicit SearchPathsManager(ItemReader *itemReader)
: m_itemReader(itemReader)
+ , m_oldSize(itemReader->extraSearchPathsStack().size())
+ {
+ }
+ SearchPathsManager(ItemReader *itemReader, const QStringList &extraSearchPaths)
+ : SearchPathsManager(itemReader)
{
m_itemReader->pushExtraSearchPaths(extraSearchPaths);
}
- ~SearchPathsManager() { m_itemReader->popExtraSearchPaths(); }
+ ~SearchPathsManager()
+ {
+ while (m_itemReader->extraSearchPathsStack().size() > m_oldSize)
+ m_itemReader->popExtraSearchPaths();
+ }
private:
ItemReader * const m_itemReader;
+ size_t m_oldSize{0};
};
ModuleLoader::ModuleLoader(Evaluator *evaluator, Logger &logger)
@@ -244,6 +253,7 @@ ModuleLoader::ModuleLoader(Evaluator *evaluator, Logger &logger)
, m_progressObserver(nullptr)
, m_reader(std::make_unique<ItemReader>(logger))
, m_evaluator(evaluator)
+ , m_moduleProviderLoader(std::make_unique<ModuleProviderLoader>(m_reader.get(), m_evaluator))
{
}
@@ -279,7 +289,7 @@ void ModuleLoader::setStoredProfiles(const QVariantMap &profiles)
void ModuleLoader::setStoredModuleProviderInfo(const ModuleProviderInfoList &moduleProviderInfo)
{
- m_moduleProviderInfo = moduleProviderInfo;
+ m_moduleProviderLoader->setModuleProviderInfo(moduleProviderInfo);
}
ModuleLoaderResult ModuleLoader::load(const SetupProjectParameters &parameters)
@@ -294,9 +304,11 @@ ModuleLoaderResult ModuleLoader::load(const SetupProjectParameters &parameters)
m_disabledItems.clear();
m_reader->clearExtraSearchPathsStack();
m_reader->setEnableTiming(parameters.logElapsedTime());
+ m_moduleProviderLoader->setProjectParameters(m_parameters);
m_elapsedTimeProbes = m_elapsedTimePrepareProducts = m_elapsedTimeHandleProducts
= m_elapsedTimeProductDependencies = m_elapsedTimeTransitiveDependencies
= m_elapsedTimePropertyChecking = 0;
+ m_elapsedTimeModuleProviders = 0;
m_elapsedTimeProbes = 0;
m_probesEncountered = m_probesRun = m_probesCachedCurrent = m_probesCachedOld = 0;
m_settings = std::make_unique<Settings>(parameters.settingsDirectory());
@@ -369,7 +381,7 @@ ModuleLoaderResult ModuleLoader::load(const SetupProjectParameters &parameters)
handleTopLevelProject(&result, root, buildDirectory,
Set<QString>() << QDir::cleanPath(parameters.projectFilePath()));
result.root = root;
- result.qbsFiles = m_reader->filesRead() - m_tempQbsFiles;
+ result.qbsFiles = m_reader->filesRead() - m_moduleProviderLoader->tempQbsFiles();
for (auto it = m_localProfiles.cbegin(); it != m_localProfiles.cend(); ++it)
result.profileConfigs.remove(it.key());
printProfilingInfo();
@@ -590,9 +602,9 @@ void ModuleLoader::handleTopLevelProject(ModuleLoaderResult *loadResult, Item *p
throw err;
handleProductError(err, &productContext);
}
- for (std::size_t i = 0; i < productContext.newlyAddedModuleProviderSearchPaths.size(); ++i)
- m_reader->popExtraSearchPaths();
- productContext.newlyAddedModuleProviderSearchPaths.clear();
+ // extraSearchPathsStack is changed during dependency resolution, check
+ // that we've rolled back all the changes
+ QBS_CHECK(m_reader->extraSearchPathsStack() == projectContext->searchPathsStack);
}
}
if (!m_productsWithDeferredDependsItems.empty() || !m_exportsWithDeferredDependsItems.empty()) {
@@ -631,7 +643,7 @@ void ModuleLoader::handleTopLevelProject(ModuleLoaderResult *loadResult, Item *p
}
loadResult->projectProbes = tlp.probes;
- loadResult->moduleProviderInfo = m_moduleProviderInfo;
+ loadResult->moduleProviderInfo = m_moduleProviderLoader->moduleProviderInfo();
m_reader->clearExtraSearchPathsStack();
AccumulatingTimer timer(m_parameters.logElapsedTime()
@@ -673,8 +685,8 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult,
return;
}
topLevelProjectContext->projects.push_back(p.release());
- m_reader->pushExtraSearchPaths(readExtraSearchPaths(projectItem)
- << projectItem->file()->dirPath());
+ SearchPathsManager searchPathsManager(m_reader.get(), readExtraSearchPaths(projectItem)
+ << projectItem->file()->dirPath());
projectContext.searchPathsStack = m_reader->extraSearchPathsStack();
projectContext.item = projectItem;
@@ -758,7 +770,6 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult,
break;
}
}
- m_reader->popExtraSearchPaths();
}
QString ModuleLoader::MultiplexInfo::toIdString(size_t row) const
@@ -1328,6 +1339,10 @@ void ModuleLoader::setupProductDependencies(ProductContext *productContext,
if (m_dependencyResolvingPass == 1)
setSearchPathsForProduct(productContext);
+
+ // Module providers may push some extra search paths which we will be cleared
+ // by this SearchPathsManager. However, they will be also added to productContext->searchPaths
+ // so second pass will take that into account
SearchPathsManager searchPathsManager(m_reader.get(), productContext->searchPaths);
DependsContext dependsContext;
@@ -1920,6 +1935,9 @@ void ModuleLoader::printProfilingInfo()
<< Tr::tr("Setting up product dependencies took %1.")
.arg(elapsedTimeString(m_elapsedTimeProductDependencies));
m_logger.qbsLog(LoggerInfo, true) << "\t\t"
+ << Tr::tr("Running module providers took %1.")
+ .arg(elapsedTimeString(m_elapsedTimeModuleProviders));
+ m_logger.qbsLog(LoggerInfo, true) << "\t\t"
<< Tr::tr("Setting up transitive product dependencies took %1.")
.arg(elapsedTimeString(m_elapsedTimeTransitiveDependencies));
m_logger.qbsLog(LoggerInfo, true) << "\t"
@@ -2046,14 +2064,7 @@ bool ModuleLoader::mergeExportItems(const ProductContext &productContext)
Item *ModuleLoader::loadItemFromFile(const QString &filePath,
const CodeLocation &referencingLocation)
{
- Item *item;
- try {
- item = m_reader->readFile(filePath);
- } catch (const ErrorInfo &e) {
- if (e.hasLocation())
- throw;
- throw ErrorInfo(e.toString(), referencingLocation);
- }
+ Item *item = m_reader->readFile(filePath, referencingLocation);
handleAllPropertyOptionsItems(item);
return item;
}
@@ -2228,20 +2239,7 @@ void ModuleLoader::setSearchPathsForProduct(ModuleLoader::ProductContext *produc
product->searchPaths << p;
}
- // Existing module provider search paths are re-used if and only if the provider configuration
- // at setup time was the same as the current one for the respective module provider.
- if (!m_moduleProviderInfo.empty()) {
- const QVariantMap configForProduct = moduleProviderConfig(*product);
- for (const ModuleProviderInfo &c : m_moduleProviderInfo) {
- if (configForProduct.value(c.name.toString()).toMap() == c.config) {
- qCDebug(lcModuleLoader) << "re-using search paths" << c.searchPaths
- << "from module provider" << c.name
- << "for product" << product->name;
- product->knownModuleProviders.insert(c.name);
- product->searchPaths << c.searchPaths;
- }
- }
- }
+ m_moduleProviderLoader->setupKnownModuleProviders(*product);
}
ModuleLoader::ShadowProductInfo ModuleLoader::getShadowProductInfo(
@@ -3109,28 +3107,13 @@ Item *ModuleLoader::searchAndLoadModuleFile(ProductContext *productContext,
auto existingPaths = findExistingModulePaths(m_reader->allSearchPaths(), moduleName);
if (existingPaths.isEmpty()) { // no suitable names found, try to use providers
- bool moduleAlreadyKnown = false;
- ModuleProviderResult result;
- for (QualifiedId providerName = moduleName; !providerName.empty();
- providerName.pop_back()) {
- if (!productContext->knownModuleProviders.insert(providerName).second) {
- moduleAlreadyKnown = true;
- break;
- }
- qCDebug(lcModuleLoader) << "Module" << moduleName.toString()
- << "not found, checking for module providers";
- result = findModuleProvider(providerName, *productContext,
- ModuleProviderLookup::Regular, dependsItemLocation);
- if (result.providerFound)
- break;
- }
- if (fallbackMode == FallbackMode::Enabled && !result.providerFound
- && !moduleAlreadyKnown) {
- qCDebug(lcModuleLoader) << "Specific module provider not found for"
- << moduleName.toString() << ", setting up fallback.";
- result = findModuleProvider(moduleName, *productContext,
- ModuleProviderLookup::Fallback, dependsItemLocation);
- }
+ AccumulatingTimer providersTimer(
+ m_parameters.logElapsedTime() ? &m_elapsedTimeModuleProviders : nullptr);
+ const auto result = m_moduleProviderLoader->executeModuleProvider(
+ *productContext,
+ dependsItemLocation,
+ moduleName,
+ fallbackMode);
if (result.providerAddedSearchPaths) {
qCDebug(lcModuleLoader) << "Re-checking for module" << moduleName.toString()
<< "with newly added search paths from module provider";
@@ -3470,10 +3453,11 @@ void ModuleLoader::instantiateModule(ProductContext *productContext, Item *expor
if (exportingProduct) {
const auto exportingProductItemValue = ItemValue::create(exportingProduct);
moduleScope->setProperty(QStringLiteral("exportingProduct"), exportingProductItemValue);
- moduleScope->setProperty(QStringLiteral("importingProduct"),
- ItemValue::create(productContext->item));
- // TODO: Remove in 1.20.
+ const auto importingProductItemValue = ItemValue::create(productContext->item);
+ moduleScope->setProperty(QStringLiteral("importingProduct"), importingProductItemValue);
+
+ // TODO: Remove in 1.21.
moduleScope->setProperty(StringConstants::productVar(), exportingProductItemValue);
moduleScope->setProperty(StringConstants::projectVar(),
@@ -3799,155 +3783,6 @@ QStringList ModuleLoader::findExistingModulePaths(
return result;
}
-QVariantMap ModuleLoader::moduleProviderConfig(ModuleLoader::ProductContext &product)
-{
- 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, &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;
- switch (it.value()->type()) {
- case Value::ItemValueType: {
- const auto childItem = static_cast<ItemValue *>(it.value().get())->item();
- childItem->setScope(item->scope());
- collectMap(childItem, QualifiedId(name) << it.key());
- continue;
- }
- case Value::JSSourceValueType:
- value = m_evaluator->value(item, it.key()).toVariant();
- break;
- case Value::VariantValueType:
- value = static_cast<VariantValue *>(it.value().get())->value();
- break;
- }
- QVariantMap m = providerConfig.value(name.toString()).toMap();
- m.insert(it.key(), value);
- providerConfig.insert(name.toString(), m);
- }
- };
- configItemValue->item()->setScope(product.item);
- collectMap(configItemValue->item(), QualifiedId());
- }
- for (auto it = product.moduleProperties.begin(); it != product.moduleProperties.end(); ++it) {
- if (!it.key().startsWith(QStringLiteral("moduleProviders.")))
- continue;
- const QString provider = it.key().mid(QStringLiteral("moduleProviders.").size());
- const QVariantMap providerConfigFromBuildConfig = it.value().toMap();
- if (providerConfigFromBuildConfig.empty())
- continue;
- QVariantMap currentMapForProvider = providerConfig.value(provider).toMap();
- for (auto propIt = providerConfigFromBuildConfig.begin();
- propIt != providerConfigFromBuildConfig.end(); ++propIt) {
- currentMapForProvider.insert(propIt.key(), propIt.value());
- }
- providerConfig.insert(provider, currentMapForProvider);
- }
- return *(product.theModuleProviderConfig = std::move(providerConfig));
-}
-
-ModuleLoader::ModuleProviderResult ModuleLoader::findModuleProvider(const QualifiedId &name,
- ModuleLoader::ProductContext &product, ModuleProviderLookup lookupType,
- const CodeLocation &dependsItemLocation)
-{
- for (const QString &path : m_reader->allSearchPaths()) {
- QString fullPath = FileInfo::resolvePath(path, QStringLiteral("module-providers"));
- switch (lookupType) {
- case ModuleProviderLookup::Regular:
- for (const QString &component : name)
- fullPath = FileInfo::resolvePath(fullPath, component);
- break;
- case ModuleProviderLookup::Fallback:
- fullPath = FileInfo::resolvePath(fullPath, QStringLiteral("__fallback"));
- break;
- }
- const QString providerFile = FileInfo::resolvePath(fullPath,
- QStringLiteral("provider.qbs"));
- if (!FileInfo::exists(providerFile)) {
- qCDebug(lcModuleLoader) << "No module provider found at" << providerFile;
- continue;
- }
- QTemporaryFile dummyItemFile;
- if (!dummyItemFile.open()) {
- throw ErrorInfo(Tr::tr("Failed to create temporary file for running module provider "
- "for dependency '%1': %2").arg(name.toString(),
- dummyItemFile.errorString()));
- }
- m_tempQbsFiles << dummyItemFile.fileName();
- qCDebug(lcModuleLoader) << "Instantiating module provider at" << providerFile;
- const QString projectBuildDir = product.project->item->variantProperty(
- StringConstants::buildDirectoryProperty())->value().toString();
- const QString searchPathBaseDir = ModuleProviderInfo::outputDirPath(projectBuildDir, name);
- const QVariant moduleConfig = moduleProviderConfig(product).value(name.toString());
- QTextStream stream(&dummyItemFile);
- using Qt::endl;
- setupDefaultCodec(stream);
- stream << "import qbs.FileInfo" << endl;
- stream << "import qbs.Utilities" << endl;
- stream << "import '" << providerFile << "' as Provider" << endl;
- stream << "Provider {" << endl;
- stream << " name: " << toJSLiteral(name.toString()) << endl;
- stream << " property var config: (" << toJSLiteral(moduleConfig) << ')' << endl;
- stream << " outputBaseDir: FileInfo.joinPaths(baseDirPrefix, "
- " Utilities.getHash(JSON.stringify(config)))" << endl;
- stream << " property string baseDirPrefix: " << toJSLiteral(searchPathBaseDir) << endl;
- stream << " property stringList searchPaths: (relativeSearchPaths || [])"
- " .map(function(p) { return FileInfo.joinPaths(outputBaseDir, p); })"
- << endl;
- stream << "}" << endl;
- stream.flush();
- Item * const providerItem = loadItemFromFile(dummyItemFile.fileName(), dependsItemLocation);
- if (providerItem->type() != ItemType::ModuleProvider) {
- throw ErrorInfo(Tr::tr("File '%1' declares an item of type '%2', "
- "but '%3' was expected.")
- .arg(providerFile, providerItem->typeName(),
- BuiltinDeclarations::instance().nameForType(ItemType::ModuleProvider)));
- }
- providerItem->setParent(product.item);
- const QVariantMap configMap = moduleConfig.toMap();
- for (auto it = configMap.begin(); it != configMap.end(); ++it) {
- const PropertyDeclaration decl = providerItem->propertyDeclaration(it.key());
- if (!decl.isValid()) {
- throw ErrorInfo(Tr::tr("No such property '%1' in module provider '%2'.")
- .arg(it.key(), name.toString()));
- }
- providerItem->setProperty(it.key(), VariantValue::create(it.value()));
- }
- EvalContextSwitcher contextSwitcher(m_evaluator->engine(), EvalContext::ModuleProvider);
- const QStringList searchPaths
- = m_evaluator->stringListValue(providerItem, QStringLiteral("searchPaths"));
- const auto addToGlobalInfo = [=] {
- m_moduleProviderInfo.emplace_back(ModuleProviderInfo(name, moduleConfig.toMap(),
- searchPaths, m_parameters.dryRun()));
- };
- if (searchPaths.empty()) {
- qCDebug(lcModuleLoader) << "Module provider did run, but did not set up "
- "any modules.";
- addToGlobalInfo();
- return {true, false};
- }
- qCDebug(lcModuleLoader) << "Module provider added" << searchPaths.size()
- << "new search path(s)";
-
- // (1) is needed so the immediate new look-up works.
- // (2) is needed so the next use of SearchPathManager considers the new paths.
- // (3) is needed for the code that removes the product-specific search paths when
- // product handling is done.
- // (4) is needed for possible re-use in subsequent products and builds.
- m_reader->pushExtraSearchPaths(searchPaths); // (1)
- product.searchPaths << searchPaths; // (2)
- product.newlyAddedModuleProviderSearchPaths.push_back(searchPaths); // (3)
- addToGlobalInfo(); // (4)
- return {true, true};
- }
- return {};
-}
-
void ModuleLoader::setScopeForDescendants(Item *item, Item *scope)
{
for (Item * const child : item->children()) {
diff --git a/src/lib/corelib/language/moduleloader.h b/src/lib/corelib/language/moduleloader.h
index 3dc091003..1e39c2cf5 100644
--- a/src/lib/corelib/language/moduleloader.h
+++ b/src/lib/corelib/language/moduleloader.h
@@ -73,6 +73,7 @@ namespace Internal {
class Evaluator;
class Item;
class ItemReader;
+class ModuleProviderLoader;
class ProgressObserver;
class QualifiedId;
@@ -137,6 +138,7 @@ public:
ModuleLoaderResult load(const SetupProjectParameters &parameters);
private:
+ friend class ModuleProviderLoader;
class ProductSortByDependencies;
class ContextBase
@@ -185,7 +187,6 @@ private:
std::unordered_map<const Item *, std::vector<ErrorInfo>> unknownProfilePropertyErrors;
QStringList searchPaths;
- std::vector<QStringList> newlyAddedModuleProviderSearchPaths;
Set<QualifiedId> knownModuleProviders;
std::optional<QVariantMap> theModuleProviderConfig;
@@ -344,19 +345,6 @@ private:
QStringList findExistingModulePaths(
const QStringList &searchPaths, const QualifiedId &moduleName);
- enum class ModuleProviderLookup { Regular, Fallback };
- struct ModuleProviderResult
- {
- ModuleProviderResult() = default;
- ModuleProviderResult(bool ran, bool added)
- : providerFound(ran), providerAddedSearchPaths(added) {}
- bool providerFound = false;
- bool providerAddedSearchPaths = false;
- };
- ModuleProviderResult findModuleProvider(const QualifiedId &name, ProductContext &product,
- ModuleProviderLookup lookupType, const CodeLocation &dependsItemLocation);
- QVariantMap moduleProviderConfig(ProductContext &product);
-
static void setScopeForDescendants(Item *item, Item *scope);
void overrideItemProperties(Item *item, const QString &buildConfigKey,
const QVariantMap &buildConfig);
@@ -414,6 +402,7 @@ private:
ProgressObserver *m_progressObserver;
const std::unique_ptr<ItemReader> m_reader;
Evaluator *m_evaluator;
+ const std::unique_ptr<ModuleProviderLoader> m_moduleProviderLoader;
QMap<QString, QStringList> m_moduleDirListCache;
QHash<std::pair<QString, QualifiedId>, std::optional<QString>> m_existingModulePathCache;
@@ -454,9 +443,6 @@ private:
std::unordered_map<ProductContext *, Set<DeferredDependsContext>> m_productsWithDeferredDependsItems;
Set<Item *> m_exportsWithDeferredDependsItems;
- ModuleProviderInfoList m_moduleProviderInfo;
- Set<QString> m_tempQbsFiles;
-
SetupProjectParameters m_parameters;
std::unique_ptr<Settings> m_settings;
Version m_qbsVersion;
@@ -465,6 +451,7 @@ private:
qint64 m_elapsedTimeProbes = 0;
qint64 m_elapsedTimePrepareProducts = 0;
qint64 m_elapsedTimeProductDependencies = 0;
+ qint64 m_elapsedTimeModuleProviders = 0;
qint64 m_elapsedTimeTransitiveDependencies = 0;
qint64 m_elapsedTimeHandleProducts = 0;
qint64 m_elapsedTimePropertyChecking = 0;
diff --git a/src/lib/corelib/language/moduleproviderloader.cpp b/src/lib/corelib/language/moduleproviderloader.cpp
new file mode 100644
index 000000000..e8e12e216
--- /dev/null
+++ b/src/lib/corelib/language/moduleproviderloader.cpp
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "moduleproviderloader.h"
+
+#include "builtindeclarations.h"
+#include "evaluator.h"
+#include "itemreader.h"
+#include "moduleloader.h"
+
+#include <language/scriptengine.h>
+#include <language/value.h>
+
+#include <logging/categories.h>
+#include <logging/translator.h>
+
+#include <tools/fileinfo.h>
+#include <tools/jsliterals.h>
+#include <tools/stringconstants.h>
+
+#include <QtCore/qtemporaryfile.h>
+
+namespace qbs {
+namespace Internal {
+
+ModuleProviderLoader::ModuleProviderLoader(ItemReader *reader, Evaluator *evaluator)
+ : m_reader(reader)
+ , m_evaluator(evaluator)
+{
+}
+
+void ModuleProviderLoader::setupKnownModuleProviders(ProductContext &product)
+{
+ // Existing module provider search paths are re-used if and only if the provider configuration
+ // at setup time was the same as the current one for the respective module provider.
+ if (!m_moduleProviderInfo.empty()) {
+ const QVariantMap configForProduct = moduleProviderConfig(product);
+ for (const ModuleProviderInfo &c : m_moduleProviderInfo) {
+ if (configForProduct.value(c.name.toString()).toMap() == c.config) {
+ qCDebug(lcModuleLoader) << "re-using search paths" << c.searchPaths
+ << "from module provider" << c.name
+ << "for product" << product.name;
+ product.knownModuleProviders.insert(c.name);
+ product.searchPaths << c.searchPaths;
+ }
+ }
+ }
+}
+
+ModuleProviderLoader::ModuleProviderResult ModuleProviderLoader::executeModuleProvider(
+ ProductContext &productContext,
+ const CodeLocation &dependsItemLocation,
+ const QualifiedId &moduleName,
+ FallbackMode fallbackMode)
+{
+ bool moduleAlreadyKnown = false;
+ ModuleProviderResult result;
+ for (QualifiedId providerName = moduleName; !providerName.empty();
+ providerName.pop_back()) {
+ if (!productContext.knownModuleProviders.insert(providerName).second) {
+ moduleAlreadyKnown = true;
+ break;
+ }
+ qCDebug(lcModuleLoader) << "Module" << moduleName.toString()
+ << "not found, checking for module providers";
+ result = findModuleProvider(providerName, productContext,
+ ModuleProviderLookup::Regular, dependsItemLocation);
+ if (result.providerFound)
+ break;
+ }
+ if (fallbackMode == FallbackMode::Enabled && !result.providerFound
+ && !moduleAlreadyKnown) {
+ qCDebug(lcModuleLoader) << "Specific module provider not found for"
+ << moduleName.toString() << ", setting up fallback.";
+ result = findModuleProvider(moduleName, productContext,
+ ModuleProviderLookup::Fallback, dependsItemLocation);
+ }
+ return result;
+}
+
+ModuleProviderLoader::ModuleProviderResult ModuleProviderLoader::findModuleProvider(
+ const QualifiedId &name,
+ ProductContext &product,
+ ModuleProviderLookup lookupType,
+ const CodeLocation &dependsItemLocation)
+{
+ const QString providerFile = findModuleProviderFile(name, lookupType);
+ if (providerFile.isEmpty())
+ return {};
+
+ const QVariantMap config = moduleProviderConfig(product).value(name.toString()).toMap();
+ const QStringList searchPaths
+ = getProviderSearchPaths(name, providerFile, product, config, dependsItemLocation);
+ const auto addToGlobalInfo = [=] {
+ m_moduleProviderInfo.emplace_back(ModuleProviderInfo(name, config,
+ searchPaths, m_parameters.dryRun()));
+ };
+ if (searchPaths.empty()) {
+ qCDebug(lcModuleLoader) << "Module provider did run, but did not set up "
+ "any modules.";
+ addToGlobalInfo();
+ return {true, false};
+ }
+ qCDebug(lcModuleLoader) << "Module provider added" << searchPaths.size()
+ << "new search path(s)";
+
+ // (1) is needed so the immediate new look-up works.
+ // (2) is needed so the next use of SearchPathManager considers the new paths.
+ // (3) is needed for possible re-use in subsequent products and builds.
+ m_reader->pushExtraSearchPaths(searchPaths); // (1)
+ product.searchPaths << searchPaths; // (2)
+ addToGlobalInfo(); // (3)
+ return {true, true};
+}
+
+QVariantMap ModuleProviderLoader::moduleProviderConfig(
+ ProductContext &product)
+{
+ 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, &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;
+ switch (it.value()->type()) {
+ case Value::ItemValueType: {
+ const auto childItem = static_cast<ItemValue *>(it.value().get())->item();
+ childItem->setScope(item->scope());
+ collectMap(childItem, QualifiedId(name) << it.key());
+ continue;
+ }
+ case Value::JSSourceValueType:
+ value = m_evaluator->value(item, it.key()).toVariant();
+ break;
+ case Value::VariantValueType:
+ value = static_cast<VariantValue *>(it.value().get())->value();
+ break;
+ }
+ QVariantMap m = providerConfig.value(name.toString()).toMap();
+ m.insert(it.key(), value);
+ providerConfig.insert(name.toString(), m);
+ }
+ };
+ configItemValue->item()->setScope(product.item);
+ collectMap(configItemValue->item(), QualifiedId());
+ }
+ for (auto it = product.moduleProperties.begin(); it != product.moduleProperties.end(); ++it) {
+ if (!it.key().startsWith(QStringLiteral("moduleProviders.")))
+ continue;
+ const QString provider = it.key().mid(QStringLiteral("moduleProviders.").size());
+ const QVariantMap providerConfigFromBuildConfig = it.value().toMap();
+ if (providerConfigFromBuildConfig.empty())
+ continue;
+ QVariantMap currentMapForProvider = providerConfig.value(provider).toMap();
+ for (auto propIt = providerConfigFromBuildConfig.begin();
+ propIt != providerConfigFromBuildConfig.end(); ++propIt) {
+ currentMapForProvider.insert(propIt.key(), propIt.value());
+ }
+ providerConfig.insert(provider, currentMapForProvider);
+ }
+ return *(product.theModuleProviderConfig = std::move(providerConfig));
+}
+
+QString ModuleProviderLoader::findModuleProviderFile(
+ const QualifiedId &name, ModuleProviderLookup lookupType)
+{
+ for (const QString &path : m_reader->allSearchPaths()) {
+ QString fullPath = FileInfo::resolvePath(path, QStringLiteral("module-providers"));
+ switch (lookupType) {
+ case ModuleProviderLookup::Regular:
+ for (const QString &component : name)
+ fullPath = FileInfo::resolvePath(fullPath, component);
+ break;
+ case ModuleProviderLookup::Fallback:
+ fullPath = FileInfo::resolvePath(fullPath, QStringLiteral("__fallback"));
+ break;
+ }
+ const QString providerFile = FileInfo::resolvePath(fullPath,
+ QStringLiteral("provider.qbs"));
+ if (!FileInfo::exists(providerFile)) {
+ qCDebug(lcModuleLoader) << "No module provider found at" << providerFile;
+ continue;
+ }
+ return providerFile;
+ }
+ return {};
+}
+
+QStringList ModuleProviderLoader::getProviderSearchPaths(
+ const QualifiedId &name,
+ const QString &providerFile,
+ ProductContext &product,
+ const QVariantMap &moduleConfig,
+ const CodeLocation &location)
+{
+ QTemporaryFile dummyItemFile;
+ if (!dummyItemFile.open()) {
+ throw ErrorInfo(Tr::tr("Failed to create temporary file for running module provider "
+ "for dependency '%1': %2").arg(name.toString(),
+ dummyItemFile.errorString()));
+ }
+ m_tempQbsFiles << dummyItemFile.fileName();
+ qCDebug(lcModuleLoader) << "Instantiating module provider at" << providerFile;
+ const QString projectBuildDir = product.project->item->variantProperty(
+ StringConstants::buildDirectoryProperty())->value().toString();
+ const QString searchPathBaseDir = ModuleProviderInfo::outputDirPath(projectBuildDir, name);
+ QTextStream stream(&dummyItemFile);
+ using Qt::endl;
+ setupDefaultCodec(stream);
+ stream << "import qbs.FileInfo" << endl;
+ stream << "import qbs.Utilities" << endl;
+ stream << "import '" << providerFile << "' as Provider" << endl;
+ stream << "Provider {" << endl;
+ stream << " name: " << toJSLiteral(name.toString()) << endl;
+ stream << " property var config: (" << toJSLiteral(moduleConfig) << ')' << endl;
+ stream << " outputBaseDir: FileInfo.joinPaths(baseDirPrefix, "
+ " Utilities.getHash(JSON.stringify(config)))" << endl;
+ stream << " property string baseDirPrefix: " << toJSLiteral(searchPathBaseDir) << endl;
+ stream << " property stringList searchPaths: (relativeSearchPaths || [])"
+ " .map(function(p) { return FileInfo.joinPaths(outputBaseDir, p); })"
+ << endl;
+ stream << "}" << endl;
+ stream.flush();
+ Item * const providerItem =
+ m_reader->readFile(dummyItemFile.fileName(), location);
+ if (providerItem->type() != ItemType::ModuleProvider) {
+ throw ErrorInfo(Tr::tr("File '%1' declares an item of type '%2', "
+ "but '%3' was expected.")
+ .arg(providerFile, providerItem->typeName(),
+ BuiltinDeclarations::instance().nameForType(ItemType::ModuleProvider)));
+ }
+ providerItem->setParent(product.item);
+ for (auto it = moduleConfig.begin(); it != moduleConfig.end(); ++it) {
+ const PropertyDeclaration decl = providerItem->propertyDeclaration(it.key());
+ if (!decl.isValid()) {
+ throw ErrorInfo(Tr::tr("No such property '%1' in module provider '%2'.")
+ .arg(it.key(), name.toString()));
+ }
+ providerItem->setProperty(it.key(), VariantValue::create(it.value()));
+ }
+ EvalContextSwitcher contextSwitcher(m_evaluator->engine(), EvalContext::ModuleProvider);
+ return m_evaluator->stringListValue(providerItem, QStringLiteral("searchPaths"));
+}
+
+} // namespace Internal
+} // namespace qbs
diff --git a/src/lib/corelib/language/moduleproviderloader.h b/src/lib/corelib/language/moduleproviderloader.h
new file mode 100644
index 000000000..e5455a1aa
--- /dev/null
+++ b/src/lib/corelib/language/moduleproviderloader.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MODULEPROVIDERLOADER_H
+#define MODULEPROVIDERLOADER_H
+
+#include "moduleloader.h"
+#include "moduleproviderinfo.h"
+
+#include <QtCore/qmap.h>
+#include <QtCore/qvariant.h>
+
+namespace qbs {
+namespace Internal {
+
+class ModuleProviderLoader
+{
+public:
+ using ProductContext = ModuleLoader::ProductContext;
+ using FallbackMode = ModuleLoader::FallbackMode;
+ explicit ModuleProviderLoader(ItemReader *itemReader, Evaluator *evaluator);
+
+ enum class ModuleProviderLookup { Regular, Fallback };
+ struct ModuleProviderResult
+ {
+ ModuleProviderResult() = default;
+ ModuleProviderResult(bool ran, bool added)
+ : providerFound(ran), providerAddedSearchPaths(added) {}
+ bool providerFound = false;
+ bool providerAddedSearchPaths = false;
+ };
+
+ const ModuleProviderInfoList &moduleProviderInfo() const { return m_moduleProviderInfo; }
+ void setModuleProviderInfo(ModuleProviderInfoList moduleProviderInfo)
+ {
+ m_moduleProviderInfo = std::move(moduleProviderInfo);
+ }
+
+ void setProjectParameters(SetupProjectParameters parameters)
+ {
+ m_parameters = std::move(parameters);
+ }
+
+ void setupKnownModuleProviders(ProductContext &product);
+ ModuleProviderResult executeModuleProvider(
+ ProductContext &productContext,
+ const CodeLocation &dependsItemLocation,
+ const QualifiedId &moduleName,
+ FallbackMode fallbackMode);
+ ModuleProviderResult findModuleProvider(
+ const QualifiedId &name,
+ ProductContext &product,
+ ModuleProviderLookup lookupType,
+ const CodeLocation &dependsItemLocation);
+ QVariantMap moduleProviderConfig(ProductContext &product);
+
+ const Set<QString> &tempQbsFiles() const { return m_tempQbsFiles; }
+
+private:
+ QString findModuleProviderFile(const QualifiedId &name, ModuleProviderLookup lookupType);
+ QStringList getProviderSearchPaths(
+ const QualifiedId &name,
+ const QString &providerFile,
+ ProductContext &product,
+ const QVariantMap &moduleConfig,
+ const CodeLocation &location);
+
+private:
+ ItemReader *const m_reader{nullptr};
+ Evaluator *const m_evaluator{nullptr};
+
+ SetupProjectParameters m_parameters;
+ ModuleProviderInfoList m_moduleProviderInfo;
+ Set<QString> m_tempQbsFiles;
+};
+
+} // namespace Internal
+} // namespace qbs
+
+#endif // MODULEPROVIDERLOADER_H
diff --git a/src/lib/corelib/logging/ilogsink.cpp b/src/lib/corelib/logging/ilogsink.cpp
index 4eb930cbf..20cf52bcd 100644
--- a/src/lib/corelib/logging/ilogsink.cpp
+++ b/src/lib/corelib/logging/ilogsink.cpp
@@ -82,14 +82,11 @@ public:
std::mutex mutex;
};
-ILogSink::ILogSink() : d(new ILogSinkPrivate)
+ILogSink::ILogSink() : d(std::make_unique<ILogSinkPrivate>())
{
}
-ILogSink::~ILogSink()
-{
- delete d;
-}
+ILogSink::~ILogSink() = default;
void ILogSink::setLogLevel(LoggerLevel level)
{
diff --git a/src/lib/corelib/logging/ilogsink.h b/src/lib/corelib/logging/ilogsink.h
index 4b25aa7b8..0a055abc1 100644
--- a/src/lib/corelib/logging/ilogsink.h
+++ b/src/lib/corelib/logging/ilogsink.h
@@ -43,6 +43,8 @@
#include <QtCore/qstring.h>
+#include <memory>
+
namespace qbs {
class ErrorInfo;
@@ -83,7 +85,7 @@ private:
const QString &tag) = 0;
class ILogSinkPrivate;
- ILogSinkPrivate * const d;
+ const std::unique_ptr<ILogSinkPrivate> d;
};
} // namespace qbs
diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h
index 29d586177..ed3238f2b 100644
--- a/src/lib/corelib/tools/persistence.h
+++ b/src/lib/corelib/tools/persistence.h
@@ -453,6 +453,33 @@ template<typename T, typename U> struct PPHelper<std::pair<T, U>>
}
};
+template<typename... Args> struct PPHelper<std::tuple<Args...>>
+{
+ template<std::size_t... Ns>
+ static void storeHelper(
+ std::index_sequence<Ns...>, const std::tuple<Args...> &tuple, PersistentPool *pool)
+ {
+ (pool->store(std::get<Ns>(tuple)), ...);
+ }
+
+ static void store(const std::tuple<Args...> &tuple, PersistentPool *pool)
+ {
+ storeHelper(std::make_index_sequence<sizeof...(Args)>(), tuple, pool);
+ }
+
+ template<std::size_t... Ns>
+ static void loadHelper(
+ std::index_sequence<Ns...>, std::tuple<Args...> &tuple, PersistentPool *pool)
+ {
+ (pool->load(std::get<Ns>(tuple)), ...);
+ }
+
+ static void load(std::tuple<Args...> &tuple, PersistentPool * pool)
+ {
+ loadHelper(std::make_index_sequence<sizeof...(Args)>(), tuple, pool);
+ }
+};
+
template<typename T> struct PPHelper<QFlags<T>>
{
using Int = typename QFlags<T>::Int;
diff --git a/src/lib/corelib/tools/profiling.cpp b/src/lib/corelib/tools/profiling.cpp
index 7e3559b54..db64a73c6 100644
--- a/src/lib/corelib/tools/profiling.cpp
+++ b/src/lib/corelib/tools/profiling.cpp
@@ -61,7 +61,7 @@ TimedActivityLogger::TimedActivityLogger(const Logger &logger, const QString &ac
{
if (!enabled)
return;
- d = new TimedActivityLoggerPrivate;
+ d = std::make_unique<TimedActivityLoggerPrivate>();
d->logger = logger;
d->activity = activity;
d->logger.qbsLog(LoggerInfo, true) << Tr::tr("Starting activity '%2'.").arg(activity);
@@ -75,8 +75,7 @@ void TimedActivityLogger::finishActivity()
const QString timeString = elapsedTimeString(d->timer.elapsed());
d->logger.qbsLog(LoggerInfo, true)
<< Tr::tr("Activity '%2' took %3.").arg(d->activity, timeString);
- delete d;
- d = nullptr;
+ d.reset();
}
TimedActivityLogger::~TimedActivityLogger()
diff --git a/src/lib/corelib/tools/profiling.h b/src/lib/corelib/tools/profiling.h
index 89f862ff9..c6fc9ede7 100644
--- a/src/lib/corelib/tools/profiling.h
+++ b/src/lib/corelib/tools/profiling.h
@@ -42,6 +42,8 @@
#include <QtCore/qelapsedtimer.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QString;
QT_END_NAMESPACE
@@ -61,7 +63,7 @@ public:
private:
class TimedActivityLoggerPrivate;
- TimedActivityLoggerPrivate *d;
+ std::unique_ptr<TimedActivityLoggerPrivate> d;
};
class AccumulatingTimer
diff --git a/src/lib/corelib/tools/qttools.cpp b/src/lib/corelib/tools/qttools.cpp
index ffd336d56..4a82bc5e0 100644
--- a/src/lib/corelib/tools/qttools.cpp
+++ b/src/lib/corelib/tools/qttools.cpp
@@ -41,6 +41,26 @@
#include <QtCore/qprocess.h>
+namespace std {
+
+size_t hash<QVariant>::operator()(const QVariant &v) const noexcept
+{
+ switch (v.userType()) {
+ case QMetaType::UnknownType: return 0;
+ case QMetaType::Int: return std::hash<int>()(v.toInt());
+ case QMetaType::UInt: return std::hash<int>()(v.toUInt());
+ case QMetaType::QString: return std::hash<QString>()(v.toString());
+ case QMetaType::QStringList: return std::hash<QStringList>()(v.toStringList());
+ case QMetaType::QVariantList: return std::hash<QVariantList>()(v.toList());
+ case QMetaType::QVariantMap: return std::hash<QVariantMap>()(v.toMap());
+ case QMetaType::QVariantHash: return std::hash<QVariantHash>()(v.toHash());
+ default:
+ QBS_ASSERT("Unsupported variant type" && false, return 0);
+ }
+}
+
+} // namespace std
+
QT_BEGIN_NAMESPACE
uint qHash(const QStringList &list)
diff --git a/src/lib/corelib/tools/qttools.h b/src/lib/corelib/tools/qttools.h
index bbec32544..86e81936b 100644
--- a/src/lib/corelib/tools/qttools.h
+++ b/src/lib/corelib/tools/qttools.h
@@ -40,6 +40,9 @@
#ifndef QBSQTTOOLS_H
#define QBSQTTOOLS_H
+#include <tools/qbsassert.h>
+#include <tools/stlutils.h>
+
#include <QtCore/qhash.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qtextstream.h>
@@ -71,6 +74,64 @@ template<typename T1, typename T2> struct hash<std::pair<T1, T2>>
return std::hash<T1>()(x.first) ^ std::hash<T2>()(x.second);
}
};
+
+template <typename... Ts>
+struct hash<std::tuple<Ts...>>
+{
+private:
+ template<std::size_t... Ns>
+ static size_t helper(std::index_sequence<Ns...>, const std::tuple<Ts...> &tuple) noexcept
+ {
+ size_t seed = 0;
+ (qbs::Internal::hashCombineHelper(seed, std::get<Ns>(tuple)), ...);
+ return seed;
+ }
+
+public:
+ size_t operator()(const std::tuple<Ts...> & tuple) const noexcept
+ {
+ return helper(std::make_index_sequence<sizeof...(Ts)>(), tuple);
+ }
+};
+
+
+template<> struct hash<QStringList>
+{
+ std::size_t operator()(const QStringList &s) const noexcept
+ {
+ return qbs::Internal::hashRange(s);
+ }
+};
+
+template<> struct hash<QVariant>
+{
+ size_t operator()(const QVariant &v) const noexcept;
+};
+
+template<> struct hash<QVariantList>
+{
+ size_t operator()(const QVariantList &v) const noexcept
+ {
+ return qbs::Internal::hashRange(v);
+ }
+};
+
+template<> struct hash<QVariantMap>
+{
+ size_t operator()(const QVariantMap &v) const noexcept
+ {
+ return qbs::Internal::hashRange(v);
+ }
+};
+
+template<> struct hash<QVariantHash>
+{
+ size_t operator()(const QVariantHash &v) const noexcept
+ {
+ return qbs::Internal::hashRange(v);
+ }
+};
+
} // namespace std
QT_BEGIN_NAMESPACE
@@ -78,6 +139,27 @@ QT_BEGIN_NAMESPACE
uint qHash(const QStringList &list);
uint qHash(const QProcessEnvironment &env);
+template<typename... Args>
+uint qHash(const std::tuple<Args...> &tuple)
+{
+ return std::hash<std::tuple<Args...>>()(tuple) % std::numeric_limits<uint>::max();
+}
+
+inline uint qHash(const QVariant &v)
+{
+ return std::hash<QVariant>()(v) % std::numeric_limits<uint>::max();
+}
+
+inline uint qHash(const QVariantMap &v)
+{
+ return std::hash<QVariantMap>()(v) % std::numeric_limits<uint>::max();
+}
+
+inline uint qHash(const QVariantHash &v)
+{
+ return std::hash<QVariantHash>()(v) % std::numeric_limits<uint>::max();
+}
+
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
namespace Qt {
inline QTextStream &endl(QTextStream &stream) { return stream << QT_PREPEND_NAMESPACE(endl); }
diff --git a/src/lib/corelib/tools/settingsmodel.cpp b/src/lib/corelib/tools/settingsmodel.cpp
index 7192ef45f..7b75cc050 100644
--- a/src/lib/corelib/tools/settingsmodel.cpp
+++ b/src/lib/corelib/tools/settingsmodel.cpp
@@ -123,17 +123,15 @@ public:
};
SettingsModel::SettingsModel(const QString &settingsDir, Settings::Scope scope, QObject *parent)
- : QAbstractItemModel(parent), d(new SettingsModelPrivate)
+ : QAbstractItemModel(parent),
+ d(std::make_unique<SettingsModelPrivate>())
{
d->settings = std::make_unique<qbs::Settings>(settingsDir);
d->settings->setScopeForWriting(scope);
d->readSettings();
}
-SettingsModel::~SettingsModel()
-{
- delete d;
-}
+SettingsModel::~SettingsModel() = default;
void SettingsModel::reload()
{
diff --git a/src/lib/corelib/tools/settingsmodel.h b/src/lib/corelib/tools/settingsmodel.h
index 1bd59737c..63651d300 100644
--- a/src/lib/corelib/tools/settingsmodel.h
+++ b/src/lib/corelib/tools/settingsmodel.h
@@ -46,6 +46,8 @@
#include <QtCore/qabstractitemmodel.h>
#include <QtCore/qvariant.h>
+#include <memory>
+
namespace qbs {
class QBS_EXPORT SettingsModel : public QAbstractItemModel
@@ -81,7 +83,7 @@ public:
private:
class SettingsModelPrivate;
- SettingsModelPrivate * const d;
+ const std::unique_ptr<SettingsModelPrivate> d;
};
} // namespace qbs
diff --git a/src/lib/corelib/tools/stlutils.h b/src/lib/corelib/tools/stlutils.h
index d4c569a95..e13fcdfe5 100644
--- a/src/lib/corelib/tools/stlutils.h
+++ b/src/lib/corelib/tools/stlutils.h
@@ -152,6 +152,37 @@ C &operator<<(C &container, const C &other)
return container;
}
+// based on http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0814r0.pdf
+template<typename T>
+void hashCombineHelper(size_t &seed, const T &val)
+{
+ seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+}
+
+template<typename... Types>
+size_t hashCombine(const Types &... args)
+{
+ size_t seed = 0;
+ (hashCombineHelper(seed, args), ...); // create hash value with seed over all args return seed;
+ return seed;
+}
+
+template<typename It>
+size_t hashRange(It first, It last)
+{
+ size_t seed = 0;
+ for (; first != last; ++first)
+ hashCombineHelper(seed, *first);
+
+ return seed;
+}
+
+template<typename R>
+size_t hashRange(R &&range)
+{
+ return hashRange(std::begin(range), std::end(range));
+}
+
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/msbuild/io/msbuildprojectwriter.cpp b/src/lib/msbuild/io/msbuildprojectwriter.cpp
index aaab11aa6..986458a7f 100644
--- a/src/lib/msbuild/io/msbuildprojectwriter.cpp
+++ b/src/lib/msbuild/io/msbuildprojectwriter.cpp
@@ -86,23 +86,20 @@ public:
};
MSBuildProjectWriter::MSBuildProjectWriter(std::ostream *device)
- : d(new MSBuildProjectWriterPrivate)
+ : d(std::make_unique<MSBuildProjectWriterPrivate>())
{
d->device = device;
d->writer = std::make_unique<QXmlStreamWriter>(&d->buffer);
d->writer->setAutoFormatting(true);
}
-MSBuildProjectWriter::~MSBuildProjectWriter()
-{
- delete d;
-}
+MSBuildProjectWriter::~MSBuildProjectWriter() = default;
bool MSBuildProjectWriter::write(const MSBuildProject *project)
{
d->buffer.clear();
d->writer->writeStartDocument();
- project->accept(d);
+ project->accept(d.get());
d->writer->writeEndDocument();
if (d->writer->hasError())
return false;
diff --git a/src/lib/msbuild/io/msbuildprojectwriter.h b/src/lib/msbuild/io/msbuildprojectwriter.h
index cfe6beb7b..9feb347c5 100644
--- a/src/lib/msbuild/io/msbuildprojectwriter.h
+++ b/src/lib/msbuild/io/msbuildprojectwriter.h
@@ -35,6 +35,8 @@
#include <QtCore/qglobal.h>
+#include <memory>
+
namespace qbs {
class MSBuildProject;
@@ -50,7 +52,7 @@ public:
bool write(const MSBuildProject *project);
private:
- MSBuildProjectWriterPrivate *d;
+ const std::unique_ptr<MSBuildProjectWriterPrivate> d;
};
} // namespace qbs
diff --git a/src/lib/scriptengine/CMakeLists.txt b/src/lib/scriptengine/CMakeLists.txt
new file mode 100644
index 000000000..01c6cd09b
--- /dev/null
+++ b/src/lib/scriptengine/CMakeLists.txt
@@ -0,0 +1,361 @@
+set(QT_SCRIPT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../shared/qtscript/src/")
+
+if (UNIX)
+ set(_USE_SYSTEM_MALLOC NO)
+else()
+ set(_USE_SYSTEM_MALLOC YES)
+endif (UNIX)
+
+set(JAVASCRIPT_CORE_INCLUDES
+ assembler
+ bytecode
+ bytecompiler
+ debugger
+ interpreter
+ jit
+ parser
+ pcre
+ profiler
+ runtime
+ wrec
+ wtf
+ wtf/unicode
+ yarr
+ API
+ ForwardingHeaders
+ generated
+)
+list_transform_prepend(JAVASCRIPT_CORE_INCLUDES "${QT_SCRIPT_PATH}/3rdparty/javascriptcore/JavaScriptCore/")
+
+set(QT_SCRIPT_PUBLIC_INCLUDES
+ "${CMAKE_CURRENT_SOURCE_DIR}/include"
+ "${CMAKE_CURRENT_BINARY_DIR}/include"
+)
+
+set(QT_SCRIPT_INCLUDES
+ "${QT_SCRIPT_PATH}/3rdparty/javascriptcore"
+ "${QT_SCRIPT_PATH}/3rdparty/javascriptcore/JavaScriptCore"
+ "${QT_SCRIPT_PATH}/script"
+ "${QT_SCRIPT_PATH}/script/api"
+ "${QT_SCRIPT_PATH}/script/parser"
+ "${CMAKE_CURRENT_BINARY_DIR}/include/QtScript/${QT_VERSION}/QtScript"
+)
+
+set(QT_SCRIPT_DEFINES
+ "QT_BUILD_SCRIPT_LIB"
+ "QT_NO_USING_NAMESPACE"
+ "JSC=QTJSC"
+ "jscyyparse=qtjscyyparse"
+ "jscyylex=qtjscyylex"
+ "jscyyerror=qtjscyyerror"
+ "WTF=QTWTF"
+ "LOG_DISABLED=1"
+ "WTF_USE_JAVASCRIPTCORE_BINDINGS=1"
+ "WTF_CHANGES=1"
+ "JS_NO_EXPORT"
+
+ # JavaScriptCore
+ "BUILDING_QT__"
+ "BUILDING_JavaScriptCore"
+ "BUILDING_WTF"
+ "ENABLE_JIT=0"
+ "ENABLE_YARR_JIT=0"
+ "ENABLE_YARR=0"
+
+ # WebKit
+ "WTF_USE_ACCELERATED_COMPOSITING"
+)
+
+if (APPLE)
+ list(APPEND QT_SCRIPT_DEFINES "ENABLE_JSC_MULTIPLE_THREADS=0")
+elseif(WIN32)
+ list(APPEND QT_SCRIPT_DEFINES "NOMINMAX" "_CRT_RAND_S")
+endif()
+
+if (MSVC)
+ set(QT_SCRIPT_CXX_FLAGS "/wd4291" "/wd4344" "/wd4396" "/wd4503" "/wd4800" "/wd4819" "/wd4996")
+else()
+ set(QT_SCRIPT_CXX_FLAGS "-fno-strict-aliasing" "-w"
+ "-Wall" "-Wreturn-type" "-Wcast-align" "-Wchar-subscripts"
+ "-Wformat-security" "-Wreturn-type" "-Wno-unused-parameter"
+ "-Wno-sign-compare" "-Wno-switch" "-Wno-switch-enum" "-Wundef"
+ "-Wmissing-noreturn" "-Winit-self" "-Wno-deprecated" "-Wno-suggest-attribute=noreturn"
+ "-Wno-nonnull-compare" "-pthread")
+endif()
+
+set(QT_SCRIPT_PUBLIC_DEPENDS Qt${QT_VERSION_MAJOR}::Core)
+if (UNIX)
+ list(APPEND QT_SCRIPT_PUBLIC_DEPENDS "pthread")
+elseif(WIN32)
+ list(APPEND QT_SCRIPT_PUBLIC_DEPENDS "winmm")
+endif()
+
+set(PCRE_SOURCES
+ pcre_compile.cpp
+ pcre_exec.cpp
+ pcre_tables.cpp
+ pcre_ucp_searchfuncs.cpp
+ pcre_xclass.cpp
+)
+list_transform_prepend(PCRE_SOURCES "${QT_SCRIPT_PATH}/3rdparty/javascriptcore/JavaScriptCore/pcre/")
+
+if (NOT _USE_SYSTEM_MALLOC)
+ set(SYSTEM_MALLOC_SOURCES
+ wtf/TCSystemAlloc.cpp
+ )
+ list_transform_prepend(SYSTEM_MALLOC_SOURCES "${QT_SCRIPT_PATH}/3rdparty/javascriptcore/JavaScriptCore/")
+
+ list(APPEND QT_SCRIPT_DEFINES "USE_SYSTEM_MALLOC")
+else()
+ set(SYSTEM_MALLOC_SOURCES "")
+endif()
+
+set(JAVASCRIPT_CORE_SOURCES
+ API/JSBase.cpp
+ API/JSCallbackConstructor.cpp
+ API/JSCallbackFunction.cpp
+ API/JSCallbackObject.cpp
+ API/JSClassRef.cpp
+ API/JSContextRef.cpp
+ API/JSObjectRef.cpp
+ API/JSStringRef.cpp
+ API/JSValueRef.cpp
+ API/OpaqueJSString.cpp
+ assembler/ARMAssembler.cpp
+ assembler/MacroAssemblerARM.cpp
+ bytecode/CodeBlock.cpp
+ bytecode/JumpTable.cpp
+ bytecode/Opcode.cpp
+ bytecode/SamplingTool.cpp
+ bytecode/StructureStubInfo.cpp
+ bytecompiler/BytecodeGenerator.cpp
+ bytecompiler/NodesCodegen.cpp
+ debugger/DebuggerActivation.cpp
+ debugger/DebuggerCallFrame.cpp
+ debugger/Debugger.cpp
+ generated/Grammar.cpp
+ interpreter/CallFrame.cpp
+ interpreter/Interpreter.cpp
+ interpreter/RegisterFile.cpp
+ parser/Lexer.cpp
+ parser/Nodes.cpp
+ parser/ParserArena.cpp
+ parser/Parser.cpp
+ profiler/Profile.cpp
+ profiler/ProfileGenerator.cpp
+ profiler/ProfileNode.cpp
+ profiler/Profiler.cpp
+ runtime/ArgList.cpp
+ runtime/Arguments.cpp
+ runtime/ArrayConstructor.cpp
+ runtime/ArrayPrototype.cpp
+ runtime/BooleanConstructor.cpp
+ runtime/BooleanObject.cpp
+ runtime/BooleanPrototype.cpp
+ runtime/CallData.cpp
+ runtime/Collector.cpp
+ runtime/CommonIdentifiers.cpp
+ runtime/Completion.cpp
+ runtime/ConstructData.cpp
+ runtime/DateConstructor.cpp
+ runtime/DateConversion.cpp
+ runtime/DateInstance.cpp
+ runtime/DatePrototype.cpp
+ runtime/ErrorConstructor.cpp
+ runtime/Error.cpp
+ runtime/ErrorInstance.cpp
+ runtime/ErrorPrototype.cpp
+ runtime/ExceptionHelpers.cpp
+ runtime/Executable.cpp
+ runtime/FunctionConstructor.cpp
+ runtime/FunctionPrototype.cpp
+ runtime/GetterSetter.cpp
+ runtime/GlobalEvalFunction.cpp
+ runtime/Identifier.cpp
+ runtime/InitializeThreading.cpp
+ runtime/InternalFunction.cpp
+ runtime/JSActivation.cpp
+ runtime/JSAPIValueWrapper.cpp
+ runtime/JSArray.cpp
+ runtime/JSByteArray.cpp
+ runtime/JSCell.cpp
+ runtime/JSFunction.cpp
+ runtime/JSGlobalData.cpp
+ runtime/JSGlobalObject.cpp
+ runtime/JSGlobalObjectFunctions.cpp
+ runtime/JSImmediate.cpp
+ runtime/JSLock.cpp
+ runtime/JSNotAnObject.cpp
+ runtime/JSNumberCell.cpp
+ runtime/JSObject.cpp
+ runtime/JSONObject.cpp
+ runtime/JSPropertyNameIterator.cpp
+ runtime/JSStaticScopeObject.cpp
+ runtime/JSString.cpp
+ runtime/JSValue.cpp
+ runtime/JSVariableObject.cpp
+ runtime/JSWrapperObject.cpp
+ runtime/LiteralParser.cpp
+ runtime/Lookup.cpp
+ runtime/MarkStackPosix.cpp
+ runtime/MarkStackSymbian.cpp
+ runtime/MarkStackWin.cpp
+ runtime/MarkStack.cpp
+ runtime/MathObject.cpp
+ runtime/NativeErrorConstructor.cpp
+ runtime/NativeErrorPrototype.cpp
+ runtime/NumberConstructor.cpp
+ runtime/NumberObject.cpp
+ runtime/NumberPrototype.cpp
+ runtime/ObjectConstructor.cpp
+ runtime/ObjectPrototype.cpp
+ runtime/Operations.cpp
+ runtime/PropertyDescriptor.cpp
+ runtime/PropertyNameArray.cpp
+ runtime/PropertySlot.cpp
+ runtime/PrototypeFunction.cpp
+ runtime/RegExpConstructor.cpp
+ runtime/RegExp.cpp
+ runtime/RegExpObject.cpp
+ runtime/RegExpPrototype.cpp
+ runtime/ScopeChain.cpp
+ runtime/SmallStrings.cpp
+ runtime/StringConstructor.cpp
+ runtime/StringObject.cpp
+ runtime/StringPrototype.cpp
+ runtime/StructureChain.cpp
+ runtime/Structure.cpp
+ runtime/TimeoutChecker.cpp
+ runtime/UString.cpp
+ runtime/UStringImpl.cpp
+ wtf/Assertions.cpp
+ wtf/ByteArray.cpp
+ wtf/CurrentTime.cpp
+ wtf/DateMath.cpp
+ wtf/dtoa.cpp
+ wtf/FastMalloc.cpp
+ wtf/HashTable.cpp
+ wtf/MainThread.cpp
+ wtf/qt/MainThreadQt.cpp
+ wtf/qt/ThreadingQt.cpp
+ wtf/RandomNumber.cpp
+ wtf/RefCountedLeakCounter.cpp
+ wtf/ThreadingNone.cpp
+ wtf/Threading.cpp
+ wtf/TypeTraits.cpp
+ wtf/unicode/CollatorDefault.cpp
+ wtf/unicode/icu/CollatorICU.cpp
+ wtf/unicode/UTF8.cpp
+)
+list_transform_prepend(JAVASCRIPT_CORE_SOURCES "${QT_SCRIPT_PATH}/3rdparty/javascriptcore/JavaScriptCore/")
+
+set(API_SOURCES
+ qscriptable.cpp
+ qscriptable.h
+ qscriptable_p.h
+ qscriptclass.cpp
+ qscriptclass.h
+ qscriptclasspropertyiterator.cpp
+ qscriptclasspropertyiterator.h
+ qscriptcontext.cpp
+ qscriptcontext.h
+ qscriptcontextinfo.cpp
+ qscriptcontextinfo.h
+ qscriptcontext_p.h
+ qscriptengineagent.cpp
+ qscriptengineagent.h
+ qscriptengineagent_p.h
+ qscriptengine.cpp
+ qscriptengine.h
+ qscriptengine_p.h
+ qscriptextensioninterface.h
+ qscriptextensionplugin.cpp
+ qscriptextensionplugin.h
+ qscriptprogram.cpp
+ qscriptprogram.h
+ qscriptprogram_p.h
+ qscriptstring.cpp
+ qscriptstring.h
+ qscriptstring_p.h
+ qscriptvalue.cpp
+ qscriptvalue.h
+ qscriptvalueiterator.cpp
+ qscriptvalueiterator.h
+ qscriptvalue_p.h
+ qtscriptglobal.h
+)
+list_transform_prepend(API_SOURCES "${QT_SCRIPT_PATH}/script/api/")
+
+set(BRIDGE_SOURCES
+ qscriptactivationobject.cpp
+ qscriptactivationobject_p.h
+ qscriptclassobject.cpp
+ qscriptclassobject_p.h
+ qscriptfunction.cpp
+ qscriptfunction_p.h
+ qscriptglobalobject.cpp
+ qscriptglobalobject_p.h
+ qscriptobject.cpp
+ qscriptobject_p.h
+ qscriptqobject.cpp
+ qscriptqobject_p.h
+ qscriptstaticscopeobject.cpp
+ qscriptstaticscopeobject_p.h
+ qscriptvariant.cpp
+ qscriptvariant_p.h
+)
+list_transform_prepend(BRIDGE_SOURCES "${QT_SCRIPT_PATH}/script/bridge/")
+
+set(PARSER_SOURCES
+ qscriptast.cpp
+ qscriptastfwd_p.h
+ qscriptast_p.h
+ qscriptastvisitor.cpp
+ qscriptastvisitor_p.h
+ qscriptgrammar.cpp
+ qscriptgrammar_p.h
+ qscriptlexer.cpp
+ qscriptlexer_p.h
+ qscriptsyntaxchecker.cpp
+ qscriptsyntaxchecker_p.h
+)
+list_transform_prepend(PARSER_SOURCES "${QT_SCRIPT_PATH}/script/parser/")
+
+find_package(Perl)
+
+get_target_property(_QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
+get_filename_component(_QT_BIN_DIRECTORY ${_QT_QMAKE_EXECUTABLE} DIRECTORY)
+
+file(GLOB API_HEADERS "${QT_SCRIPT_PATH}/script/api/*.h")
+
+message("${QT_SCRIPT_PATH}")
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/QtScript/qscriptengine.h"
+ COMMAND ${PERL_EXECUTABLE} "${_QT_BIN_DIRECTORY}/syncqt.pl"
+ -minimal
+ -version "${QT_VERSION}"
+ -outdir ${CMAKE_CURRENT_BINARY_DIR}
+ "${QT_SCRIPT_PATH}/.."
+ BYPRODUCTS
+ DEPENDS ${API_HEADERS}
+ )
+
+add_qbs_library(qbsscriptengine
+ STATIC
+ DEFINES ${QT_SCRIPT_DEFINES}
+ DEPENDS Qt${QT_VERSION_MAJOR}::CorePrivate Qt6Core5Compat
+ PUBLIC_DEPENDS ${QT_SCRIPT_PUBLIC_DEPENDS}
+ INCLUDES ${QT_SCRIPT_PUBLIC_INCLUDES} ${QT_SCRIPT_INCLUDES} ${JAVASCRIPT_CORE_INCLUDES}
+ PUBLIC_INCLUDES ${QT_SCRIPT_PUBLIC_INCLUDES}
+ SOURCES
+ "${CMAKE_CURRENT_BINARY_DIR}/include/QtScript/qscriptengine.h"
+ ${PCRE_SOURCES}
+ ${SYSTEM_MALLOC_SOURCES}
+ ${JAVASCRIPT_CORE_SOURCES}
+ ${API_SOURCES}
+ ${BRIDGE_SOURCES}
+ ${PARSER_SOURCES}
+ )
+set_property(TARGET qbsscriptengine PROPERTY CXX_STANDARD 14)
+target_compile_options(qbsscriptengine PRIVATE ${QT_SCRIPT_CXX_FLAGS})
diff --git a/src/lib/scriptengine/scriptengine.qbs b/src/lib/scriptengine/scriptengine.qbs
index 3225ceaac..c7061fa98 100644
--- a/src/lib/scriptengine/scriptengine.qbs
+++ b/src/lib/scriptengine/scriptengine.qbs
@@ -368,7 +368,7 @@ Project {
Export {
Depends { name: "QtScriptFwdHeaders" }
Depends { name: "cpp" }
- property stringList includePaths: [product.sourceDirectory + "/include"]
+ property stringList includePaths: [exportingProduct.sourceDirectory + "/include"]
.concat(QtScriptFwdHeaders.publicIncludePaths)
Properties {
condition: qbs.targetOS.contains("unix")
@@ -441,10 +441,10 @@ Project {
Export {
Depends { name: "Qt.core" }
property stringList publicIncludePaths: [
- FileInfo.joinPaths(product.buildDirectory, "include")
+ FileInfo.joinPaths(exportingProduct.buildDirectory, "include")
]
property stringList privateIncludePaths: [
- FileInfo.joinPaths(product.buildDirectory, "include",
+ FileInfo.joinPaths(exportingProduct.buildDirectory, "include",
"QtScript", Qt.core.version, "QtScript")
]
}
diff --git a/src/libexec/qbs_processlauncher/CMakeLists.txt b/src/libexec/qbs_processlauncher/CMakeLists.txt
index 73aca9f07..03ab07cbe 100644
--- a/src/libexec/qbs_processlauncher/CMakeLists.txt
+++ b/src/libexec/qbs_processlauncher/CMakeLists.txt
@@ -15,7 +15,7 @@ list_transform_prepend(PROTOCOL_SOURCES ${PATH_TO_PROTOCOL_SOURCES}/)
add_qbs_app(qbs_processlauncher
DESTINATION ${QBS_LIBEXEC_INSTALL_DIR}
- DEPENDS Qt5::Core Qt5::Network
+ DEPENDS Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Network
INCLUDES ${PATH_TO_PROTOCOL_SOURCES}
SOURCES ${SOURCES} ${PROTOCOL_SOURCES}
)
diff --git a/src/plugins/scanner/qt/qtscanner.cpp b/src/plugins/scanner/qt/qtscanner.cpp
index 310de33fc..81f0d602b 100644
--- a/src/plugins/scanner/qt/qtscanner.cpp
+++ b/src/plugins/scanner/qt/qtscanner.cpp
@@ -71,11 +71,11 @@ struct OpaqQrc
int fd = 0;
int mapl = 0;
#else
- QFile *file = nullptr;
+ std::unique_ptr<QFile> file;
#endif
char *map = nullptr;
- QXmlStreamReader *xml = nullptr;
+ std::unique_ptr<QXmlStreamReader> xml;
QByteArray current;
OpaqQrc() = default;
@@ -86,10 +86,7 @@ struct OpaqQrc
munmap (map, mapl);
if (fd)
close (fd);
-#else
- delete file;
#endif
- delete xml;
}
};
@@ -118,7 +115,8 @@ static void *openScannerQrc(const unsigned short *filePath, const char *fileTags
if (map == nullptr)
return nullptr;
#else
- opaque->file = new QFile(QString::fromUtf16(reinterpret_cast<const char16_t *>(filePath)));
+ opaque->file = std::make_unique<QFile>(
+ QString::fromUtf16(reinterpret_cast<const char16_t *>(filePath)));
if (!opaque->file->open(QFile::ReadOnly))
return nullptr;
@@ -129,7 +127,8 @@ static void *openScannerQrc(const unsigned short *filePath, const char *fileTags
#endif
opaque->map = reinterpret_cast<char *>(map);
- opaque->xml = new QXmlStreamReader(QByteArray::fromRawData(opaque->map, fileSize));
+ opaque->xml = std::make_unique<QXmlStreamReader>(
+ QByteArray::fromRawData(opaque->map, fileSize));
return static_cast<void *>(opaque.release());
}
diff --git a/src/shared/qtscript b/src/shared/qtscript
-Subproject 0d3b268f3880dea9555601fbd4d559201c239b7
+Subproject e19477e1129a4c64e023006c59878637d594e99
diff --git a/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs b/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs
index cc86a4402..2efe8d4e8 100644
--- a/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs
+++ b/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs
@@ -64,7 +64,7 @@ Project {
Export {
Depends { name: "cpp" }
- cpp.includePaths: [product.sourceDirectory]
+ cpp.includePaths: [exportingProduct.sourceDirectory]
}
}
}
diff --git a/tests/auto/api/testdata/link-static-lib/link-static-lib.qbs b/tests/auto/api/testdata/link-static-lib/link-static-lib.qbs
index 6960c7d17..829aa5f3e 100644
--- a/tests/auto/api/testdata/link-static-lib/link-static-lib.qbs
+++ b/tests/auto/api/testdata/link-static-lib/link-static-lib.qbs
@@ -25,7 +25,7 @@ Project {
Depends { name: "helper2" }
Export {
Depends { name: "cpp" }
- cpp.includePaths: [product.sourceDirectory + '/helper1']
+ cpp.includePaths: [exportingProduct.sourceDirectory + '/helper1']
}
}
@@ -38,7 +38,7 @@ Project {
Depends { name: "cpp" }
Export {
Depends { name: "cpp" }
- cpp.includePaths: [product.sourceDirectory + '/helper2']
+ cpp.includePaths: [exportingProduct.sourceDirectory + '/helper2']
}
}
}
diff --git a/tests/auto/blackbox/find/find-android.qbs b/tests/auto/blackbox/find/find-android.qbs
index de5c78d10..1cde0ed84 100644
--- a/tests/auto/blackbox/find/find-android.qbs
+++ b/tests/auto/blackbox/find/find-android.qbs
@@ -41,6 +41,7 @@ Product {
if (product.moduleProperty("Android.sdk", "present")) {
tools["sdk"] = product.moduleProperty("Android.sdk", "sdkDir");
tools["sdk-build-tools-dx"] = product.Android.sdk.dxFilePath;
+ tools["sdk-build-tools-d8"] = product.Android.sdk.d8FilePath;
}
if (product.java && product.java.present)
diff --git a/tests/auto/blackbox/testdata-android/qt-app/TestQt6.java b/tests/auto/blackbox/testdata-android/qt-app/TestQt6.java
new file mode 100644
index 000000000..239507122
--- /dev/null
+++ b/tests/auto/blackbox/testdata-android/qt-app/TestQt6.java
@@ -0,0 +1,54 @@
+package org.qbs.example;
+
+import org.qtproject.qt.android.bindings.QtActivity;
+import android.os.*;
+import android.content.*;
+import android.app.*;
+import android.util.Log;
+
+import java.lang.String;
+import android.content.Intent;
+
+import org.qbs.example.*;
+
+
+public class TestQt6 extends QtActivity
+{
+ public static native void testFunc(String test);
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.d("qbs", "onCreate Test");
+ Intent theIntent = getIntent();
+ if (theIntent != null) {
+ String theAction = theIntent.getAction();
+ if (theAction != null) {
+ Log.d("qbs onCreate ", theAction);
+ }
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.d("qbs", "onDestroy");
+ System.exit(0);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ Log.d("qbs onActivityResult", "requestCode: "+requestCode);
+ if (resultCode == RESULT_OK) {
+ Log.d("qbs onActivityResult - resultCode: ", "SUCCESS");
+ } else {
+ Log.d("qbs onActivityResult - resultCode: ", "CANCEL");
+ }
+ }
+
+ @Override
+ public void onNewIntent(Intent intent) {
+ Log.d("qbs", "onNewIntent");
+ super.onNewIntent(intent);
+ setIntent(intent);
+ }
+}
diff --git a/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs b/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs
index 94093af64..04dcbf403 100644
--- a/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs
+++ b/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs
@@ -1,7 +1,16 @@
Project {
QtGuiApplication {
Depends { name: "Lib" }
- files: ["main.cpp", "MainWindow.cpp", "MainWindow.h", "Test.java"]
+ files: ["main.cpp", "MainWindow.cpp", "MainWindow.h" ]
+ Group {
+ condition: Qt.core.versionMajor == 5
+ files: ["Test.java"]
+ }
+ Group {
+ condition: Qt.core.versionMajor == 6
+ files: ["TestQt6.java"]
+ }
+
Android.sdk.packageName: "my.qtapp"
Android.sdk.apkBaseName: name
Depends { name: "Qt"; submodules: ["core", "widgets"] }
diff --git a/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs b/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs
index a52bb4c4e..f23cf1a39 100644
--- a/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs
+++ b/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs
@@ -1,3 +1,9 @@
BareMetalProduct {
type: "application"
+
+ Group {
+ condition: qbs.toolchain.contains("cosmic")
+ files: "cosmic.lkf"
+ fileTags: "linkerscript"
+ }
}
diff --git a/tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs b/tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs
index 5db988078..eaddef340 100644
--- a/tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs
+++ b/tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs
@@ -121,14 +121,14 @@ Product {
&& qbs.architecture.startsWith("arm")
&& cpp.compilerName.startsWith("armcc")
cpp.assemblerFlags: ["--cpu", "cortex-m0"]
- cpp.driverFlags: ["--cpu", "cortex-m0"]
+ cpp.commonCompilerFlags: ["--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"]
+ cpp.commonCompilerFlags: ["-mcpu=cortex-m0", "--target=arm-arm-none-eabi"]
}
Properties {
condition: qbs.toolchain.contains("gcc")
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
index 5e8bbd62d..bfd10106d 100644
--- 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
@@ -2,6 +2,8 @@ import "../BareMetalApplication.qbs" as BareMetalApplication
Project {
property bool supportsCpp: {
+ if (qbs.toolchain.contains("cosmic"))
+ return false;
if (qbs.toolchain.contains("sdcc"))
return false;
if (qbs.toolchain.contains("keil")) {
diff --git a/tests/auto/blackbox/testdata-baremetal/cosmic.lkf b/tests/auto/blackbox/testdata-baremetal/cosmic.lkf
new file mode 100644
index 000000000..90c254d1e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/cosmic.lkf
@@ -0,0 +1 @@
+@*
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-cosmic.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-cosmic.s
new file mode 100644
index 000000000..4b45cc989
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-cosmic.s
@@ -0,0 +1,5 @@
+_main:
+ movs r0, #0
+ bx lr
+ xdef _main
+ end
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs12-cosmic.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs12-cosmic.s
new file mode 100644
index 000000000..c33c2b32d
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs12-cosmic.s
@@ -0,0 +1,5 @@
+_main:
+ .dcall "2,0,_main"
+ rts
+ xdef _main
+ end
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-cosmic.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-cosmic.s
new file mode 100644
index 000000000..c33c2b32d
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-cosmic.s
@@ -0,0 +1,5 @@
+_main:
+ .dcall "2,0,_main"
+ rts
+ xdef _main
+ end
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-cosmic.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-cosmic.s
new file mode 100644
index 000000000..811b1d79e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-cosmic.s
@@ -0,0 +1,5 @@
+_main:
+ .dcall "8,0,_main"
+ rts
+ xdef _main
+ 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 ed38f79b6..e8805225c 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
@@ -2,7 +2,18 @@ import "../BareMetalApplication.qbs" as BareMetalApplication
BareMetalApplication {
condition: {
- if (qbs.toolchainType === "keil") {
+ if (qbs.toolchainType === "cosmic") {
+ if (qbs.architecture.startsWith("arm"))
+ return true;
+ if (qbs.architecture === "stm8")
+ return true;
+ if (qbs.architecture === "hcs8")
+ return true;
+ if (qbs.architecture === "hcs12")
+ return true;
+ if (qbs.architecture === "m68k")
+ return true;
+ } else if (qbs.toolchainType === "keil") {
if (qbs.architecture.startsWith("arm"))
return true;
if (qbs.architecture === "mcs51")
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-cosmic.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-cosmic.s
new file mode 100644
index 000000000..818b0d680
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-cosmic.s
@@ -0,0 +1,7 @@
+ scross off
+_main:
+ .dcall "2,0,_main"
+ ret
+ .scheck _main
+ xdef _main
+ end
diff --git a/tests/auto/blackbox/testdata-baremetal/target-platform/target-platform.qbs b/tests/auto/blackbox/testdata-baremetal/target-platform/target-platform.qbs
index 50be8e91a..d29e7e619 100644
--- a/tests/auto/blackbox/testdata-baremetal/target-platform/target-platform.qbs
+++ b/tests/auto/blackbox/testdata-baremetal/target-platform/target-platform.qbs
@@ -3,7 +3,8 @@ Product {
condition: {
if (qbs.toolchainType === "keil"
|| qbs.toolchainType === "iar"
- || qbs.toolchainType === "sdcc") {
+ || qbs.toolchainType === "sdcc"
+ || qbs.toolchainType === "cosmic") {
var hasNoPlatform = (qbs.targetPlatform === "none");
var hasNoOS = (qbs.targetOS.length === 1 && qbs.targetOS[0] === "none");
console.info("has no platform: " + hasNoPlatform);
diff --git a/tests/auto/blackbox/testdata/innosetup/inc/qbsinc.iss b/tests/auto/blackbox/testdata-windows/innosetup/inc/qbsinc.iss
index e69de29bb..e69de29bb 100644
--- a/tests/auto/blackbox/testdata/innosetup/inc/qbsinc.iss
+++ b/tests/auto/blackbox/testdata-windows/innosetup/inc/qbsinc.iss
diff --git a/tests/auto/blackbox/testdata/innosetup/innosetup.qbs b/tests/auto/blackbox/testdata-windows/innosetup/innosetup.qbs
index 718dec6f5..718dec6f5 100644
--- a/tests/auto/blackbox/testdata/innosetup/innosetup.qbs
+++ b/tests/auto/blackbox/testdata-windows/innosetup/innosetup.qbs
diff --git a/tests/auto/blackbox/testdata/innosetup/test.iss b/tests/auto/blackbox/testdata-windows/innosetup/test.iss
index f9f9195a6..f9f9195a6 100644
--- a/tests/auto/blackbox/testdata/innosetup/test.iss
+++ b/tests/auto/blackbox/testdata-windows/innosetup/test.iss
diff --git a/tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs b/tests/auto/blackbox/testdata-windows/innosetupDependencies/innosetupDependencies.qbs
index ab68d3011..ab68d3011 100644
--- a/tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs
+++ b/tests/auto/blackbox/testdata-windows/innosetupDependencies/innosetupDependencies.qbs
diff --git a/tests/auto/blackbox/testdata/innosetupDependencies/main.c b/tests/auto/blackbox/testdata-windows/innosetupDependencies/main.c
index 76e819701..76e819701 100644
--- a/tests/auto/blackbox/testdata/innosetupDependencies/main.c
+++ b/tests/auto/blackbox/testdata-windows/innosetupDependencies/main.c
diff --git a/tests/auto/blackbox/testdata/innosetupDependencies/test.iss b/tests/auto/blackbox/testdata-windows/innosetupDependencies/test.iss
index 430f9941b..430f9941b 100644
--- a/tests/auto/blackbox/testdata/innosetupDependencies/test.iss
+++ b/tests/auto/blackbox/testdata-windows/innosetupDependencies/test.iss
diff --git a/tests/auto/blackbox/testdata/wix/ExampleScript.bat b/tests/auto/blackbox/testdata-windows/wix/ExampleScript.bat
index 3af583cd8..3af583cd8 100644
--- a/tests/auto/blackbox/testdata/wix/ExampleScript.bat
+++ b/tests/auto/blackbox/testdata-windows/wix/ExampleScript.bat
diff --git a/tests/auto/blackbox/testdata/wix/QbsBootstrapper.wxs b/tests/auto/blackbox/testdata-windows/wix/QbsBootstrapper.wxs
index 272f6af5b..272f6af5b 100644
--- a/tests/auto/blackbox/testdata/wix/QbsBootstrapper.wxs
+++ b/tests/auto/blackbox/testdata-windows/wix/QbsBootstrapper.wxs
diff --git a/tests/auto/blackbox/testdata/wix/QbsSetup.wxs b/tests/auto/blackbox/testdata-windows/wix/QbsSetup.wxs
index 8f97ff667..8f97ff667 100644
--- a/tests/auto/blackbox/testdata/wix/QbsSetup.wxs
+++ b/tests/auto/blackbox/testdata-windows/wix/QbsSetup.wxs
diff --git a/tests/auto/blackbox/testdata/wix/Qt.wxs b/tests/auto/blackbox/testdata-windows/wix/Qt.wxs
index fbd992c43..fbd992c43 100644
--- a/tests/auto/blackbox/testdata/wix/Qt.wxs
+++ b/tests/auto/blackbox/testdata-windows/wix/Qt.wxs
diff --git a/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs b/tests/auto/blackbox/testdata-windows/wix/WiXInstallers.qbs
index 07f61ba2c..7e1dbf5e3 100644
--- a/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs
+++ b/tests/auto/blackbox/testdata-windows/wix/WiXInstallers.qbs
@@ -12,8 +12,8 @@ Project {
Export {
Depends { name: "wix" }
wix.defines: base.concat(["msiName=" +
- FileInfo.joinPaths(product.buildDirectory,
- product.targetName + wix.windowsInstallerSuffix)])
+ FileInfo.joinPaths(exportingProduct.buildDirectory,
+ exportingProduct.targetName + wix.windowsInstallerSuffix)])
}
}
diff --git a/tests/auto/blackbox/testdata/wix/de.wxl b/tests/auto/blackbox/testdata-windows/wix/de.wxl
index 75394cfdd..75394cfdd 100644
--- a/tests/auto/blackbox/testdata/wix/de.wxl
+++ b/tests/auto/blackbox/testdata-windows/wix/de.wxl
diff --git a/tests/auto/blackbox/testdata/wixDependencies/QbsSetup.wxs b/tests/auto/blackbox/testdata-windows/wixDependencies/QbsSetup.wxs
index ec839a269..ec839a269 100644
--- a/tests/auto/blackbox/testdata/wixDependencies/QbsSetup.wxs
+++ b/tests/auto/blackbox/testdata-windows/wixDependencies/QbsSetup.wxs
diff --git a/tests/auto/blackbox/testdata/wixDependencies/main.c b/tests/auto/blackbox/testdata-windows/wixDependencies/main.c
index 76e819701..76e819701 100644
--- a/tests/auto/blackbox/testdata/wixDependencies/main.c
+++ b/tests/auto/blackbox/testdata-windows/wixDependencies/main.c
diff --git a/tests/auto/blackbox/testdata/wixDependencies/wixDependencies.qbs b/tests/auto/blackbox/testdata-windows/wixDependencies/wixDependencies.qbs
index d42a18054..d42a18054 100644
--- a/tests/auto/blackbox/testdata/wixDependencies/wixDependencies.qbs
+++ b/tests/auto/blackbox/testdata-windows/wixDependencies/wixDependencies.qbs
diff --git a/tests/auto/blackbox/testdata/proper quoting/proper quoting.qbs b/tests/auto/blackbox/testdata/proper quoting/proper quoting.qbs
index cf1fabf24..2d9afb134 100644
--- a/tests/auto/blackbox/testdata/proper quoting/proper quoting.qbs
+++ b/tests/auto/blackbox/testdata/proper quoting/proper quoting.qbs
@@ -40,7 +40,7 @@ Project {
Depends { name: "cpp" }
Export {
Depends { name: "cpp" }
- cpp.includePaths: [product.sourceDirectory + '/some helper']
+ cpp.includePaths: [exportingProduct.sourceDirectory + '/some helper']
}
}
}
diff --git a/tests/auto/blackbox/testdata/protobuf/create-proto-library.qbs b/tests/auto/blackbox/testdata/protobuf/create-proto-library.qbs
index 0dc6fb2ea..b01a47a39 100644
--- a/tests/auto/blackbox/testdata/protobuf/create-proto-library.qbs
+++ b/tests/auto/blackbox/testdata/protobuf/create-proto-library.qbs
@@ -32,7 +32,7 @@ Project {
Depends { name: "protobuf.cpp"; required: false }
cpp.cxxLanguageVersion: "c++11"
cpp.minimumMacosVersion: "10.8"
- cpp.includePaths: product.protobuf.cpp.outputDir
+ cpp.includePaths: exportingProduct.protobuf.cpp.outputDir
}
}
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 1b9fa0b15..1082ba595 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -5958,6 +5958,67 @@ void TestBlackbox::qbsConfig()
}
}
+void TestBlackbox::qbsConfigAddProfile()
+{
+ QbsRunParameters params("config");
+ QTemporaryDir settingsDir1;
+ QTemporaryDir settingsDir2;
+ QVERIFY(settingsDir1.isValid());
+ QVERIFY(settingsDir2.isValid());
+ const QStringList settingsDir1Args = QStringList{"--settings-dir", settingsDir1.path()};
+ const QStringList settingsDir2Args = QStringList{"--settings-dir", settingsDir2.path()};
+
+ QFETCH(QStringList, args);
+ QFETCH(QString, errorMsg);
+
+ // Step 1: Run --add-profile.
+ params.arguments = settingsDir1Args;
+ params.arguments << "--add-profile";
+ params.arguments << args;
+ params.expectFailure = !errorMsg.isEmpty();
+ QCOMPARE(runQbs(params) == 0, !params.expectFailure);
+ if (params.expectFailure) {
+ QVERIFY(QString::fromLocal8Bit(m_qbsStderr).contains(errorMsg));
+ return;
+ }
+ params.expectFailure = false;
+ params.arguments = settingsDir1Args;
+ params.arguments << "--list";
+ QCOMPARE(runQbs(params), 0);
+ const QByteArray output1 = m_qbsStdout;
+
+ // Step 2: Set properties manually.
+ for (int i = 1; i < args.size(); i += 2) {
+ params.arguments = settingsDir2Args;
+ params.arguments << ("profiles." + args.first() + '.' + args.at(i)) << args.at(i + 1);
+ QCOMPARE(runQbs(params), 0);
+ }
+ params.arguments = settingsDir2Args;
+ params.arguments << "--list";
+ QCOMPARE(runQbs(params), 0);
+ const QByteArray output2 = m_qbsStdout;
+
+ // Step3: Compare results.
+ QCOMPARE(output1, output2);
+}
+
+void TestBlackbox::qbsConfigAddProfile_data()
+{
+ QTest::addColumn<QStringList>("args");
+ QTest::addColumn<QString>("errorMsg");
+ QTest::newRow("no arguments") << QStringList() << QString("Profile name missing");
+ QTest::newRow("empty name") << QStringList{"", "p", "v"}
+ << QString("Profile name must not be empty");
+ QTest::newRow("no properties") << QStringList("p")
+ << QString("Profile properties must be provided");
+ QTest::newRow("one property") << QStringList{"p", "p", "v"} << QString();
+ QTest::newRow("two properties") << QStringList{"p", "p1", "v1", "p2", "v2"} << QString();
+ QTest::newRow("missing value") << QStringList{"p", "p"}
+ << QString("Profile properties must be key/value pairs");
+ QTest::newRow("missing values") << QStringList{"p", "p1", "v1", "p2"}
+ << QString("Profile properties must be key/value pairs");
+}
+
static QJsonObject getNextSessionPacket(QProcess &session, QByteArray &data)
{
int totalSize = -1;
@@ -7362,94 +7423,6 @@ void TestBlackbox::generator_data()
QTest::newRow("no update") << QString() << QStringList();
}
-static bool haveWiX(const Profile &profile)
-{
- if (profile.value("wix.toolchainInstallPath").isValid() &&
- profile.value("wix.toolchainInstallRoot").isValid()) {
- return true;
- }
-
- QStringList regKeys;
- regKeys << QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows Installer XML\\")
- << QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Installer XML\\");
-
- QStringList paths = QProcessEnvironment::systemEnvironment().value("PATH")
- .split(HostOsInfo::pathListSeparator(), QBS_SKIP_EMPTY_PARTS);
-
- for (const QString &key : qAsConst(regKeys)) {
- const QStringList versions = QSettings(key, QSettings::NativeFormat).childGroups();
- for (const QString &version : versions) {
- QSettings settings(key + version, QSettings::NativeFormat);
- QString str = settings.value(QStringLiteral("InstallRoot")).toString();
- if (!str.isEmpty())
- paths.prepend(str);
- }
- }
-
- for (const QString &path : qAsConst(paths)) {
- if (regularFileExists(QDir::fromNativeSeparators(path) +
- HostOsInfo::appendExecutableSuffix(QStringLiteral("/candle"))) &&
- regularFileExists(QDir::fromNativeSeparators(path) +
- HostOsInfo::appendExecutableSuffix(QStringLiteral("/light")))) {
- return true;
- }
- }
-
- return false;
-}
-
-void TestBlackbox::wix()
-{
- const SettingsPtr s = settings();
- Profile profile(profileName(), s.get());
-
- if (!haveWiX(profile)) {
- QSKIP("WiX is not installed");
- return;
- }
-
- QByteArray arch = profile.value("qbs.architecture").toString().toLatin1();
- if (arch.isEmpty())
- arch = QByteArrayLiteral("x86");
-
- QDir::setCurrent(testDataDir + "/wix");
- QCOMPARE(runQbs(), 0);
- QVERIFY2(m_qbsStdout.contains("compiling QbsSetup.wxs"), m_qbsStdout);
- QVERIFY2(m_qbsStdout.contains("linking qbs.msi"), m_qbsStdout);
- QVERIFY(regularFileExists(relativeProductBuildDir("QbsSetup") + "/qbs.msi"));
-
- if (HostOsInfo::isWindowsHost()) {
- QVERIFY2(m_qbsStdout.contains("compiling QbsBootstrapper.wxs"), m_qbsStdout);
- QVERIFY2(m_qbsStdout.contains("linking qbs-setup-" + arch + ".exe"), m_qbsStdout);
- QVERIFY(regularFileExists(relativeProductBuildDir("QbsBootstrapper")
- + "/qbs-setup-" + arch + ".exe"));
- }
-}
-
-void TestBlackbox::wixDependencies()
-{
- const SettingsPtr s = settings();
- Profile profile(profileName(), s.get());
-
- if (!haveWiX(profile)) {
- QSKIP("WiX is not installed");
- return;
- }
-
- QByteArray arch = profile.value("qbs.architecture").toString().toLatin1();
- if (arch.isEmpty())
- arch = QByteArrayLiteral("x86");
-
- QDir::setCurrent(testDataDir + "/wixDependencies");
- QbsRunParameters params;
- if (!HostOsInfo::isWindowsHost())
- params.arguments << "qbs.targetOS:windows";
- QCOMPARE(runQbs(params), 0);
- QVERIFY2(m_qbsStdout.contains("compiling QbsSetup.wxs"), m_qbsStdout);
- QVERIFY2(m_qbsStdout.contains("linking qbs.msi"), m_qbsStdout);
- QVERIFY(regularFileExists(relativeBuildDir() + "/qbs.msi"));
-}
-
void TestBlackbox::nodejs()
{
const SettingsPtr s = settings();
@@ -7567,47 +7540,6 @@ void TestBlackbox::includeLookup()
QVERIFY2(m_qbsStdout.contains("definition.."), m_qbsStdout.constData());
}
-void TestBlackbox::innoSetup()
-{
- const SettingsPtr s = settings();
- Profile profile(profileName(), s.get());
-
- QDir::setCurrent(testDataDir + "/innosetup");
-
- QCOMPARE(runQbs({"resolve"}), 0);
- const bool withInnosetup = m_qbsStdout.contains("has innosetup: true");
- const bool withoutInnosetup = m_qbsStdout.contains("has innosetup: false");
- QVERIFY2(withInnosetup || withoutInnosetup, m_qbsStdout.constData());
- if (withoutInnosetup)
- QSKIP("innosetup module not present");
-
- QCOMPARE(runQbs(), 0);
- QVERIFY(m_qbsStdout.contains("compiling test.iss"));
- QVERIFY(m_qbsStdout.contains("compiling Example1.iss"));
- QVERIFY(regularFileExists(relativeProductBuildDir("QbsSetup") + "/qbs.setup.test.exe"));
- QVERIFY(regularFileExists(relativeProductBuildDir("Example1") + "/Example1.exe"));
-}
-
-void TestBlackbox::innoSetupDependencies()
-{
- const SettingsPtr s = settings();
- Profile profile(profileName(), s.get());
-
- QDir::setCurrent(testDataDir + "/innosetupDependencies");
-
- QCOMPARE(runQbs({"resolve"}), 0);
- const bool withInnosetup = m_qbsStdout.contains("has innosetup: true");
- const bool withoutInnosetup = m_qbsStdout.contains("has innosetup: false");
- QVERIFY2(withInnosetup || withoutInnosetup, m_qbsStdout.constData());
- if (withoutInnosetup)
- QSKIP("innosetup module not present");
-
- QbsRunParameters params;
- QCOMPARE(runQbs(params), 0);
- QVERIFY(m_qbsStdout.contains("compiling test.iss"));
- QVERIFY(regularFileExists(relativeBuildDir() + "/qbs.setup.test.exe"));
-}
-
void TestBlackbox::inputTagsChangeTracking_data()
{
QTest::addColumn<QString>("generateInput");
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index 8cc21378a..6395eb679 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -143,8 +143,6 @@ private slots:
void importingProduct();
void importsConflict();
void includeLookup();
- void innoSetup();
- void innoSetupDependencies();
void inputTagsChangeTracking_data();
void inputTagsChangeTracking();
void inputsFromDependencies();
@@ -258,6 +256,8 @@ private slots:
void protobufLibraryInstall();
void pseudoMultiplexing();
void qbsConfig();
+ void qbsConfigAddProfile();
+ void qbsConfigAddProfile_data();
void qbsSession();
void qbsVersion();
void qtBug51237();
@@ -335,8 +335,6 @@ private slots:
void wholeArchive_data();
void wildCardsAndRules();
void wildcardRenaming();
- void wix();
- void wixDependencies();
void zip();
void zip_data();
void zipInvalid();
diff --git a/tests/auto/blackbox/tst_blackboxandroid.cpp b/tests/auto/blackbox/tst_blackboxandroid.cpp
index f8ed8a0b9..ba864ed78 100644
--- a/tests/auto/blackbox/tst_blackboxandroid.cpp
+++ b/tests/auto/blackbox/tst_blackboxandroid.cpp
@@ -58,6 +58,7 @@ QMap<QString, QString> TestBlackboxAndroid::findAndroid(int *status, const QStri
return {
{"sdk", QDir::fromNativeSeparators(tools["sdk"].toString())},
{"sdk-build-tools-dx", QDir::fromNativeSeparators(tools["sdk-build-tools-dx"].toString())},
+ {"sdk-build-tools-d8", QDir::fromNativeSeparators(tools["sdk-build-tools-d8"].toString())},
{"ndk", QDir::fromNativeSeparators(tools["ndk"].toString())},
{"ndk-samples", QDir::fromNativeSeparators(tools["ndk-samples"].toString())},
{"jar", QDir::fromNativeSeparators(tools["jar"].toString())},
@@ -83,6 +84,7 @@ void TestBlackboxAndroid::android()
QFETCH(bool, enableAapt2);
QFETCH(bool, generateAab);
QFETCH(bool, isIncrementalBuild);
+ QFETCH(bool, enableD8);
// skip tests on github except when run in docker - this var is not propagated into the image
if (qEnvironmentVariableIsSet("GITHUB_ACTIONS"))
@@ -181,11 +183,12 @@ void TestBlackboxAndroid::android()
}
if (projectDir == "multiple-libs-per-apk") {
- const auto dxPath = androidPaths["sdk-build-tools-dx"];
- QVERIFY(!dxPath.isEmpty());
+ const auto dexCompilerPath = enableD8 ? androidPaths["sdk-build-tools-d8"]
+ : androidPaths["sdk-build-tools-dx"];
+ QVERIFY(!dexCompilerPath.isEmpty());
const auto lines = m_qbsStdout.split('\n');
const auto it = std::find_if(lines.cbegin(), lines.cend(), [&](const QByteArray &line) {
- return !line.isEmpty() && line.startsWith(dxPath.toUtf8());
+ return !line.isEmpty() && line.startsWith(dexCompilerPath.toUtf8());
});
QVERIFY2(it != lines.cend(), qPrintable(m_qbsStdout.constData()));
const auto line = *it;
@@ -290,6 +293,7 @@ void TestBlackboxAndroid::android_data()
QTest::addColumn<bool>("enableAapt2");
QTest::addColumn<bool>("generateAab");
QTest::addColumn<bool>("isIncrementalBuild");
+ QTest::addColumn<bool>("enableD8");
const auto aaptVersion = [](bool enableAapt2) {
return QString("modules.Android.sdk.aaptName:") + (enableAapt2 ? "aapt2" : "aapt");
@@ -301,6 +305,11 @@ void TestBlackboxAndroid::android_data()
bool generateAab = false;
bool isIncrementalBuild = false;
+ const auto dexCompilerVersion = [](bool enableD8) {
+ return QString("modules.Android.sdk.dexCompilerName:") + (enableD8 ? "d8" : "dx");
+ };
+ bool enableD8 = true;
+
auto qtAppExpectedFiles = [&](bool generateAab, bool enableAapt2, bool codeSign = true,
QString keyAlias="androiddebugkey") {
QByteArrayList expectedFile;
@@ -379,7 +388,7 @@ void TestBlackboxAndroid::android_data()
keyPassword, keyAlias)
<< aaptVersion(enableAapt2)
<< packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;;
codeSign = false;
QTest::newRow("qt app no signing")
<< "qt-app" << QStringList("qt-app")
@@ -391,7 +400,7 @@ void TestBlackboxAndroid::android_data()
keyPassword, keyAlias)
<< aaptVersion(enableAapt2)
<< packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = true;
codeSign = true;
QTest::newRow("qt app aapt2")
@@ -404,7 +413,7 @@ void TestBlackboxAndroid::android_data()
keyPassword, keyAlias)
<< aaptVersion(enableAapt2)
<< packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
generateAab = true;
QTest::newRow("qt app aab")
<< "qt-app" << QStringList("qt-app")
@@ -416,7 +425,7 @@ void TestBlackboxAndroid::android_data()
keyPassword, keyAlias)
<< aaptVersion(enableAapt2)
<< packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
codeSign = false;
QTest::newRow("qt app aab no signing")
<< "qt-app" << QStringList("qt-app")
@@ -428,7 +437,7 @@ void TestBlackboxAndroid::android_data()
keyPassword, keyAlias)
<< aaptVersion(enableAapt2)
<< packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
const QByteArrayList ndkArchsForQtSave = ndkArchsForQt;
ndkArchsForQt = {ndkArchsForQt.first()};
@@ -438,7 +447,7 @@ void TestBlackboxAndroid::android_data()
enableAapt2)))
<< QStringList{aaptVersion(enableAapt2), packageType(generateAab),
"modules.qbs.architectures:" + archsForQt.first()}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
ndkArchsForQt = ndkArchsForQtSave;
auto teaPotAppExpectedFiles = [&](const QByteArrayList &archs, bool generateAab) {
@@ -459,26 +468,25 @@ void TestBlackboxAndroid::android_data()
expectedFile << "resources.arsc";
return expectedFile;
};
-
generateAab = false;
enableAapt2 = false;
QTest::newRow("teapot")
<< "teapot" << QStringList("TeapotNativeActivity")
<< (QList<QByteArrayList>() << teaPotAppExpectedFiles(archs, generateAab))
<< QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = true;
QTest::newRow("teapot aapt2")
<< "teapot" << QStringList("TeapotNativeActivity")
<< (QList<QByteArrayList>() << teaPotAppExpectedFiles(archs, generateAab))
<< QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
generateAab = true;
QTest::newRow("teapot aapt2 aab")
<< "teapot" << QStringList("TeapotNativeActivity")
<< (QList<QByteArrayList>() << teaPotAppExpectedFiles(archs, generateAab))
<< QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = false;
generateAab = false;
QTest::newRow("minimal-native")
@@ -490,7 +498,7 @@ void TestBlackboxAndroid::android_data()
<< QStringList{"products.minimalnative.multiplexByQbsProperties:[]",
"modules.qbs.architecture:" + archsStringList.first(),
aaptVersion(enableAapt2)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = true;
QTest::newRow("minimal-native aapt2")
<< "minimal-native" << QStringList("minimalnative")
@@ -502,7 +510,7 @@ void TestBlackboxAndroid::android_data()
<< QStringList{"products.minimalnative.multiplexByQbsProperties:[]",
"modules.qbs.architecture:" + archsStringList.first(),
aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
generateAab = true;
QTest::newRow("minimal-native aapt2 aab")
<< "minimal-native" << QStringList("minimalnative")
@@ -515,7 +523,7 @@ void TestBlackboxAndroid::android_data()
<< QStringList{"products.minimalnative.multiplexByQbsProperties:[]",
"modules.qbs.architecture:" + archsStringList.first(),
aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
auto qmlAppExpectedFiles = [&](bool generateAab, bool enableAapt2) {
QByteArrayList expectedFile;
@@ -619,6 +627,8 @@ void TestBlackboxAndroid::android_data()
"lib/${ARCH}/libqml_QtQml_Models_modelsplugin_${ARCH}.so",
"lib/${ARCH}/libqml_QtQml_WorkerScript_workerscriptplugin_${ARCH}.so",
"lib/${ARCH}/libqml_QtQml_qmlplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Window_quickwindow_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_tooling_quicktooling_${ARCH}.so",
"lib/${ARCH}/libqml_QtQuick_Controls_Basic_impl_qtquickcontrols2basicstyleimplplugin_${ARCH}.so",
"lib/${ARCH}/libqml_QtQuick_Controls_Basic_qtquickcontrols2basicstyleplugin_${ARCH}.so",
"lib/${ARCH}/libqml_QtQuick_Controls_Fusion_impl_qtquickcontrols2fusionstyleimplplugin_${ARCH}.so",
@@ -649,27 +659,6 @@ void TestBlackboxAndroid::android_data()
return expectedFile;
};
- auto qmlAppMinistroExpectedFiles = [&](bool generateAab, bool enableAapt2) {
- QByteArrayList expectedFile;
- if (singleArchQt) {
- expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
- "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list",
- cxxLibPath("libgnustl_shared.so", true),
- "lib/${ARCH}/libqmlapp.so"}, generateAab);
- } else {
- expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
- "assets/android_rcc_bundle.rcc",
- cxxLibPath("libgnustl_shared.so", true),
- "lib/${ARCH}/libqmlapp_${ARCH}.so"}, generateAab);
- }
- if (generateAab)
- expectedFile << "base/resources.pb" << "base/assets.pb" << "base/native.pb";
- else
- expectedFile << "resources.arsc";
- if (!enableAapt2 && version < qbs::Version(6, 0))
- expectedFile << "res/layout/splash.xml";
- return expectedFile;
- };
auto qmlAppCustomMetaDataExpectedFiles = [&](bool generateAab, bool enableAapt2) {
QByteArrayList expectedFile;
if (singleArchQt) {
@@ -774,6 +763,8 @@ void TestBlackboxAndroid::android_data()
"lib/${ARCH}/libqml_QtQml_Models_modelsplugin_${ARCH}.so",
"lib/${ARCH}/libqml_QtQml_WorkerScript_workerscriptplugin_${ARCH}.so",
"lib/${ARCH}/libqml_QtQml_qmlplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Window_quickwindow_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_tooling_quicktooling_${ARCH}.so",
"lib/${ARCH}/libqml_QtQuick_Controls_Basic_impl_qtquickcontrols2basicstyleimplplugin_${ARCH}.so",
"lib/${ARCH}/libqml_QtQuick_Controls_Basic_qtquickcontrols2basicstyleplugin_${ARCH}.so",
"lib/${ARCH}/libqml_QtQuick_Controls_Fusion_impl_qtquickcontrols2fusionstyleimplplugin_${ARCH}.so",
@@ -825,7 +816,7 @@ void TestBlackboxAndroid::android_data()
<< (QList<QByteArrayList>() << qmlAppExpectedFiles(generateAab, enableAapt2))
<< (QStringList() << qmlAppCustomProperties << aaptVersion(enableAapt2)
<< packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = true;
QTest::newRow("qml app aapt2")
@@ -833,46 +824,14 @@ void TestBlackboxAndroid::android_data()
<< (QList<QByteArrayList>() << qmlAppExpectedFiles(generateAab, enableAapt2))
<< (QStringList() << qmlAppCustomProperties << aaptVersion(enableAapt2)
<< packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
generateAab = true;
QTest::newRow("qml app aab")
<< "qml-app" << QStringList("qmlapp")
<< (QList<QByteArrayList>() << qmlAppExpectedFiles(generateAab, enableAapt2))
<< (QStringList() << qmlAppCustomProperties << aaptVersion(enableAapt2)
<< packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
- enableAapt2 = false;
- generateAab = false;
- isIncrementalBuild = true;
- QTest::newRow("qml app using Ministro")
- << "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << (QByteArrayList()
- << qmlAppMinistroExpectedFiles(generateAab,
- enableAapt2)))
- << (QStringList() << "modules.Qt.android_support.useMinistro:true"
- << "modules.Android.sdk.automaticSources:false" << aaptVersion(enableAapt2)
- << packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
- enableAapt2 = true;
- QTest::newRow("qml app using Ministro aapt2")
- << "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << qmlAppMinistroExpectedFiles(generateAab,
- enableAapt2))
- << (QStringList() << "modules.Qt.android_support.useMinistro:true"
- << "modules.Android.sdk.automaticSources:false" << aaptVersion(enableAapt2)
- << packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
- generateAab = true;
- if (!singleArchQt) {
- QTest::newRow("qml app using Ministro aab")
- << "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << qmlAppMinistroExpectedFiles(generateAab,
- enableAapt2))
- << (QStringList() << "modules.Qt.android_support.useMinistro:true"
- << "modules.Android.sdk.automaticSources:false" << aaptVersion(enableAapt2)
- << packageType(generateAab))
- << enableAapt2 << generateAab << isIncrementalBuild;
- }
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = false;
generateAab = false;
QTest::newRow("qml app with custom metadata")
@@ -882,7 +841,7 @@ void TestBlackboxAndroid::android_data()
enableAapt2)))
<< QStringList{"modules.Android.sdk.automaticSources:true",
aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = true;
QTest::newRow("qml app with custom metadata aapt2")
<< "qml-app" << QStringList("qmlapp")
@@ -891,7 +850,7 @@ void TestBlackboxAndroid::android_data()
enableAapt2)))
<< QStringList{"modules.Android.sdk.automaticSources:true", aaptVersion(enableAapt2),
packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
generateAab = true;
if (!singleArchQt) {
QTest::newRow("qml app with custom metadata aab")
@@ -901,7 +860,7 @@ void TestBlackboxAndroid::android_data()
enableAapt2)))
<< QStringList{"modules.Android.sdk.automaticSources:true", aaptVersion(enableAapt2),
packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
}
isIncrementalBuild = false;
enableAapt2 = false;
@@ -936,44 +895,45 @@ void TestBlackboxAndroid::android_data()
<< QStringList("com.example.android.basicmediadecoder")
<< (QList<QByteArrayList>() << noNativeExpectedFiles(generateAab))
<< QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = true;
QTest::newRow("no native aapt2")
<< "no-native"
<< QStringList("com.example.android.basicmediadecoder")
<< (QList<QByteArrayList>() << noNativeExpectedFiles(generateAab))
<< QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
generateAab = true;
QTest::newRow("no native aab")
<< "no-native"
<< QStringList("com.example.android.basicmediadecoder")
<< (QList<QByteArrayList>() << noNativeExpectedFiles(generateAab))
<< QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = false;
generateAab = false;
QTest::newRow("aidl") << "aidl" << QStringList("io.qbs.aidltest")
<< (QList<QByteArrayList>() << (QByteArrayList()
<< commonFiles(generateAab)))
<< QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = true;
QTest::newRow("aidl") << "aidl" << QStringList("io.qbs.aidltest")
<< (QList<QByteArrayList>() << (QByteArrayList()
<< commonFiles(generateAab)
<< "resources.arsc"))
<< QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
generateAab = true;
QTest::newRow("aidl") << "aidl" << QStringList("io.qbs.aidltest")
<< (QList<QByteArrayList>() << (QByteArrayList()
<< commonFiles(generateAab)
<< "base/resources.pb"))
<< QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = false;
generateAab = false;
+ enableD8 = false;
QTest::newRow("multiple libs")
<< "multiple-libs-per-apk"
<< QStringList("twolibs")
@@ -982,8 +942,22 @@ void TestBlackboxAndroid::android_data()
"lib/${ARCH}/liblib1.so",
"lib/${ARCH}/liblib2.so",
cxxLibPath("libstlport_shared.so", false)}, generateAab))
- << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab),
+ dexCompilerVersion(enableD8)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ enableD8 = true;
+ QTest::newRow("multiple libs with d8")
+ << "multiple-libs-per-apk"
+ << QStringList("twolibs")
+ << (QList<QByteArrayList>() << commonFiles(generateAab) + expandArchs(archs, {
+ "resources.arsc",
+ "lib/${ARCH}/liblib1.so",
+ "lib/${ARCH}/liblib2.so",
+ cxxLibPath("libstlport_shared.so", false)}, generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab),
+ dexCompilerVersion(enableD8)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ enableD8 = false;
enableAapt2 = true;
QTest::newRow("multiple libs aapt2")
<< "multiple-libs-per-apk"
@@ -993,8 +967,9 @@ void TestBlackboxAndroid::android_data()
"lib/${ARCH}/liblib1.so",
"lib/${ARCH}/liblib2.so",
cxxLibPath("libstlport_shared.so", false)}, generateAab))
- << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab),
+ dexCompilerVersion(enableD8)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
generateAab = true;
QTest::newRow("multiple libs aab")
<< "multiple-libs-per-apk"
@@ -1004,8 +979,9 @@ void TestBlackboxAndroid::android_data()
"lib/${ARCH}/liblib1.so",
"lib/${ARCH}/liblib2.so",
cxxLibPath("libstlport_shared.so", false)}, generateAab))
- << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab),
+ dexCompilerVersion(enableD8)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = false;
generateAab = false;
auto expectedFiles1 = [&](bool generateAab) {
@@ -1034,16 +1010,18 @@ void TestBlackboxAndroid::android_data()
<< "multiple-apks-per-project"
<< (QStringList() << "twolibs1" << "twolibs2")
<< QList<QByteArrayList>{expectedFiles1(generateAab), expectedFiles2(generateAab)}
- << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab),
+ dexCompilerVersion(enableD8)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
enableAapt2 = true;
QTest::newRow("multiple apks aapt2")
<< "multiple-apks-per-project"
<< (QStringList() << "twolibs1" << "twolibs2")
<< (QList<QByteArrayList>() << expectedFiles1(generateAab)
<< (QByteArrayList() << expectedFiles2(generateAab) << "resources.arsc"))
- << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab),
+ dexCompilerVersion(enableD8)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
generateAab = true;
QTest::newRow("multiple apks aab")
<< "multiple-apks-per-project"
@@ -1051,8 +1029,9 @@ void TestBlackboxAndroid::android_data()
<< (QList<QByteArrayList>() << expectedFiles1(generateAab)
<< (QByteArrayList() << expectedFiles2(generateAab) << "base/resources.pb"
<< "base/native.pb"))
- << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
- << enableAapt2 << generateAab << isIncrementalBuild;
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab),
+ dexCompilerVersion(enableD8)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
}
QTEST_MAIN(TestBlackboxAndroid)
diff --git a/tests/auto/blackbox/tst_blackboxapple.cpp b/tests/auto/blackbox/tst_blackboxapple.cpp
index f8645bac6..2744f907e 100644
--- a/tests/auto/blackbox/tst_blackboxapple.cpp
+++ b/tests/auto/blackbox/tst_blackboxapple.cpp
@@ -244,8 +244,8 @@ void TestBlackboxApple::appleMultiConfig()
QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A/Resources/Info.plist").isRegularFile());
QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/Current").isDirSymLink());
- for (const QString &variant : { "release", "debug", "profiling" }) {
- for (const QString &arch : { "x86_64" }) {
+ for (const QString variant : { "release", "debug", "profiling" }) {
+ for (const QString arch : { "x86_64" }) {
QProcess process;
process.setProgram("/usr/bin/arch");
process.setArguments({
diff --git a/tests/auto/blackbox/tst_blackboxbase.cpp b/tests/auto/blackbox/tst_blackboxbase.cpp
index 0e383c831..ed0b90b55 100644
--- a/tests/auto/blackbox/tst_blackboxbase.cpp
+++ b/tests/auto/blackbox/tst_blackboxbase.cpp
@@ -96,14 +96,16 @@ int TestBlackboxBase::runQbs(const QbsRunParameters &params)
process.setWorkingDirectory(params.workingDir);
process.setProcessEnvironment(params.environment);
process.start(qbsExecutableFilePath, args);
+ int exitCode = 0;
if (!process.waitForStarted() || !process.waitForFinished(testTimeoutInMsecs())
|| process.exitStatus() != QProcess::NormalExit) {
- m_qbsStderr = process.readAllStandardError();
if (!params.expectCrash) {
QTest::qFail("qbs did not run correctly", __FILE__, __LINE__);
qDebug("%s", qPrintable(process.errorString()));
}
- return -1;
+ exitCode = -1;
+ } else {
+ exitCode = process.exitCode();
}
m_qbsStderr = process.readAllStandardError();
@@ -111,14 +113,14 @@ int TestBlackboxBase::runQbs(const QbsRunParameters &params)
sanitizeOutput(&m_qbsStderr);
sanitizeOutput(&m_qbsStdout);
const bool shouldLog = (process.exitStatus() != QProcess::NormalExit
- || process.exitCode() != 0) && !params.expectFailure;
+ || exitCode != 0) && !params.expectFailure;
if (!m_qbsStderr.isEmpty()
&& (shouldLog || qEnvironmentVariableIsSet("QBS_AUTOTEST_ALWAYS_LOG_STDERR")))
qDebug("%s", m_qbsStderr.constData());
if (!m_qbsStdout.isEmpty()
&& (shouldLog || qEnvironmentVariableIsSet("QBS_AUTOTEST_ALWAYS_LOG_STDOUT")))
qDebug("%s", m_qbsStdout.constData());
- return process.exitCode();
+ return exitCode;
}
/*!
diff --git a/tests/auto/blackbox/tst_blackboxwindows.cpp b/tests/auto/blackbox/tst_blackboxwindows.cpp
index e3fb98457..94257c062 100644
--- a/tests/auto/blackbox/tst_blackboxwindows.cpp
+++ b/tests/auto/blackbox/tst_blackboxwindows.cpp
@@ -33,11 +33,14 @@
#include "../shared.h"
#include <tools/hostosinfo.h>
+#include <tools/profile.h>
+#include <tools/qttools.h>
#include <QtCore/qdir.h>
#include <QtCore/qregularexpression.h>
using qbs::Internal::HostOsInfo;
+using qbs::Profile;
struct SigntoolInfo
{
@@ -117,6 +120,47 @@ void TestBlackboxWindows::initTestCase()
TestBlackboxBase::initTestCase();
}
+void TestBlackboxWindows::innoSetup()
+{
+ const SettingsPtr s = settings();
+ Profile profile(profileName(), s.get());
+
+ QDir::setCurrent(testDataDir + "/innosetup");
+
+ QCOMPARE(runQbs({"resolve"}), 0);
+ const bool withInnosetup = m_qbsStdout.contains("has innosetup: true");
+ const bool withoutInnosetup = m_qbsStdout.contains("has innosetup: false");
+ QVERIFY2(withInnosetup || withoutInnosetup, m_qbsStdout.constData());
+ if (withoutInnosetup)
+ QSKIP("innosetup module not present");
+
+ QCOMPARE(runQbs(), 0);
+ QVERIFY(m_qbsStdout.contains("compiling test.iss"));
+ QVERIFY(m_qbsStdout.contains("compiling Example1.iss"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("QbsSetup") + "/qbs.setup.test.exe"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Example1") + "/Example1.exe"));
+}
+
+void TestBlackboxWindows::innoSetupDependencies()
+{
+ const SettingsPtr s = settings();
+ Profile profile(profileName(), s.get());
+
+ QDir::setCurrent(testDataDir + "/innosetupDependencies");
+
+ QCOMPARE(runQbs({"resolve"}), 0);
+ const bool withInnosetup = m_qbsStdout.contains("has innosetup: true");
+ const bool withoutInnosetup = m_qbsStdout.contains("has innosetup: false");
+ QVERIFY2(withInnosetup || withoutInnosetup, m_qbsStdout.constData());
+ if (withoutInnosetup)
+ QSKIP("innosetup module not present");
+
+ QbsRunParameters params;
+ QCOMPARE(runQbs(params), 0);
+ QVERIFY(m_qbsStdout.contains("compiling test.iss"));
+ QVERIFY(regularFileExists(relativeBuildDir() + "/qbs.setup.test.exe"));
+}
+
void TestBlackboxWindows::standaloneCodesign()
{
QFETCH(SigntoolInfo::CodeSignResult, result);
@@ -171,4 +215,93 @@ void TestBlackboxWindows::standaloneCodesign_data()
<< "http://timestamp.digicert.com";
}
+
+static bool haveWiX(const Profile &profile)
+{
+ if (profile.value("wix.toolchainInstallPath").isValid() &&
+ profile.value("wix.toolchainInstallRoot").isValid()) {
+ return true;
+ }
+
+ QStringList regKeys;
+ regKeys << QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows Installer XML\\")
+ << QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Installer XML\\");
+
+ QStringList paths = QProcessEnvironment::systemEnvironment().value("PATH")
+ .split(HostOsInfo::pathListSeparator(), QBS_SKIP_EMPTY_PARTS);
+
+ for (const QString &key : qAsConst(regKeys)) {
+ const QStringList versions = QSettings(key, QSettings::NativeFormat).childGroups();
+ for (const QString &version : versions) {
+ QSettings settings(key + version, QSettings::NativeFormat);
+ QString str = settings.value(QStringLiteral("InstallRoot")).toString();
+ if (!str.isEmpty())
+ paths.prepend(str);
+ }
+ }
+
+ for (const QString &path : qAsConst(paths)) {
+ if (regularFileExists(QDir::fromNativeSeparators(path) +
+ HostOsInfo::appendExecutableSuffix(QStringLiteral("/candle"))) &&
+ regularFileExists(QDir::fromNativeSeparators(path) +
+ HostOsInfo::appendExecutableSuffix(QStringLiteral("/light")))) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void TestBlackboxWindows::wix()
+{
+ const SettingsPtr s = settings();
+ Profile profile(profileName(), s.get());
+
+ if (!haveWiX(profile)) {
+ QSKIP("WiX is not installed");
+ return;
+ }
+
+ QByteArray arch = profile.value("qbs.architecture").toString().toLatin1();
+ if (arch.isEmpty())
+ arch = QByteArrayLiteral("x86");
+
+ QDir::setCurrent(testDataDir + "/wix");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY2(m_qbsStdout.contains("compiling QbsSetup.wxs"), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains("linking qbs.msi"), m_qbsStdout);
+ QVERIFY(regularFileExists(relativeProductBuildDir("QbsSetup") + "/qbs.msi"));
+
+ if (HostOsInfo::isWindowsHost()) {
+ QVERIFY2(m_qbsStdout.contains("compiling QbsBootstrapper.wxs"), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains("linking qbs-setup-" + arch + ".exe"), m_qbsStdout);
+ QVERIFY(regularFileExists(relativeProductBuildDir("QbsBootstrapper")
+ + "/qbs-setup-" + arch + ".exe"));
+ }
+}
+
+void TestBlackboxWindows::wixDependencies()
+{
+ const SettingsPtr s = settings();
+ Profile profile(profileName(), s.get());
+
+ if (!haveWiX(profile)) {
+ QSKIP("WiX is not installed");
+ return;
+ }
+
+ QByteArray arch = profile.value("qbs.architecture").toString().toLatin1();
+ if (arch.isEmpty())
+ arch = QByteArrayLiteral("x86");
+
+ QDir::setCurrent(testDataDir + "/wixDependencies");
+ QbsRunParameters params;
+ if (!HostOsInfo::isWindowsHost())
+ params.arguments << "qbs.targetOS:windows";
+ QCOMPARE(runQbs(params), 0);
+ QVERIFY2(m_qbsStdout.contains("compiling QbsSetup.wxs"), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains("linking qbs.msi"), m_qbsStdout);
+ QVERIFY(regularFileExists(relativeBuildDir() + "/qbs.msi"));
+}
+
QTEST_MAIN(TestBlackboxWindows)
diff --git a/tests/auto/blackbox/tst_blackboxwindows.h b/tests/auto/blackbox/tst_blackboxwindows.h
index fbc597313..ad8d60ca3 100644
--- a/tests/auto/blackbox/tst_blackboxwindows.h
+++ b/tests/auto/blackbox/tst_blackboxwindows.h
@@ -44,8 +44,12 @@ public slots:
void initTestCase() override;
private slots:
+ void innoSetup();
+ void innoSetupDependencies();
void standaloneCodesign();
void standaloneCodesign_data();
+ void wix();
+ void wixDependencies();
};
#endif // TST_BLACKBOXWINDOWS_H
diff --git a/tests/auto/buildgraph/CMakeLists.txt b/tests/auto/buildgraph/CMakeLists.txt
index a3019295e..3d9d0348d 100644
--- a/tests/auto/buildgraph/CMakeLists.txt
+++ b/tests/auto/buildgraph/CMakeLists.txt
@@ -2,4 +2,6 @@ add_qbs_test(buildgraph
SOURCES
tst_buildgraph.cpp
tst_buildgraph.h
+ DEPENDS
+ qbsscriptengine
)
diff --git a/tests/auto/language/CMakeLists.txt b/tests/auto/language/CMakeLists.txt
index 008a66fe0..b008f52d7 100644
--- a/tests/auto/language/CMakeLists.txt
+++ b/tests/auto/language/CMakeLists.txt
@@ -2,7 +2,7 @@ add_qbs_test(language
DEFINES
"QBS_VERSION=\"${QBS_VERSION}\""
DEPENDS
- Qt5::Script
+ qbsscriptengine
SOURCES
tst_language.cpp
tst_language.h
diff --git a/tests/auto/tools/tst_tools.cpp b/tests/auto/tools/tst_tools.cpp
index 92e0978b5..894cfdcf6 100644
--- a/tests/auto/tools/tst_tools.cpp
+++ b/tests/auto/tools/tst_tools.cpp
@@ -68,6 +68,16 @@
using namespace qbs;
using namespace qbs::Internal;
+namespace std {
+template<typename T> struct hash<std::vector<T>>
+{
+ std::size_t operator()(const std::vector<T> &v) const noexcept
+ {
+ return hashRange(v);
+ }
+};
+} // namespace std
+
TestTools::TestTools(Settings *settings)
: m_settings(settings), testDataDir(testWorkDir("tools"))
{
@@ -1299,6 +1309,40 @@ void TestTools::stringutils_trimmed()
QCOMPARE(trimmed(std::move(a)), std::string("a"));
}
+void TestTools::hash_tuple()
+{
+ using Key = std::tuple<int, int>;
+
+ Key key0{0, 5};
+ Key key1{10, 20};
+ Key key2{30, 40};
+
+ std::unordered_map<Key, int> map;
+ map.insert({key1, 1});
+ map.insert({key2, 2});
+
+ QCOMPARE(map[key0], 0);
+ QCOMPARE(map[key1], 1);
+ QCOMPARE(map[key2], 2);
+}
+
+void TestTools::hash_range()
+{
+ using Key = std::vector<int>;
+
+ Key key0;
+ Key key1{1};
+ Key key2{1, 2};
+
+ std::unordered_map<Key, int> map;
+ map.insert({key1, 1});
+ map.insert({key2, 2});
+
+ QCOMPARE(map[key0], 0);
+ QCOMPARE(map[key1], 1);
+ QCOMPARE(map[key2], 2);
+}
+
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
diff --git a/tests/auto/tools/tst_tools.h b/tests/auto/tools/tst_tools.h
index d1ba0a57b..619174976 100644
--- a/tests/auto/tools/tst_tools.h
+++ b/tests/auto/tools/tst_tools.h
@@ -100,6 +100,9 @@ private slots:
void stringutils_endsWith();
void stringutils_trimmed();
+ void hash_tuple();
+ void hash_range();
+
private:
QString setupSettingsDir1();
QString setupSettingsDir2();
diff --git a/tests/benchmarker/CMakeLists.txt b/tests/benchmarker/CMakeLists.txt
index d77d6d9c4..12a6b3076 100644
--- a/tests/benchmarker/CMakeLists.txt
+++ b/tests/benchmarker/CMakeLists.txt
@@ -13,6 +13,6 @@ set(SOURCES
)
add_qbs_app(qbs_benchmarker
- DEPENDS Qt5::Core Qt5::Concurrent
+ DEPENDS Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Concurrent
SOURCES ${SOURCES}
)
diff --git a/tests/benchmarker/benchmarker.cpp b/tests/benchmarker/benchmarker.cpp
index 3c5fcde4e..c6de412a3 100644
--- a/tests/benchmarker/benchmarker.cpp
+++ b/tests/benchmarker/benchmarker.cpp
@@ -32,6 +32,7 @@
#include "valgrindrunner.h"
#include <QtConcurrent/qtconcurrentrun.h>
+#include <QtCore/QCoreApplication>
#include <iostream>
#include <utility>
@@ -118,9 +119,15 @@ void Benchmarker::buildQbs(const QString &buildDir) const
{
if (!QDir::root().mkpath(buildDir))
throw Exception(QStringLiteral("Failed to create directory '%1'.").arg(buildDir));
- runProcess(QStringList() << "qmake" << "CONFIG+=force_debug_info"
- << (m_qbsRepo + "/qbs.pro"), buildDir);
- runProcess(QStringList() << "make" << "-s", buildDir);
+ runProcess(QStringList() << QCoreApplication::applicationDirPath() + "/qbs"
+ << "resolve"
+ << "config:benchmarker"
+ << "qbs.buildVariant:profiling"
+ << "qbs.installPrefix:''"
+ << "-f" << m_qbsRepo + "/qbs.qbs", buildDir);
+ runProcess(QStringList() << QCoreApplication::applicationDirPath() + "/qbs"
+ << "build"
+ << "config:benchmarker", buildDir);
}
} // namespace qbsBenchmarker
diff --git a/tests/benchmarker/valgrindrunner.cpp b/tests/benchmarker/valgrindrunner.cpp
index 72745dc16..7509dbb52 100644
--- a/tests/benchmarker/valgrindrunner.cpp
+++ b/tests/benchmarker/valgrindrunner.cpp
@@ -48,7 +48,7 @@ ValgrindRunner::ValgrindRunner(Activities activities, QString testProject,
const QString &qbsBuildDir, const QString &baseOutputDir)
: m_activities(activities)
, m_testProject(std::move(testProject))
- , m_qbsBinary(qbsBuildDir + "/bin/qbs")
+ , m_qbsBinary(qbsBuildDir + "/benchmarker/install-root/bin/qbs")
, m_baseOutputDir(baseOutputDir)
{
if (!QDir::root().mkpath(m_baseOutputDir))
diff --git a/tests/fuzzy-test/CMakeLists.txt b/tests/fuzzy-test/CMakeLists.txt
index fe3a1a54e..43101f68b 100644
--- a/tests/fuzzy-test/CMakeLists.txt
+++ b/tests/fuzzy-test/CMakeLists.txt
@@ -7,6 +7,6 @@ set(SOURCES
)
add_qbs_app(qbs_fuzzy-test
- DEPENDS Qt5::Core
+ DEPENDS Qt${QT_VERSION_MAJOR}::Core
SOURCES ${SOURCES}
)