aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/CMakeLists.txt10
-rw-r--r--tests/auto/api/CMakeLists.txt9
-rw-r--r--tests/auto/api/api.pro28
-rw-r--r--tests/auto/api/api.qbs3
-rw-r--r--tests/auto/api/testdata/QBS-728/QBS-728.qbs2
-rw-r--r--tests/auto/api/testdata/app-without-sources/app-without-sources.qbs2
-rw-r--r--tests/auto/api/testdata/build-properties-source/build-properties-source.qbs5
-rw-r--r--tests/auto/api/testdata/build-properties-source/main.cpp4
-rw-r--r--tests/auto/api/testdata/change-dependent-lib/change-dependent-lib.qbs2
-rw-r--r--tests/auto/api/testdata/change-dependent-lib/main.cpp5
-rw-r--r--tests/auto/api/testdata/change-dependent-lib/mylib.cpp4
-rw-r--r--tests/auto/api/testdata/codegen/codegen.qbs6
-rw-r--r--tests/auto/api/testdata/dependency-on-multiplexed-type/dependency-on-multiplexed-type.qbs2
-rw-r--r--tests/auto/api/testdata/disabled-product/disabled-product.qbs2
-rw-r--r--tests/auto/api/testdata/disappeared-wildcard-file/disappeared-wildcard-file.qbs4
-rw-r--r--tests/auto/api/testdata/disappeared-wildcard-file/file1.txt (renamed from tests/auto/blackbox/testdata/concurrent-executor/dummy1.input)0
-rw-r--r--tests/auto/api/testdata/disappeared-wildcard-file/file2.txt (renamed from tests/auto/blackbox/testdata/concurrent-executor/dummy2.input)0
-rw-r--r--tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs7
-rw-r--r--tests/auto/api/testdata/export-simple/export-simple.qbs2
-rw-r--r--tests/auto/api/testdata/export-simple/lib1.cpp4
-rw-r--r--tests/auto/api/testdata/export-simple/main.cpp5
-rw-r--r--tests/auto/api/testdata/infinite-loop-js/infinite-loop.qbs2
-rw-r--r--tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs8
-rw-r--r--tests/auto/api/testdata/infinite-loop-scanning-scan/file.in (renamed from tests/auto/blackbox/testdata/innosetup/inc/qbsinc.iss)0
-rw-r--r--tests/auto/api/testdata/infinite-loop-scanning-scan/infinite-loop.qbs21
-rw-r--r--tests/auto/api/testdata/infinite-loop-scanning-scan/modules/m/m.qbs6
-rw-r--r--tests/auto/api/testdata/infinite-loop-scanning-searchpaths/file.in0
-rw-r--r--tests/auto/api/testdata/infinite-loop-scanning-searchpaths/infinite-loop.qbs21
-rw-r--r--tests/auto/api/testdata/infinite-loop-scanning-searchpaths/modules/m/m.qbs7
-rw-r--r--tests/auto/api/testdata/installed-artifact/installed-artifact.qbs1
-rw-r--r--tests/auto/api/testdata/is-runnable/is-runnable.qbs2
-rw-r--r--tests/auto/api/testdata/lib-same-source/main.cpp4
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs-staticlibs/dynamic1.cpp4
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs-staticlibs/dynamic2.cpp4
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs-staticlibs/link-dynamiclibs-staticlibs.qbs9
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs-staticlibs/main.cpp4
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs-staticlibs/static1.cpp4
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs-staticlibs/static2.cpp4
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs/lib1.cpp4
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs/lib2.cpp4
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs/lib3.cpp4
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs/lib4.cpp4
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs/lib4.h2
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs10
-rw-r--r--tests/auto/api/testdata/link-dynamiclibs/main.cpp4
-rw-r--r--tests/auto/api/testdata/link-static-lib/link-static-lib.qbs4
-rw-r--r--tests/auto/api/testdata/link-static-lib/main.cpp2
-rw-r--r--tests/auto/api/testdata/link-static-lib/mystaticlib.cpp5
-rw-r--r--tests/auto/api/testdata/link-staticlibs-dynamiclibs/dynamic1.cpp4
-rw-r--r--tests/auto/api/testdata/link-staticlibs-dynamiclibs/dynamic2.cpp4
-rw-r--r--tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs14
-rw-r--r--tests/auto/api/testdata/link-staticlibs-dynamiclibs/main.cpp4
-rw-r--r--tests/auto/api/testdata/link-staticlibs-dynamiclibs/static1.cpp5
-rw-r--r--tests/auto/api/testdata/link-staticlibs-dynamiclibs/static2.cpp4
-rw-r--r--tests/auto/api/testdata/lots-of-dots/m.a.i.n.cpp2
-rw-r--r--tests/auto/api/testdata/moc-hpp-included/moc-hpp-included.qbs2
-rw-r--r--tests/auto/api/testdata/moc-hpp-included/object.cpp2
-rw-r--r--tests/auto/api/testdata/moc-hpp/object.cpp2
-rw-r--r--tests/auto/api/testdata/multiplexing/multiplexing.qbs7
-rw-r--r--tests/auto/api/testdata/new-output-artifact-in-dependency/new-output-artifact-in-dependency.qbs2
-rw-r--r--tests/auto/api/testdata/objc/objc.qbs2
-rw-r--r--tests/auto/api/testdata/precompiled-header-dynamic/precompiled-header-dynamic.qbs2
-rw-r--r--tests/auto/api/testdata/process-result/process-result.qbs11
-rw-r--r--tests/auto/api/testdata/project-with-properties-item/project-with-properties-item.qbs2
-rw-r--r--tests/auto/api/testdata/properties-blocks/main.cpp7
-rw-r--r--tests/auto/api/testdata/properties-blocks/properties-blocks.qbs2
-rw-r--r--tests/auto/api/testdata/qt5-plugin/qt5-plugin.qbs3
-rw-r--r--tests/auto/api/testdata/remove-file-dependency/main.cpp2
-rw-r--r--tests/auto/api/testdata/rename-product/rename.qbs2
-rw-r--r--tests/auto/api/testdata/rename-target-artifact/rename.qbs2
-rw-r--r--tests/auto/api/testdata/renamed-qbs-source-file/renamed-qbs-source-file.qbs9
-rw-r--r--tests/auto/api/testdata/renamed-qbs-source-file/the-product/the-prodduct.qbs1
-rw-r--r--tests/auto/api/testdata/restored-warnings/restored-warnings.qbs27
-rw-r--r--tests/auto/api/testdata/same-base-name/same-base-name.qbs4
-rw-r--r--tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs10
-rw-r--r--tests/auto/api/testdata/timeout-js/timeout.qbs2
-rw-r--r--tests/auto/api/testdata/timeout-process/timeout.qbs14
-rw-r--r--tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs3
-rw-r--r--tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs9
-rw-r--r--tests/auto/api/testdata/transformer-data/transformer-data.qbs4
-rw-r--r--tests/auto/api/testdata/two-default-property-values/modules/mymodule/mymodule.qbs2
-rw-r--r--tests/auto/api/tst_api.cpp669
-rw-r--r--tests/auto/api/tst_api.h6
-rw-r--r--tests/auto/auto.pri18
-rw-r--r--tests/auto/auto.pro19
-rw-r--r--tests/auto/auto.qbs10
-rw-r--r--tests/auto/blackbox/CMakeLists.txt99
-rw-r--r--tests/auto/blackbox/blackbox-android.pro21
-rw-r--r--tests/auto/blackbox/blackbox-apple.pro20
-rw-r--r--tests/auto/blackbox/blackbox-baremetal.qbs21
-rw-r--r--tests/auto/blackbox/blackbox-clangdb.pro18
-rw-r--r--tests/auto/blackbox/blackbox-examples.qbs21
-rw-r--r--tests/auto/blackbox/blackbox-java.pro18
-rw-r--r--tests/auto/blackbox/blackbox-joblimits.pro18
-rw-r--r--tests/auto/blackbox/blackbox-providers.qbs21
-rw-r--r--tests/auto/blackbox/blackbox-qt.pro18
-rw-r--r--tests/auto/blackbox/blackbox-tutorial.qbs21
-rw-r--r--tests/auto/blackbox/blackbox-windows.qbs21
-rw-r--r--tests/auto/blackbox/blackbox.pro21
-rw-r--r--tests/auto/blackbox/blackbox.qbs1
-rw-r--r--tests/auto/blackbox/find/find-android.qbs50
-rw-r--r--tests/auto/blackbox/find/find-xcode.qbs4
-rw-r--r--tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml1
-rw-r--r--tests/auto/blackbox/testdata-android/minimal-native/minimal-native.qbs2
-rw-r--r--tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml1
-rw-r--r--tests/auto/blackbox/testdata-android/minimal-native/src/main/native/native.c1
-rw-r--r--tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs9
-rw-r--r--tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/src/main/AndroidManifest.xml2
-rw-r--r--tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs2
-rw-r--r--tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/src/main/AndroidManifest.xml2
-rw-r--r--tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs4
-rw-r--r--tests/auto/blackbox/testdata-android/multiple-libs-per-apk/src/main/AndroidManifest.xml2
-rw-r--r--tests/auto/blackbox/testdata-android/qml-app/qml-app.qbs4
-rw-r--r--tests/auto/blackbox/testdata-android/qml-app/src/main/AndroidManifest.xml5
-rw-r--r--tests/auto/blackbox/testdata-android/qt-app/MainWindow.cpp11
-rw-r--r--tests/auto/blackbox/testdata-android/qt-app/MainWindow.h15
-rw-r--r--tests/auto/blackbox/testdata-android/qt-app/Test.java54
-rw-r--r--tests/auto/blackbox/testdata-android/qt-app/TestQt6.java54
-rw-r--r--tests/auto/blackbox/testdata-android/qt-app/main.cpp11
-rw-r--r--tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs27
-rw-r--r--tests/auto/blackbox/testdata-android/qt-app/test.keystorebin0 -> 1284 bytes
-rw-r--r--tests/auto/blackbox/testdata-android/teapot/teapot.qbs5
-rw-r--r--tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/aggregateDependencyLinking.qbs31
-rw-r--r--tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs65
-rw-r--r--tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs24
-rw-r--r--tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/ByteArray-Info.plist11
-rw-r--r--tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/byteArrayInfoPlist.qbs37
-rw-r--r--tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/main.c (renamed from tests/auto/blackbox/testdata/innosetupDependencies/main.c)0
-rw-r--r--tests/auto/blackbox/testdata-apple/codesign/app.cpp (renamed from tests/auto/blackbox/testdata/path-probe/main.cpp)0
-rw-r--r--tests/auto/blackbox/testdata-apple/codesign/codesign.qbs57
-rw-r--r--tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs2
-rw-r--r--tests/auto/blackbox/testdata-apple/frameworkStructure/frameworkStructure.qbs6
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/100.pngbin0 -> 6652 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/114.pngbin0 -> 7757 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/120.pngbin0 -> 7734 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/128.pngbin0 -> 8774 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/144.pngbin0 -> 9498 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/152.pngbin0 -> 10734 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/16.pngbin0 -> 811 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/167.pngbin0 -> 11990 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/172.pngbin0 -> 12179 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/180.pngbin0 -> 12444 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/196.pngbin0 -> 14143 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/20.pngbin0 -> 1012 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/216.pngbin0 -> 15831 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/256.pngbin0 -> 18825 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/29.pngbin0 -> 1644 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/32.pngbin0 -> 1835 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/40.pngbin0 -> 2484 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/48.pngbin0 -> 2746 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/50.pngbin0 -> 3075 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/512.pngbin0 -> 41488 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/55.pngbin0 -> 3418 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/57.pngbin0 -> 3532 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/58.pngbin0 -> 3543 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/60.pngbin0 -> 3679 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/64.pngbin0 -> 3984 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/72.pngbin0 -> 4525 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/76.pngbin0 -> 4785 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/80.pngbin0 -> 5180 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/87.pngbin0 -> 5632 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/88.pngbin0 -> 5784 bytes
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/Contents.json299
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/appiconset.qbs10
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/appiconset/main.c (renamed from tests/auto/blackbox/testdata/wixDependencies/main.c)0
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/assetcatalog/assetcatalogempty.qbs10
-rw-r--r--tests/auto/blackbox/testdata-apple/ib/iconsetapp/iconsetapp.qbs5
-rw-r--r--tests/auto/blackbox/testdata-apple/infoPlistVariables/Info.plist24
-rw-r--r--tests/auto/blackbox/testdata-apple/infoPlistVariables/infoPlistVariables.qbs16
-rw-r--r--tests/auto/blackbox/testdata-apple/infoPlistVariables/main.c1
-rw-r--r--tests/auto/blackbox/testdata-apple/multiarch-helpers.js74
-rw-r--r--tests/auto/blackbox/testdata-apple/objc-arc/objc-arc.qbs2
-rw-r--r--tests/auto/blackbox/testdata-apple/overrideInfoPlist/Override-Info.plist10
-rw-r--r--tests/auto/blackbox/testdata-apple/overrideInfoPlist/main.c1
-rw-r--r--tests/auto/blackbox/testdata-apple/overrideInfoPlist/overrideInfoPlist.qbs16
-rw-r--r--tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs21
-rw-r--r--tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs29
-rw-r--r--tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs158
-rw-r--r--tests/auto/blackbox/testdata-baremetal/BareMetalStaticLibrary.qbs3
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/app.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/compiler-defines-by-language.qbs73
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/cpptest.cpp0
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/ctest.c0
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-include-paths/compiler-include-paths.qbs9
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-include-paths/main.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-listing/compiler-listing.qbs14
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-listing/fun.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/compiler-listing/main.c6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/cosmic.lkf1
-rw-r--r--tests/auto/blackbox/testdata-baremetal/defines/defines.qbs6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/defines/main.c11
-rw-r--r--tests/auto/blackbox/testdata-baremetal/distribution-include-paths/bar/bar.h6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/distribution-include-paths/distribution-include-paths.qbs6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/distribution-include-paths/foo/foo.h6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/distribution-include-paths/main.c7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs34
-rw-r--r--tests/auto/blackbox/testdata-baremetal/external-static-libraries/lib-a.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/external-static-libraries/lib-b.c6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/external-static-libraries/main.c6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs8
-rw-r--r--tests/auto/blackbox/testdata-baremetal/linker-map/main.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-application/main.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-application/one-object-application.qbs5
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/78k-iar.s6
-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/arm-gcc.s5
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-keil.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr-gcc.s6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr32-gcc.s8
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr32-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/c166-keil.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/cr16-iar.s6
-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/hcs12-iar.s7
-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/hcs8-iar.s6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-sdcc.s6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m16c-iar.s6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-gcc.s5
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-iar.s6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32r-gcc.s9
-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/m68k-gcc.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-iar.s6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs251-keil.s8
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-keil.s8
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-sdcc.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/msp430-gcc.s5
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/msp430-iar.s6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/one-object-asm-application.qbs122
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/r32c-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rh850-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-gcc.s11
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rl78-gcc.s11
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rl78-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-gcc.s8
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-iar.s5
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/sh-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-cosmic.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-sdcc.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/v850-gcc.s11
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/v850-iar.s7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/one-object-asm-application/xtensa-gcc.s11
-rw-r--r--tests/auto/blackbox/testdata-baremetal/preinclude-headers/main.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/preinclude-headers/preinclude-headers.qbs18
-rw-r--r--tests/auto/blackbox/testdata-baremetal/preinclude-headers/preinclude.h6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/shared-libraries/app.c12
-rw-r--r--tests/auto/blackbox/testdata-baremetal/shared-libraries/shared-libraries.qbs32
-rw-r--r--tests/auto/blackbox/testdata-baremetal/shared-libraries/shared.c19
-rw-r--r--tests/auto/blackbox/testdata-baremetal/static-library-dependencies/a1.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/static-library-dependencies/a2.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/static-library-dependencies/app.c6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/static-library-dependencies/b.c6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/static-library-dependencies/c.c6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/static-library-dependencies/d.c7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/static-library-dependencies/e.c7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/static-library-dependencies/static-library-dependencies.qbs40
-rw-r--r--tests/auto/blackbox/testdata-baremetal/system-include-paths/bar/bar.h6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/system-include-paths/foo/foo.h6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/system-include-paths/main.c7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/system-include-paths/system-include-paths.qbs6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/target-platform/target-platform.qbs19
-rw-r--r--tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/dmc.qbs31
-rw-r--r--tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/sdcc.qbs29
-rw-r--r--tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/watcom.qbs34
-rw-r--r--tests/auto/blackbox/testdata-baremetal/toolchain-probe/toolchain-probe.qbs7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/two-object-application/fun.c4
-rw-r--r--tests/auto/blackbox/testdata-baremetal/two-object-application/main.c6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/two-object-application/two-object-application.qbs5
-rw-r--r--tests/auto/blackbox/testdata-baremetal/user-include-paths/bar/bar.h6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/user-include-paths/foo/foo.h6
-rw-r--r--tests/auto/blackbox/testdata-baremetal/user-include-paths/main.c7
-rw-r--r--tests/auto/blackbox/testdata-baremetal/user-include-paths/user-include-paths.qbs6
-rw-r--r--tests/auto/blackbox/testdata-clangdb/project1/project.qbs4
-rw-r--r--tests/auto/blackbox/testdata-java/java/vehicles.qbs18
-rw-r--r--tests/auto/blackbox/testdata-joblimits/job-limits-init/job-limits-init.qbs10
-rw-r--r--tests/auto/blackbox/testdata-joblimits/job-limits/job-limits.qbs4
-rw-r--r--tests/auto/blackbox/testdata-joblimits/job-limits/main.cpp12
-rw-r--r--tests/auto/blackbox/testdata-providers/allowed-values/allowed-values.qbs4
-rw-r--r--tests/auto/blackbox/testdata-providers/allowed-values/module-providers/provider.qbs14
-rw-r--r--tests/auto/blackbox/testdata-providers/broken-provider/broken-provider.qbs13
-rw-r--r--tests/auto/blackbox/testdata-providers/broken-provider/module-providers/provider_a.qbs5
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/conan-module-provider.qbs11
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/conanfile.txt3
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/main.cpp8
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlib/CMakeLists.txt9
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlib/conanfile.py36
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlib/testlib.cpp7
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlib/testlib.h10
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/CMakeLists.txt7
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/conanfile.py35
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/lorem_ipsum.txt1
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/testlibdep.cpp6
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/testlibdep.h3
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlibheader/conanfile.py15
-rw-r--r--tests/auto/blackbox/testdata-providers/conan-provider/testlibheader/header.h6
-rw-r--r--tests/auto/blackbox/testdata-providers/fallback-module-provider/fallback-module-provider.qbs (renamed from tests/auto/blackbox/testdata/fallback-module-provider/fallback-module-provider.qbs)0
-rw-r--r--tests/auto/blackbox/testdata-providers/fallback-module-provider/libdir/qbsmetatestmodule.pc (renamed from tests/auto/blackbox/testdata/fallback-module-provider/libdir/qbsmetatestmodule.pc)0
-rw-r--r--tests/auto/blackbox/testdata-providers/fallback-module-provider/main.cpp (renamed from tests/auto/blackbox/testdata/fallback-module-provider/main.cpp)0
-rw-r--r--tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers-cache.qbs11
-rw-r--r--tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers/provider_a.qbs9
-rw-r--r--tests/auto/blackbox/testdata-providers/module-providers/main.cpp (renamed from tests/auto/blackbox/testdata/module-providers/main.cpp)2
-rw-r--r--tests/auto/blackbox/testdata-providers/module-providers/module-providers.qbs36
-rw-r--r--tests/auto/blackbox/testdata-providers/module-providers/module-providers/mygenerator/provider.qbs (renamed from tests/auto/blackbox/testdata/module-providers/module-providers/mygenerator/provider.qbs)0
-rw-r--r--tests/auto/blackbox/testdata-providers/module-providers/module-providers/othergenerator/provider.qbs19
-rw-r--r--tests/auto/blackbox/testdata-providers/non-eager-provider/module-providers/provider_a.qbs11
-rw-r--r--tests/auto/blackbox/testdata-providers/non-eager-provider/non-eager-provider.qbs13
-rw-r--r--tests/auto/blackbox/testdata-providers/probe-in-module-provider/module-providers/provider_a.qbs23
-rw-r--r--tests/auto/blackbox/testdata-providers/probe-in-module-provider/probe-in-module-provider.qbs9
-rw-r--r--tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_a.qbs9
-rw-r--r--tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_b.qbs9
-rw-r--r--tests/auto/blackbox/testdata-providers/providers-properties/providers-properties.qbs12
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/module-providers/provider_a.qbs9
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/qbs-module-properties-in-providers.qbs34
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_a.qbs8
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_b.qbs9
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/qbs-module-providers-cli-override.qbs13
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/named_provider.qbs8
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/qbsmetatestmodule/provider.qbs8
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/qbs-module-providers-compatibility.qbs7
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-providers-helpers.js23
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_a.qbs8
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_b.qbs9
-rw-r--r--tests/auto/blackbox/testdata-providers/qbs-module-providers/qbs-module-providers.qbs28
-rw-r--r--tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.cpp14
-rw-r--r--tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.h21
-rw-r--r--tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libs.qbs42
-rw-r--r--tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/main.cpp11
-rw-r--r--tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/qbspkgconfig-module-provider.qbs6
-rw-r--r--tests/auto/blackbox/testdata-providers/removal-version/module-providers/provider_a.qbs14
-rw-r--r--tests/auto/blackbox/testdata-providers/removal-version/removal-version.qbs12
-rw-r--r--tests/auto/blackbox/testdata-qt/auto-qrc/auto-qrc.qbs9
-rw-r--r--tests/auto/blackbox/testdata-qt/dbus-adaptors/car.cpp4
-rw-r--r--tests/auto/blackbox/testdata-qt/dbus-adaptors/main.cpp6
-rw-r--r--tests/auto/blackbox/testdata-qt/dbus-interfaces/controller.cpp3
-rw-r--r--tests/auto/blackbox/testdata-qt/dbus-interfaces/main.cpp7
-rw-r--r--tests/auto/blackbox/testdata-qt/forced-moc/forced-moc.qbs13
-rw-r--r--tests/auto/blackbox/testdata-qt/included-moc-cpp/included-moc-cpp.qbs9
-rw-r--r--tests/auto/blackbox/testdata-qt/linker-variant/qt-linker-variant.qbs2
-rw-r--r--tests/auto/blackbox/testdata-qt/metatypes/metatypes.qbs28
-rw-r--r--tests/auto/blackbox/testdata-qt/metatypes/mocableclass1.cpp3
-rw-r--r--tests/auto/blackbox/testdata-qt/metatypes/mocableclass1.h8
-rw-r--r--tests/auto/blackbox/testdata-qt/metatypes/mocableclass2.cpp10
-rw-r--r--tests/auto/blackbox/testdata-qt/metatypes/unmocableclass.cpp7
-rw-r--r--tests/auto/blackbox/testdata-qt/mixed-build-variants/mixed-build-variants.qbs2
-rw-r--r--tests/auto/blackbox/testdata-qt/moc-compiler-defines/main.cpp7
-rw-r--r--tests/auto/blackbox/testdata-qt/moc-compiler-defines/moc-compiler-defines.qbs3
-rw-r--r--tests/auto/blackbox/testdata-qt/moc-compiler-defines/object.cpp6
-rw-r--r--tests/auto/blackbox/testdata-qt/moc-compiler-defines/object.h58
-rw-r--r--tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/lib.cpp8
-rw-r--r--tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/lib.h18
-rw-r--r--tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/main.cpp3
-rw-r--r--tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/symbols-test.qbs27
-rw-r--r--tests/auto/blackbox/testdata-qt/pkgconfig-qt/dump-libpath.qbs6
-rw-r--r--tests/auto/blackbox/testdata-qt/pkgconfig-qt/main.cpp1
-rw-r--r--tests/auto/blackbox/testdata-qt/pkgconfig-qt/module-providers/dummyProvider.qbs3
-rw-r--r--tests/auto/blackbox/testdata-qt/pkgconfig-qt/pkgconfig-qt.qbs6
-rw-r--r--tests/auto/blackbox/testdata-qt/pkgconfig/pkgconfig.qbs7
-rw-r--r--tests/auto/blackbox/testdata-qt/plugin-meta-data/plugin-meta-data.qbs21
-rw-r--r--tests/auto/blackbox/testdata-qt/plugin-support/plugin-support.qbs10
-rw-r--r--tests/auto/blackbox/testdata-qt/qdoc/qdoc.qbs22
-rw-r--r--tests/auto/blackbox/testdata-qt/qdoc/qdoc.qdoc7
-rw-r--r--tests/auto/blackbox/testdata-qt/qdoc/qdoc.qdocconf13
-rw-r--r--tests/auto/blackbox/testdata-qt/qml-debugging/qml-debugging.qbs5
-rw-r--r--tests/auto/blackbox/testdata-qt/qmltyperegistrar/example.qml58
-rw-r--r--tests/auto/blackbox/testdata-qt/qmltyperegistrar/main.cpp71
-rw-r--r--tests/auto/blackbox/testdata-qt/qmltyperegistrar/person.cpp78
-rw-r--r--tests/auto/blackbox/testdata-qt/qmltyperegistrar/person.h78
-rw-r--r--tests/auto/blackbox/testdata-qt/qmltyperegistrar/qmltyperegistrar.qbs33
-rw-r--r--tests/auto/blackbox/testdata-qt/qrc/i.qbs13
-rw-r--r--tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs31
-rw-r--r--tests/auto/blackbox/testdata-qt/quick-compiler/quick-compiler.qbs6
-rw-r--r--tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/lib.cpp1
-rw-r--r--tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/static-qt-plugin-linking.qbs9
-rw-r--r--tests/auto/blackbox/testdata-windows/codesign/app.cpp1
-rw-r--r--tests/auto/blackbox/testdata-windows/codesign/codesign.qbs43
-rw-r--r--tests/auto/blackbox/testdata-windows/innosetup/inc/qbsinc.iss0
-rw-r--r--tests/auto/blackbox/testdata-windows/innosetup/innosetup.qbs (renamed from tests/auto/blackbox/testdata/innosetup/innosetup.qbs)7
-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)4
-rw-r--r--tests/auto/blackbox/testdata-windows/innosetupDependencies/main.c1
-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)7
-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.c1
-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/allowed-values/allowed-values.qbs19
-rw-r--r--tests/auto/blackbox/testdata/allowed-values/modules/a/a.qbs18
-rw-r--r--tests/auto/blackbox/testdata/assembly/assembly.qbs16
-rw-r--r--tests/auto/blackbox/testdata/autotest-timeout/autotests-timeout.qbs12
-rw-r--r--tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs9
-rw-r--r--tests/auto/blackbox/testdata/autotests/autotests.qbs10
-rw-r--r--tests/auto/blackbox/testdata/badInterpreter/badInterpreter.qbs9
-rw-r--r--tests/auto/blackbox/testdata/build-variant-defaults/build-variant-defaults.qbs16
-rw-r--r--tests/auto/blackbox/testdata/build-variant-defaults/main.cpp1
-rw-r--r--tests/auto/blackbox/testdata/buildenv-change/buildenv-change.qbs2
-rw-r--r--tests/auto/blackbox/testdata/capnproto/bar.capnp8
-rw-r--r--tests/auto/blackbox/testdata/capnproto/baz.capnp8
-rw-r--r--tests/auto/blackbox/testdata/capnproto/capnproto_absolute_import.cpp14
-rw-r--r--tests/auto/blackbox/testdata/capnproto/capnproto_absolute_import.qbs21
-rw-r--r--tests/auto/blackbox/testdata/capnproto/capnproto_cpp.cpp13
-rw-r--r--tests/auto/blackbox/testdata/capnproto/capnproto_cpp.qbs19
-rw-r--r--tests/auto/blackbox/testdata/capnproto/capnproto_relative_import.cpp14
-rw-r--r--tests/auto/blackbox/testdata/capnproto/capnproto_relative_import.qbs19
-rw-r--r--tests/auto/blackbox/testdata/capnproto/conanfile.txt6
-rw-r--r--tests/auto/blackbox/testdata/capnproto/foo.capnp6
-rw-r--r--tests/auto/blackbox/testdata/capnproto/greeter-client.cpp25
-rw-r--r--tests/auto/blackbox/testdata/capnproto/greeter-server.cpp27
-rw-r--r--tests/auto/blackbox/testdata/capnproto/greeter.capnp13
-rw-r--r--tests/auto/blackbox/testdata/capnproto/greeter_cpp.qbs39
-rw-r--r--tests/auto/blackbox/testdata/capnproto/imports/foo.capnp6
-rw-r--r--tests/auto/blackbox/testdata/change-in-imported-file/change-in-imported-file.qbs2
-rw-r--r--tests/auto/blackbox/testdata/change-tracking-and-multiplexing/change-tracking-and-multiplexing.qbs4
-rw-r--r--tests/auto/blackbox/testdata/choose-module-instance/other-searchpath/modules/limerick/generic.qbs2
-rw-r--r--tests/auto/blackbox/testdata/clean/clean.qbs2
-rw-r--r--tests/auto/blackbox/testdata/cli/dotnettest.qbs6
-rw-r--r--tests/auto/blackbox/testdata/command-file/command-file.qbs4
-rw-r--r--tests/auto/blackbox/testdata/compilerDefinesByLanguage/CppDefinesApp.qbs2
-rw-r--r--tests/auto/blackbox/testdata/conanfile-probe/testapp/conanfile-probe-project.qbs23
-rw-r--r--tests/auto/blackbox/testdata/conanfile-probe/testapp/conanfile.py26
-rw-r--r--tests/auto/blackbox/testdata/conanfile-probe/testlib/conanfile.py25
-rw-r--r--tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs67
-rw-r--r--tests/auto/blackbox/testdata/concurrent-executor/util.js8
-rw-r--r--tests/auto/blackbox/testdata/conditional-filetagger/conditional-filetagger.qbs2
-rw-r--r--tests/auto/blackbox/testdata/configure/configure.qbs7
-rw-r--r--tests/auto/blackbox/testdata/configure/main.cpp2
-rw-r--r--tests/auto/blackbox/testdata/configure/modules/definition/module.qbs2
-rw-r--r--tests/auto/blackbox/testdata/conflicting-property-values/conflicting-property-values.qbs41
-rw-r--r--tests/auto/blackbox/testdata/cpu-features/cpu-features.qbs4
-rw-r--r--tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs4
-rw-r--r--tests/auto/blackbox/testdata/date-property/date-property.qbs18
-rw-r--r--tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs2
-rw-r--r--tests/auto/blackbox/testdata/dependency-profile-mismatch/dependency-profile-mismatch.qbs12
-rw-r--r--tests/auto/blackbox/testdata/dependency-scanning-loop/dependency-scanning-loop.qbs34
-rw-r--r--tests/auto/blackbox/testdata/dependency-scanning-loop/main.cpp1
-rw-r--r--tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs4
-rw-r--r--tests/auto/blackbox/testdata/deprecated-property/modules/themodule/m.qbs8
-rw-r--r--tests/auto/blackbox/testdata/disappeared-profile/modules-dir/modules/m/m.qbs4
-rw-r--r--tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs6
-rw-r--r--tests/auto/blackbox/testdata/distribution-include-paths/distribution-include-paths.qbs4
-rw-r--r--tests/auto/blackbox/testdata/distribution-include-paths/main.cpp8
-rw-r--r--tests/auto/blackbox/testdata/distribution-include-paths/subdir/gagagugu.h4
-rw-r--r--tests/auto/blackbox/testdata/dot-dot-pc-file/dot-dot-pc-file.qbs7
-rw-r--r--tests/auto/blackbox/testdata/dot-dot-pc-file/libdir/qbs.metatest.module.pc5
-rw-r--r--tests/auto/blackbox/testdata/dot-dot-pc-file/main.cpp5
-rw-r--r--tests/auto/blackbox/testdata/driver-linker-flags/driver-linker-flags.qbs2
-rw-r--r--tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs4
-rw-r--r--tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thelib/thelib.qbs2
-rw-r--r--tests/auto/blackbox/testdata/dynamic-library-in-module/modules/theotherlib/theotherlib.qbs2
-rw-r--r--tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs8
-rw-r--r--tests/auto/blackbox/testdata/dynamic-project/dynamic-project.qbs3
-rw-r--r--tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js4
-rw-r--r--tests/auto/blackbox/testdata/empty-profile/empty-profile.qbs3
-rw-r--r--tests/auto/blackbox/testdata/empty-profile/main.cpp1
-rw-r--r--tests/auto/blackbox/testdata/enableExceptions/exceptions.qbs2
-rw-r--r--tests/auto/blackbox/testdata/enableExceptions/none.qbs2
-rw-r--r--tests/auto/blackbox/testdata/env-merging/env-merging.qbs8
-rw-r--r--tests/auto/blackbox/testdata/escaped-linker-flags/escaped-linker-flags.qbs5
-rw-r--r--tests/auto/blackbox/testdata/export-rule/export-rule.qbs2
-rw-r--r--tests/auto/blackbox/testdata/exports-cmake/Foo.cpp5
-rw-r--r--tests/auto/blackbox/testdata/exports-cmake/Foo.h16
-rw-r--r--tests/auto/blackbox/testdata/exports-cmake/cmake/CMakeLists.txt7
-rw-r--r--tests/auto/blackbox/testdata/exports-cmake/cmake/main.cpp6
-rw-r--r--tests/auto/blackbox/testdata/exports-cmake/exports-cmake.qbs70
-rw-r--r--tests/auto/blackbox/testdata/exports-cmake/find-cmake.qbs46
-rw-r--r--tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs9
-rw-r--r--tests/auto/blackbox/testdata/exports-qbs/consumer.qbs8
-rw-r--r--tests/auto/blackbox/testdata/exports-qbs/lib.qbs8
-rw-r--r--tests/auto/blackbox/testdata/exports-qbs/tool.qbs4
-rw-r--r--tests/auto/blackbox/testdata/external-libs/external-libs.qbs6
-rw-r--r--tests/auto/blackbox/testdata/fileDependencies/awesomelib/awesome.h2
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/bar.fbs9
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/baz.fbs9
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/conanfile.txt6
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat.c36
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat.cpp22
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_absolute_import.cpp25
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_absolute_import.qbs24
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_c.qbs21
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_cpp.qbs21
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_filename_extension.cpp22
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_filename_extension.qbs23
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_filename_suffix.cpp22
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_filename_suffix.qbs23
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_keep_prefix.cpp26
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_keep_prefix.qbs25
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_relative_import.cpp25
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/flat_relative_import.qbs22
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/foo.fbs8
-rw-r--r--tests/auto/blackbox/testdata/flatbuf/imports/imported_foo/imported_foo.fbs8
-rw-r--r--tests/auto/blackbox/testdata/freedesktop/freedesktop.qbs23
-rw-r--r--tests/auto/blackbox/testdata/freedesktop/main.cpp4
-rw-r--r--tests/auto/blackbox/testdata/freedesktop/myapp.appdata.xml15
-rw-r--r--tests/auto/blackbox/testdata/freedesktop/myapp.desktop4
-rw-r--r--tests/auto/blackbox/testdata/freedesktop/myapp.png0
-rw-r--r--tests/auto/blackbox/testdata/generate-linker-map-file/generate-linker-map-file.qbs7
-rw-r--r--tests/auto/blackbox/testdata/generator/generator.qbs4
-rw-r--r--tests/auto/blackbox/testdata/groups-in-modules/groups-in-modules.qbs11
-rw-r--r--tests/auto/blackbox/testdata/groups-in-modules/imports/Helper7Base.qbs8
-rw-r--r--tests/auto/blackbox/testdata/groups-in-modules/modules/helper/helper.qbs2
-rw-r--r--tests/auto/blackbox/testdata/groups-in-modules/modules/helper7/helper7.c1
-rw-r--r--tests/auto/blackbox/testdata/groups-in-modules/modules/helper7/helper7.qbs3
-rw-r--r--tests/auto/blackbox/testdata/grpc/conanfile.txt7
-rw-r--r--tests/auto/blackbox/testdata/grpc/grpc.cpp4
-rw-r--r--tests/auto/blackbox/testdata/grpc/grpc_cpp.qbs17
-rw-r--r--tests/auto/blackbox/testdata/host-os-properties/host-os-properties.qbs16
-rw-r--r--tests/auto/blackbox/testdata/host-os-properties/main.cpp7
-rw-r--r--tests/auto/blackbox/testdata/importing-product/importing-product.qbs2
-rw-r--r--tests/auto/blackbox/testdata/includeLookup/includeLookup.qbs7
-rw-r--r--tests/auto/blackbox/testdata/includeLookup/main.cpp2
-rw-r--r--tests/auto/blackbox/testdata/input-tags-change-tracking/input-tags-change-tracking.qbs4
-rw-r--r--tests/auto/blackbox/testdata/inputs-from-dependencies/inputs-from-dependencies.qbs2
-rw-r--r--tests/auto/blackbox/testdata/install-locations/install-locations.qbs26
-rw-r--r--tests/auto/blackbox/testdata/install-locations/theplugin.cpp3
-rw-r--r--tests/auto/blackbox/testdata/installable-as-auxiliary-input/installable-as-auxiliary-input.qbs13
-rw-r--r--tests/auto/blackbox/testdata/installable/installable.qbs3
-rw-r--r--tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs2
-rw-r--r--tests/auto/blackbox/testdata/installpackage/installpackage.qbs4
-rw-r--r--tests/auto/blackbox/testdata/invalid-artifact-path/invalid-artifact-path.qbs18
-rw-r--r--tests/auto/blackbox/testdata/invalid-command-property/invalid-command-property.qbs2
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs3
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-file/file.qbs4
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs2
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-host/host.qbs31
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-process/main.cpp10
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-process/process.qbs11
-rw-r--r--tests/auto/blackbox/testdata/last-module-candidate-broken/last-module-candidate-broken.qbs5
-rw-r--r--tests/auto/blackbox/testdata/last-module-candidate-broken/main.cpp1
-rw-r--r--tests/auto/blackbox/testdata/last-module-candidate-broken/qbs/modules/Foo/Foo1.qbs3
-rw-r--r--tests/auto/blackbox/testdata/last-module-candidate-broken/qbs/modules/Foo/Foo2.qbs2
-rw-r--r--tests/auto/blackbox/testdata/ld/ld.qbs2
-rw-r--r--tests/auto/blackbox/testdata/ld/main.cpp5
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/modules/bisonhelper/bisonhelper.qbs3
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs14
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/two-grammars/two-grammars.qbs6
-rw-r--r--tests/auto/blackbox/testdata/linker-library-duplicates/setup-run-environment.qbs7
-rw-r--r--tests/auto/blackbox/testdata/linker-module-definition/linker-module-definition.qbs20
-rw-r--r--tests/auto/blackbox/testdata/linker-module-definition/testapp.cpp39
-rw-r--r--tests/auto/blackbox/testdata/linker-module-definition/testlib.cpp41
-rw-r--r--tests/auto/blackbox/testdata/linker-module-definition/testlib.def3
-rw-r--r--tests/auto/blackbox/testdata/linker-variant/linker-variant.qbs2
-rw-r--r--tests/auto/blackbox/testdata/linkerMode/darwin.s6
-rw-r--r--tests/auto/blackbox/testdata/linkerMode/linkerMode.qbs6
-rw-r--r--tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs7
-rw-r--r--tests/auto/blackbox/testdata/list-property-order/modules/lower/lower.qbs2
-rw-r--r--tests/auto/blackbox/testdata/list-property-order/product.qbs1
-rw-r--r--tests/auto/blackbox/testdata/loadablemodule/loadablemodule.qbs14
-rw-r--r--tests/auto/blackbox/testdata/localDeployment/localDeployment.qbs8
-rw-r--r--tests/auto/blackbox/testdata/lsp/lsp.qbs11
-rw-r--r--tests/auto/blackbox/testdata/lsp/modules/Prefix/m1/m1.qbs5
-rw-r--r--tests/auto/blackbox/testdata/lsp/modules/Prefix/m2/m2.qbs (renamed from tests/auto/language/testdata/erroneous/modules/prefix1/prefix1.qbs)0
-rw-r--r--tests/auto/blackbox/testdata/lsp/modules/Prefix/m3/m3.qbs2
-rw-r--r--tests/auto/blackbox/testdata/lsp/modules/m/m.qbs2
-rw-r--r--tests/auto/blackbox/testdata/makefile-generator/app.qbs10
-rw-r--r--tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs9
-rw-r--r--tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newestmodule/newestmodule.qbs2
-rw-r--r--tests/auto/blackbox/testdata/minimumSystemVersion/fakewindows.qbs2
-rw-r--r--tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs9
-rw-r--r--tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs19
-rw-r--r--tests/auto/blackbox/testdata/minimumSystemVersion/unspecified-forced.qbs14
-rw-r--r--tests/auto/blackbox/testdata/minimumSystemVersion/unspecified.qbs14
-rw-r--r--tests/auto/blackbox/testdata/module-conditions/module-conditions.qbs2
-rw-r--r--tests/auto/blackbox/testdata/module-providers/module-providers.qbs20
-rw-r--r--tests/auto/blackbox/testdata/msvc-asm-flags/include/header.inc0
-rw-r--r--tests/auto/blackbox/testdata/msvc-asm-flags/msvc-asm-flags.asm8
-rw-r--r--tests/auto/blackbox/testdata/msvc-asm-flags/msvc-asm-flags.qbs6
-rw-r--r--tests/auto/blackbox/testdata/multiplexed-tool/multiplexed-tool.qbs10
-rw-r--r--tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs2
-rw-r--r--tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs2
-rw-r--r--tests/auto/blackbox/testdata/no-such-profile/no-such-profile.qbs2
-rw-r--r--tests/auto/blackbox/testdata/nodejs/hello.qbs8
-rw-r--r--tests/auto/blackbox/testdata/nsis/hello.qbs2
-rw-r--r--tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs2
-rw-r--r--tests/auto/blackbox/testdata/output-redirection/output-redirection.qbs3
-rw-r--r--tests/auto/blackbox/testdata/overrideProjectProperties/helper_lib.qbs2
-rw-r--r--tests/auto/blackbox/testdata/path-list-in-probe/main.cpp4
-rw-r--r--tests/auto/blackbox/testdata/path-list-in-probe/path-list-in-probe.qbs18
-rw-r--r--tests/auto/blackbox/testdata/path-probe/BaseApp.qbs70
-rw-r--r--tests/auto/blackbox/testdata/path-probe/candidate-filter.qbs6
-rw-r--r--tests/auto/blackbox/testdata/path-probe/environment-paths.qbs10
-rw-r--r--tests/auto/blackbox/testdata/path-probe/mult-files-common-suffixes.qbs10
-rw-r--r--tests/auto/blackbox/testdata/path-probe/mult-files-mult-suffixes.qbs3
-rw-r--r--tests/auto/blackbox/testdata/path-probe/mult-files-mult-variants.qbs3
-rw-r--r--tests/auto/blackbox/testdata/path-probe/mult-files-suffixes.qbs1
-rw-r--r--tests/auto/blackbox/testdata/path-probe/mult-files.qbs1
-rw-r--r--tests/auto/blackbox/testdata/path-probe/name-filter.qbs1
-rw-r--r--tests/auto/blackbox/testdata/path-probe/non-existent-selector.qbs1
-rw-r--r--tests/auto/blackbox/testdata/path-probe/non-existent.qbs1
-rw-r--r--tests/auto/blackbox/testdata/path-probe/single-file-mult-variants.qbs1
-rw-r--r--tests/auto/blackbox/testdata/path-probe/single-file-selector-array.qbs1
-rw-r--r--tests/auto/blackbox/testdata/path-probe/single-file-selector.qbs1
-rw-r--r--tests/auto/blackbox/testdata/path-probe/single-file-suffixes.qbs3
-rw-r--r--tests/auto/blackbox/testdata/path-probe/single-file.qbs1
-rw-r--r--tests/auto/blackbox/testdata/path-probe/usr/bin/tool0
-rw-r--r--tests/auto/blackbox/testdata/plugin-dependency/helper1.cpp4
-rw-r--r--tests/auto/blackbox/testdata/plugin-dependency/helper2.cpp4
-rw-r--r--tests/auto/blackbox/testdata/plugin-dependency/plugin-dependency.qbs8
-rw-r--r--tests/auto/blackbox/testdata/plugin-dependency/plugin1.cpp4
-rw-r--r--tests/auto/blackbox/testdata/plugin-dependency/plugin2.cpp4
-rw-r--r--tests/auto/blackbox/testdata/plugin-dependency/plugin3.cpp4
-rw-r--r--tests/auto/blackbox/testdata/plugin-dependency/plugin4.cpp4
-rw-r--r--tests/auto/blackbox/testdata/precompiled-headers-and-redefine/precompiled-headers-and-redefine.qbs2
-rw-r--r--tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs2
-rw-r--r--tests/auto/blackbox/testdata/probe-in-exported-module/modules/mymodule/mymodule.qbs2
-rw-r--r--tests/auto/blackbox/testdata/probeProperties/probeProperties.qbs51
-rw-r--r--tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs3
-rw-r--r--tests/auto/blackbox/testdata/product-dependencies-by-type/product-dependencies-by-type.qbs4
-rw-r--r--tests/auto/blackbox/testdata/product-in-exported-module/modules/m/m.qbs3
-rw-r--r--tests/auto/blackbox/testdata/product-in-exported-module/product-in-exported-module.qbs10
-rw-r--r--tests/auto/blackbox/testdata/productproperties/header.qbs2
-rw-r--r--tests/auto/blackbox/testdata/proper quoting/main.cpp10
-rw-r--r--tests/auto/blackbox/testdata/proper quoting/my static lib.cpp5
-rw-r--r--tests/auto/blackbox/testdata/proper quoting/proper quoting.qbs10
-rw-r--r--tests/auto/blackbox/testdata/property-assignment-on-non-present-module/property-assignment-on-non-present-module.qbs4
-rw-r--r--tests/auto/blackbox/testdata/property-evaluation-context/modules/base/base.qbs4
-rw-r--r--tests/auto/blackbox/testdata/property-evaluation-context/modules/top/top.qbs6
-rw-r--r--tests/auto/blackbox/testdata/property-evaluation-context/property-evaluation-context.qbs34
-rw-r--r--tests/auto/blackbox/testdata/propertyChanges/modules/TestModule/module.qbs2
-rw-r--r--tests/auto/blackbox/testdata/propertyChanges/propertyChanges.qbs4
-rw-r--r--tests/auto/blackbox/testdata/protobuf-library-install/hello.proto8
-rw-r--r--tests/auto/blackbox/testdata/protobuf-library-install/hello/world.proto6
-rw-r--r--tests/auto/blackbox/testdata/protobuf-library-install/protobuf-library.qbs34
-rw-r--r--tests/auto/blackbox/testdata/protobuf/addressbook_cpp.qbs12
-rw-r--r--tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.options3
-rw-r--r--tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.proto38
-rw-r--r--tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.qbs29
-rw-r--r--tests/auto/blackbox/testdata/protobuf/addressbook_objc.qbs10
-rw-r--r--tests/auto/blackbox/testdata/protobuf/conanfile.txt6
-rw-r--r--tests/auto/blackbox/testdata/protobuf/create-proto-library.qbs53
-rw-r--r--tests/auto/blackbox/testdata/protobuf/import-main.cpp4
-rw-r--r--tests/auto/blackbox/testdata/protobuf/import.qbs12
-rw-r--r--tests/auto/blackbox/testdata/protobuf/main.cpp4
-rw-r--r--tests/auto/blackbox/testdata/protobuf/main.m4
-rw-r--r--tests/auto/blackbox/testdata/protobuf/main_nanopb.cpp61
-rw-r--r--tests/auto/blackbox/testdata/protobuf/needs-import-dir-main.cpp4
-rw-r--r--tests/auto/blackbox/testdata/protobuf/needs-import-dir.qbs12
-rw-r--r--tests/auto/blackbox/testdata/qbs-config-import-export/config.json11
-rw-r--r--tests/auto/blackbox/testdata/qbs-config-import-export/config.txt4
-rw-r--r--tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs2
-rw-r--r--tests/auto/blackbox/testdata/remove-duplicate-libs/remove-duplicate-libs.qbs4
-rw-r--r--tests/auto/blackbox/testdata/reproducible-build/reproducible-build.qbs5
-rw-r--r--tests/auto/blackbox/testdata/require-deprecated/blubb.js13
-rw-r--r--tests/auto/blackbox/testdata/require-deprecated/require.qbs21
-rw-r--r--tests/auto/blackbox/testdata/require-deprecated/zort.js11
-rw-r--r--tests/auto/blackbox/testdata/response-files/response-files.qbs10
-rw-r--r--tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication-lib.cpp3
-rw-r--r--tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication-main.cpp5
-rw-r--r--tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication.qbs47
-rw-r--r--tests/auto/blackbox/testdata/rule-with-non-required-inputs/rule-with-non-required-inputs.qbs2
-rw-r--r--tests/auto/blackbox/testdata/run-multiplexed/main.cpp1
-rw-r--r--tests/auto/blackbox/testdata/run-multiplexed/run-multiplexed.qbs21
-rw-r--r--tests/auto/blackbox/testdata/sanitizer/sanitizer.cpp4
-rw-r--r--tests/auto/blackbox/testdata/sanitizer/sanitizer.qbs44
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/app.h1
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/app.qbs4
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/main.cpp3
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-non-dependency/lib/lib.h3
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-non-dependency/other/other.qbs24
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-non-dependency/p.qbs6
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-other-product/app/app.h1
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-other-product/app/app.qbs4
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-other-product/app/main.cpp3
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-other-product/lib/lib.h3
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-other-product/lib/lib.qbs7
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-other-product/other/other.qbs24
-rw-r--r--tests/auto/blackbox/testdata/scan-result-in-other-product/p.qbs7
-rw-r--r--tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs30
-rw-r--r--tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs25
-rw-r--r--tests/auto/blackbox/testdata/smart-relinking/smart-relinking.qbs2
-rw-r--r--tests/auto/blackbox/testdata/source-artifact-changes/source-artifact-changes.qbs4
-rw-r--r--tests/auto/blackbox/testdata/static-lib-without-sources/static-lib-without-sources.qbs2
-rw-r--r--tests/auto/blackbox/testdata/successive-changes/successive-changes.qbs2
-rw-r--r--tests/auto/blackbox/testdata/symbolLinkMode/lib.cpp4
-rw-r--r--tests/auto/blackbox/testdata/symbolLinkMode/main.cpp8
-rw-r--r--tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs21
-rw-r--r--tests/auto/blackbox/testdata/system-include-paths/main.cpp2
-rw-r--r--tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs5
-rw-r--r--tests/auto/blackbox/testdata/trackAddFile/after/main.cpp2
-rw-r--r--tests/auto/blackbox/testdata/trackAddFile/after/trackAddFile.qbs8
-rw-r--r--tests/auto/blackbox/testdata/trackAddFile/after/zort.cpp2
-rw-r--r--tests/auto/blackbox/testdata/trackAddFile/before/main.cpp2
-rw-r--r--tests/auto/blackbox/testdata/trackAddFile/before/narf.cpp2
-rw-r--r--tests/auto/blackbox/testdata/trackAddFile/before/trackAddFile.qbs8
-rw-r--r--tests/auto/blackbox/testdata/trackExternalProductChanges/trackExternalProductChanges.qbs5
-rw-r--r--tests/auto/blackbox/testdata/trackFileTags/after/main.cpp2
-rw-r--r--tests/auto/blackbox/testdata/trackFileTags/after/trackFileTags.qbs8
-rw-r--r--tests/auto/blackbox/testdata/trackFileTags/before/main.cpp2
-rw-r--r--tests/auto/blackbox/testdata/trackFileTags/before/trackFileTags.qbs8
-rw-r--r--tests/auto/blackbox/testdata/trackProducts/after/zoo.cpp2
-rw-r--r--tests/auto/blackbox/testdata/trackProducts/before/bar.cpp2
-rw-r--r--tests/auto/blackbox/testdata/trackProducts/before/foo.cpp2
-rw-r--r--tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/a/a.qbs5
-rw-r--r--tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/b/b.qbs3
-rw-r--r--tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/c/c.qbs3
-rw-r--r--tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/d/d.qbs4
-rw-r--r--tests/auto/blackbox/testdata/transitive-invalid-dependencies/transitive-invalid-dependencies.qbs11
-rw-r--r--tests/auto/blackbox/testdata/undefined-target-platform/undefined-target-platform.qbs13
-rw-r--r--tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs8
-rw-r--r--tests/auto/blackbox/testdata/vcs/vcstest.qbs8
-rw-r--r--tests/auto/blackbox/testdata/versionscript/versionscript.qbs6
-rw-r--r--tests/auto/blackbox/testdata/whole-archive/whole-archive.qbs3
-rw-r--r--tests/auto/blackbox/testdata/wildcards-and-change-tracking/nonrecursive/subdir1/file.txt0
-rw-r--r--tests/auto/blackbox/testdata/wildcards-and-change-tracking/nonrecursive/subdir2/file.txt0
-rw-r--r--tests/auto/blackbox/testdata/wildcards-and-change-tracking/recursive1/recursive.txt0
-rw-r--r--tests/auto/blackbox/testdata/wildcards-and-change-tracking/recursive2/recursive.txt0
-rw-r--r--tests/auto/blackbox/testdata/wildcards-and-change-tracking/wildcards-and-change-tracking.qbs16
-rw-r--r--tests/auto/blackbox/testdata/wildcards-and-rules/wildcards-and-rules.qbs2
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp2366
-rw-r--r--tests/auto/blackbox/tst_blackbox.h64
-rw-r--r--tests/auto/blackbox/tst_blackboxandroid.cpp1053
-rw-r--r--tests/auto/blackbox/tst_blackboxapple.cpp740
-rw-r--r--tests/auto/blackbox/tst_blackboxapple.h12
-rw-r--r--tests/auto/blackbox/tst_blackboxbaremetal.cpp311
-rw-r--r--tests/auto/blackbox/tst_blackboxbaremetal.h77
-rw-r--r--tests/auto/blackbox/tst_blackboxbase.cpp67
-rw-r--r--tests/auto/blackbox/tst_blackboxbase.h28
-rw-r--r--tests/auto/blackbox/tst_blackboxexamples.cpp105
-rw-r--r--tests/auto/blackbox/tst_blackboxexamples.h53
-rw-r--r--tests/auto/blackbox/tst_blackboxjava.cpp21
-rw-r--r--tests/auto/blackbox/tst_blackboxjava.h3
-rw-r--r--tests/auto/blackbox/tst_blackboxjoblimits.cpp15
-rw-r--r--tests/auto/blackbox/tst_blackboxproviders.cpp443
-rw-r--r--tests/auto/blackbox/tst_blackboxproviders.h65
-rw-r--r--tests/auto/blackbox/tst_blackboxqt.cpp297
-rw-r--r--tests/auto/blackbox/tst_blackboxqt.h14
-rw-r--r--tests/auto/blackbox/tst_blackboxtutorial.cpp72
-rw-r--r--tests/auto/blackbox/tst_blackboxtutorial.h48
-rw-r--r--tests/auto/blackbox/tst_blackboxwindows.cpp307
-rw-r--r--tests/auto/blackbox/tst_blackboxwindows.h55
-rw-r--r--tests/auto/blackbox/tst_clangdb.cpp12
-rw-r--r--tests/auto/buildgraph/CMakeLists.txt7
-rw-r--r--tests/auto/buildgraph/buildgraph.pro13
-rw-r--r--tests/auto/buildgraph/buildgraph.qbs5
-rw-r--r--tests/auto/buildgraph/tst_buildgraph.cpp3
-rw-r--r--tests/auto/cmdlineparser/CMakeLists.txt23
-rw-r--r--tests/auto/cmdlineparser/cmdlineparser.pro7
-rw-r--r--tests/auto/cmdlineparser/cmdlineparser.qbs2
-rw-r--r--tests/auto/cmdlineparser/tst_cmdlineparser.cpp22
-rw-r--r--tests/auto/language/CMakeLists.txt10
-rw-r--r--tests/auto/language/language.pro25
-rw-r--r--tests/auto/language/language.qbs9
-rw-r--r--tests/auto/language/testdata/ParentWithExport.qbs2
-rw-r--r--tests/auto/language/testdata/additional-product-types.qbs8
-rw-r--r--tests/auto/language/testdata/chained-probes/modules/m/m.qbs4
-rw-r--r--tests/auto/language/testdata/conditionaldepends.qbs8
-rw-r--r--tests/auto/language/testdata/conditionaldepends_base.qbs2
-rw-r--r--tests/auto/language/testdata/dotted-names/dotted-names.qbs2
-rw-r--r--tests/auto/language/testdata/dotted-names/modules/x/y/xy.qbs2
-rw-r--r--tests/auto/language/testdata/duplicate-multiplex-value.qbs (renamed from tests/auto/language/testdata/erroneous/duplicate-multiplex-value.qbs)2
-rw-r--r--tests/auto/language/testdata/duplicate-multiplex-value2.qbs (renamed from tests/auto/language/testdata/erroneous/duplicate-multiplex-value2.qbs)2
-rw-r--r--tests/auto/language/testdata/erroneous/ambiguous-multiplex-dependency.qbs14
-rw-r--r--tests/auto/language/testdata/erroneous/conflicting_fileTagsFilter.qbs7
-rw-r--r--tests/auto/language/testdata/erroneous/dependency-profile-mismatch-2.qbs17
-rw-r--r--tests/auto/language/testdata/erroneous/dependency-profile-mismatch.qbs14
-rw-r--r--tests/auto/language/testdata/erroneous/dependency_cycle.qbs6
-rw-r--r--tests/auto/language/testdata/erroneous/dependency_cycle2.qbs8
-rw-r--r--tests/auto/language/testdata/erroneous/dependency_cycle3a.qbs11
-rw-r--r--tests/auto/language/testdata/erroneous/frozen-object-list.qbs17
-rw-r--r--tests/auto/language/testdata/erroneous/frozen-object.qbs18
-rw-r--r--tests/auto/language/testdata/erroneous/invalid_file.qbs2
-rw-r--r--tests/auto/language/testdata/erroneous/missing-colon.qbs6
-rw-r--r--tests/auto/language/testdata/erroneous/missing-js-file.qbs3
-rw-r--r--tests/auto/language/testdata/erroneous/module-property-binding-in-project.qbs3
-rw-r--r--tests/auto/language/testdata/erroneous/module-with-id.qbs4
-rw-r--r--tests/auto/language/testdata/erroneous/modules/missing-js-file-module/missing-js-file-module.qbs3
-rw-r--r--tests/auto/language/testdata/erroneous/modules/missing-js-file-module/missing-js-file.js1
-rw-r--r--tests/auto/language/testdata/erroneous/modules/module-with-id/ModuleWithId.qbs1
-rw-r--r--tests/auto/language/testdata/erroneous/modules/module-with-id/ModuleWithIdParent.qbs1
-rw-r--r--tests/auto/language/testdata/erroneous/original-in-export-item.qbs2
-rw-r--r--tests/auto/language/testdata/erroneous/original-in-export-item2.qbs2
-rw-r--r--tests/auto/language/testdata/erroneous/original-in-export-item3.qbs2
-rw-r--r--tests/auto/language/testdata/erroneous/original-in-module-prototype.qbs2
-rw-r--r--tests/auto/language/testdata/erroneous/properties-item-with-invalid-condition.qbs2
-rw-r--r--tests/auto/language/testdata/eval-error-in-non-present-module.qbs2
-rw-r--r--tests/auto/language/testdata/exports.qbs28
-rw-r--r--tests/auto/language/testdata/exports_product.qbs2
-rw-r--r--tests/auto/language/testdata/getNativeSetting.qbs8
-rw-r--r--tests/auto/language/testdata/groupconditions.qbs2
-rw-r--r--tests/auto/language/testdata/inherited-properties-items/imports/DebugName.qbs2
-rw-r--r--tests/auto/language/testdata/inherited-properties-items/imports/ReleaseName.qbs2
-rw-r--r--tests/auto/language/testdata/inherited-properties-items/inherited-properties-items-product.qbs2
-rw-r--r--tests/auto/language/testdata/inherited-properties-items/inherited-properties-items.qbs2
-rw-r--r--tests/auto/language/testdata/invalid-prop-on-non-required-module/invalid-prop-on-non-required-module.qbs19
-rw-r--r--tests/auto/language/testdata/invalid-prop-on-non-required-module/modules/dep/dep.qbs1
-rw-r--r--tests/auto/language/testdata/invalid-prop-on-non-required-module/modules/deploader/deploader.qbs7
-rw-r--r--tests/auto/language/testdata/jsextensions.js8
-rw-r--r--tests/auto/language/testdata/local-profile-as-top-level-profile.qbs7
-rw-r--r--tests/auto/language/testdata/module-depends-on-product.qbs (renamed from tests/auto/language/testdata/erroneous/module-depends-on-product.qbs)0
-rw-r--r--tests/auto/language/testdata/module-name-collisions/complex-collision.qbs4
-rw-r--r--tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/middle1.qbs1
-rw-r--r--tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/suffix1/suffix1.qbs1
-rw-r--r--tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/suffix2/suffix2.qbs1
-rw-r--r--tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle2/suffix/suffix.qbs1
-rw-r--r--tests/auto/language/testdata/module-name-collisions/modules/prefix1/prefix1.qbs2
-rw-r--r--tests/auto/language/testdata/module-name-collisions/modules/prefix1/suffix/suffix.qbs (renamed from tests/auto/language/testdata/erroneous/modules/prefix1/suffix/suffix.qbs)0
-rw-r--r--tests/auto/language/testdata/module-name-collisions/modules/prefix2/prefix2.qbs3
-rw-r--r--tests/auto/language/testdata/module-name-collisions/modules/prefix2/suffix/suffix.qbs2
-rw-r--r--tests/auto/language/testdata/module-name-collisions/no-collision1.qbs4
-rw-r--r--tests/auto/language/testdata/module-name-collisions/no-collision2.qbs4
-rw-r--r--tests/auto/language/testdata/module-name-collisions/simple-collision1.qbs (renamed from tests/auto/language/testdata/erroneous/same-module-prefix1.qbs)0
-rw-r--r--tests/auto/language/testdata/module-name-collisions/simple-collision2.qbs (renamed from tests/auto/language/testdata/erroneous/same-module-prefix2.qbs)0
-rw-r--r--tests/auto/language/testdata/module-parameters/module-parameters.qbs35
-rw-r--r--tests/auto/language/testdata/module-parameters/modules/broken/broken.qbs4
-rw-r--r--tests/auto/language/testdata/module-parameters/modules/higher/higher.qbs4
-rw-r--r--tests/auto/language/testdata/module-parameters/modules/highest/highest.qbs7
-rw-r--r--tests/auto/language/testdata/module-parameters/modules/lower/lower.qbs3
-rw-r--r--tests/auto/language/testdata/modulepropertiesingroups.qbs9
-rw-r--r--tests/auto/language/testdata/modules/broken/broken.qbs2
-rw-r--r--tests/auto/language/testdata/modules/dummy/dummy.qbs2
-rw-r--r--tests/auto/language/testdata/modules/dummyqt/core/dummycore.qbs3
-rw-r--r--tests/auto/language/testdata/modules/module-with-product-dependency/module-with-product-dependency.qbs (renamed from tests/auto/language/testdata/erroneous/modules/module-with-product-dependency/module-with-product-dependency.qbs)0
-rw-r--r--tests/auto/language/testdata/modules/multiple_backends/backend1.qbs2
-rw-r--r--tests/auto/language/testdata/modules/multiple_backends/backend2.qbs2
-rw-r--r--tests/auto/language/testdata/modules/multiple_backends/backend3.qbs2
-rw-r--r--tests/auto/language/testdata/multiplexed-exports.qbs2
-rw-r--r--tests/auto/language/testdata/probes-and-multiplexing.qbs15
-rw-r--r--tests/auto/language/testdata/profilevaluesandoverriddenvalues.qbs2
-rw-r--r--tests/auto/language/testdata/qbs-properties-in-project-condition.qbs2
-rw-r--r--tests/auto/language/testdata/rfc1034identifier.qbs2
-rw-r--r--tests/auto/language/testdata/subdir/exports-mylib.qbs4
-rw-r--r--tests/auto/language/testdata/subdir2/exports-mylib2.qbs2
-rw-r--r--tests/auto/language/testdata/suppressed-and-non-suppressed-errors.qbs2
-rw-r--r--tests/auto/language/testdata/throw.qbs16
-rw-r--r--tests/auto/language/testdata/use-internal-profile.qbs13
-rw-r--r--tests/auto/language/tst_language.cpp990
-rw-r--r--tests/auto/language/tst_language.h53
-rw-r--r--tests/auto/pkgconfig/CMakeLists.txt8
-rw-r--r--tests/auto/pkgconfig/pkgconfig.qbs19
-rw-r--r--tests/auto/pkgconfig/testdata/base.name.json20
-rw-r--r--tests/auto/pkgconfig/testdata/base.name.pc12
-rw-r--r--tests/auto/pkgconfig/testdata/empty-variable.json21
-rw-r--r--tests/auto/pkgconfig/testdata/empty-variable.pc13
-rw-r--r--tests/auto/pkgconfig/testdata/lib/pkgconfig/prefix.pc13
-rw-r--r--tests/auto/pkgconfig/testdata/non-l-required.json12
-rw-r--r--tests/auto/pkgconfig/testdata/non-l-required.pc5
-rw-r--r--tests/auto/pkgconfig/testdata/private-dep.pc6
-rw-r--r--tests/auto/pkgconfig/testdata/public-dep.pc6
-rw-r--r--tests/auto/pkgconfig/testdata/requires-test.json18
-rw-r--r--tests/auto/pkgconfig/testdata/requires-test.pc8
-rw-r--r--tests/auto/pkgconfig/testdata/simple.json20
-rw-r--r--tests/auto/pkgconfig/testdata/simple.pc12
-rw-r--r--tests/auto/pkgconfig/testdata/special-flags.json30
-rw-r--r--tests/auto/pkgconfig/testdata/special-flags.pc11
-rw-r--r--tests/auto/pkgconfig/testdata/sysroot.json21
-rw-r--r--tests/auto/pkgconfig/testdata/sysroot.pc12
-rw-r--r--tests/auto/pkgconfig/testdata/system.json17
-rw-r--r--tests/auto/pkgconfig/testdata/system.pc10
-rw-r--r--tests/auto/pkgconfig/testdata/tilde.json11
-rw-r--r--tests/auto/pkgconfig/testdata/tilde.pc5
-rw-r--r--tests/auto/pkgconfig/testdata/variables.json17
-rw-r--r--tests/auto/pkgconfig/testdata/variables.pc11
-rw-r--r--tests/auto/pkgconfig/testdata/whitespace.json24
-rw-r--r--tests/auto/pkgconfig/testdata/whitespace.pc11
-rw-r--r--tests/auto/pkgconfig/tst_pkgconfig.cpp266
-rw-r--r--tests/auto/pkgconfig/tst_pkgconfig.h57
-rw-r--r--tests/auto/shared.h57
-rw-r--r--tests/auto/tools/CMakeLists.txt7
-rw-r--r--tests/auto/tools/tools.pro6
-rw-r--r--tests/auto/tools/tools.qbs3
-rw-r--r--tests/auto/tools/tst_tools.cpp74
-rw-r--r--tests/auto/tools/tst_tools.h4
871 files changed, 14172 insertions, 2774 deletions
diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt
new file mode 100644
index 000000000..8b1a124aa
--- /dev/null
+++ b/tests/auto/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_subdirectory(api)
+add_subdirectory(cmdlineparser)
+add_subdirectory(blackbox)
+
+if(WITH_UNIT_TESTS)
+ add_subdirectory(buildgraph)
+ add_subdirectory(language)
+ add_subdirectory(pkgconfig)
+ add_subdirectory(tools)
+endif()
diff --git a/tests/auto/api/CMakeLists.txt b/tests/auto/api/CMakeLists.txt
new file mode 100644
index 000000000..c1f89972d
--- /dev/null
+++ b/tests/auto/api/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_qbs_test(api
+ DEFINES
+ "QBS_RELATIVE_LIBEXEC_PATH=\"${QBS_RELATIVE_LIBEXEC_PATH}\""
+ "QBS_RELATIVE_SEARCH_PATH=\"${QBS_RELATIVE_SEARCH_PATH}\""
+ "QBS_RELATIVE_PLUGINS_PATH=\"${QBS_RELATIVE_PLUGINS_PATH}\""
+ SOURCES
+ tst_api.cpp
+ tst_api.h
+ )
diff --git a/tests/auto/api/api.pro b/tests/auto/api/api.pro
deleted file mode 100644
index d9c42e7bb..000000000
--- a/tests/auto/api/api.pro
+++ /dev/null
@@ -1,28 +0,0 @@
-TARGET = tst_api
-
-HEADERS = tst_api.h
-SOURCES = tst_api.cpp
-
-include(../../../src/library_dirname.pri)
-isEmpty(QBS_RELATIVE_LIBEXEC_PATH) {
- win32:QBS_RELATIVE_LIBEXEC_PATH=.
- else:QBS_RELATIVE_LIBEXEC_PATH=../libexec/qbs
-}
-isEmpty(QBS_RELATIVE_PLUGINS_PATH):QBS_RELATIVE_PLUGINS_PATH=../$${QBS_LIBRARY_DIRNAME}
-isEmpty(QBS_RELATIVE_SEARCH_PATH):QBS_RELATIVE_SEARCH_PATH=..
-DEFINES += QBS_RELATIVE_LIBEXEC_PATH=\\\"$${QBS_RELATIVE_LIBEXEC_PATH}\\\"
-DEFINES += QBS_RELATIVE_PLUGINS_PATH=\\\"$${QBS_RELATIVE_PLUGINS_PATH}\\\"
-DEFINES += QBS_RELATIVE_SEARCH_PATH=\\\"$${QBS_RELATIVE_SEARCH_PATH}\\\"
-qbs_enable_project_file_updates:DEFINES += QBS_ENABLE_PROJECT_FILE_UPDATES
-
-include(../auto.pri)
-
-DATA_DIRS = testdata
-
-for(data_dir, DATA_DIRS) {
- files = $$files($$PWD/$$data_dir/*, true)
- win32:files ~= s|\\\\|/|g
- for(file, files):!exists($$file/*):FILES += $$file
-}
-
-OTHER_FILES += $$FILES
diff --git a/tests/auto/api/api.qbs b/tests/auto/api/api.qbs
index 09e0af7dc..10064c888 100644
--- a/tests/auto/api/api.qbs
+++ b/tests/auto/api/api.qbs
@@ -1,4 +1,3 @@
-import qbs
import qbs.Utilities
QbsAutotest {
@@ -9,7 +8,7 @@ QbsAutotest {
"QBS_RELATIVE_LIBEXEC_PATH=" + Utilities.cStringQuote(qbsbuildconfig.relativeLibexecPath),
"QBS_RELATIVE_SEARCH_PATH=" + Utilities.cStringQuote(qbsbuildconfig.relativeSearchPath),
"QBS_RELATIVE_PLUGINS_PATH=" + Utilities.cStringQuote(qbsbuildconfig.relativePluginsPath)
- ]).concat(qbsbuildconfig.enableProjectFileUpdates ? ["QBS_ENABLE_PROJECT_FILE_UPDATES"] : [])
+ ])
Group {
name: "testdata"
diff --git a/tests/auto/api/testdata/QBS-728/QBS-728.qbs b/tests/auto/api/testdata/QBS-728/QBS-728.qbs
index 5969e13cc..cdeb7c6db 100644
--- a/tests/auto/api/testdata/QBS-728/QBS-728.qbs
+++ b/tests/auto/api/testdata/QBS-728/QBS-728.qbs
@@ -1,5 +1,5 @@
Product {
- property bool isBlubbOS: qbs.targetOS.contains("blubb-OS")
+ property bool isBlubbOS: qbs.targetOS.includes("blubb-OS")
qbs.profiles: isBlubbOS ? ["blubb-profile"] : [project.profile]
qbs.architecture: "blubb-arch"
}
diff --git a/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs b/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs
index 4cc25ad66..db707f515 100644
--- a/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs
+++ b/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs
@@ -26,7 +26,7 @@ Project {
// HACK: cpp.entryPoint currently not working 100% with gcc
Properties {
- condition: qbs.toolchain.contains("msvc")
+ condition: qbs.toolchain.includes("msvc")
cpp.entryPoint: "main"
cpp.dynamicLibraries: ["ucrt", "kernel32"]
}
diff --git a/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs b/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs
index 571feced8..3237e90dc 100644
--- a/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs
+++ b/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs
@@ -6,11 +6,6 @@ Project {
Depends { name: 'cpp' }
- Properties {
- condition: qbs.toolchain.contains("gcc")
- cpp.cxxFlags: "-march=native"
- }
-
Group {
cpp.defines: ['WORLD="BANANA"']
files : [ "main.cpp" ]
diff --git a/tests/auto/api/testdata/build-properties-source/main.cpp b/tests/auto/api/testdata/build-properties-source/main.cpp
index f830ee1fd..89ec55463 100644
--- a/tests/auto/api/testdata/build-properties-source/main.cpp
+++ b/tests/auto/api/testdata/build-properties-source/main.cpp
@@ -26,7 +26,7 @@
**
****************************************************************************/
-#include <stdio.h>
+#include <cstdio>
#ifndef WORLD
# error WORLD is not defined
@@ -34,5 +34,5 @@
int main()
{
- puts("Hello " WORLD "!");
+ std::puts("Hello " WORLD "!");
}
diff --git a/tests/auto/api/testdata/change-dependent-lib/change-dependent-lib.qbs b/tests/auto/api/testdata/change-dependent-lib/change-dependent-lib.qbs
index 222dc4476..cb925eeca 100644
--- a/tests/auto/api/testdata/change-dependent-lib/change-dependent-lib.qbs
+++ b/tests/auto/api/testdata/change-dependent-lib/change-dependent-lib.qbs
@@ -18,7 +18,7 @@ Project {
cpp.defines: ["XXXX"]
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
diff --git a/tests/auto/api/testdata/change-dependent-lib/main.cpp b/tests/auto/api/testdata/change-dependent-lib/main.cpp
index 8ad414c46..9334da1ef 100644
--- a/tests/auto/api/testdata/change-dependent-lib/main.cpp
+++ b/tests/auto/api/testdata/change-dependent-lib/main.cpp
@@ -28,13 +28,12 @@
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_IMPORT int mylib_hello();
int main()
{
- puts("application says hello!");
+ std::puts("application says hello!");
return mylib_hello();
}
-
diff --git a/tests/auto/api/testdata/change-dependent-lib/mylib.cpp b/tests/auto/api/testdata/change-dependent-lib/mylib.cpp
index 28cb69f95..b8c3e9082 100644
--- a/tests/auto/api/testdata/change-dependent-lib/mylib.cpp
+++ b/tests/auto/api/testdata/change-dependent-lib/mylib.cpp
@@ -28,10 +28,10 @@
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT int mylib_hello()
{
- puts("mylib says hello!");
+ std::puts("mylib says hello!");
return 0;
}
diff --git a/tests/auto/api/testdata/codegen/codegen.qbs b/tests/auto/api/testdata/codegen/codegen.qbs
index d8a217572..42e4c6b08 100644
--- a/tests/auto/api/testdata/codegen/codegen.qbs
+++ b/tests/auto/api/testdata/codegen/codegen.qbs
@@ -43,7 +43,7 @@ Project {
// check whether multipart module name translation is working
var actual = product.moduleProperty("Qt.core", "mocName");
- if (!actual || !actual.contains("moc"))
+ if (!actual || !actual.includes("moc"))
throw "multipart module name translation is broken";
// check whether we can access project properties here
@@ -57,7 +57,7 @@ Project {
code = expandMacros(code, product.replacements);
var args = ['echo ' + code + '>' + output.filePath]
var cmd
- if (product.moduleProperty("qbs", "hostOS").contains('windows')) {
+ if (product.moduleProperty("qbs", "hostOS").includes('windows')) {
cmd = new Command(product.qbs.windowsShellPath, ['/C'].concat(args));
} else {
args[0] = args[0].replace(/\(/g, '\\(')
@@ -65,7 +65,7 @@ Project {
args[0] = args[0].replace(/;/g, '\\;')
cmd = new Command(product.qbs.shellPath, ['-c'].concat(args))
}
- cmd.description = 'generate\t' + FileInfo.fileName(output.filePath);
+ cmd.description = 'generating ' + FileInfo.fileName(output.filePath);
cmd.highlight = 'codegen';
return cmd;
}
diff --git a/tests/auto/api/testdata/dependency-on-multiplexed-type/dependency-on-multiplexed-type.qbs b/tests/auto/api/testdata/dependency-on-multiplexed-type/dependency-on-multiplexed-type.qbs
index cfc2769d2..f0ffebe39 100644
--- a/tests/auto/api/testdata/dependency-on-multiplexed-type/dependency-on-multiplexed-type.qbs
+++ b/tests/auto/api/testdata/dependency-on-multiplexed-type/dependency-on-multiplexed-type.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Project {
Product { name: "dep"; type: "x" }
Product {
diff --git a/tests/auto/api/testdata/disabled-product/disabled-product.qbs b/tests/auto/api/testdata/disabled-product/disabled-product.qbs
index dad8f5d4c..e7eea7380 100644
--- a/tests/auto/api/testdata/disabled-product/disabled-product.qbs
+++ b/tests/auto/api/testdata/disabled-product/disabled-product.qbs
@@ -2,7 +2,7 @@ CppApplication {
condition: false
files: "main.cpp"
Group {
- condition: qbs.targetOS.contains("stuff")
+ condition: qbs.targetOS.includes("stuff")
qbs.install: false
}
}
diff --git a/tests/auto/api/testdata/disappeared-wildcard-file/disappeared-wildcard-file.qbs b/tests/auto/api/testdata/disappeared-wildcard-file/disappeared-wildcard-file.qbs
new file mode 100644
index 000000000..3c38e18a7
--- /dev/null
+++ b/tests/auto/api/testdata/disappeared-wildcard-file/disappeared-wildcard-file.qbs
@@ -0,0 +1,4 @@
+Product {
+ name: "dummy"
+ files: "*.txt"
+}
diff --git a/tests/auto/blackbox/testdata/concurrent-executor/dummy1.input b/tests/auto/api/testdata/disappeared-wildcard-file/file1.txt
index e69de29bb..e69de29bb 100644
--- a/tests/auto/blackbox/testdata/concurrent-executor/dummy1.input
+++ b/tests/auto/api/testdata/disappeared-wildcard-file/file1.txt
diff --git a/tests/auto/blackbox/testdata/concurrent-executor/dummy2.input b/tests/auto/api/testdata/disappeared-wildcard-file/file2.txt
index e69de29bb..e69de29bb 100644
--- a/tests/auto/blackbox/testdata/concurrent-executor/dummy2.input
+++ b/tests/auto/api/testdata/disappeared-wildcard-file/file2.txt
diff --git a/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs b/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs
index 05886a99e..0ebb73413 100644
--- a/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs
+++ b/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs
@@ -1,4 +1,5 @@
import qbs.FileInfo
+import qbs.Host
import qbs.TextFile
Project {
@@ -11,6 +12,12 @@ Project {
}
}
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "p"
type: ["mytype"]
diff --git a/tests/auto/api/testdata/export-simple/export-simple.qbs b/tests/auto/api/testdata/export-simple/export-simple.qbs
index 01177049d..84ce5541d 100644
--- a/tests/auto/api/testdata/export-simple/export-simple.qbs
+++ b/tests/auto/api/testdata/export-simple/export-simple.qbs
@@ -43,7 +43,7 @@ Project {
}
Depends { name: "cpp" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
diff --git a/tests/auto/api/testdata/export-simple/lib1.cpp b/tests/auto/api/testdata/export-simple/lib1.cpp
index 2b22d4993..7981edf92 100644
--- a/tests/auto/api/testdata/export-simple/lib1.cpp
+++ b/tests/auto/api/testdata/export-simple/lib1.cpp
@@ -27,10 +27,10 @@
****************************************************************************/
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT int lib1_hello()
{
- puts("lib1 says hello!");
+ std::puts("lib1 says hello!");
return 0;
}
diff --git a/tests/auto/api/testdata/export-simple/main.cpp b/tests/auto/api/testdata/export-simple/main.cpp
index 820e6f3bc..060037b82 100644
--- a/tests/auto/api/testdata/export-simple/main.cpp
+++ b/tests/auto/api/testdata/export-simple/main.cpp
@@ -27,13 +27,12 @@
****************************************************************************/
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_IMPORT int lib1_hello();
int main()
{
- puts("application says hello!");
+ std::puts("application says hello!");
return lib1_hello();
}
-
diff --git a/tests/auto/api/testdata/infinite-loop-js/infinite-loop.qbs b/tests/auto/api/testdata/infinite-loop-js/infinite-loop.qbs
index bb616a9e2..224e90ca6 100644
--- a/tests/auto/api/testdata/infinite-loop-js/infinite-loop.qbs
+++ b/tests/auto/api/testdata/infinite-loop-js/infinite-loop.qbs
@@ -8,7 +8,7 @@ Product {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Running infinite loop";
+ cmd.description = "running infinite loop";
cmd.sourceCode = function() {
while (true)
;
diff --git a/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs b/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs
index f4ea8bf83..687955f2f 100644
--- a/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs
+++ b/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs
@@ -1,3 +1,5 @@
+import qbs.Host
+
Project {
CppApplication {
type: "application"
@@ -6,7 +8,7 @@ Project {
name: "infinite-loop"
cpp.cxxLanguageVersion: "c++11"
Properties {
- condition: qbs.toolchain.contains("gcc")
+ condition: qbs.toolchain.includes("gcc")
cpp.driverFlags: "-pthread"
}
}
@@ -17,14 +19,14 @@ Project {
Depends { name: "infinite-loop" }
Depends {
name: "cpp" // Make sure build environment is set up properly.
- condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("gcc")
+ condition: Host.os().includes("windows") && qbs.toolchain.includes("gcc")
}
Rule {
inputsFromDependencies: "application"
outputFileTags: "mytype"
prepare: {
var cmd = new Command(inputs["application"][0].filePath);
- cmd.description = "Calling application that runs forever";
+ cmd.description = "calling application that runs forever";
return cmd;
}
}
diff --git a/tests/auto/blackbox/testdata/innosetup/inc/qbsinc.iss b/tests/auto/api/testdata/infinite-loop-scanning-scan/file.in
index e69de29bb..e69de29bb 100644
--- a/tests/auto/blackbox/testdata/innosetup/inc/qbsinc.iss
+++ b/tests/auto/api/testdata/infinite-loop-scanning-scan/file.in
diff --git a/tests/auto/api/testdata/infinite-loop-scanning-scan/infinite-loop.qbs b/tests/auto/api/testdata/infinite-loop-scanning-scan/infinite-loop.qbs
new file mode 100644
index 000000000..5e3e33b6e
--- /dev/null
+++ b/tests/auto/api/testdata/infinite-loop-scanning-scan/infinite-loop.qbs
@@ -0,0 +1,21 @@
+Product {
+ type: "t"
+ Depends { name: "m" }
+ Group {
+ files: "file.in"
+ fileTags: "i"
+ }
+ Rule {
+ inputs: "i"
+ Artifact {
+ filePath: "dummy"
+ fileTags: "t"
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.silent = true;
+ cmd.sourceCode = function() {};
+ return cmd;
+ }
+ }
+}
diff --git a/tests/auto/api/testdata/infinite-loop-scanning-scan/modules/m/m.qbs b/tests/auto/api/testdata/infinite-loop-scanning-scan/modules/m/m.qbs
new file mode 100644
index 000000000..9c8a18072
--- /dev/null
+++ b/tests/auto/api/testdata/infinite-loop-scanning-scan/modules/m/m.qbs
@@ -0,0 +1,6 @@
+Module {
+ Scanner {
+ inputs: "i"
+ scan: { while (true); }
+ }
+} \ No newline at end of file
diff --git a/tests/auto/api/testdata/infinite-loop-scanning-searchpaths/file.in b/tests/auto/api/testdata/infinite-loop-scanning-searchpaths/file.in
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/api/testdata/infinite-loop-scanning-searchpaths/file.in
diff --git a/tests/auto/api/testdata/infinite-loop-scanning-searchpaths/infinite-loop.qbs b/tests/auto/api/testdata/infinite-loop-scanning-searchpaths/infinite-loop.qbs
new file mode 100644
index 000000000..5e3e33b6e
--- /dev/null
+++ b/tests/auto/api/testdata/infinite-loop-scanning-searchpaths/infinite-loop.qbs
@@ -0,0 +1,21 @@
+Product {
+ type: "t"
+ Depends { name: "m" }
+ Group {
+ files: "file.in"
+ fileTags: "i"
+ }
+ Rule {
+ inputs: "i"
+ Artifact {
+ filePath: "dummy"
+ fileTags: "t"
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.silent = true;
+ cmd.sourceCode = function() {};
+ return cmd;
+ }
+ }
+}
diff --git a/tests/auto/api/testdata/infinite-loop-scanning-searchpaths/modules/m/m.qbs b/tests/auto/api/testdata/infinite-loop-scanning-searchpaths/modules/m/m.qbs
new file mode 100644
index 000000000..0476478b9
--- /dev/null
+++ b/tests/auto/api/testdata/infinite-loop-scanning-searchpaths/modules/m/m.qbs
@@ -0,0 +1,7 @@
+Module {
+ Scanner {
+ inputs: "i"
+ searchPaths: { while (true); }
+ scan: []
+ }
+}
diff --git a/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs b/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs
index d3f91662a..e4e050213 100644
--- a/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs
+++ b/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs
@@ -17,6 +17,7 @@ Project {
}
qbs.installPrefix: "/usr"
install: true
+ installDebugInformation: false
installDir: "bin"
Group {
fileTagsFilter: "obj"
diff --git a/tests/auto/api/testdata/is-runnable/is-runnable.qbs b/tests/auto/api/testdata/is-runnable/is-runnable.qbs
index 870279294..e93cc38aa 100644
--- a/tests/auto/api/testdata/is-runnable/is-runnable.qbs
+++ b/tests/auto/api/testdata/is-runnable/is-runnable.qbs
@@ -5,7 +5,7 @@ Project {
DynamicLibrary {
name: "lib"
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
diff --git a/tests/auto/api/testdata/lib-same-source/main.cpp b/tests/auto/api/testdata/lib-same-source/main.cpp
index 47e1013f9..c9602f59f 100644
--- a/tests/auto/api/testdata/lib-same-source/main.cpp
+++ b/tests/auto/api/testdata/lib-same-source/main.cpp
@@ -26,9 +26,9 @@
**
****************************************************************************/
-#include <stdio.h>
+#include <cstdio>
int main()
{
- puts("Hello WOrld!");
+ std::puts("Hello WOrld!");
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/dynamic1.cpp b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/dynamic1.cpp
index ed5f822fb..555c91afe 100644
--- a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/dynamic1.cpp
+++ b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/dynamic1.cpp
@@ -1,4 +1,4 @@
-#include <stdio.h>
+#include <cstdio>
#include "../dllexport.h"
@@ -7,6 +7,6 @@ void static1_hello();
DLL_EXPORT int dynamic1_hello()
{
static1_hello();
- puts("dynamic1 says hello!");
+ std::puts("dynamic1 says hello!");
return 0;
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/dynamic2.cpp b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/dynamic2.cpp
index b2db5d23e..d5fcbaab4 100644
--- a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/dynamic2.cpp
+++ b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/dynamic2.cpp
@@ -1,10 +1,10 @@
#include "../dllexport.h"
#include "static2.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT void dynamic2_hello()
{
TestMe tm;
tm.hello();
- puts("dynamic2 says hello!");
+ std::puts("dynamic2 says hello!");
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/link-dynamiclibs-staticlibs.qbs b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/link-dynamiclibs-staticlibs.qbs
index b2a54080c..0c86d05c6 100644
--- a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/link-dynamiclibs-staticlibs.qbs
+++ b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/link-dynamiclibs-staticlibs.qbs
@@ -12,7 +12,7 @@ Project {
Depends { name: "cpp" }
Depends { name: "static1" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -31,7 +31,7 @@ Project {
Depends { name: "static2" }
cpp.visibility: 'hidden'
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -40,6 +40,11 @@ Project {
name: "static2"
files: [ "static2.cpp", "static2.h" ]
Depends { name: "cpp" }
+ Probe {
+ id: tcPrinter
+ property bool isGcc: qbs.toolchain.contains("gcc")
+ configure: { console.info("is gcc: " + isGcc); }
+ }
}
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/main.cpp b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/main.cpp
index 73c0922d6..9b0a190b4 100644
--- a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/main.cpp
+++ b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/main.cpp
@@ -1,11 +1,11 @@
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_IMPORT int dynamic1_hello();
int main()
{
int result = dynamic1_hello();
- puts("application says hello!");
+ std::puts("application says hello!");
return result;
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/static1.cpp b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/static1.cpp
index 81c53bd4e..d07910f96 100644
--- a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/static1.cpp
+++ b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/static1.cpp
@@ -1,10 +1,10 @@
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_IMPORT void dynamic2_hello();
void static1_hello()
{
dynamic2_hello();
- puts("static1 says hello!");
+ std::puts("static1 says hello!");
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/static2.cpp b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/static2.cpp
index 073b13609..99a60be0c 100644
--- a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/static2.cpp
+++ b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/static2.cpp
@@ -1,7 +1,7 @@
#include "static2.h"
-#include <stdio.h>
+#include <cstdio>
void TestMe::hello() const
{
- puts("static2 says hello!");
+ std::puts("static2 says hello!");
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs/lib1.cpp b/tests/auto/api/testdata/link-dynamiclibs/lib1.cpp
index 14666cf58..e2e943b37 100644
--- a/tests/auto/api/testdata/link-dynamiclibs/lib1.cpp
+++ b/tests/auto/api/testdata/link-dynamiclibs/lib1.cpp
@@ -27,13 +27,13 @@
****************************************************************************/
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_IMPORT void lib2_hello();
DLL_EXPORT int lib1_hello()
{
- puts("lib1 says hello!");
+ std::puts("lib1 says hello!");
lib2_hello();
return 0;
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs/lib2.cpp b/tests/auto/api/testdata/link-dynamiclibs/lib2.cpp
index 01938b16b..f8bf990a3 100644
--- a/tests/auto/api/testdata/link-dynamiclibs/lib2.cpp
+++ b/tests/auto/api/testdata/link-dynamiclibs/lib2.cpp
@@ -27,13 +27,13 @@
****************************************************************************/
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_IMPORT void lib3_hello();
DLL_EXPORT void lib2_hello()
{
- puts("lib2 says hello!");
+ std::puts("lib2 says hello!");
lib3_hello();
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs/lib3.cpp b/tests/auto/api/testdata/link-dynamiclibs/lib3.cpp
index b90a99981..ff2d351ba 100644
--- a/tests/auto/api/testdata/link-dynamiclibs/lib3.cpp
+++ b/tests/auto/api/testdata/link-dynamiclibs/lib3.cpp
@@ -27,11 +27,11 @@
****************************************************************************/
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT void lib3_hello()
{
- puts("lib3 says hello!");
+ std::puts("lib3 says hello!");
}
DLL_EXPORT char* lib3_greeting()
diff --git a/tests/auto/api/testdata/link-dynamiclibs/lib4.cpp b/tests/auto/api/testdata/link-dynamiclibs/lib4.cpp
index 2d66e40f6..ebb97afc9 100644
--- a/tests/auto/api/testdata/link-dynamiclibs/lib4.cpp
+++ b/tests/auto/api/testdata/link-dynamiclibs/lib4.cpp
@@ -34,10 +34,10 @@ TestMe::TestMe()
void TestMe::hello1() const
{
- puts("lib4 says hello!");
+ std::puts("lib4 says hello!");
}
void TestMe::hello2Impl() const
{
- puts("lib4 says hello inline!");
+ std::puts("lib4 says hello inline!");
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs/lib4.h b/tests/auto/api/testdata/link-dynamiclibs/lib4.h
index 63258b2ea..69bde04ec 100644
--- a/tests/auto/api/testdata/link-dynamiclibs/lib4.h
+++ b/tests/auto/api/testdata/link-dynamiclibs/lib4.h
@@ -30,7 +30,7 @@
#define LIB4_H
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
#ifdef TEST_LIB
# define LIB_EXPORT DLL_EXPORT
diff --git a/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs b/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs
index cc86a4402..e0bce7264 100644
--- a/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs
+++ b/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs
@@ -17,7 +17,7 @@ Project {
Depends { name: "cpp" }
Depends { name: "lib2" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -31,7 +31,7 @@ Project {
Depends { name: "cpp" }
Depends { name: "lib3" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -44,7 +44,7 @@ Project {
}
Depends { name: "cpp" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -58,13 +58,13 @@ Project {
}
Depends { name: "cpp" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
Export {
Depends { name: "cpp" }
- cpp.includePaths: [product.sourceDirectory]
+ cpp.includePaths: [exportingProduct.sourceDirectory]
}
}
}
diff --git a/tests/auto/api/testdata/link-dynamiclibs/main.cpp b/tests/auto/api/testdata/link-dynamiclibs/main.cpp
index 64f7948cb..b6165d30f 100644
--- a/tests/auto/api/testdata/link-dynamiclibs/main.cpp
+++ b/tests/auto/api/testdata/link-dynamiclibs/main.cpp
@@ -26,14 +26,14 @@
**
****************************************************************************/
-#include <stdio.h>
+#include <cstdio>
#include <lib4.h>
DLL_IMPORT int lib1_hello();
int main()
{
- puts("application says hello!");
+ std::puts("application says hello!");
TestMe test;
test.hello1();
test.hello2();
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/api/testdata/link-static-lib/main.cpp b/tests/auto/api/testdata/link-static-lib/main.cpp
index 5f6aed0b9..2d94a4b0b 100644
--- a/tests/auto/api/testdata/link-static-lib/main.cpp
+++ b/tests/auto/api/testdata/link-static-lib/main.cpp
@@ -26,7 +26,7 @@
**
****************************************************************************/
-#include <stdio.h>
+#include <cstdio>
int bla();
diff --git a/tests/auto/api/testdata/link-static-lib/mystaticlib.cpp b/tests/auto/api/testdata/link-static-lib/mystaticlib.cpp
index 71777ef05..0b5d02fd4 100644
--- a/tests/auto/api/testdata/link-static-lib/mystaticlib.cpp
+++ b/tests/auto/api/testdata/link-static-lib/mystaticlib.cpp
@@ -26,12 +26,13 @@
**
****************************************************************************/
-#include <stdio.h>
#include <helper1.h>
+#include <cstdio>
+
int bla()
{
int n = getSomeNumber();
- printf("Hello World! The magic number is %d.", n);
+ std::printf("Hello World! The magic number is %d.", n);
return n;
}
diff --git a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/dynamic1.cpp b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/dynamic1.cpp
index 3f8a5f8d7..b4379f8c9 100644
--- a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/dynamic1.cpp
+++ b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/dynamic1.cpp
@@ -1,11 +1,11 @@
#include "../dllexport.h"
#include "static2.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT int dynamic1_hello()
{
TestMe tm;
tm.hello();
- puts("dynamic1 says hello!");
+ std::puts("dynamic1 says hello!");
return 1;
}
diff --git a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/dynamic2.cpp b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/dynamic2.cpp
index 75594185e..3511b4759 100644
--- a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/dynamic2.cpp
+++ b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/dynamic2.cpp
@@ -1,7 +1,7 @@
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT void dynamic2_hello()
{
- puts("dynamic2 says hello!");
+ std::puts("dynamic2 says hello!");
}
diff --git a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs
index d7ed6c862..c30cf40f9 100644
--- a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs
+++ b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs
@@ -14,9 +14,13 @@ Project {
Probe {
id: osCheck
- property bool isNormalUnix: qbs.targetOS.contains("unix")
- && !qbs.targetOS.contains("darwin")
- configure: { console.info("is normal unix: " + (isNormalUnix ? "yes" : "no")); }
+ property bool isNormalUnix: qbs.targetOS.includes("unix")
+ && !qbs.targetOS.includes("darwin")
+ property bool isGcc: qbs.toolchain.contains("gcc")
+ configure: {
+ console.info("is normal unix: " + (isNormalUnix ? "yes" : "no"));
+ console.info("is gcc: " + isGcc);
+ }
}
}
@@ -26,7 +30,7 @@ Project {
Depends { name: "cpp" }
Depends { name: "static2" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -44,7 +48,7 @@ Project {
Depends { name: "cpp" }
cpp.visibility: 'hidden'
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
diff --git a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/main.cpp b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/main.cpp
index 4b8193341..b9e522ac4 100644
--- a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/main.cpp
+++ b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/main.cpp
@@ -1,10 +1,10 @@
-#include <stdio.h>
+#include <cstdio>
void static1_hello();
int main()
{
static1_hello();
- puts("application says hello!");
+ std::puts("application says hello!");
return 0;
}
diff --git a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/static1.cpp b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/static1.cpp
index a3058c63b..320344f91 100644
--- a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/static1.cpp
+++ b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/static1.cpp
@@ -1,10 +1,11 @@
#include "../dllexport.h"
-#include <stdio.h>
+
+#include <cstdio>
DLL_IMPORT int dynamic1_hello();
void static1_hello()
{
int n = dynamic1_hello();
- printf("static%d says hello!\n", n);
+ std::printf("static%d says hello!\n", n);
}
diff --git a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/static2.cpp b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/static2.cpp
index 374bf7ceb..88c6d2a3f 100644
--- a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/static2.cpp
+++ b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/static2.cpp
@@ -1,11 +1,11 @@
#include "../dllexport.h"
#include "static2.h"
-#include <stdio.h>
+#include <cstdio>
DLL_IMPORT void dynamic2_hello();
void TestMe::hello() const
{
dynamic2_hello();
- puts("static2 says hello!");
+ std::puts("static2 says hello!");
}
diff --git a/tests/auto/api/testdata/lots-of-dots/m.a.i.n.cpp b/tests/auto/api/testdata/lots-of-dots/m.a.i.n.cpp
index 427f9907d..e1701dc47 100644
--- a/tests/auto/api/testdata/lots-of-dots/m.a.i.n.cpp
+++ b/tests/auto/api/testdata/lots-of-dots/m.a.i.n.cpp
@@ -33,6 +33,6 @@
int main()
{
ObjectNarf obj;
- puts("...");
+ std::puts("...");
}
diff --git a/tests/auto/api/testdata/moc-hpp-included/moc-hpp-included.qbs b/tests/auto/api/testdata/moc-hpp-included/moc-hpp-included.qbs
index a484b9c22..38d3d88ca 100644
--- a/tests/auto/api/testdata/moc-hpp-included/moc-hpp-included.qbs
+++ b/tests/auto/api/testdata/moc-hpp-included/moc-hpp-included.qbs
@@ -11,7 +11,7 @@ Project {
files: ["object.cpp", "object.h"]
Group {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
files: ["object2.mm", "object2.h"]
}
}
diff --git a/tests/auto/api/testdata/moc-hpp-included/object.cpp b/tests/auto/api/testdata/moc-hpp-included/object.cpp
index 4f1502af5..dd0b237cf 100644
--- a/tests/auto/api/testdata/moc-hpp-included/object.cpp
+++ b/tests/auto/api/testdata/moc-hpp-included/object.cpp
@@ -38,6 +38,6 @@ Object::Object(QObject *parent)
int main()
{
Object obj;
- printf("Hello World\n");
+ std::printf("Hello World\n");
}
diff --git a/tests/auto/api/testdata/moc-hpp/object.cpp b/tests/auto/api/testdata/moc-hpp/object.cpp
index 601893c34..4c0e59393 100644
--- a/tests/auto/api/testdata/moc-hpp/object.cpp
+++ b/tests/auto/api/testdata/moc-hpp/object.cpp
@@ -36,6 +36,6 @@ Object::Object(QObject *parent)
int main()
{
Object obj;
- printf("Hello World\n");
+ std::printf("Hello World\n");
}
diff --git a/tests/auto/api/testdata/multiplexing/multiplexing.qbs b/tests/auto/api/testdata/multiplexing/multiplexing.qbs
index 243c73d46..75958ed60 100644
--- a/tests/auto/api/testdata/multiplexing/multiplexing.qbs
+++ b/tests/auto/api/testdata/multiplexing/multiplexing.qbs
@@ -74,6 +74,13 @@ Project {
qbs.architectures: ["TRS-80", "C64"]
qbs.buildVariants: ["debug", "release"]
}
+ Product {
+ name: "multiplex-without-aggregator-4-depends-2"
+ multiplexByQbsProperties: ["architectures", "buildVariants"]
+ qbs.architectures: ["TRS-80", "C64"]
+ qbs.buildVariants: ["debug", "release"]
+ Depends { name: "multiplex-without-aggregator-2" }
+ }
}
Product {
diff --git a/tests/auto/api/testdata/new-output-artifact-in-dependency/new-output-artifact-in-dependency.qbs b/tests/auto/api/testdata/new-output-artifact-in-dependency/new-output-artifact-in-dependency.qbs
index 5c3e475b0..e87af67c7 100644
--- a/tests/auto/api/testdata/new-output-artifact-in-dependency/new-output-artifact-in-dependency.qbs
+++ b/tests/auto/api/testdata/new-output-artifact-in-dependency/new-output-artifact-in-dependency.qbs
@@ -4,7 +4,7 @@ Project {
name: "lib"
files: "lib.cpp"
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
diff --git a/tests/auto/api/testdata/objc/objc.qbs b/tests/auto/api/testdata/objc/objc.qbs
index 845eb8d32..2fba48d9b 100644
--- a/tests/auto/api/testdata/objc/objc.qbs
+++ b/tests/auto/api/testdata/objc/objc.qbs
@@ -1,6 +1,6 @@
Project {
CppApplication {
- condition: qbs.targetOS.contains("macos")
+ condition: qbs.targetOS.includes("macos")
files: "main.mm"
cpp.frameworks: [ "Foundation" ]
}
diff --git a/tests/auto/api/testdata/precompiled-header-dynamic/precompiled-header-dynamic.qbs b/tests/auto/api/testdata/precompiled-header-dynamic/precompiled-header-dynamic.qbs
index 2fd58d24e..1b0728669 100644
--- a/tests/auto/api/testdata/precompiled-header-dynamic/precompiled-header-dynamic.qbs
+++ b/tests/auto/api/testdata/precompiled-header-dynamic/precompiled-header-dynamic.qbs
@@ -21,7 +21,7 @@ CppApplication {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Generating " + output.fileName;
+ cmd.description = "generating " + output.fileName;
cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); }
return [cmd];
}
diff --git a/tests/auto/api/testdata/process-result/process-result.qbs b/tests/auto/api/testdata/process-result/process-result.qbs
index 84706ace8..dc9ff2839 100644
--- a/tests/auto/api/testdata/process-result/process-result.qbs
+++ b/tests/auto/api/testdata/process-result/process-result.qbs
@@ -1,9 +1,18 @@
+import qbs.Host
+
Project {
CppApplication {
name: "app"
+ consoleApplication: true
files: ["main.cpp"]
}
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "app-caller"
type: "mytype"
Depends { name: "app" }
@@ -20,7 +29,7 @@ Project {
cmd.stdoutFilePath = product.buildDirectory + "/stdout.txt";
if (product.redirectStderr)
cmd.stderrFilePath = product.buildDirectory + "/stderr.txt";
- cmd.description = "Building app-caller";
+ cmd.description = "building app-caller";
return [cmd];
}
}
diff --git a/tests/auto/api/testdata/project-with-properties-item/project-with-properties-item.qbs b/tests/auto/api/testdata/project-with-properties-item/project-with-properties-item.qbs
index 866ec4ecb..812c6a65e 100644
--- a/tests/auto/api/testdata/project-with-properties-item/project-with-properties-item.qbs
+++ b/tests/auto/api/testdata/project-with-properties-item/project-with-properties-item.qbs
@@ -3,7 +3,7 @@ Project {
property string libPath: "/usr/lib"
Properties {
- condition: qbs.targetOS.contains("macos")
+ condition: qbs.targetOS.includes("macos")
binPath: "/Users/boo"
libPath: "/Libraries/foo"
}
diff --git a/tests/auto/api/testdata/properties-blocks/main.cpp b/tests/auto/api/testdata/properties-blocks/main.cpp
index 5473bffa7..a01a5850e 100644
--- a/tests/auto/api/testdata/properties-blocks/main.cpp
+++ b/tests/auto/api/testdata/properties-blocks/main.cpp
@@ -26,7 +26,7 @@
**
****************************************************************************/
-#include <stdio.h>
+#include <cstdio>
#ifndef HAVE_MAIN_CPP
# error missing define HAVE_MAIN_CPP
@@ -38,9 +38,8 @@
int main()
{
#ifdef _DEBUG
- puts("Hello World! (debug version)");
+ std::puts("Hello World! (debug version)");
#else
- puts("Hello World! (release version)");
+ std::puts("Hello World! (release version)");
#endif
}
-
diff --git a/tests/auto/api/testdata/properties-blocks/properties-blocks.qbs b/tests/auto/api/testdata/properties-blocks/properties-blocks.qbs
index dda4652d2..c234a6b41 100644
--- a/tests/auto/api/testdata/properties-blocks/properties-blocks.qbs
+++ b/tests/auto/api/testdata/properties-blocks/properties-blocks.qbs
@@ -14,7 +14,7 @@ Product {
}
Properties {
- condition: qbs.targetOS.contains("weird")
+ condition: qbs.targetOS.includes("weird")
cpp.staticLibraries: "abc"
}
diff --git a/tests/auto/api/testdata/qt5-plugin/qt5-plugin.qbs b/tests/auto/api/testdata/qt5-plugin/qt5-plugin.qbs
index 204711625..1558e3bc9 100644
--- a/tests/auto/api/testdata/qt5-plugin/qt5-plugin.qbs
+++ b/tests/auto/api/testdata/qt5-plugin/qt5-plugin.qbs
@@ -1,4 +1,3 @@
-import qbs.base
import qbs.File
import qbs.FileInfo
@@ -8,7 +7,7 @@ DynamicLibrary {
Depends { name: "Qt.core" }
Depends { name: "cpp" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
diff --git a/tests/auto/api/testdata/remove-file-dependency/main.cpp b/tests/auto/api/testdata/remove-file-dependency/main.cpp
index 5c0b03938..47cd716d7 100644
--- a/tests/auto/api/testdata/remove-file-dependency/main.cpp
+++ b/tests/auto/api/testdata/remove-file-dependency/main.cpp
@@ -31,7 +31,7 @@
int main()
{
- printf("The magic value is %d.\n", magicValue());
+ std::printf("The magic value is %d.\n", magicValue());
return 0;
}
diff --git a/tests/auto/api/testdata/rename-product/rename.qbs b/tests/auto/api/testdata/rename-product/rename.qbs
index 9d23bf804..aa59d9650 100644
--- a/tests/auto/api/testdata/rename-product/rename.qbs
+++ b/tests/auto/api/testdata/rename-product/rename.qbs
@@ -11,7 +11,7 @@ Project {
cpp.defines: "MY_EXPORT=DLL_EXPORT"
files: "lib.cpp"
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
diff --git a/tests/auto/api/testdata/rename-target-artifact/rename.qbs b/tests/auto/api/testdata/rename-target-artifact/rename.qbs
index 810b0eb08..aea4b8d9e 100644
--- a/tests/auto/api/testdata/rename-target-artifact/rename.qbs
+++ b/tests/auto/api/testdata/rename-target-artifact/rename.qbs
@@ -14,7 +14,7 @@ Project {
qbs.buildVariant: "release"
files: "lib.cpp"
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
diff --git a/tests/auto/api/testdata/renamed-qbs-source-file/renamed-qbs-source-file.qbs b/tests/auto/api/testdata/renamed-qbs-source-file/renamed-qbs-source-file.qbs
new file mode 100644
index 000000000..d295d43ea
--- /dev/null
+++ b/tests/auto/api/testdata/renamed-qbs-source-file/renamed-qbs-source-file.qbs
@@ -0,0 +1,9 @@
+Project {
+ references: "the-product/the-prodduct.qbs"
+ Product {
+ Group {
+ files: "the-product/*.qbs"
+ fileTags: []
+ }
+ }
+}
diff --git a/tests/auto/api/testdata/renamed-qbs-source-file/the-product/the-prodduct.qbs b/tests/auto/api/testdata/renamed-qbs-source-file/the-product/the-prodduct.qbs
new file mode 100644
index 000000000..86718b571
--- /dev/null
+++ b/tests/auto/api/testdata/renamed-qbs-source-file/the-product/the-prodduct.qbs
@@ -0,0 +1 @@
+Product { }
diff --git a/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs b/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs
index bbdfbeadb..9d4abb757 100644
--- a/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs
+++ b/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs
@@ -1,14 +1,25 @@
import qbs.Process 1.5
-CppApplication {
- name: "theProduct"
+Project {
+ CppApplication {
+ name: "theProduct"
- property bool moreFiles: false
- cpp.blubb: true
+ cpp.blubb: true
- files: ["file.cpp", "main.cpp"]
- Group {
- condition: moreFiles
- files: ["blubb.cpp"]
+ files: ["file.cpp", "main.cpp"]
+ }
+
+ Product {
+ name: "theOtherProduct"
+ property bool dummy: { throw "this one comes from a thread"; }
+ }
+
+ Product {
+ name: "aThirdProduct"
+ property bool moreFiles: false
+ Group {
+ condition: moreFiles
+ files: ["blubb.txt"]
+ }
}
}
diff --git a/tests/auto/api/testdata/same-base-name/same-base-name.qbs b/tests/auto/api/testdata/same-base-name/same-base-name.qbs
index 8448d04fd..ba0adfaac 100644
--- a/tests/auto/api/testdata/same-base-name/same-base-name.qbs
+++ b/tests/auto/api/testdata/same-base-name/same-base-name.qbs
@@ -16,7 +16,7 @@ Project {
]
Group {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
files: [
"lib.m",
"lib.mm"
@@ -25,7 +25,7 @@ Project {
Export {
Depends { name: "cpp" }
- cpp.frameworks: qbs.targetOS.contains("darwin") ? "Foundation" : undefined
+ cpp.frameworks: qbs.targetOS.includes("darwin") ? "Foundation" : undefined
}
}
}
diff --git a/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs b/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs
index b584b4d41..67800b8eb 100644
--- a/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs
+++ b/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs
@@ -44,23 +44,23 @@ Project {
]
Group {
- condition: qbs.targetOS.contains("macos")
+ condition: qbs.targetOS.includes("macos")
files: ["d.mm"]
}
Properties {
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
cpp.defines: ["WITH_SETUPAPI"]
cpp.staticLibraries: ["setupapi"]
}
Properties {
- condition: qbs.targetOS.contains("macos")
+ condition: qbs.targetOS.includes("macos")
cpp.defines: ["WITH_LEX_YACC"]
cpp.staticLibraries: ["l", "y"]
cpp.frameworks: ["Foundation"]
}
Properties {
- condition: qbs.targetOS.contains("linux")
+ condition: qbs.targetOS.includes("linux")
cpp.defines: ["WITH_PTHREAD"]
cpp.staticLibraries: ["pthread"]
}
@@ -84,7 +84,7 @@ Project {
Depends { name: "e" }
Properties {
- condition: qbs.targetOS.contains("linux")
+ condition: qbs.targetOS.includes("linux")
cpp.driverFlags: ["-static"]
}
diff --git a/tests/auto/api/testdata/timeout-js/timeout.qbs b/tests/auto/api/testdata/timeout-js/timeout.qbs
index 26aa4ce87..72c72573b 100644
--- a/tests/auto/api/testdata/timeout-js/timeout.qbs
+++ b/tests/auto/api/testdata/timeout-js/timeout.qbs
@@ -8,7 +8,7 @@ Product {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Running infinite loop";
+ cmd.description = "running infinite loop";
cmd.sourceCode = function() {
while (true)
;
diff --git a/tests/auto/api/testdata/timeout-process/timeout.qbs b/tests/auto/api/testdata/timeout-process/timeout.qbs
index bb8deac9b..403506eed 100644
--- a/tests/auto/api/testdata/timeout-process/timeout.qbs
+++ b/tests/auto/api/testdata/timeout-process/timeout.qbs
@@ -1,3 +1,5 @@
+import qbs.Host
+
Project {
CppApplication {
type: "application"
@@ -7,25 +9,31 @@ Project {
cpp.cxxLanguageVersion: "c++11"
cpp.minimumOsxVersion: "10.8" // For <chrono>
Properties {
- condition: qbs.toolchain.contains("gcc")
+ condition: qbs.toolchain.includes("gcc")
cpp.driverFlags: "-pthread"
}
}
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
type: "product-under-test"
name: "caller"
Depends { name: "infinite-loop" }
Depends {
name: "cpp" // Make sure build environment is set up properly.
- condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("gcc")
+ condition: Host.os().includes("windows") && qbs.toolchain.includes("gcc")
}
Rule {
inputsFromDependencies: "application"
outputFileTags: "product-under-test"
prepare: {
var cmd = new Command(inputs["application"][0].filePath);
- cmd.description = "Calling application that runs forever";
+ cmd.description = "calling application that runs forever";
cmd.timeout = 3;
return cmd;
}
diff --git a/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs b/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs
index d72ebda17..e2b1ec6df 100644
--- a/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs
+++ b/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs
@@ -1,11 +1,12 @@
import qbs.FileInfo
+import qbs.Host
Module {
Depends { name: "cpp" }
Group {
name: "thetool binary"
files: FileInfo.cleanPath(FileInfo.joinPaths(path, "..", "..",
- "thetool" + (qbs.hostOS.contains("windows") ? ".exe" : "")));
+ "thetool" + (Host.os().includes("windows") ? ".exe" : "")));
fileTags: ["thetool.thetool"]
filesAreTargets: true
}
diff --git a/tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs b/tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs
index 575f4020e..ab4e07170 100644
--- a/tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs
+++ b/tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs
@@ -1,9 +1,18 @@
+import qbs.Host
+
Project {
CppApplication {
name: "thetool"
consoleApplication: true
files: "main.cpp"
+ property bool skip: {
+ var result = qbs.targetPlatform !== Host.platform();
+ if (result)
+ console.info("Skip this test");
+ return result;
+ }
+
install: true
installDir: ""
qbs.installPrefix: ""
diff --git a/tests/auto/api/testdata/transformer-data/transformer-data.qbs b/tests/auto/api/testdata/transformer-data/transformer-data.qbs
index f9433ed73..d29dbdbae 100644
--- a/tests/auto/api/testdata/transformer-data/transformer-data.qbs
+++ b/tests/auto/api/testdata/transformer-data/transformer-data.qbs
@@ -11,7 +11,7 @@ Product {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.sourceCode = function() {
var f = new TextFile(output.filePath, TextFile.WriteOnly);
f.close();
@@ -27,7 +27,7 @@ Product {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); };
return [cmd];
}
diff --git a/tests/auto/api/testdata/two-default-property-values/modules/mymodule/mymodule.qbs b/tests/auto/api/testdata/two-default-property-values/modules/mymodule/mymodule.qbs
index 8ac7b75a3..67f34ed66 100644
--- a/tests/auto/api/testdata/two-default-property-values/modules/mymodule/mymodule.qbs
+++ b/tests/auto/api/testdata/two-default-property-values/modules/mymodule/mymodule.qbs
@@ -12,7 +12,7 @@ Module {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.sourceCode = function() {
var f = new TextFile(output.filePath, TextFile.WriteOnly);
f.close();
diff --git a/tests/auto/api/tst_api.cpp b/tests/auto/api/tst_api.cpp
index 235f2ac04..45463312b 100644
--- a/tests/auto/api/tst_api.cpp
+++ b/tests/auto/api/tst_api.cpp
@@ -144,7 +144,7 @@ static bool waitForFinished(qbs::AbstractJob *job, int timeout = 0)
TestApi::TestApi()
: m_logSink(new LogSink)
- , m_sourceDataDir(QDir::cleanPath(SRCDIR "/testdata"))
+ , m_sourceDataDir(testDataSourceDir(SRCDIR "/testdata"))
, m_workingDataDir(testWorkDir(QStringLiteral("api")))
{
}
@@ -196,7 +196,7 @@ void TestApi::addedFilePersistent()
// On the initial run, linking will fail.
const QString relProjectFilePath = "added-file-persistent";
ProcessResultReceiver receiver;
- qbs::ErrorInfo errorInfo = doBuildProject(relProjectFilePath, 0, &receiver);
+ qbs::ErrorInfo errorInfo = doBuildProject(relProjectFilePath, nullptr, &receiver);
QVERIFY(errorInfo.hasError());
QVERIFY2(isAboutUndefinedSymbols(receiver.output), qPrintable((receiver.output)));
receiver.output.clear();
@@ -206,7 +206,7 @@ void TestApi::addedFilePersistent()
const qbs::SetupProjectParameters params = defaultSetupParameters(relProjectFilePath);
REPLACE_IN_FILE(params.projectFilePath(), "/* 'file.cpp' */", "'file.cpp'");
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(params, m_logSink,
- 0));
+ nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
setupJob.reset(nullptr);
@@ -215,14 +215,14 @@ void TestApi::addedFilePersistent()
// Consequently, the linking step must fail as in the initial run.
WAIT_FOR_NEW_TIMESTAMP();
REPLACE_IN_FILE(params.projectFilePath(), "'file.cpp'", "/* 'file.cpp' */");
- errorInfo = doBuildProject(relProjectFilePath, 0, &receiver);
+ errorInfo = doBuildProject(relProjectFilePath, nullptr, &receiver);
QVERIFY(errorInfo.hasError());
QVERIFY2(isAboutUndefinedSymbols(receiver.output), qPrintable((receiver.output)));
// Add the file again. qbs must schedule it for rule application on the next build.
WAIT_FOR_NEW_TIMESTAMP();
REPLACE_IN_FILE(params.projectFilePath(), "/* 'file.cpp' */", "'file.cpp'");
- setupJob.reset(qbs::Project().setupProject(params, m_logSink, 0));
+ setupJob.reset(qbs::Project().setupProject(params, m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
setupJob.reset(nullptr);
@@ -249,7 +249,7 @@ void TestApi::buildGraphInfo()
setupParams.setTopLevelProfile(p.p.name());
setupParams.setOverriddenValues({std::make_pair("qbs.architecture", "arm")});
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
const QString bgFilePath = setupParams.buildRoot() + QLatin1Char('/')
@@ -295,14 +295,14 @@ void TestApi::buildGraphLocking()
qbs::SetupProjectParameters setupParams
= defaultSetupParameters("buildgraph-locking");
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
const qbs::Project project = setupJob->project();
Q_UNUSED(project);
// Case 1: Setting up a competing project from scratch.
- setupJob.reset(qbs::Project().setupProject(setupParams, m_logSink, 0));
+ setupJob.reset(qbs::Project().setupProject(setupParams, m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY(setupJob->error().hasError());
QVERIFY2(setupJob->error().toString().contains("lock"),
@@ -311,7 +311,7 @@ void TestApi::buildGraphLocking()
// Case 2: Setting up a non-competing project and then making it competing.
qbs::SetupProjectParameters setupParams2 = setupParams;
setupParams2.setBuildRoot(setupParams.buildRoot() + "/2");
- setupJob.reset(qbs::Project().setupProject(setupParams2, m_logSink, 0));
+ setupJob.reset(qbs::Project().setupProject(setupParams2, m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
const QString buildDirName = relativeBuildDir(setupParams2.configurationName());
@@ -320,7 +320,7 @@ void TestApi::buildGraphLocking()
QVERIFY2(QFileInfo(lockFile).isFile(), qPrintable(lockFile));
qbs::Project project2 = setupJob->project();
QVERIFY(project2.isValid());
- setupJob.reset(project2.setupProject(setupParams, m_logSink, 0));
+ setupJob.reset(project2.setupProject(setupParams, m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY(setupJob->error().hasError());
QVERIFY2(setupJob->error().toString().contains("lock"),
@@ -330,7 +330,7 @@ void TestApi::buildGraphLocking()
// Case 3: Changing the build directory of an existing project to something non-competing.
qbs::SetupProjectParameters setupParams3 = setupParams2;
setupParams3.setBuildRoot(setupParams.buildRoot() + "/3");
- setupJob.reset(qbs::Project().setupProject(setupParams3, m_logSink, 0));
+ setupJob.reset(qbs::Project().setupProject(setupParams3, m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
project2 = qbs::Project();
@@ -342,7 +342,7 @@ void TestApi::buildGraphLocking()
QVERIFY(project3.isValid());
// Case 4: Changing the build directory again, but cancelling the job.
- setupJob.reset(project3.setupProject(setupParams2, m_logSink, 0));
+ setupJob.reset(project3.setupProject(setupParams2, m_logSink, nullptr));
QThread::sleep(1);
setupJob->cancel();
waitForFinished(setupJob.get());
@@ -362,7 +362,10 @@ void TestApi::buildProject()
+ QLatin1String(".qbs");
qbs::SetupProjectParameters params = defaultSetupParameters(projectFilePath);
removeBuildDir(params);
- qbs::ErrorInfo errorInfo = doBuildProject(projectFilePath);
+ ProcessResultReceiver resultReceiver;
+ qbs::ErrorInfo errorInfo = doBuildProject(projectFilePath, nullptr, &resultReceiver);
+ if (resultReceiver.output.contains("mingw32_gt_pch_use_address"))
+ QSKIP("https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91440");
VERIFY_NO_ERROR(errorInfo);
QVERIFY(regularFileExists(relativeBuildGraphFilePath()));
if (!productFileName.isEmpty()) {
@@ -373,7 +376,7 @@ void TestApi::buildProject()
WAIT_FOR_NEW_TIMESTAMP();
qbs::BuildOptions options;
options.setForceTimestampCheck(true);
- errorInfo = doBuildProject(projectFilePath, 0, 0, 0, options);
+ errorInfo = doBuildProject(projectFilePath, nullptr, nullptr, nullptr, options);
VERIFY_NO_ERROR(errorInfo);
if (!productFileName.isEmpty())
QVERIFY2(regularFileExists(productFileName), qPrintable(productFileName));
@@ -457,7 +460,7 @@ void TestApi::buildProjectDryRun()
removeBuildDir(params);
qbs::BuildOptions options;
options.setDryRun(true);
- const qbs::ErrorInfo errorInfo = doBuildProject(projectFilePath, 0, 0, 0, options);
+ const qbs::ErrorInfo errorInfo = doBuildProject(projectFilePath, nullptr, nullptr, nullptr, options);
VERIFY_NO_ERROR(errorInfo);
QVERIFY2(!QFileInfo::exists(relativeBuildDir()), qPrintable(QDir(relativeBuildDir())
.entryList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::System).join(", ")));
@@ -473,7 +476,7 @@ void TestApi::buildSingleFile()
qbs::SetupProjectParameters setupParams
= defaultSetupParameters("build-single-file");
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
qbs::Project project = setupJob->project();
@@ -483,9 +486,14 @@ void TestApi::buildSingleFile()
m_logSink->setLogLevel(qbs::LoggerMaxLevel);
std::unique_ptr<qbs::BuildJob> buildJob(project.buildAllProducts(options));
BuildDescriptionReceiver receiver;
+ ProcessResultReceiver resultReceiver;
+ connect(buildJob.get(), &qbs::BuildJob::reportProcessResult,
+ &resultReceiver, &ProcessResultReceiver::handleProcessResult);
connect(buildJob.get(), &qbs::BuildJob::reportCommandDescription, &receiver,
&BuildDescriptionReceiver::handleDescription);
waitForFinished(buildJob.get());
+ if (resultReceiver.output.contains("mingw32_gt_pch_use_address"))
+ QSKIP("https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91440");
QVERIFY2(!buildJob->error().hasError(), qPrintable(buildJob->error().toString()));
QCOMPARE(receiver.descriptions.count("compiling"), 2);
QCOMPARE(receiver.descriptions.count("precompiling"), 1);
@@ -502,6 +510,8 @@ void TestApi::canonicalToolchainList()
QStringList({"xcode", "clang", "llvm", "gcc"}));
QCOMPARE(qbs::canonicalToolchain(QStringList({"clang", "llvm", "gcc"})),
QStringList({"clang", "llvm", "gcc"}));
+ QCOMPARE(qbs::canonicalToolchain(QStringList({"clang-cl", "msvc"})),
+ QStringList({"clang-cl", "msvc"}));
QCOMPARE(qbs::canonicalToolchain(QStringList({"llvm", "gcc"})),
QStringList({"llvm", "gcc"}));
QCOMPARE(qbs::canonicalToolchain(QStringList({"mingw", "gcc"})),
@@ -516,6 +526,8 @@ void TestApi::canonicalToolchainList()
QStringList({"xcode", "clang", "llvm", "gcc"}));
QCOMPARE(qbs::canonicalToolchain(QStringList({"clang"})),
QStringList({"clang", "llvm", "gcc"}));
+ QCOMPARE(qbs::canonicalToolchain(QStringList({"clang-cl"})),
+ QStringList({"clang-cl", "msvc"}));
QCOMPARE(qbs::canonicalToolchain(QStringList({"llvm"})),
QStringList({"llvm", "gcc"}));
QCOMPARE(qbs::canonicalToolchain(QStringList({"mingw"})),
@@ -592,7 +604,7 @@ void TestApi::checkOutputs()
qbs::BuildOptions options;
options.setForceOutputCheck(check);
removeBuildDir(params);
- qbs::ErrorInfo errorInfo = doBuildProject("/check-outputs", 0, 0, 0, options);
+ qbs::ErrorInfo errorInfo = doBuildProject("/check-outputs", nullptr, nullptr, nullptr, options);
if (check)
QVERIFY(errorInfo.hasError());
else
@@ -616,37 +628,29 @@ qbs::GroupData findGroup(const qbs::ProductData &product, const QString &name)
return qbs::GroupData();
}
-#ifdef QBS_ENABLE_PROJECT_FILE_UPDATES
-
static qbs::Project::ProductSelection defaultProducts()
{
return qbs::Project::ProductSelectionDefaultOnly;
}
-static void printProjectData(const qbs::ProjectData &project)
-{
- const auto products = project.products();
- for (const qbs::ProductData &p : products) {
- qDebug(" Product '%s' at %s", qPrintable(p.name()), qPrintable(p.location().toString()));
- const auto groups = p.groups();
- for (const qbs::GroupData &g : groups) {
- qDebug(" Group '%s' at %s", qPrintable(g.name()), qPrintable(g.location().toString()));
- qDebug(" Files: %s", qPrintable(g.allFilePaths().join(QLatin1String(", "))));
- }
- }
-}
-
void TestApi::changeContent()
{
qbs::SetupProjectParameters setupParams = defaultSetupParameters("project-editing");
- std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
- waitForFinished(job.get());
- QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
- qbs::Project project = job->project();
- qbs::ProjectData projectData = project.projectData();
- QCOMPARE(projectData.allProducts().size(), 1);
- qbs::ProductData product = projectData.allProducts().front();
+ std::unique_ptr<qbs::SetupProjectJob> job;
+ qbs::Project project;
+ qbs::ProjectData projectData;
+ qbs::ProductData product;
+
+ const auto resolve = [&] {
+ job.reset(project.setupProject(setupParams, m_logSink, 0));
+ waitForFinished(job.get());
+ QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
+ project = job->project();
+ projectData = project.projectData();
+ QCOMPARE(projectData.allProducts().size(), 1);
+ product = projectData.allProducts().front();
+ };
+ resolve();
QVERIFY(product.groups().size() >= 8);
// Error handling: Invalid product.
@@ -659,12 +663,16 @@ void TestApi::changeContent()
QVERIFY(errorInfo.hasError());
QVERIFY(errorInfo.toString().contains("empty"));
+ WAIT_FOR_NEW_TIMESTAMP();
errorInfo = project.addGroup(product, "New Group 1");
VERIFY_NO_ERROR(errorInfo);
errorInfo = project.addGroup(product, "New Group 2");
VERIFY_NO_ERROR(errorInfo);
+ resolve();
+ QVERIFY(product.groups().size() >= 10);
+
// Error handling: Group already inserted.
errorInfo = project.addGroup(product, "New Group 1");
QVERIFY(errorInfo.hasError());
@@ -677,20 +685,14 @@ void TestApi::changeContent()
QVERIFY2(errorInfo.toString().contains("more than once"), qPrintable(errorInfo.toString()));
// Add files to empty array literal.
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
- QVERIFY(product.groups().size() >= 10);
+ WAIT_FOR_NEW_TIMESTAMP();
qbs::GroupData group = findGroup(product, "New Group 1");
QVERIFY(group.isValid());
errorInfo = project.addFiles(product, group, QStringList() << "file.h" << "file.cpp");
VERIFY_NO_ERROR(errorInfo);
// Error handling: Add the same file again.
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
- QVERIFY(product.groups().size() >= 10);
+ resolve();
group = findGroup(product, "New Group 1");
QVERIFY(group.isValid());
errorInfo = project.addFiles(product, group, QStringList() << "file.cpp");
@@ -698,14 +700,12 @@ void TestApi::changeContent()
QVERIFY2(errorInfo.toString().contains("already"), qPrintable(errorInfo.toString()));
// Remove one of the newly added files again.
+ WAIT_FOR_NEW_TIMESTAMP();
errorInfo = project.removeFiles(product, group, QStringList("file.h"));
VERIFY_NO_ERROR(errorInfo);
// Error handling: Try to remove the same file again.
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
- QVERIFY(product.groups().size() >= 10);
+ resolve();
group = findGroup(product, "New Group 1");
QVERIFY(group.isValid());
errorInfo = project.removeFiles(product, group, QStringList() << "file.h");
@@ -720,38 +720,34 @@ void TestApi::changeContent()
QVERIFY2(errorInfo.toString().contains("complex"), qPrintable(errorInfo.toString()));
// Remove file from product's 'files' binding.
+ WAIT_FOR_NEW_TIMESTAMP();
errorInfo = project.removeFiles(product, qbs::GroupData(), QStringList("main.cpp"));
VERIFY_NO_ERROR(errorInfo);
+ resolve();
// Add file to non-empty array literal.
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
+ WAIT_FOR_NEW_TIMESTAMP();
group = findGroup(product, "Existing Group 1");
QVERIFY(group.isValid());
errorInfo = project.addFiles(product, group, QStringList() << "newfile1.txt");
VERIFY_NO_ERROR(errorInfo);
+ resolve();
// Add files to list represented as a single string.
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
+ WAIT_FOR_NEW_TIMESTAMP();
errorInfo = project.addFiles(product, qbs::GroupData(), QStringList() << "newfile2.txt");
VERIFY_NO_ERROR(errorInfo);
+ resolve();
// Add files to list represented as an identifier.
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
+ WAIT_FOR_NEW_TIMESTAMP();
group = findGroup(product, "Existing Group 2");
QVERIFY(group.isValid());
errorInfo = project.addFiles(product, group, QStringList() << "newfile3.txt");
VERIFY_NO_ERROR(errorInfo);
+ resolve();
// Add files to list represented as a block of code (not yet implemented).
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
group = findGroup(product, "Existing Group 3");
QVERIFY(group.isValid());
errorInfo = project.addFiles(product, group, QStringList() << "newfile4.txt");
@@ -759,18 +755,14 @@ void TestApi::changeContent()
QVERIFY2(errorInfo.toString().contains("complex"), qPrintable(errorInfo.toString()));
// Add file to group with directory prefix.
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
+ WAIT_FOR_NEW_TIMESTAMP();
group = findGroup(product, "Existing Group 4");
QVERIFY(group.isValid());
errorInfo = project.addFiles(product, group, QStringList() << "file.txt");
VERIFY_NO_ERROR(errorInfo);
+ resolve();
// Error handling: Add file to group with non-directory prefix.
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
group = findGroup(product, "Existing Group 5");
QVERIFY(group.isValid());
errorInfo = project.addFiles(product, group, QStringList() << "newfile1.txt");
@@ -778,16 +770,12 @@ void TestApi::changeContent()
QVERIFY2(errorInfo.toString().contains("prefix"), qPrintable(errorInfo.toString()));
// Remove group.
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
+ WAIT_FOR_NEW_TIMESTAMP();
group = findGroup(product, "Existing Group 5");
QVERIFY(group.isValid());
errorInfo = project.removeGroup(product, group);
VERIFY_NO_ERROR(errorInfo);
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- QVERIFY(projectData.products().front().groups().size() >= 9);
+ resolve();
// Error handling: Try to remove the same group again.
errorInfo = project.removeGroup(product, group);
@@ -805,9 +793,7 @@ void TestApi::changeContent()
newFile.close();
errorInfo = project.addFiles(product, group, QStringList() << newFile.fileName());
VERIFY_NO_ERROR(errorInfo);
- projectData = project.projectData();
- QVERIFY(projectData.products().size() == 1);
- product = projectData.products().front();
+ resolve();
group = findGroup(product, "Group with wildcards");
QVERIFY(group.isValid());
QCOMPARE(group.sourceArtifactsFromWildcards().size(), 1);
@@ -838,46 +824,13 @@ void TestApi::changeContent()
QVERIFY(rcvr.descriptions.contains("compiling file.cpp"));
QVERIFY(!rcvr.descriptions.contains("compiling main.cpp"));
- // Now check whether the data updates were done correctly.
- projectData = project.projectData();
- job.reset(project.setupProject(setupParams, m_logSink, 0));
- waitForFinished(job.get());
- QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
- project = job->project();
- qbs::ProjectData newProjectData = project.projectData();
-
- // Can't use Project::operator== here, as the target artifacts will differ due to the build
- // not having run yet.
- bool projectDataMatches = newProjectData.products().size() == 1
- && projectData.products().size() == 1
- && newProjectData.products().front().groups() == projectData.products().front().groups();
- if (!projectDataMatches) {
- qDebug("This is the assumed project:");
- printProjectData(projectData);
- qDebug("This is the actual project:");
- printProjectData(newProjectData);
- }
- QVERIFY(projectDataMatches); // Will fail if e.g. code locations don't match.
-
- // Now try building again and check if the newly resolved product behaves the same way.
- buildJob.reset(project.buildAllProducts(buildOptions, defaultProducts(), this));
- connect(buildJob.get(), &qbs::BuildJob::reportCommandDescription,
- &rcvr, &BuildDescriptionReceiver::handleDescription);
- waitForFinished(buildJob.get());
- QVERIFY2(!buildJob->error().hasError(), qPrintable(buildJob->error().toString()));
- QVERIFY(rcvr.descriptions.contains("compiling file.cpp"));
- QVERIFY(!rcvr.descriptions.contains("compiling main.cpp"));
-
- // Now, after the build, the project data must be entirely identical.
- QVERIFY(projectData == project.projectData());
-
// Error handling: Try to change the project during a build.
buildJob.reset(project.buildAllProducts(buildOptions, defaultProducts(), this));
- errorInfo = project.addGroup(newProjectData.products().front(), "blubb");
+ errorInfo = project.addGroup(projectData.products().front(), "blubb");
QVERIFY(errorInfo.hasError());
QVERIFY2(errorInfo.toString().contains("in progress"), qPrintable(errorInfo.toString()));
waitForFinished(buildJob.get());
- errorInfo = project.addGroup(newProjectData.products().front(), "blubb");
+ errorInfo = project.addGroup(projectData.products().front(), "blubb");
VERIFY_NO_ERROR(errorInfo);
project = qbs::Project();
@@ -888,16 +841,11 @@ void TestApi::changeContent()
setupParams.setProjectFilePath(QDir::cleanPath(m_workingDataDir +
"/project-editing/project-with-no-files.qbs"));
- job.reset(project.setupProject(setupParams, m_logSink, 0));
- waitForFinished(job.get());
- QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
- project = job->project();
- projectData = project.projectData();
- QCOMPARE(projectData.allProducts().size(), 1);
- product = projectData.allProducts().front();
+ resolve();
+ WAIT_FOR_NEW_TIMESTAMP();
errorInfo = project.addFiles(product, qbs::GroupData(), QStringList("main.cpp"));
VERIFY_NO_ERROR(errorInfo);
- projectData = project.projectData();
+ resolve();
rcvr.descriptions.clear();
buildJob.reset(project.buildAllProducts(buildOptions, defaultProducts(), this));
connect(buildJob.get(), &qbs::BuildJob::reportCommandDescription,
@@ -908,27 +856,13 @@ void TestApi::changeContent()
job.reset(project.setupProject(setupParams, m_logSink, 0));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
- // Can't use Project::operator== here, as the target artifacts will differ due to the build
- // not having run yet.
- newProjectData = job->project().projectData();
- projectDataMatches = newProjectData.products().size() == 1
- && projectData.products().size() == 1
- && newProjectData.products().front().groups() == projectData.products().front().groups();
- if (!projectDataMatches) {
- printProjectData(projectData);
- qDebug("\n====\n");
- printProjectData(newProjectData);
- }
- QVERIFY(projectDataMatches);
}
-#endif // QBS_ENABLE_PROJECT_FILE_UPDATES
-
void TestApi::commandExtraction()
{
qbs::SetupProjectParameters setupParams = defaultSetupParameters("/command-extraction");
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
qbs::Project project = setupJob->project();
@@ -971,7 +905,7 @@ void TestApi::dependencyOnMultiplexedType()
qbs::SetupProjectParameters setupParams
= defaultSetupParameters("/dependency-on-multiplexed-type");
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
qbs::Project project = setupJob->project();
@@ -994,16 +928,12 @@ void TestApi::dependencyOnMultiplexedType()
} else {
QVERIFY(p.name() == "p2");
++p2Count;
-
- // FIXME: This is an odd effect of our current algorithm: We collect the products
- // matching the requested type and add Depends items with their names ("p1" in
- // this case). Later, the algorithm checking for compatibility regarding the
- // multiplexing axes picks the aggregate. However, the aggregate does not have
- // a matching type... It's not entirely clear what the real expected
- // result should be here.
- QCOMPARE(p.dependencies().size(), 2);
+ QVERIFY(p.dependencies().contains("dep"));
}
}
+ QCOMPARE(depCount, 1);
+ QCOMPARE(p1Count, 3);
+ QCOMPARE(p2Count, 1);
std::unique_ptr<qbs::BuildJob> buildJob(project.buildAllProducts(qbs::BuildOptions()));
waitForFinished(buildJob.get());
QVERIFY2(!buildJob->error().hasError(), qPrintable(buildJob->error().toString()));
@@ -1060,7 +990,7 @@ void TestApi::errorInSetupRunEnvironment()
qbs::SetupProjectParameters setupParams
= defaultSetupParameters("error-in-setup-run-environment");
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
const qbs::Project project = job->project();
@@ -1076,7 +1006,7 @@ void TestApi::errorInSetupRunEnvironment()
qbs::ErrorInfo error;
const QProcessEnvironment env = runEnv.runEnvironment(&error);
QVERIFY(error.hasError());
- QVERIFY(error.toString().contains("trallala"));
+ QVERIFY2(error.toString().contains("trallala"), qPrintable(error.toString()));
} catch (const qbs::ErrorInfo &) {
exceptionCaught = true;
}
@@ -1087,7 +1017,7 @@ void TestApi::excludedInputs()
{
qbs::SetupProjectParameters setupParams = defaultSetupParameters("excluded-inputs");
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
const qbs::Project project = job->project();
@@ -1095,10 +1025,11 @@ void TestApi::excludedInputs()
waitForFinished(buildJob.get());
QVERIFY2(!buildJob->error().hasError(), qPrintable(job->error().toString()));
QVERIFY(project.isValid());
- QCOMPARE(project.projectData().products().size(), 2);
+ const qbs::ProjectData projectData = project.projectData();
+ QCOMPARE(projectData.products().size(), 2);
qbs::ProductData depProduct;
qbs::ProductData pProduct;
- for (qbs::ProductData &p : project.projectData().products()) {
+ for (const qbs::ProductData &p : projectData.products()) {
if (p.name() == "dep")
depProduct = p;
else if (p.name() == "p")
@@ -1129,7 +1060,7 @@ void TestApi::excludedInputs()
QCOMPARE(dummyCount, 3);
}
-static qbs::ErrorInfo forceRuleEvaluation(const qbs::Project project)
+static qbs::ErrorInfo forceRuleEvaluation(const qbs::Project &project)
{
qbs::BuildOptions buildOptions;
buildOptions.setDryRun(true);
@@ -1143,7 +1074,7 @@ void TestApi::disabledInstallGroup()
qbs::SetupProjectParameters setupParams
= defaultSetupParameters("disabled_install_group");
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
const qbs::Project project = job->project();
@@ -1175,6 +1106,95 @@ void TestApi::disabledProject()
VERIFY_NO_ERROR(errorInfo);
}
+void TestApi::disappearedWildcardFile()
+{
+ const qbs::SetupProjectParameters setupParams
+ = defaultSetupParameters("disappeared-wildcard-file/disappeared-wildcard-file.qbs");
+ std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
+ m_logSink, nullptr));
+ QVERIFY(waitForFinished(setupJob.get()));
+ VERIFY_NO_ERROR(setupJob->error());
+
+ qbs::Project project = setupJob->project();
+ qbs::ProjectData projectData = project.projectData();
+ QVERIFY(projectData.isValid());
+ QList<qbs::ProductData> products = projectData.allProducts();
+ QCOMPARE(products.size(), 1);
+ QCOMPARE(products.first().groups().size(), 1);
+ QCOMPARE(products.first().groups().first().allFilePaths().size(), 2);
+
+ std::unique_ptr<qbs::BuildJob> buildJob(project.buildAllProducts({}));
+ QVERIFY(waitForFinished(buildJob.get()));
+ VERIFY_NO_ERROR(buildJob->error());
+
+ WAIT_FOR_NEW_TIMESTAMP();
+ const QString fileToRemove = QFileInfo(setupParams.projectFilePath()).path() + "/file2.txt";
+ QVERIFY(QFile::remove(fileToRemove));
+ buildJob.reset(project.buildAllProducts({}));
+ QVERIFY(waitForFinished(buildJob.get()));
+ QVERIFY(buildJob->error().hasError());
+ QVERIFY2(buildJob->error().toString().contains(
+ tr("Source file '%1' has disappeared.")
+ .arg(fileToRemove)), qPrintable(buildJob->error().toString()));
+
+ setupJob.reset(project.setupProject(setupParams, m_logSink, nullptr));
+ QVERIFY(waitForFinished(setupJob.get()));
+ VERIFY_NO_ERROR(setupJob->error());
+
+ project = setupJob->project();
+ projectData = project.projectData();
+ QVERIFY(projectData.isValid());
+ products = projectData.allProducts();
+ QCOMPARE(products.size(), 1);
+ QCOMPARE(products.first().groups().size(), 1);
+ QCOMPARE(products.first().groups().first().allFilePaths().size(), 1);
+
+ buildJob.reset(project.buildAllProducts({}));
+ QVERIFY(waitForFinished(buildJob.get()));
+ VERIFY_NO_ERROR(buildJob->error());
+}
+
+void TestApi::renamedQbsSource()
+{
+ const qbs::SetupProjectParameters setupParams
+ = defaultSetupParameters("renamed-qbs-source-file/renamed-qbs-source-file.qbs");
+ std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
+ m_logSink, nullptr));
+ QVERIFY(waitForFinished(setupJob.get()));
+ VERIFY_NO_ERROR(setupJob->error());
+ qbs::Project project = setupJob->project();
+ QCOMPARE(project.projectData().allProducts().size(), 2);
+
+ std::unique_ptr<qbs::BuildJob> buildJob(project.buildAllProducts({}));
+ QVERIFY(waitForFinished(buildJob.get()));
+ VERIFY_NO_ERROR(buildJob->error());
+
+ WAIT_FOR_NEW_TIMESTAMP();
+ const QString oldFilePath = QFileInfo(setupParams.projectFilePath()).path()
+ + "/the-product/the-prodduct.qbs";
+ const QString newFilePath = QFileInfo(setupParams.projectFilePath()).path()
+ + "/the-product/the-product.qbs";
+ QVERIFY(QFile::rename(oldFilePath, newFilePath));
+ REPLACE_IN_FILE(setupParams.projectFilePath(), "prodduct", "product");
+ buildJob.reset(project.buildAllProducts({}));
+ QVERIFY(waitForFinished(buildJob.get()));
+ QVERIFY(buildJob->error().hasError());
+ QVERIFY2(buildJob->error().toString().contains(
+ tr("Source file '%1' has disappeared.")
+ .arg(oldFilePath)), qPrintable(buildJob->error().toString()));
+
+ setupJob.reset(project.setupProject(setupParams, m_logSink, nullptr));
+ QVERIFY(waitForFinished(setupJob.get()));
+ VERIFY_NO_ERROR(setupJob->error());
+
+ project = setupJob->project();
+ QCOMPARE(project.projectData().allProducts().size(), 2);
+
+ buildJob.reset(project.buildAllProducts({}));
+ QVERIFY(waitForFinished(buildJob.get()));
+ VERIFY_NO_ERROR(buildJob->error());
+}
+
void TestApi::duplicateProductNames()
{
QFETCH(QString, projectFileName);
@@ -1210,6 +1230,8 @@ void TestApi::explicitlyDependsOn()
BuildDescriptionReceiver receiver;
qbs::ErrorInfo errorInfo = doBuildProject("explicitly-depends-on", &receiver);
VERIFY_NO_ERROR(errorInfo);
+ if (m_logSink->output.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QVERIFY2(receiver.descriptions.contains("compiling compiler.cpp"),
qPrintable(receiver.descriptions));
QVERIFY2(receiver.descriptions.contains("compiling a.in"), qPrintable(receiver.descriptions));
@@ -1266,7 +1288,7 @@ void TestApi::fallbackGcc()
QVERIFY(project.isValid());
QList<qbs::ProductData> products = project.allProducts();
QCOMPARE(products.size(), 2);
- for (const qbs::ProductData &p : qAsConst(products)) {
+ for (const qbs::ProductData &p : std::as_const(products)) {
if (p.profile() == "unixProfile") {
qbs::PropertyMap moduleProps = p.moduleProperties();
QCOMPARE(moduleProps.getModuleProperty("qbs", "targetOS").toStringList(),
@@ -1305,7 +1327,7 @@ void TestApi::fileTagsFilterOverride()
qbs::SetupProjectParameters setupParams
= defaultSetupParameters("filetagsfilter_override");
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
qbs::Project project = job->project();
@@ -1326,7 +1348,7 @@ void TestApi::generatedFilesList()
qbs::SetupProjectParameters setupParams
= defaultSetupParameters("generated-files-list");
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
QVERIFY(waitForFinished(setupJob.get()));
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
qbs::Project project = setupJob->project();
@@ -1385,7 +1407,7 @@ void TestApi::infiniteLoopBuilding()
qbs::SetupProjectParameters setupParams
= defaultSetupParameters(projectDirName + "/infinite-loop.qbs");
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
qbs::Project project = setupJob->project();
@@ -1400,13 +1422,16 @@ void TestApi::infiniteLoopBuilding_data()
QTest::addColumn<QString>("projectDirName");
QTest::newRow("JS Command") << QString("infinite-loop-js");
QTest::newRow("Process Command") << QString("infinite-loop-process");
+ QTest::newRow("Scanner (scan property)") << QString("infinite-loop-scanning-scan");
+ QTest::newRow("Scanner (searchPaths property)")
+ << QString("infinite-loop-scanning-searchpaths");
}
void TestApi::infiniteLoopResolving()
{
qbs::SetupProjectParameters setupParams = defaultSetupParameters("infinite-loop-resolving");
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
QTimer::singleShot(1000, setupJob.get(), &qbs::AbstractJob::cancel);
QVERIFY(waitForFinished(setupJob.get(), testTimeoutInMsecs()));
QVERIFY2(setupJob->error().toString().toLower().contains("cancel"),
@@ -1435,7 +1460,7 @@ void TestApi::inheritQbsSearchPaths()
QVariantMap overriddenValues;
overriddenValues.insert("project.qbsSearchPaths",
QStringList() << m_workingDataDir + "/inherit-qbs-search-paths/subdir");
- errorInfo = doBuildProject(projectFilePath, 0, 0, 0, qbs::BuildOptions(), overriddenValues);
+ errorInfo = doBuildProject(projectFilePath, nullptr, nullptr, nullptr, qbs::BuildOptions(), overriddenValues);
VERIFY_NO_ERROR(errorInfo);
}
@@ -1452,7 +1477,7 @@ void TestApi::installableFiles()
overriddenValues.insert(QStringLiteral("qbs.installRoot"), QStringLiteral("/tmp"));
setupParams.setOverriddenValues(overriddenValues);
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
qbs::Project project = job->project();
@@ -1481,7 +1506,7 @@ void TestApi::installableFiles()
setupParams = defaultSetupParameters("recursive-wildcards");
setupParams.setOverriddenValues(overriddenValues);
- job.reset(project.setupProject(setupParams, m_logSink, 0));
+ job.reset(project.setupProject(setupParams, m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
project = job->project();
@@ -1502,7 +1527,7 @@ void TestApi::isRunnable()
{
qbs::SetupProjectParameters setupParams = defaultSetupParameters("is-runnable");
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
qbs::Project project = job->project();
@@ -1528,27 +1553,30 @@ void TestApi::linkDynamicAndStaticLibs()
BuildDescriptionReceiver bdr;
qbs::BuildOptions options;
options.setEchoMode(qbs::CommandEchoModeCommandLine);
+ m_logSink->output.clear();
const qbs::ErrorInfo errorInfo = doBuildProject("link-dynamiclibs-staticlibs", &bdr, nullptr,
nullptr, options);
VERIFY_NO_ERROR(errorInfo);
+ const bool isGcc = m_logSink->output.contains("is gcc: true");
+ const bool isNotGcc = m_logSink->output.contains("is gcc: false");
+ if (isNotGcc)
+ QSKIP("The remainder of this test applies only to GCC");
+ QVERIFY(isGcc);
+
// The dependent static libs should not appear in the link command for the executable.
- const SettingsPtr s = settings();
- const qbs::Profile buildProfile(profileName(), s.get());
- if (buildProfile.value("qbs.toolchain").toStringList().contains("gcc")) {
- static const std::regex appLinkCmdRex(" -o [^ ]*/HelloWorld" QBS_HOST_EXE_SUFFIX " ");
- QString appLinkCmd;
- for (const QString &line : qAsConst(bdr.descriptionLines)) {
- const auto ln = line.toStdString();
- if (std::regex_search(ln, appLinkCmdRex)) {
- appLinkCmd = line;
- break;
- }
+ static const std::regex appLinkCmdRex(" -o [^ ]*/HelloWorld" QBS_HOST_EXE_SUFFIX " ");
+ QString appLinkCmd;
+ for (const QString &line : std::as_const(bdr.descriptionLines)) {
+ const auto ln = line.toStdString();
+ if (std::regex_search(ln, appLinkCmdRex)) {
+ appLinkCmd = line;
+ break;
}
- QVERIFY(!appLinkCmd.isEmpty());
- QVERIFY(!appLinkCmd.contains("static1"));
- QVERIFY(!appLinkCmd.contains("static2"));
}
+ QVERIFY(!appLinkCmd.isEmpty());
+ QVERIFY(!appLinkCmd.contains("static1"));
+ QVERIFY(!appLinkCmd.contains("static2"));
}
void TestApi::linkStaticAndDynamicLibs()
@@ -1563,31 +1591,32 @@ void TestApi::linkStaticAndDynamicLibs()
const bool isNormalUnix = m_logSink->output.contains("is normal unix: yes");
const bool isNotNormalUnix = m_logSink->output.contains("is normal unix: no");
QVERIFY2(isNormalUnix != isNotNormalUnix, qPrintable(m_logSink->output));
+ const bool isGcc = m_logSink->output.contains("is gcc: true");
+ const bool isNotGcc = m_logSink->output.contains("is gcc: false");
+ if (isNotGcc)
+ QSKIP("The remainder of this test applies only to GCC");
+ QVERIFY(isGcc);
// The dependencies libdynamic1.so and libstatic2.a must not appear in the link command for the
// executable. The -rpath-link line for libdynamic1.so must be there.
- const SettingsPtr s = settings();
- const qbs::Profile buildProfile(profileName(), s.get());
- if (buildProfile.value("qbs.toolchain").toStringList().contains("gcc")) {
- static const std::regex appLinkCmdRex(" -o [^ ]*/HelloWorld" QBS_HOST_EXE_SUFFIX " ");
- QString appLinkCmd;
- for (const QString &line : qAsConst(bdr.descriptionLines)) {
- const auto ln = line.toStdString();
- if (std::regex_search(ln, appLinkCmdRex)) {
- appLinkCmd = line;
- break;
- }
- }
- QVERIFY(!appLinkCmd.isEmpty());
- if (isNormalUnix) {
- const std::regex rpathLinkRex("-rpath-link=\\S*/"
- + relativeProductBuildDir("dynamic2").toStdString());
- const auto ln = appLinkCmd.toStdString();
- QVERIFY(std::regex_search(ln, rpathLinkRex));
+ static const std::regex appLinkCmdRex(" -o [^ ]*/HelloWorld" QBS_HOST_EXE_SUFFIX " ");
+ QString appLinkCmd;
+ for (const QString &line : std::as_const(bdr.descriptionLines)) {
+ const auto ln = line.toStdString();
+ if (std::regex_search(ln, appLinkCmdRex)) {
+ appLinkCmd = line;
+ break;
}
- QVERIFY(!appLinkCmd.contains("libstatic2.a"));
- QVERIFY(!appLinkCmd.contains("libdynamic2.so"));
}
+ QVERIFY(!appLinkCmd.isEmpty());
+ if (isNormalUnix) {
+ const std::regex rpathLinkRex("-rpath-link=\\S*/"
+ + relativeProductBuildDir("dynamic2").toStdString());
+ const auto ln = appLinkCmd.toStdString();
+ QVERIFY(std::regex_search(ln, rpathLinkRex));
+ }
+ QVERIFY(!appLinkCmd.contains("libstatic2.a"));
+ QVERIFY(!appLinkCmd.contains("libdynamic2.so"));
}
void TestApi::listBuildSystemFiles()
@@ -1595,15 +1624,14 @@ void TestApi::listBuildSystemFiles()
qbs::SetupProjectParameters setupParams
= defaultSetupParameters("subprojects/toplevelproject.qbs");
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
- const auto buildSystemFiles = qbs::Internal::Set<QString>::fromStdSet(
- job->project().buildSystemFiles());
- QVERIFY(buildSystemFiles.contains(setupParams.projectFilePath()));
- QVERIFY(buildSystemFiles.contains(setupParams.buildRoot() + "/subproject2/subproject2.qbs"));
- QVERIFY(buildSystemFiles.contains(setupParams.buildRoot()
- + "/subproject2/subproject3/subproject3.qbs"));
+ const auto buildSystemFiles = job->project().buildSystemFiles();
+ QVERIFY(buildSystemFiles.count(setupParams.projectFilePath()));
+ QVERIFY(buildSystemFiles.count(setupParams.buildRoot() + "/subproject2/subproject2.qbs"));
+ QVERIFY(buildSystemFiles.count(setupParams.buildRoot()
+ + "/subproject2/subproject3/subproject3.qbs"));
}
void TestApi::localProfiles()
@@ -1614,7 +1642,7 @@ void TestApi::localProfiles()
setupParams.setOverriddenValues(
{std::make_pair(QString("project.enableProfiles"), enableProfiles)});
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
QString taskDescriptions;
const auto taskDescHandler = [&taskDescriptions](const QString &desc, int, qbs::AbstractJob *) {
taskDescriptions += '\n' + desc;
@@ -1636,7 +1664,7 @@ void TestApi::localProfiles()
qbs::ProductData libClang;
qbs::ProductData appDebug;
qbs::ProductData appRelease;
- for (const qbs::ProductData &p : qAsConst(products)) {
+ for (const qbs::ProductData &p : std::as_const(products)) {
if (p.name() == "lib") {
if (p.profile() == "mingwProfile")
libMingw = p;
@@ -1666,7 +1694,7 @@ void TestApi::localProfiles()
QStringList({"mingw", "gcc"}));
if (moduleProps.getModuleProperty("cpp", "present").toBool()) {
QCOMPARE(moduleProps.getModuleProperty("cpp", "cxxCompilerName").toString(),
- QString("g++"));
+ qbs::Internal::HostOsInfo::appendExecutableSuffix(QString("g++")));
}
moduleProps = libClang.moduleProperties();
QCOMPARE(moduleProps.getModuleProperty("qbs", "targetOS").toStringList(),
@@ -1675,7 +1703,7 @@ void TestApi::localProfiles()
QStringList({"clang", "llvm", "gcc"}));
if (moduleProps.getModuleProperty("cpp", "present").toBool()) {
QCOMPARE(moduleProps.getModuleProperty("cpp", "cxxCompilerName").toString(),
- QString("clang++"));
+ qbs::Internal::HostOsInfo::appendExecutableSuffix(QString("clang++")));
}
moduleProps = appDebug.moduleProperties();
if (moduleProps.getModuleProperty("cpp", "present").toBool())
@@ -1685,7 +1713,7 @@ void TestApi::localProfiles()
QCOMPARE(moduleProps.getModuleProperty("cpp", "optimization").toString(), QString("fast"));
taskDescriptions.clear();
- job.reset(qbs::Project().setupProject(setupParams, m_logSink, 0));
+ job.reset(qbs::Project().setupProject(setupParams, m_logSink, nullptr));
connect(job.get(), &qbs::AbstractJob::taskStarted, taskDescHandler);
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
@@ -1699,20 +1727,20 @@ void TestApi::localProfiles()
projectFile.resize(0);
projectFile.write(content);
projectFile.close();
- job.reset(qbs::Project().setupProject(setupParams, m_logSink, 0));
+ job.reset(qbs::Project().setupProject(setupParams, m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
project = job->project().projectData();
products = project.allProducts();
QCOMPARE(products.size(), 4);
int clangProfiles = 0;
- for (const qbs::ProductData &p : qAsConst(products)) {
+ for (const qbs::ProductData &p : std::as_const(products)) {
if (p.profile() == "clangProfile") {
++clangProfiles;
moduleProps = p.moduleProperties();
if (moduleProps.getModuleProperty("cpp", "present").toBool()) {
QCOMPARE(moduleProps.getModuleProperty("cpp", "cxxCompilerName").toString(),
- QString("g++"));
+ qbs::Internal::HostOsInfo::appendExecutableSuffix(QString("g++")));
}
}
}
@@ -1733,7 +1761,7 @@ void TestApi::missingSourceFile()
setupParams.setProductErrorMode(qbs::ErrorHandlingMode::Relaxed);
m_logSink->setLogLevel(qbs::LoggerMinLevel);
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
qbs::ProjectData project = job->project().projectData();
@@ -1744,7 +1772,7 @@ void TestApi::missingSourceFile()
QCOMPARE(group.allSourceArtifacts().size(), 2);
QFile::rename("file2.txt.missing", "file2.txt");
- job.reset(qbs::Project().setupProject(setupParams, m_logSink, 0));
+ job.reset(qbs::Project().setupProject(setupParams, m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
project = job->project().projectData();
@@ -1797,12 +1825,13 @@ void TestApi::multiArch()
overriddenValues.insert("project.targetProfile", targetProfile.name());
setupParams.setOverriddenValues(overriddenValues);
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
qbs::Project project = setupJob->project();
QCOMPARE(project.profile(), profileName());
- const QList<qbs::ProductData> &products = project.projectData().products();
+ const qbs::ProjectData projectData = project.projectData();
+ const QList<qbs::ProductData> &products = projectData.products();
QCOMPARE(products.size(), 3);
QList<qbs::ProductData> hostProducts;
QList<qbs::ProductData> targetProducts;
@@ -1861,26 +1890,23 @@ void TestApi::multiArch()
QFile p2ArtifactInstalled(installRoot + "/host/host-tool.output");
QVERIFY2(p2ArtifactInstalled.exists(), qPrintable(p2ArtifactInstalled.fileName()));
- // Error check: Try to build for the same profile twice.
+ // Specifying the same profile twice should not result in an attempt to multiplex.
overriddenValues.insert("project.targetProfile", hostProfile.name());
setupParams.setOverriddenValues(overriddenValues);
- setupJob.reset(project.setupProject(setupParams, m_logSink, 0));
+ setupJob.reset(project.setupProject(setupParams, m_logSink, nullptr));
waitForFinished(setupJob.get());
- QVERIFY(setupJob->error().hasError());
- QVERIFY2(setupJob->error().toString().contains("Duplicate entry 'host' in qbs.profiles."),
- qPrintable(setupJob->error().toString()));
+ QVERIFY(!setupJob->error().hasError());
+ QCOMPARE(int(setupJob->project().projectData().products().size()), 2);
- // Error check: Try to build for the same profile twice, this time attaching
- // the properties via the product name.
+ // The same, but this time attaching the properties via the product name.
overriddenValues.remove(QStringLiteral("project.targetProfile"));
overriddenValues.insert("products.p1.myProfiles",
targetProfile.name() + ',' + targetProfile.name());
setupParams.setOverriddenValues(overriddenValues);
- setupJob.reset(project.setupProject(setupParams, m_logSink, 0));
+ setupJob.reset(project.setupProject(setupParams, m_logSink, nullptr));
waitForFinished(setupJob.get());
- QVERIFY(setupJob->error().hasError());
- QVERIFY2(setupJob->error().toString().contains("Duplicate entry 'target' in qbs.profiles."),
- qPrintable(setupJob->error().toString()));
+ QVERIFY(!setupJob->error().hasError());
+ QCOMPARE(int(setupJob->project().projectData().products().size()), 2);
}
struct ProductDataSelector
@@ -1899,7 +1925,8 @@ struct ProductDataSelector
bool qbsPropertiesMatch(const qbs::ProductData &p) const
{
for (auto it = qbsProperties.begin(); it != qbsProperties.end(); ++it) {
- if (it.value() != p.moduleProperties().getModuleProperty("qbs", it.key()))
+ if (!qbs::qVariantsEqual(
+ it.value(), p.moduleProperties().getModuleProperty("qbs", it.key())))
return false;
}
return true;
@@ -1926,7 +1953,7 @@ void TestApi::multiplexing()
{
qbs::SetupProjectParameters setupParams = defaultSetupParameters("multiplexing");
std::unique_ptr<qbs::SetupProjectJob> setupJob(
- qbs::Project().setupProject(setupParams, m_logSink, 0));
+ qbs::Project().setupProject(setupParams, m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
qbs::Project project = setupJob->project();
@@ -2035,6 +2062,31 @@ void TestApi::multiplexing()
QVERIFY(product.dependencies().empty());
selector.clear();
+ selector.name = "multiplex-without-aggregator-4-depends-2";
+ selector.qbsProperties["architecture"] = "C64";
+ selector.qbsProperties["buildVariant"] = "debug";
+ product = takeMatchingProduct(products, selector);
+ QVERIFY(product.isValid());
+ QVERIFY(product.isMultiplexed());
+ QCOMPARE(product.dependencies().size(), 1);
+ selector.qbsProperties["buildVariant"] = "release";
+ product = takeMatchingProduct(products, selector);
+ QVERIFY(product.isValid());
+ QVERIFY(product.isMultiplexed());
+ QCOMPARE(product.dependencies().size(), 1);
+ selector.qbsProperties["architecture"] = "TRS-80";
+ selector.qbsProperties["buildVariant"] = "debug";
+ product = takeMatchingProduct(products, selector);
+ QVERIFY(product.isValid());
+ QVERIFY(product.isMultiplexed());
+ QCOMPARE(product.dependencies().size(), 1);
+ selector.qbsProperties["buildVariant"] = "release";
+ product = takeMatchingProduct(products, selector);
+ QVERIFY(product.isValid());
+ QVERIFY(product.isMultiplexed());
+ QCOMPARE(product.dependencies().size(), 1);
+
+ selector.clear();
selector.name = "multiplex-with-aggregator-2";
selector.qbsProperties["architecture"] = "C64";
product = takeMatchingProduct(products, selector);
@@ -2137,12 +2189,12 @@ void TestApi::newOutputArtifactInDependency()
void TestApi::newPatternMatch()
{
TaskReceiver receiver;
- qbs::ErrorInfo errorInfo = doBuildProject("new-pattern-match", 0, 0, &receiver);
+ qbs::ErrorInfo errorInfo = doBuildProject("new-pattern-match", nullptr, nullptr, &receiver);
VERIFY_NO_ERROR(errorInfo);
QVERIFY2(receiver.taskDescriptions.contains("Resolving"), qPrintable(m_logSink->output));
receiver.taskDescriptions.clear();
- errorInfo = doBuildProject("new-pattern-match", 0, 0, &receiver);
+ errorInfo = doBuildProject("new-pattern-match", nullptr, nullptr, &receiver);
VERIFY_NO_ERROR(errorInfo);
QVERIFY(!receiver.taskDescriptions.contains("Resolving"));
@@ -2150,18 +2202,18 @@ void TestApi::newPatternMatch()
QFile f("test.txt");
QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
f.close();
- errorInfo = doBuildProject("new-pattern-match", 0, 0, &receiver);
+ errorInfo = doBuildProject("new-pattern-match", nullptr, nullptr, &receiver);
VERIFY_NO_ERROR(errorInfo);
QVERIFY(receiver.taskDescriptions.contains("Resolving"));
receiver.taskDescriptions.clear();
- errorInfo = doBuildProject("new-pattern-match", 0, 0, &receiver);
+ errorInfo = doBuildProject("new-pattern-match", nullptr, nullptr, &receiver);
VERIFY_NO_ERROR(errorInfo);
QVERIFY(!receiver.taskDescriptions.contains("Resolving"));
WAIT_FOR_NEW_TIMESTAMP();
f.remove();
- errorInfo = doBuildProject("new-pattern-match", 0, 0, &receiver);
+ errorInfo = doBuildProject("new-pattern-match", nullptr, nullptr, &receiver);
VERIFY_NO_ERROR(errorInfo);
QVERIFY(receiver.taskDescriptions.contains("Resolving"));
}
@@ -2169,9 +2221,9 @@ void TestApi::newPatternMatch()
void TestApi::nonexistingProjectPropertyFromProduct()
{
qbs::SetupProjectParameters setupParams
- = defaultSetupParameters("nonexistingprojectproperties");
+ = defaultSetupParameters("nonexistingprojectproperties/invalidaccessfromproduct.qbs");
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QEXPECT_FAIL("", "QBS-432", Abort);
QVERIFY(job->error().hasError());
@@ -2188,7 +2240,7 @@ void TestApi::nonexistingProjectPropertyFromCommandLine()
projectProperties.insert(QStringLiteral("project.blubb"), QStringLiteral("true"));
setupParams.setOverriddenValues(projectProperties);
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY(job->error().hasError());
QVERIFY2(job->error().toString().contains(QLatin1String("blubb")),
@@ -2206,7 +2258,7 @@ void TestApi::projectDataAfterProductInvalidation()
qbs::SetupProjectParameters setupParams = defaultSetupParameters("project-data-after-"
"product-invalidation/project-data-after-product-invalidation.qbs");
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
qbs::Project project = setupJob->project();
@@ -2228,7 +2280,7 @@ void TestApi::projectDataAfterProductInvalidation()
projectFile.resize(0);
projectFile.write(content);
projectFile.flush();
- setupJob.reset(project.setupProject(setupParams, m_logSink, 0));
+ setupJob.reset(project.setupProject(setupParams, m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
QVERIFY(!project.isValid());
@@ -2260,6 +2312,8 @@ void TestApi::processResult()
ProcessResultReceiver resultReceiver;
const qbs::ErrorInfo errorInfo = doBuildProject("process-result",
nullptr, &resultReceiver, nullptr, qbs::BuildOptions(), overridden);
+ if (m_logSink->output.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QCOMPARE(expectedExitCode != 0, errorInfo.hasError());
QVERIFY(resultReceiver.results.size() > 1);
const qbs::ProcessResult &result = resultReceiver.results.back();
@@ -2311,20 +2365,20 @@ void TestApi::projectInvalidation()
qbs::SetupProjectParameters setupParams = defaultSetupParameters("project-invalidation");
QVERIFY(QFile::copy("project.no-error.qbs", "project-invalidation.qbs"));
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
qbs::Project project = setupJob->project();
QVERIFY(project.isValid());
WAIT_FOR_NEW_TIMESTAMP();
copyFileAndUpdateTimestamp("project.early-error.qbs", "project-invalidation.qbs");
- setupJob.reset(project.setupProject(setupParams, m_logSink, 0));
+ setupJob.reset(project.setupProject(setupParams, m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY(setupJob->error().hasError());
QVERIFY(project.isValid()); // Error in Loader, old project still valid.
WAIT_FOR_NEW_TIMESTAMP();
copyFileAndUpdateTimestamp("project.late-error.qbs", "project-invalidation.qbs");
- setupJob.reset(project.setupProject(setupParams, m_logSink, 0));
+ setupJob.reset(project.setupProject(setupParams, m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY(setupJob->error().hasError());
QVERIFY(!project.isValid()); // Error in build data re-resolving, old project not valid anymore.
@@ -2334,13 +2388,13 @@ void TestApi::projectLocking()
{
qbs::SetupProjectParameters setupParams = defaultSetupParameters("project-locking");
std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
qbs::Project project = setupJob->project();
- setupJob.reset(project.setupProject(setupParams, m_logSink, 0));
+ setupJob.reset(project.setupProject(setupParams, m_logSink, nullptr));
std::unique_ptr<qbs::SetupProjectJob> setupJob2(project.setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob2.get());
QVERIFY(setupJob2->error().hasError());
QVERIFY2(setupJob2->error().toString()
@@ -2357,14 +2411,14 @@ void TestApi::projectPropertiesByName()
QVERIFY(errorInfo.hasError());
QVariantMap overridden;
overridden.insert("project.theDefines", QStringList() << "SUB1" << "SUB2");
- errorInfo = doBuildProject(projectFile, 0, 0, 0, qbs::BuildOptions(), overridden);
+ errorInfo = doBuildProject(projectFile, nullptr, nullptr, nullptr, qbs::BuildOptions(), overridden);
QVERIFY(errorInfo.hasError());
overridden.clear();
overridden.insert("projects.subproject1.theDefines", QStringList() << "SUB1");
- errorInfo = doBuildProject(projectFile, 0, 0, 0, qbs::BuildOptions(), overridden);
+ errorInfo = doBuildProject(projectFile, nullptr, nullptr, nullptr, qbs::BuildOptions(), overridden);
QVERIFY(errorInfo.hasError());
overridden.insert("projects.subproject2.theDefines", QStringList() << "SUB2");
- errorInfo = doBuildProject(projectFile, 0, 0, 0, qbs::BuildOptions(), overridden);
+ errorInfo = doBuildProject(projectFile, nullptr, nullptr, nullptr, qbs::BuildOptions(), overridden);
VERIFY_NO_ERROR(errorInfo);
}
@@ -2424,7 +2478,7 @@ void TestApi::referencedFileErrors()
params.setProductErrorMode(relaxedMode ? qbs::ErrorHandlingMode::Relaxed
: qbs::ErrorHandlingMode::Strict);
m_logSink->setLogLevel(qbs::LoggerMinLevel);
- std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(params, m_logSink, 0));
+ std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(params, m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(job->error().hasError() != relaxedMode, qPrintable(job->error().toString()));
const qbs::Project project = job->project();
@@ -2459,7 +2513,9 @@ qbs::SetupProjectParameters TestApi::defaultSetupParameters(const QString &proje
}
qbs::SetupProjectParameters setupParams;
- setupParams.setEnvironment(QProcessEnvironment::systemEnvironment());
+ auto environment = QProcessEnvironment::systemEnvironment();
+ environment.insert("QBS_AUTOTEST_CODE_SIGNING_REQUIRED", "0");
+ setupParams.setEnvironment(environment);
setupParams.setProjectFilePath(projectFilePath);
setupParams.setPropertyCheckingMode(qbs::ErrorHandlingMode::Strict);
setupParams.setOverrideBuildGraphData(true);
@@ -2474,6 +2530,7 @@ qbs::SetupProjectParameters TestApi::defaultSetupParameters(const QString &proje
setupParams.setLibexecPath(QDir::cleanPath(QCoreApplication::applicationDirPath()
+ QLatin1String("/" QBS_RELATIVE_LIBEXEC_PATH)));
setupParams.setTopLevelProfile(profileName());
+ setupParams.setMaxJobCount(2);
setupParams.setConfigurationName(QStringLiteral("default"));
setupParams.setSettingsDirectory(settings()->baseDirectory());
return setupParams;
@@ -2484,21 +2541,21 @@ void TestApi::references()
qbs::SetupProjectParameters setupParams = defaultSetupParameters("references/invalid1.qbs");
const QString projectDir = QDir::cleanPath(m_workingDataDir + "/references");
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY(job->error().hasError());
QString errorString = job->error().toString();
QVERIFY2(errorString.contains("does not contain"), qPrintable(errorString));
setupParams.setProjectFilePath(projectDir + QLatin1String("/invalid2.qbs"));
- job.reset(qbs::Project().setupProject(setupParams, m_logSink, 0));
+ job.reset(qbs::Project().setupProject(setupParams, m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY(job->error().hasError());
errorString = job->error().toString();
QVERIFY2(errorString.contains("contains more than one"), qPrintable(errorString));
setupParams.setProjectFilePath(projectDir + QLatin1String("/valid.qbs"));
- job.reset(qbs::Project().setupProject(setupParams, m_logSink, 0));
+ job.reset(qbs::Project().setupProject(setupParams, m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
const qbs::ProjectData topLevelProject = job->project().projectData();
@@ -2514,7 +2571,7 @@ void TestApi::relaxedModeRecovery()
setupParams.setProductErrorMode(qbs::ErrorHandlingMode::Relaxed);
setupParams.setPropertyCheckingMode(qbs::ErrorHandlingMode::Relaxed);
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
if (m_logSink->warnings.size() != 4) {
@@ -2600,7 +2657,7 @@ void TestApi::removeFileDependency()
QFile::remove("someheader.h");
ProcessResultReceiver receiver;
- errorInfo = doBuildProject("remove-file-dependency/removeFileDependency.qbs", 0, &receiver);
+ errorInfo = doBuildProject("remove-file-dependency/removeFileDependency.qbs", nullptr, &receiver);
QVERIFY(errorInfo.hasError());
QVERIFY2(receiver.output.contains("someheader.h"), qPrintable(receiver.output));
}
@@ -2613,7 +2670,7 @@ void TestApi::resolveProject()
const qbs::SetupProjectParameters params = defaultSetupParameters(projectSubDir);
removeBuildDir(params);
const std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(params,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
VERIFY_NO_ERROR(setupJob->error());
QVERIFY2(!QFile::exists(productFileName), qPrintable(productFileName));
@@ -2634,7 +2691,7 @@ void TestApi::resolveProjectDryRun()
params.setDryRun(true);
removeBuildDir(params);
const std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(params,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
VERIFY_NO_ERROR(setupJob->error());
QVERIFY2(!QFile::exists(productFileName), qPrintable(productFileName));
@@ -2654,44 +2711,51 @@ void TestApi::restoredWarnings()
// Initial resolving: Errors are new.
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
job.reset(nullptr);
- QCOMPARE(toSet(m_logSink->warnings).size(), 2);
+ QCOMPARE(toSet(m_logSink->warnings).size(), 5);
const auto beforeErrors = m_logSink->warnings;
for (const qbs::ErrorInfo &e : beforeErrors) {
const QString msg = e.toString();
QVERIFY2(msg.contains("Superfluous version")
- || msg.contains("Property 'blubb' is not declared"),
+ || msg.contains("Property 'blubb' is not declared")
+ || msg.contains("this one comes from a thread")
+ || msg.contains("Product 'theOtherProduct' had errors and was disabled")
+ || msg.contains("Product 'theProduct' had errors and was disabled"),
qPrintable(msg));
}
m_logSink->warnings.clear();
// Re-resolving with no changes: Errors come from the stored build graph.
- job.reset(qbs::Project().setupProject(setupParams, m_logSink, 0));
+ job.reset(qbs::Project().setupProject(setupParams, m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
job.reset(nullptr);
- QCOMPARE(toSet(m_logSink->warnings).size(), 2);
+ QCOMPARE(toSet(m_logSink->warnings).size(), 5);
m_logSink->warnings.clear();
// Re-resolving with changes: Errors come from the re-resolving, stored ones must be suppressed.
QVariantMap overridenValues;
- overridenValues.insert("products.theProduct.moreFiles", true);
+ overridenValues.insert("products.aThirdProduct.moreFiles", true);
setupParams.setOverriddenValues(overridenValues);
- job.reset(qbs::Project().setupProject(setupParams, m_logSink, 0));
+ job.reset(qbs::Project().setupProject(setupParams, m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
job.reset(nullptr);
- QCOMPARE(toSet(m_logSink->warnings).size(), 3); // One more for the additional group
+ QCOMPARE(toSet(m_logSink->warnings).size(), 6); // One more for the additional group
const auto afterErrors = m_logSink->warnings;
for (const qbs::ErrorInfo &e : afterErrors) {
const QString msg = e.toString();
- QVERIFY2(msg.contains("Superfluous version")
- || msg.contains("Property 'blubb' is not declared")
- || msg.contains("blubb.cpp' does not exist"),
- qPrintable(msg));
+ QVERIFY2(
+ msg.contains("Superfluous version") || msg.contains("Property 'blubb' is not declared")
+ || msg.contains("blubb.txt' does not exist")
+ || msg.contains("this one comes from a thread")
+ || msg.contains("Product 'theOtherProduct' had errors and was disabled")
+ || msg.contains("Product 'theThirdProduct' had errors and was disabled")
+ || msg.contains("Product 'theProduct' had errors and was disabled"),
+ qPrintable(msg));
}
m_logSink->warnings.clear();
}
@@ -2710,7 +2774,7 @@ void TestApi::runEnvForDisabledProduct()
const qbs::SetupProjectParameters params
= defaultSetupParameters("run-disabled-product/run-disabled-product.qbs");
const std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(params,
- m_logSink, 0));
+ m_logSink, nullptr));
QVERIFY(waitForFinished(setupJob.get()));
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
const qbs::Project project = setupJob->project();
@@ -2747,7 +2811,7 @@ void TestApi::sourceFileInBuildDir()
const QString generatedFile = relativeProductBuildDir("theProduct") + "/generated.cpp";
QVERIFY2(regularFileExists(generatedFile), qPrintable(generatedFile));
std::unique_ptr<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(job.get());
QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString()));
const qbs::ProjectData projectData = job->project().projectData();
@@ -2820,7 +2884,7 @@ void TestApi::targetArtifactStatus()
= defaultSetupParameters("target-artifact-status/target-artifact-status.qbs");
params.setOverriddenValues({std::make_pair("products.p.enableTagging", enableTagging)});
const std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(params,
- m_logSink, 0));
+ m_logSink, nullptr));
waitForFinished(setupJob.get());
VERIFY_NO_ERROR(setupJob->error());
const qbs::Project project = setupJob->project();
@@ -2838,10 +2902,13 @@ void TestApi::targetArtifactStatus()
void TestApi::timeout()
{
QFETCH(QString, projectDirName);
+ QFETCH(QString, cancelOutput);
const auto setupParams = defaultSetupParameters(projectDirName + "/timeout.qbs");
std::unique_ptr<qbs::SetupProjectJob> setupJob{
qbs::Project().setupProject(setupParams, m_logSink, nullptr)};
waitForFinished(setupJob.get());
+ if (m_logSink->output.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
auto project = setupJob->project();
const auto products = project.projectData().products();
@@ -2868,42 +2935,54 @@ void TestApi::timeout()
const auto errorString = buildJob->error().toString();
QVERIFY2(errorString.contains("cancel"), qPrintable(errorString));
QVERIFY(errorString.contains("timeout"));
+ QVERIFY(errorString.contains(cancelOutput));
}
void TestApi::timeout_data()
{
QTest::addColumn<QString>("projectDirName");
- QTest::newRow("JS Command") << QString("timeout-js");
- QTest::newRow("Process Command") << QString("timeout-process");
+ QTest::addColumn<QString>("cancelOutput");
+ QTest::newRow("JS Command") << QString("timeout-js") << QString("infinite loop");
+ QTest::newRow("Process Command") << QString("timeout-process") << QString("infinite-loop");
}
void TestApi::toolInModule()
{
QVariantMap overrides({std::make_pair("qbs.installRoot", m_workingDataDir
+ "/tool-in-module/use-outside-project")});
- const qbs::ErrorInfo error
- = doBuildProject("tool-in-module/use-within-project/use-within-project.qbs", nullptr,
- nullptr, nullptr, qbs::BuildOptions(), overrides);
- QVERIFY2(!error.hasError(), qPrintable(error.toString()));
+
+ qbs::SetupProjectParameters params
+ = defaultSetupParameters("tool-in-module/use-within-project/use-within-project.qbs");
+ params.setOverriddenValues(overrides);
+ std::unique_ptr<qbs::SetupProjectJob> setupJob(
+ qbs::Project().setupProject(params, m_logSink, nullptr));
+ QVERIFY(waitForFinished(setupJob.get()));
+ QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
+ if (m_logSink->output.contains("Skip this test"))
+ QSKIP("Skip this test");
+
+ std::unique_ptr<qbs::BuildJob> buildJob(setupJob->project()
+ .buildAllProducts(qbs::BuildOptions()));
+
+ QVERIFY(waitForFinished(buildJob.get()));
+ QVERIFY2(!buildJob->error().hasError(), qPrintable(buildJob->error().toString()));
+
const QString toolOutput = relativeProductBuildDir("user-in-project") + "/tool-output.txt";
QVERIFY2(QFile::exists(toolOutput), qPrintable(toolOutput));
- const qbs::SetupProjectParameters params
- = defaultSetupParameters("tool-in-module/use-outside-project/use-outside-project.qbs");
- const std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(params,
- m_logSink, 0));
+ params = defaultSetupParameters("tool-in-module/use-outside-project/use-outside-project.qbs");
+ setupJob.reset(qbs::Project().setupProject(params, m_logSink, nullptr));
QVERIFY(waitForFinished(setupJob.get()));
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
- const qbs::Project project = setupJob->project();
- const qbs::ProjectData projectData = project.projectData();
- const QList<qbs::ProductData> products = projectData.products();
+ const auto project = setupJob->project();
+ const auto projectData = project.projectData();
+ const auto products = projectData.products();
QCOMPARE(products.size(), 1);
const qbs::ProductData product = products.front();
const auto groups = product.groups();
for (const qbs::GroupData &group : groups)
QVERIFY(group.name() != "thetool binary");
- const std::unique_ptr<qbs::BuildJob> buildJob(setupJob->project()
- .buildAllProducts(qbs::BuildOptions()));
+ buildJob.reset(setupJob->project().buildAllProducts(qbs::BuildOptions()));
QVERIFY(waitForFinished(buildJob.get()));
QVERIFY2(!buildJob->error().hasError(), qPrintable(buildJob->error().toString()));
const QString toolOutput2 = relativeProductBuildDir("user-outside-project")
@@ -2917,18 +2996,18 @@ void TestApi::trackAddQObjectHeader()
= defaultSetupParameters("missing-qobject-header/missingheader.qbs");
QFile qbsFile(params.projectFilePath());
QVERIFY(qbsFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
- qbsFile.write("import qbs.base 1.0\nCppApplication {\n Depends { name: 'Qt.core' }\n"
+ qbsFile.write("CppApplication {\n Depends { name: 'Qt.core' }\n"
" files: ['main.cpp', 'myobject.cpp']\n}");
qbsFile.close();
ProcessResultReceiver receiver;
qbs::ErrorInfo errorInfo
- = doBuildProject("missing-qobject-header/missingheader.qbs", 0, &receiver);
+ = doBuildProject("missing-qobject-header/missingheader.qbs", nullptr, &receiver);
QVERIFY(errorInfo.hasError());
QVERIFY2(isAboutUndefinedSymbols(receiver.output), qPrintable(receiver.output));
WAIT_FOR_NEW_TIMESTAMP();
QVERIFY(qbsFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
- qbsFile.write("import qbs.base 1.0\nCppApplication {\n Depends { name: 'Qt.core' }\n"
+ qbsFile.write("CppApplication {\n Depends { name: 'Qt.core' }\n"
" files: ['main.cpp', 'myobject.cpp','myobject.h']\n}");
qbsFile.close();
errorInfo = doBuildProject("missing-qobject-header/missingheader.qbs");
@@ -2942,7 +3021,7 @@ void TestApi::trackRemoveQObjectHeader()
removeBuildDir(params);
QFile qbsFile(params.projectFilePath());
QVERIFY(qbsFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
- qbsFile.write("import qbs.base 1.0\nCppApplication {\n Depends { name: 'Qt.core' }\n"
+ qbsFile.write("CppApplication {\n Depends { name: 'Qt.core' }\n"
" files: ['main.cpp', 'myobject.cpp','myobject.h']\n}");
qbsFile.close();
qbs::ErrorInfo errorInfo = doBuildProject("missing-qobject-header/missingheader.qbs");
@@ -2950,11 +3029,11 @@ void TestApi::trackRemoveQObjectHeader()
WAIT_FOR_NEW_TIMESTAMP();
QVERIFY(qbsFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
- qbsFile.write("import qbs.base 1.0\nCppApplication {\n Depends { name: 'Qt.core' }\n"
+ qbsFile.write("CppApplication {\n Depends { name: 'Qt.core' }\n"
" files: ['main.cpp', 'myobject.cpp']\n}");
qbsFile.close();
ProcessResultReceiver receiver;
- errorInfo = doBuildProject("missing-qobject-header/missingheader.qbs", 0, &receiver);
+ errorInfo = doBuildProject("missing-qobject-header/missingheader.qbs", nullptr, &receiver);
QVERIFY(errorInfo.hasError());
QVERIFY2(isAboutUndefinedSymbols(receiver.output), qPrintable(receiver.output));
}
@@ -2964,7 +3043,7 @@ void TestApi::transformerData()
const qbs::SetupProjectParameters params
= defaultSetupParameters("transformer-data/transformer-data.qbs");
const std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(params,
- m_logSink, 0));
+ m_logSink, nullptr));
QVERIFY(waitForFinished(setupJob.get()));
QVERIFY2(!setupJob->error().hasError(), qPrintable(setupJob->error().toString()));
const qbs::Project project = setupJob->project();
@@ -3038,13 +3117,13 @@ void TestApi::uic()
qbs::ErrorInfo TestApi::doBuildProject(
const QString &projectFilePath, BuildDescriptionReceiver *buildDescriptionReceiver,
ProcessResultReceiver *procResultReceiver, TaskReceiver *taskReceiver,
- const qbs::BuildOptions &options, const QVariantMap overriddenValues)
+ const qbs::BuildOptions &options, const QVariantMap &overriddenValues)
{
qbs::SetupProjectParameters params = defaultSetupParameters(projectFilePath);
params.setOverriddenValues(overriddenValues);
params.setDryRun(options.dryRun());
const std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(params,
- m_logSink, 0));
+ m_logSink, nullptr));
if (taskReceiver) {
connect(setupJob.get(), &qbs::AbstractJob::taskStarted,
taskReceiver, &TaskReceiver::handleTaskStart);
diff --git a/tests/auto/api/tst_api.h b/tests/auto/api/tst_api.h
index aa00ddc99..cca6d4970 100644
--- a/tests/auto/api/tst_api.h
+++ b/tests/auto/api/tst_api.h
@@ -69,9 +69,7 @@ private slots:
void buildProjectDryRun_data();
void buildSingleFile();
void canonicalToolchainList();
-#ifdef QBS_ENABLE_PROJECT_FILE_UPDATES
void changeContent();
-#endif
void changeDependentLib();
void checkOutputs();
void checkOutputs_data();
@@ -80,6 +78,7 @@ private slots:
void disabledInstallGroup();
void disabledProduct();
void disabledProject();
+ void disappearedWildcardFile();
void duplicateProductNames();
void duplicateProductNames_data();
void emptyFileTagList();
@@ -132,6 +131,7 @@ private slots:
void removeFileDependency();
void renameProduct();
void renameTargetArtifact();
+ void renamedQbsSource();
void resolveProject();
void resolveProject_data();
void resolveProjectDryRun();
@@ -161,7 +161,7 @@ private:
ProcessResultReceiver *procResultReceiver = 0,
TaskReceiver *taskReceiver = 0,
const qbs::BuildOptions &options = qbs::BuildOptions(),
- const QVariantMap overriddenValues = QVariantMap());
+ const QVariantMap &overriddenValues = QVariantMap());
LogSink * const m_logSink;
const QString m_sourceDataDir;
diff --git a/tests/auto/auto.pri b/tests/auto/auto.pri
deleted file mode 100644
index fd8afad50..000000000
--- a/tests/auto/auto.pri
+++ /dev/null
@@ -1,18 +0,0 @@
-TEMPLATE = app
-DESTDIR = ../../../bin
-DEFINES += SRCDIR=\\\"$$_PRO_FILE_PWD_\\\"
-qbs_test_suite_name = $$replace(_PRO_FILE_, ^.*/([^/.]+)\\.pro$, \\1)
-qbs_test_suite_name = $$upper($$replace(qbs_test_suite_name, -, _))
-DEFINES += QBS_TEST_SUITE_NAME=\\\"$${qbs_test_suite_name}\\\"
-INCLUDEPATH += $$PWD/../../src $$PWD/../../src/app/shared
-
-QT = core testlib
-CONFIG += testcase console
-CONFIG -= app_bundle
-CONFIG += c++14
-target.CONFIG += no_default_install
-
-dev_lib_frameworks=$$QMAKE_XCODE_DEVELOPER_PATH/Library/Frameworks
-exists($$dev_lib_frameworks): LIBS += -F$$dev_lib_frameworks
-
-include(../../src/lib/corelib/use_corelib.pri)
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
deleted file mode 100644
index 1afe48176..000000000
--- a/tests/auto/auto.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-TEMPLATE=subdirs
-
-qbs_enable_unit_tests {
- SUBDIRS += \
- buildgraph \
- language \
- tools \
-}
-
-SUBDIRS += \
- cmdlineparser \
- blackbox/blackbox.pro \
- blackbox/blackbox-android.pro \
- blackbox/blackbox-apple.pro \
- blackbox/blackbox-clangdb.pro \
- blackbox/blackbox-java.pro \
- blackbox/blackbox-joblimits.pro \
- blackbox/blackbox-qt.pro \
- api
diff --git a/tests/auto/auto.qbs b/tests/auto/auto.qbs
index bf75d0f23..b042d180a 100644
--- a/tests/auto/auto.qbs
+++ b/tests/auto/auto.qbs
@@ -1,19 +1,23 @@
-import qbs
-
Project {
name: "Autotests"
references: [
"api/api.qbs",
- "blackbox/blackbox.qbs",
"blackbox/blackbox-android.qbs",
"blackbox/blackbox-apple.qbs",
+ "blackbox/blackbox-baremetal.qbs",
"blackbox/blackbox-clangdb.qbs",
+ "blackbox/blackbox-examples.qbs",
"blackbox/blackbox-java.qbs",
"blackbox/blackbox-joblimits.qbs",
+ "blackbox/blackbox-providers.qbs",
"blackbox/blackbox-qt.qbs",
+ "blackbox/blackbox-tutorial.qbs",
+ "blackbox/blackbox-windows.qbs",
+ "blackbox/blackbox.qbs",
"buildgraph/buildgraph.qbs",
"cmdlineparser/cmdlineparser.qbs",
"language/language.qbs",
+ "pkgconfig/pkgconfig.qbs",
"tools/tools.qbs",
]
}
diff --git a/tests/auto/blackbox/CMakeLists.txt b/tests/auto/blackbox/CMakeLists.txt
new file mode 100644
index 000000000..88e19acdf
--- /dev/null
+++ b/tests/auto/blackbox/CMakeLists.txt
@@ -0,0 +1,99 @@
+add_qbs_test(blackbox
+ DEFINES
+ ${QBS_UNIT_TESTS_DEFINES}
+ "QBS_VERSION=\"${QBS_VERSION}\""
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackbox.cpp
+ tst_blackbox.h
+ )
+
+add_qbs_test(blackbox-android
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackboxandroid.cpp
+ tst_blackboxandroid.h
+ )
+
+add_qbs_test(blackbox-apple
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackboxapple.cpp
+ tst_blackboxapple.h
+ )
+
+add_qbs_test(blackbox-baremetal
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackboxbaremetal.cpp
+ tst_blackboxbaremetal.h
+ )
+
+add_qbs_test(blackbox-clangdb
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_clangdb.cpp
+ tst_clangdb.h
+ )
+
+add_qbs_test(blackbox-java
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackboxjava.cpp
+ tst_blackboxjava.h
+ )
+
+add_qbs_test(blackbox-joblimits
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackboxjoblimits.cpp
+ )
+
+add_qbs_test(blackbox-providers
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackboxproviders.cpp
+ )
+
+add_qbs_test(blackbox-qt
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackboxqt.cpp
+ tst_blackboxqt.h
+ )
+
+add_qbs_test(blackbox-tutorial
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackboxtutorial.h
+ tst_blackboxtutorial.cpp
+ )
+
+add_qbs_test(blackbox-windows
+ SOURCES
+ ../shared.h
+ tst_blackboxbase.cpp
+ tst_blackboxbase.h
+ tst_blackboxwindows.cpp
+ tst_blackboxwindows.h
+ )
diff --git a/tests/auto/blackbox/blackbox-android.pro b/tests/auto/blackbox/blackbox-android.pro
deleted file mode 100644
index 7aca99e8d..000000000
--- a/tests/auto/blackbox/blackbox-android.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-TARGET = tst_blackbox-android
-
-HEADERS = tst_blackboxandroid.h tst_blackboxbase.h
-SOURCES = tst_blackboxandroid.cpp tst_blackboxbase.cpp
-OBJECTS_DIR = android
-MOC_DIR = $${OBJECTS_DIR}-moc
-
-include(../auto.pri)
-
-DATA_DIRS = testdata-android ../find
-
-for(data_dir, DATA_DIRS) {
- files = $$files($$PWD/$$data_dir/*, true)
- win32:files ~= s|\\\\|/|g
- for(file, files):!exists($$file/*):FILES += $$file
-}
-
-OTHER_FILES += $$FILES
-
-DISTFILES += \
- testdata/texttemplate/expected-output-one.txt
diff --git a/tests/auto/blackbox/blackbox-apple.pro b/tests/auto/blackbox/blackbox-apple.pro
deleted file mode 100644
index 1a009e222..000000000
--- a/tests/auto/blackbox/blackbox-apple.pro
+++ /dev/null
@@ -1,20 +0,0 @@
-TARGET = tst_blackbox-apple
-
-HEADERS = tst_blackboxapple.h tst_blackboxbase.h
-SOURCES = tst_blackboxapple.cpp tst_blackboxbase.cpp
-OBJECTS_DIR = apple
-MOC_DIR = $${OBJECTS_DIR}-moc
-
-include(../auto.pri)
-
-QT += xml
-
-DATA_DIRS = testdata-apple ../find
-
-for(data_dir, DATA_DIRS) {
- files = $$files($$PWD/$$data_dir/*, true)
- win32:files ~= s|\\\\|/|g
- for(file, files):!exists($$file/*):FILES += $$file
-}
-
-OTHER_FILES += $$FILES
diff --git a/tests/auto/blackbox/blackbox-baremetal.qbs b/tests/auto/blackbox/blackbox-baremetal.qbs
new file mode 100644
index 000000000..18ae588fe
--- /dev/null
+++ b/tests/auto/blackbox/blackbox-baremetal.qbs
@@ -0,0 +1,21 @@
+import qbs.Utilities
+
+QbsAutotest {
+ testName: "blackbox-baremetal"
+ Depends { name: "qbs_app" }
+ Depends { name: "qbs-setup-toolchains" }
+ Group {
+ name: "testdata"
+ prefix: "testdata-baremetal/"
+ files: ["**/*"]
+ fileTags: []
+ }
+ files: [
+ "../shared.h",
+ "tst_blackboxbase.cpp",
+ "tst_blackboxbase.h",
+ "tst_blackboxbaremetal.cpp",
+ "tst_blackboxbaremetal.h",
+ ]
+ cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)])
+}
diff --git a/tests/auto/blackbox/blackbox-clangdb.pro b/tests/auto/blackbox/blackbox-clangdb.pro
deleted file mode 100644
index 6e4075175..000000000
--- a/tests/auto/blackbox/blackbox-clangdb.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-TARGET = tst_blackbox-clangdb
-
-HEADERS = tst_blackboxbase.h tst_clangdb.h
-SOURCES = tst_blackboxbase.cpp tst_clangdb.cpp
-OBJECTS_DIR = clangdb
-MOC_DIR = $${OBJECTS_DIR}-moc
-
-include(../auto.pri)
-
-DATA_DIRS = testdata-clangdb
-
-for(data_dir, DATA_DIRS) {
- files = $$files($$PWD/$$data_dir/*, true)
- win32:files ~= s|\\\\|/|g
- for(file, files):!exists($$file/*):FILES += $$file
-}
-
-OTHER_FILES += $$FILES
diff --git a/tests/auto/blackbox/blackbox-examples.qbs b/tests/auto/blackbox/blackbox-examples.qbs
new file mode 100644
index 000000000..77d32636c
--- /dev/null
+++ b/tests/auto/blackbox/blackbox-examples.qbs
@@ -0,0 +1,21 @@
+import qbs.Utilities
+
+QbsAutotest {
+ testName: "blackbox-examples"
+ Depends { name: "qbs_app" }
+ Depends { name: "qbs-setup-toolchains" }
+ Group {
+ name: "testdata"
+ prefix: "../../../examples/"
+ files: ["**/*"]
+ fileTags: []
+ }
+ files: [
+ "../shared.h",
+ "tst_blackboxexamples.cpp",
+ "tst_blackboxexamples.h",
+ "tst_blackboxbase.cpp",
+ "tst_blackboxbase.h",
+ ]
+ cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)])
+}
diff --git a/tests/auto/blackbox/blackbox-java.pro b/tests/auto/blackbox/blackbox-java.pro
deleted file mode 100644
index d297d9e09..000000000
--- a/tests/auto/blackbox/blackbox-java.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-TARGET = tst_blackbox-java
-
-HEADERS = tst_blackboxjava.h tst_blackboxbase.h
-SOURCES = tst_blackboxjava.cpp tst_blackboxbase.cpp
-OBJECTS_DIR = java
-MOC_DIR = $${OBJECTS_DIR}-moc
-
-include(../auto.pri)
-
-DATA_DIRS = testdata-java ../find
-
-for(data_dir, DATA_DIRS) {
- files = $$files($$PWD/$$data_dir/*, true)
- win32:files ~= s|\\\\|/|g
- for(file, files):!exists($$file/*):FILES += $$file
-}
-
-OTHER_FILES += $$FILES
diff --git a/tests/auto/blackbox/blackbox-joblimits.pro b/tests/auto/blackbox/blackbox-joblimits.pro
deleted file mode 100644
index 85413473e..000000000
--- a/tests/auto/blackbox/blackbox-joblimits.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-TARGET = tst_blackbox-joblimits
-
-HEADERS = tst_blackboxbase.h
-SOURCES = tst_blackboxjoblimits.cpp tst_blackboxbase.cpp
-OBJECTS_DIR = joblimits
-MOC_DIR = $${OBJECTS_DIR}-moc
-
-include(../auto.pri)
-
-DATA_DIRS = testdata-joblimits ../find
-
-for(data_dir, DATA_DIRS) {
- files = $$files($$PWD/$$data_dir/*, true)
- win32:files ~= s|\\\\|/|g
- for(file, files):!exists($$file/*):FILES += $$file
-}
-
-OTHER_FILES += $$FILES
diff --git a/tests/auto/blackbox/blackbox-providers.qbs b/tests/auto/blackbox/blackbox-providers.qbs
new file mode 100644
index 000000000..95ebaa423
--- /dev/null
+++ b/tests/auto/blackbox/blackbox-providers.qbs
@@ -0,0 +1,21 @@
+import qbs.Utilities
+
+QbsAutotest {
+ testName: "blackbox-providers"
+ Depends { name: "qbs_app" }
+ Depends { name: "qbs-setup-toolchains" }
+ Group {
+ name: "testdata"
+ prefix: "testdata-providers/"
+ files: ["**/*"]
+ fileTags: []
+ }
+ files: [
+ "../shared.h",
+ "tst_blackboxbase.cpp",
+ "tst_blackboxbase.h",
+ "tst_blackboxproviders.cpp",
+ "tst_blackboxproviders.h",
+ ]
+ cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)])
+}
diff --git a/tests/auto/blackbox/blackbox-qt.pro b/tests/auto/blackbox/blackbox-qt.pro
deleted file mode 100644
index e17a04a7e..000000000
--- a/tests/auto/blackbox/blackbox-qt.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-TARGET = tst_blackbox-qt
-
-HEADERS = tst_blackboxqt.h tst_blackboxbase.h
-SOURCES = tst_blackboxqt.cpp tst_blackboxbase.cpp
-OBJECTS_DIR = qt
-MOC_DIR = $${OBJECTS_DIR}-moc
-
-include(../auto.pri)
-
-DATA_DIRS = testdata-qt ../find
-
-for(data_dir, DATA_DIRS) {
- files = $$files($$PWD/$$data_dir/*, true)
- win32:files ~= s|\\\\|/|g
- for(file, files):!exists($$file/*):FILES += $$file
-}
-
-OTHER_FILES += $$FILES
diff --git a/tests/auto/blackbox/blackbox-tutorial.qbs b/tests/auto/blackbox/blackbox-tutorial.qbs
new file mode 100644
index 000000000..174821ffa
--- /dev/null
+++ b/tests/auto/blackbox/blackbox-tutorial.qbs
@@ -0,0 +1,21 @@
+import qbs.Utilities
+
+QbsAutotest {
+ testName: "blackbox-tutorial"
+ Depends { name: "qbs_app" }
+ Depends { name: "qbs-setup-toolchains" }
+ Group {
+ name: "testdata"
+ prefix: "../../../tutorial/"
+ files: ["**/*"]
+ fileTags: []
+ }
+ files: [
+ "../shared.h",
+ "tst_blackboxtutorial.cpp",
+ "tst_blackboxtutorial.h",
+ "tst_blackboxbase.cpp",
+ "tst_blackboxbase.h",
+ ]
+ cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)])
+}
diff --git a/tests/auto/blackbox/blackbox-windows.qbs b/tests/auto/blackbox/blackbox-windows.qbs
new file mode 100644
index 000000000..e32421e3b
--- /dev/null
+++ b/tests/auto/blackbox/blackbox-windows.qbs
@@ -0,0 +1,21 @@
+import qbs.Utilities
+
+QbsAutotest {
+ testName: "blackbox-windows"
+ Depends { name: "qbs_app" }
+ Depends { name: "qbs-setup-toolchains" }
+ Group {
+ name: "testdata"
+ prefix: "testdata-windows/"
+ files: ["**/*"]
+ fileTags: []
+ }
+ files: [
+ "../shared.h",
+ "tst_blackboxbase.cpp",
+ "tst_blackboxbase.h",
+ "tst_blackboxwindows.cpp",
+ "tst_blackboxwindows.h",
+ ]
+ cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)])
+}
diff --git a/tests/auto/blackbox/blackbox.pro b/tests/auto/blackbox/blackbox.pro
deleted file mode 100644
index 42848d077..000000000
--- a/tests/auto/blackbox/blackbox.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-TARGET = tst_blackbox
-
-HEADERS = tst_blackbox.h tst_blackboxbase.h
-SOURCES = tst_blackbox.cpp tst_blackboxbase.cpp
-OBJECTS_DIR = generic
-MOC_DIR = $${OBJECTS_DIR}-moc
-qbs_enable_unit_tests:DEFINES += QBS_ENABLE_UNIT_TESTS
-
-include(../auto.pri)
-
-QT += xml
-
-DATA_DIRS = testdata ../find
-
-for(data_dir, DATA_DIRS) {
- files = $$files($$PWD/$$data_dir/*, true)
- win32:files ~= s|\\\\|/|g
- for(file, files):!exists($$file/*):FILES += $$file
-}
-
-OTHER_FILES += $$FILES
diff --git a/tests/auto/blackbox/blackbox.qbs b/tests/auto/blackbox/blackbox.qbs
index 3f0ff959a..ac6bf750e 100644
--- a/tests/auto/blackbox/blackbox.qbs
+++ b/tests/auto/blackbox/blackbox.qbs
@@ -25,4 +25,5 @@ QbsAutotest {
]
cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)])
.concat(qbsbuildconfig.enableUnitTests ? ["QBS_ENABLE_UNIT_TESTS"] : [])
+ .concat("QBS_VERSION=" + Utilities.cStringQuote(qbsversion.version))
}
diff --git a/tests/auto/blackbox/find/find-android.qbs b/tests/auto/blackbox/find/find-android.qbs
index 26dedc60f..1cde0ed84 100644
--- a/tests/auto/blackbox/find/find-android.qbs
+++ b/tests/auto/blackbox/find/find-android.qbs
@@ -3,12 +3,23 @@ import qbs.TextFile
Product {
property string packageName: ""
qbs.targetPlatform: "android"
+ multiplexByQbsProperties: ["architectures"]
+
+ Properties {
+ condition: qbs.architectures && qbs.architectures.length > 1
+ aggregate: true
+ multiplexedType: "json_arch"
+ }
Depends { name: "Android.sdk"; required: false }
Depends { name: "Android.ndk"; required: false }
type: ["json"]
+
Rule {
multiplex: true
+ property stringList inputTags: "json_arch"
+ inputsFromDependencies: inputTags
+ inputs: product.aggregate ? [] : inputTags
Artifact {
filePath: ["android.json"]
fileTags: ["json"]
@@ -18,17 +29,51 @@ Product {
cmd.description = output.filePath;
cmd.sourceCode = function() {
var tools = {};
+
+ for (var i in inputs["json_arch"]) {
+ var tf = new TextFile(inputs["json_arch"][i].filePath, TextFile.ReadOnly);
+ var json = JSON.parse(tf.readAll());
+ tools["ndk"] = json["ndk"];
+ tools["ndk-samples"] = json["ndk-samples"];
+ tf.close();
+ }
+
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)
+ tools["jar"] = product.java.jarFilePath;
+
+ var tf;
+ try {
+ tf = new TextFile(output.filePath, TextFile.WriteOnly);
+ tf.writeLine(JSON.stringify(tools, undefined, 4));
+ } finally {
+ if (tf)
+ tf.close();
+ }
+ };
+ return cmd;
+ }
+ }
+ Rule {
+ multiplex: true
+ Artifact {
+ filePath: ["android_arch.json"]
+ fileTags: ["json_arch"]
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = output.filePath;
+ cmd.sourceCode = function() {
+ var tools = {};
if (product.moduleProperty("Android.ndk", "present")) {
tools["ndk"] = product.moduleProperty("Android.ndk", "ndkDir");
tools["ndk-samples"] = product.Android.ndk.ndkSamplesDir;
}
- if (product.java && product.java.present)
- tools["jar"] = product.java.jarFilePath;
var tf;
try {
@@ -43,3 +88,4 @@ Product {
}
}
}
+
diff --git a/tests/auto/blackbox/find/find-xcode.qbs b/tests/auto/blackbox/find/find-xcode.qbs
index bb6ee9718..15c2aa17e 100644
--- a/tests/auto/blackbox/find/find-xcode.qbs
+++ b/tests/auto/blackbox/find/find-xcode.qbs
@@ -14,7 +14,9 @@ Product {
cmd.description = output.filePath;
cmd.sourceCode = function() {
var tools = {};
- if (product.moduleProperty("xcode", "present")) {
+ var present = product.moduleProperty("xcode", "present");
+ tools["present"] = !!present;
+ if (present) {
var keys = [
"developerPath",
"version"
diff --git a/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml
index e8a950847..1d27681ac 100644
--- a/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml
+++ b/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:versionName="1.0" android:versionCode="1"
package="io.qbs.aidltest">
<application android:label="AidlTest">
<activity android:name="MainActivity">
diff --git a/tests/auto/blackbox/testdata-android/minimal-native/minimal-native.qbs b/tests/auto/blackbox/testdata-android/minimal-native/minimal-native.qbs
index 570152707..7231f7e62 100644
--- a/tests/auto/blackbox/testdata-android/minimal-native/minimal-native.qbs
+++ b/tests/auto/blackbox/testdata-android/minimal-native/minimal-native.qbs
@@ -1,7 +1,7 @@
CppApplication {
name: "minimalnative"
qbs.buildVariant: "release"
- Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" }
+ Properties { condition: qbs.toolchain.includes("clang"); Android.ndk.appStl: "c++_shared" }
Android.sdk.packageName: "my.minimalnative"
Android.sdk.apkBaseName: name
Android.ndk.appStl: "stlport_shared"
diff --git a/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml
index 575e95e8d..f61dc9850 100644
--- a/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml
+++ b/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:versionName="1.0" android:versionCode="1"
package="somedefault">
<application android:label="MinimalNative">
<activity android:name="MainActivity">
diff --git a/tests/auto/blackbox/testdata-android/minimal-native/src/main/native/native.c b/tests/auto/blackbox/testdata-android/minimal-native/src/main/native/native.c
index 6b625858b..f49b4f90f 100644
--- a/tests/auto/blackbox/testdata-android/minimal-native/src/main/native/native.c
+++ b/tests/auto/blackbox/testdata-android/minimal-native/src/main/native/native.c
@@ -4,5 +4,6 @@
jstring
Java_minimalnative_MinimalNative_stringFromNative(JNIEnv* env, jobject thiz)
{
+ (void)thiz;
return (*env)->NewStringUTF(env, "This message comes from native code.");
}
diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs
index c4a78a30b..c7b9b3de2 100644
--- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs
+++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs
@@ -5,9 +5,12 @@ Project {
name: "p1lib1"
files: ["src/main/jni/lib1.cpp"]
qbs.targetPlatform: "android"
- Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" }
+ Properties { condition: qbs.toolchain.includes("clang"); Android.ndk.appStl: "c++_shared" }
Android.ndk.appStl: "stlport_shared"
- qbs.architectures: !qbs.architecture ? ["armv7a", "x86"] : undefined
+ Properties {
+ qbs.architectures: !qbs.architecture ? ["armv7a", "x86"] : undefined
+ overrideListProperties: true
+ }
cpp.useRPaths: false
}
@@ -17,7 +20,7 @@ Project {
name: "p1lib2"
files: ["src/main/jni/lib2.cpp"]
qbs.targetPlatform: "android"
- Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" }
+ Properties { condition: qbs.toolchain.includes("clang"); Android.ndk.appStl: "c++_shared" }
Android.ndk.appStl: "stlport_shared"
cpp.useRPaths: false
}
diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/src/main/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/src/main/AndroidManifest.xml
index 289969409..272fe55de 100644
--- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/src/main/AndroidManifest.xml
+++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/src/main/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.qt.dummy1" android:versionCode="1" android:versionName="1.0">
- <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="19"/>
+ <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
<uses-feature android:glEsVersion="0x00020000"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:allowBackup="true" android:hasCode="true">
diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs
index 9be70dcda..f880a576d 100644
--- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs
+++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs
@@ -13,7 +13,7 @@ Project {
name: "p2lib2"
files: ["src/main/jni/lib2.cpp"]
qbs.targetPlatform: "android"
- Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" }
+ Properties { condition: qbs.toolchain.includes("clang"); Android.ndk.appStl: "c++_shared" }
Android.ndk.appStl: "stlport_shared"
}
diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/src/main/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/src/main/AndroidManifest.xml
index ef0fbe54f..871aadbe6 100644
--- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/src/main/AndroidManifest.xml
+++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/src/main/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.qt.dummy2" android:versionCode="1" android:versionName="1.0">
- <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="19"/>
+ <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
<uses-feature android:glEsVersion="0x00020000"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:allowBackup="true" android:hasCode="true">
diff --git a/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs b/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs
index 8b9ded211..a5e193905 100644
--- a/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs
+++ b/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs
@@ -5,7 +5,7 @@ Project {
name: "lib1"
files: ["src/main/jni/lib1.cpp"]
qbs.targetPlatform: "android"
- Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" }
+ Properties { condition: qbs.toolchain.includes("clang"); Android.ndk.appStl: "c++_shared" }
Android.ndk.appStl: "stlport_shared"
cpp.useRPaths: false
}
@@ -16,7 +16,7 @@ Project {
name: "lib2"
files: ["src/main/jni/lib2.cpp"]
qbs.targetPlatform: "android"
- Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" }
+ Properties { condition: qbs.toolchain.includes("clang"); Android.ndk.appStl: "c++_shared" }
Android.ndk.appStl: "stlport_shared"
cpp.useRPaths: false
}
diff --git a/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/src/main/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/src/main/AndroidManifest.xml
index 6694afc18..f184a8f1f 100644
--- a/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/src/main/AndroidManifest.xml
+++ b/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/src/main/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.qt.dummy" android:versionCode="1" android:versionName="1.0">
- <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="19"/>
+ <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
<uses-feature android:glEsVersion="0x00020000"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:allowBackup="true" android:hasCode="true">
diff --git a/tests/auto/blackbox/testdata-android/qml-app/qml-app.qbs b/tests/auto/blackbox/testdata-android/qml-app/qml-app.qbs
index e91a14902..5760fa4f0 100644
--- a/tests/auto/blackbox/testdata-android/qml-app/qml-app.qbs
+++ b/tests/auto/blackbox/testdata-android/qml-app/qml-app.qbs
@@ -3,12 +3,12 @@ QtApplication {
Depends { name: "Qt.quick" }
Depends { name: "Qt.android_support" }
Properties {
- condition: qbs.targetOS.contains("android")
+ condition: qbs.targetOS.includes("android")
Qt.android_support.extraPrefixDirs: path
}
Android.sdk.packageName: "my.qmlapp"
Android.sdk.apkBaseName: name
- property stringList qmlImportPaths: path
+ Qt.android_support.qmlImportPaths: path
files: [
"main.cpp",
"qml.qrc",
diff --git a/tests/auto/blackbox/testdata-android/qml-app/src/main/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/qml-app/src/main/AndroidManifest.xml
index 066ec0a63..c8237c639 100644
--- a/tests/auto/blackbox/testdata-android/qml-app/src/main/AndroidManifest.xml
+++ b/tests/auto/blackbox/testdata-android/qml-app/src/main/AndroidManifest.xml
@@ -16,7 +16,6 @@
<!-- Application arguments -->
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
- <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
@@ -31,8 +30,6 @@
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Messages maps -->
- <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
- <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<!-- Messages maps -->
@@ -67,7 +64,7 @@
</application>
- <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="16"/>
+ <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
diff --git a/tests/auto/blackbox/testdata-android/qt-app/MainWindow.cpp b/tests/auto/blackbox/testdata-android/qt-app/MainWindow.cpp
new file mode 100644
index 000000000..b2e08c83e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-android/qt-app/MainWindow.cpp
@@ -0,0 +1,11 @@
+#include "MainWindow.h"
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+{
+}
+
+MainWindow::~MainWindow()
+{
+}
+
diff --git a/tests/auto/blackbox/testdata-android/qt-app/MainWindow.h b/tests/auto/blackbox/testdata-android/qt-app/MainWindow.h
new file mode 100644
index 000000000..ace53a4a0
--- /dev/null
+++ b/tests/auto/blackbox/testdata-android/qt-app/MainWindow.h
@@ -0,0 +1,15 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = nullptr);
+ ~MainWindow();
+};
+
+#endif // MAINWINDOW_H
diff --git a/tests/auto/blackbox/testdata-android/qt-app/Test.java b/tests/auto/blackbox/testdata-android/qt-app/Test.java
new file mode 100644
index 000000000..c57486d56
--- /dev/null
+++ b/tests/auto/blackbox/testdata-android/qt-app/Test.java
@@ -0,0 +1,54 @@
+package org.qbs.example;
+
+import org.qtproject.qt5.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 Test 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/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/main.cpp b/tests/auto/blackbox/testdata-android/qt-app/main.cpp
new file mode 100644
index 000000000..0a0916fca
--- /dev/null
+++ b/tests/auto/blackbox/testdata-android/qt-app/main.cpp
@@ -0,0 +1,11 @@
+#include "MainWindow.h"
+
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+ return a.exec();
+}
diff --git a/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs b/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs
new file mode 100644
index 000000000..04dcbf403
--- /dev/null
+++ b/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs
@@ -0,0 +1,27 @@
+Project {
+ QtGuiApplication {
+ Depends { name: "Lib" }
+ 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"] }
+ }
+
+ StaticLibrary {
+ name: "Lib"
+ Export {
+ Depends {
+ name: "Qt.android_support";
+ }
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-android/qt-app/test.keystore b/tests/auto/blackbox/testdata-android/qt-app/test.keystore
new file mode 100644
index 000000000..5713d10d2
--- /dev/null
+++ b/tests/auto/blackbox/testdata-android/qt-app/test.keystore
Binary files differ
diff --git a/tests/auto/blackbox/testdata-android/teapot/teapot.qbs b/tests/auto/blackbox/testdata-android/teapot/teapot.qbs
index 2b5cb8aba..0b1dead6e 100644
--- a/tests/auto/blackbox/testdata-android/teapot/teapot.qbs
+++ b/tests/auto/blackbox/testdata-android/teapot/teapot.qbs
@@ -51,7 +51,7 @@ Project {
files: ["*.cpp", "*.h"].concat(
!File.exists(ndkHelperProbe.dir + "/gl3stub.cpp") ? ["gl3stub.c"] : [])
}
- Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" }
+ Properties { condition: qbs.toolchain.includes("clang"); Android.ndk.appStl: "c++_shared" }
Android.ndk.appStl: "gnustl_shared"
cpp.cxxLanguageVersion: "c++11"
@@ -133,10 +133,11 @@ Project {
FileTagger { patterns: ["*.inl"]; fileTags: ["hpp"] }
+ version: "2.0"
Android.sdk.apkBaseName: name
Android.sdk.packageName: "com.sample.teapot"
Android.sdk.sourceSetDir: teapotProbe.dir
- Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" }
+ Properties { condition: qbs.toolchain.includes("clang"); Android.ndk.appStl: "c++_shared" }
Android.ndk.appStl: "gnustl_shared"
cpp.cxxLanguageVersion: "c++11"
cpp.dynamicLibraries: ["log", "android", "EGL", "GLESv2"]
diff --git a/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/aggregateDependencyLinking.qbs b/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/aggregateDependencyLinking.qbs
index e7c8867bd..6f57c1e44 100644
--- a/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/aggregateDependencyLinking.qbs
+++ b/tests/auto/blackbox/testdata-apple/aggregateDependencyLinking/aggregateDependencyLinking.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Project {
minimumQbsVersion: "1.8"
@@ -9,11 +7,27 @@ Project {
Depends { name: "cpp" }
Depends { name: "bundle" }
+ property bool hasX86Mac: true // cannot use xcode.version in qbs.architectures
+ property bool hasArmMac: false
bundle.isBundle: false
// This will generate 2 multiplex configs and an aggregate.
- qbs.architectures: ["x86", "x86_64"]
+ qbs.architectures: {
+ if (qbs.targetPlatform === "macos") {
+ if (hasX86Mac)
+ return ["x86_64", "x86"];
+ else if (hasArmMac)
+ return ["arm64", "x86_64"];
+ } else if (qbs.targetPlatform === "ios") {
+ return ["arm64", "armv7a"];
+ }
+ console.info("Cannot build fat binaries for this target platform ("
+ + qbs.targetPlatform + ")");
+ return original;
+ }
+
qbs.buildVariant: "debug"
+ cpp.minimumMacosVersion: "10.8"
}
CppApplication {
@@ -21,15 +35,22 @@ Project {
files: ["app.c"]
// This should link only against the aggregate static library, and not against
- // the {debug, x86_64} variant, or worse - against both the single arch variant
+ // the {debug, arm64} variant, or worse - against both the single arch variant
// and the lipo-ed one.
Depends { name: "multi_arch_lib" }
Depends { name: "bundle" }
bundle.isBundle: false
- qbs.architecture: "x86_64"
+ qbs.architecture: {
+ if (qbs.targetPlatform === "macos")
+ return "x86_64";
+ else if (qbs.targetPlatform === "ios")
+ return "arm64";
+ return original;
+ }
qbs.buildVariant: "debug"
+ cpp.minimumMacosVersion: "10.8"
multiplexByQbsProperties: []
}
}
diff --git a/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs b/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs
index 438624f70..5615722d5 100644
--- a/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs
+++ b/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs
@@ -1,23 +1,32 @@
import qbs.Utilities
+import "../multiarch-helpers.js" as Helpers
+
Project {
minimumQbsVersion: "1.8"
- property bool enableX86
+ condition: xcodeVersion
+ property string xcodeVersion
CppApplication {
Depends { name: "singlelib" }
Depends { name: "bundle" }
+ property bool isShallow: {
+ console.info("isShallow: " + bundle.isShallow);
+ return bundle.isShallow;
+ }
name: "singleapp"
targetName: "singleapp"
files: ["app.c"]
cpp.rpaths: [cpp.rpathOrigin + "/../../../"]
cpp.minimumMacosVersion: "10.6"
+ cpp.minimumIosVersion: "8.0"
// Turn off multiplexing
aggregate: false
multiplexByQbsProperties: []
install: true
+ installDebugInformation: false
installDir: ""
}
@@ -29,13 +38,15 @@ Project {
files: ["app.c"]
cpp.rpaths: [cpp.rpathOrigin + "/../../../"]
cpp.minimumMacosVersion: "10.6"
+ cpp.minimumIosVersion: "8.0"
// Force aggregation when not needed
aggregate: true
- qbs.architectures: ["x86_64"]
+ qbs.architectures: [Helpers.getNewArch(qbs)]
qbs.buildVariants: ["release"]
install: true
+ installDebugInformation: false
installDir: ""
}
@@ -45,7 +56,7 @@ Project {
name: "singlelib"
targetName: "singlelib"
files: ["lib.c"]
- cpp.sonamePrefix: qbs.targetOS.contains("darwin") ? "@rpath" : undefined
+ cpp.sonamePrefix: qbs.targetOS.includes("darwin") ? "@rpath" : undefined
cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)]
// Turn off multiplexing
@@ -53,6 +64,7 @@ Project {
multiplexByQbsProperties: []
install: true
+ installDebugInformation: false
installDir: ""
}
@@ -64,8 +76,10 @@ Project {
files: ["app.c"]
cpp.rpaths: [cpp.rpathOrigin + "/../../../"]
cpp.minimumMacosVersion: "10.6"
+ cpp.minimumIosVersion: "8.0"
install: true
+ installDebugInformation: false
installDir: ""
}
@@ -77,13 +91,16 @@ Project {
files: ["app.c"]
cpp.rpaths: [cpp.rpathOrigin + "/../../../"]
cpp.minimumMacosVersion: "10.6"
- qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"]
- qbs.architecture: "x86_64"
- multiplexByQbsProperties: project.enableX86 ? ["architectures", "buildVariants"]
- : ["buildVariants"]
+ cpp.minimumIosVersion: "8.0"
+ qbs.architectures: Helpers.getArchitectures(qbs, project.xcodeVersion)
+ qbs.architecture: Helpers.getNewArch(qbs)
+ multiplexByQbsProperties: Helpers.enableOldArch(qbs, project.xcodeVersion)
+ ? ["architectures", "buildVariants"]
+ : ["buildVariants"]
qbs.buildVariants: "debug"
install: true
+ installDebugInformation: false
installDir: ""
}
@@ -95,10 +112,12 @@ Project {
files: ["app.c"]
cpp.rpaths: [cpp.rpathOrigin + "/../../../"]
cpp.minimumMacosVersion: "10.6"
- qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"]
- qbs.buildVariants: ["debug", "profile"]
+ cpp.minimumIosVersion: "8.0"
+ qbs.architectures: Helpers.getArchitectures(qbs, project.xcodeVersion)
+ qbs.buildVariants: ["debug", "profiling"]
install: true
+ installDebugInformation: false
installDir: ""
}
@@ -108,12 +127,14 @@ Project {
name: "multilib"
targetName: "multilib"
files: ["lib.c"]
- cpp.sonamePrefix: qbs.targetOS.contains("darwin") ? "@rpath" : undefined
+ cpp.minimumIosVersion: "8.0"
+ cpp.sonamePrefix: qbs.targetOS.includes("darwin") ? "@rpath" : undefined
cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)]
- qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"]
- qbs.buildVariants: ["release", "debug", "profile"]
+ qbs.architectures: Helpers.getArchitectures(qbs, project.xcodeVersion)
+ qbs.buildVariants: ["release", "debug", "profiling"]
install: true
+ installDebugInformation: false
installDir: ""
}
@@ -123,12 +144,14 @@ Project {
name: "multilib-no-release"
targetName: "multilib-no-release"
files: ["lib.c"]
- cpp.sonamePrefix: qbs.targetOS.contains("darwin") ? "@rpath" : undefined
+ cpp.minimumIosVersion: "8.0"
+ cpp.sonamePrefix: qbs.targetOS.includes("darwin") ? "@rpath" : undefined
cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)]
- qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"]
- qbs.buildVariants: ["debug", "profile"]
+ qbs.architectures: Helpers.getArchitectures(qbs, project.xcodeVersion)
+ qbs.buildVariants: ["debug", "profiling"]
install: true
+ installDebugInformation: false
installDir: ""
}
@@ -138,11 +161,13 @@ Project {
Depends { name: "multilibB" }
name: "multilibA"
files: ["lib.c"]
+ cpp.minimumIosVersion: "8.0"
cpp.sonamePrefix: "@rpath"
cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)]
- qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"]
- qbs.buildVariants: ["debug", "profile"]
+ qbs.architectures: Helpers.getArchitectures(qbs, project.xcodeVersion)
+ qbs.buildVariants: ["debug", "profiling"]
install: true
+ installDebugInformation: false
installDir: ""
}
DynamicLibrary {
@@ -150,11 +175,13 @@ Project {
Depends { name: "bundle" }
name: "multilibB"
files: ["lib.c"]
+ cpp.minimumIosVersion: "8.0"
cpp.sonamePrefix: "@rpath"
cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)]
- qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"]
- qbs.buildVariants: ["debug", "profile"]
+ qbs.architectures: Helpers.getArchitectures(qbs, project.xcodeVersion)
+ qbs.buildVariants: ["debug", "profiling"]
install: true
+ installDebugInformation: false
installDir: ""
}
}
diff --git a/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs b/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs
index 8cf031e33..33ac58967 100644
--- a/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs
+++ b/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs
@@ -3,12 +3,21 @@ Project {
property stringList buildableProducts: ["A", "B", "C", "D", "E", "F", "G"]
+ Product {
+ Depends { name: "bundle" }
+ condition: {
+ console.info("bundle.isShallow: " + bundle.isShallow);
+ console.info("qbs.targetOS: " + qbs.targetOS);
+ return false;
+ }
+ }
+
Application {
Depends { name: "cpp" }
Depends { name: "B" }
Depends { name: "C" }
Depends { name: "D" }
- condition: buildableProducts.contains("A")
+ condition: buildableProducts.includes("A")
name: "A"
bundle.isBundle: true
bundle.publicHeaders: ["dummy.h"]
@@ -24,7 +33,7 @@ Project {
Depends { name: "B" }
Depends { name: "C" }
Depends { name: "D" }
- condition: buildableProducts.contains("ABadApple")
+ condition: buildableProducts.includes("ABadApple")
name: "ABadApple"
bundle._productTypeIdentifier: "com.apple.product-type.will.never.exist.ever.guaranteed"
bundle.isBundle: true
@@ -41,7 +50,7 @@ Project {
Depends { name: "B" }
Depends { name: "C" }
Depends { name: "D" }
- condition: buildableProducts.contains("ABadThirdParty")
+ condition: buildableProducts.includes("ABadThirdParty")
name: "ABadThirdParty"
bundle._productTypeIdentifier: "org.special.third.party.non.existent.product.type"
bundle.isBundle: true
@@ -94,7 +103,7 @@ Project {
ApplicationExtension {
Depends { name: "cpp" }
- condition: buildableProducts.contains("E")
+ condition: buildableProducts.includes("E")
name: "E"
bundle.isBundle: true
bundle.publicHeaders: ["dummy.h"]
@@ -107,7 +116,7 @@ Project {
XPCService {
Depends { name: "cpp" }
- condition: buildableProducts.contains("F")
+ condition: buildableProducts.includes("F")
name: "F"
bundle.isBundle: true
bundle.publicHeaders: ["dummy.h"]
@@ -120,11 +129,14 @@ Project {
Product {
Depends { name: "bundle" }
- condition: buildableProducts.contains("G")
+ condition: buildableProducts.includes("G")
type: ["inapppurchase"]
name: "G"
bundle.isBundle: true
bundle.resources: ["resource.txt"]
+ // XCode 12.5 does not support com.apple.product-type.in-app-purchase-content type anymore,
+ // so use older specs from Qbs
+ bundle._useXcodeBuildSpecs: false
Group {
fileTagsFilter: product.type.concat(project.bundleFileTags)
qbs.install: true
diff --git a/tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/ByteArray-Info.plist b/tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/ByteArray-Info.plist
new file mode 100644
index 000000000..df0429f25
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/ByteArray-Info.plist
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>DataKey</key>
+ <!--The data value-->
+ <data>VGhlIGRhdGEgdmFsdWU=</data>
+ <key>StringKey</key>
+ <string>The string value</string>
+</dict>
+</plist>
diff --git a/tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/byteArrayInfoPlist.qbs b/tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/byteArrayInfoPlist.qbs
new file mode 100644
index 000000000..4df0886ff
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/byteArrayInfoPlist.qbs
@@ -0,0 +1,37 @@
+import qbs.BundleTools
+import qbs.TextFile
+
+CppApplication {
+ Depends { name: "bundle" }
+ cpp.minimumMacosVersion: "10.7"
+ files: ["main.c", "ByteArray-Info.plist"]
+ type: base.concat(["txt_output"])
+
+ Properties {
+ condition: qbs.targetOS.includes("darwin")
+ bundle.isBundle: true
+ bundle.identifierPrefix: "com.test"
+ }
+
+ Rule {
+ inputs: ["aggregate_infoplist"]
+ Artifact {
+ filePath: input.fileName + ".out"
+ fileTags: ["txt_output"]
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "generating" + output.fileName + " from " + input.fileName;
+ cmd.highlight = "codegen";
+ cmd.sourceCode = function() {
+ var plist = new BundleTools.infoPlistContents(input.filePath);
+ var content = plist["DataKey"];
+ var int8view = new Uint8Array(content);
+ file = new TextFile(output.filePath, TextFile.WriteOnly);
+ file.write(String.fromCharCode.apply(null, int8view));
+ file.close();
+ }
+ return [cmd];
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/innosetupDependencies/main.c b/tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/main.c
index 76e819701..76e819701 100644
--- a/tests/auto/blackbox/testdata/innosetupDependencies/main.c
+++ b/tests/auto/blackbox/testdata-apple/byteArrayInfoPlist/main.c
diff --git a/tests/auto/blackbox/testdata/path-probe/main.cpp b/tests/auto/blackbox/testdata-apple/codesign/app.cpp
index 76e819701..76e819701 100644
--- a/tests/auto/blackbox/testdata/path-probe/main.cpp
+++ b/tests/auto/blackbox/testdata-apple/codesign/app.cpp
diff --git a/tests/auto/blackbox/testdata-apple/codesign/codesign.qbs b/tests/auto/blackbox/testdata-apple/codesign/codesign.qbs
new file mode 100644
index 000000000..c1fc0502a
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/codesign/codesign.qbs
@@ -0,0 +1,57 @@
+import "../multiarch-helpers.js" as Helpers
+
+Project {
+ name: "p"
+ // we do not have the access to xcode version in qbs.architectures so we need to pass it here
+ property string xcodeVersion
+
+ property bool isBundle: true
+ property bool enableSigning: true
+ property bool multiArch: false
+ property bool multiVariant: false
+
+ CppApplication {
+ name: "A"
+ version: "1.0.0"
+ bundle.isBundle: project.isBundle
+ files: "app.cpp"
+ codesign.enableCodeSigning: project.enableSigning
+ codesign.signingType: "ad-hoc"
+ install: true
+ installDir: ""
+
+ qbs.architectures:
+ multiArch ? Helpers.getArchitectures(qbs, project.xcodeVersion) : []
+ qbs.buildVariants: project.multiVariant ? ["debug", "release"] : []
+ }
+
+ DynamicLibrary {
+ Depends { name: "cpp" }
+ name: "B"
+ version: "1.0.0"
+ bundle.isBundle: project.isBundle
+ files: "app.cpp"
+ codesign.enableCodeSigning: project.enableSigning
+ codesign.signingType: "ad-hoc"
+ install: true
+ installDir: ""
+ qbs.architectures:
+ multiArch ? Helpers.getArchitectures(qbs, project.xcodeVersion) : []
+ qbs.buildVariants: project.multiVariant ? ["debug", "release"] : []
+ }
+
+ LoadableModule {
+ Depends { name: "cpp" }
+ name: "C"
+ version: "1.0.0"
+ bundle.isBundle: project.isBundle
+ files: "app.cpp"
+ codesign.enableCodeSigning: project.enableSigning
+ codesign.signingType: "ad-hoc"
+ install: true
+ installDir: ""
+ qbs.architectures:
+ multiArch ? Helpers.getArchitectures(qbs, project.xcodeVersion) : []
+ qbs.buildVariants: project.multiVariant ? ["debug", "release"] : []
+ }
+}
diff --git a/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs b/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs
index 9eff57b60..2179e9c84 100644
--- a/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs
+++ b/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs
@@ -5,7 +5,7 @@ CppApplication {
// - will actually link (as of Xcode 8.1)
// - exist for the given architecture(s)
cpp.minimumMacosVersion: qbs.architecture === "x86_64h" ? "10.12" : "10.6"
- cpp.minimumIosVersion: ["armv7s", "arm64", "x86_64"].contains(qbs.architecture) ? "7.0" : "6.0"
+ cpp.minimumIosVersion: ["armv7s", "arm64", "x86_64"].includes(qbs.architecture) ? "7.0" : "6.0"
cpp.minimumTvosVersion: "9.0"
cpp.minimumWatchosVersion: "2.0"
diff --git a/tests/auto/blackbox/testdata-apple/frameworkStructure/frameworkStructure.qbs b/tests/auto/blackbox/testdata-apple/frameworkStructure/frameworkStructure.qbs
index a812ae513..3c6d39332 100644
--- a/tests/auto/blackbox/testdata-apple/frameworkStructure/frameworkStructure.qbs
+++ b/tests/auto/blackbox/testdata-apple/frameworkStructure/frameworkStructure.qbs
@@ -2,6 +2,12 @@ Project {
property bool includeHeaders: true
Library {
Depends { name: "cpp" }
+ Depends { name: "bundle" }
+
+ property bool isShallow: {
+ console.info("isShallow: " + bundle.isShallow);
+ return bundle.isShallow;
+ }
name: "Widget"
bundle.isBundle: true
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/100.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/100.png
new file mode 100644
index 000000000..98f8eaeb7
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/100.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/114.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/114.png
new file mode 100644
index 000000000..a14be545e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/114.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/120.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/120.png
new file mode 100644
index 000000000..b910f96df
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/120.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/128.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/128.png
new file mode 100644
index 000000000..7cf0327dc
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/128.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/144.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/144.png
new file mode 100644
index 000000000..c7f18cda1
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/144.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/152.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/152.png
new file mode 100644
index 000000000..af411d7e3
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/152.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/16.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/16.png
new file mode 100644
index 000000000..be3743a22
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/16.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/167.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/167.png
new file mode 100644
index 000000000..855952774
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/167.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/172.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/172.png
new file mode 100644
index 000000000..a410f8bb2
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/172.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/180.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/180.png
new file mode 100644
index 000000000..fcef493f4
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/180.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/196.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/196.png
new file mode 100644
index 000000000..c974bf14a
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/196.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/20.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/20.png
new file mode 100644
index 000000000..25897fc42
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/20.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/216.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/216.png
new file mode 100644
index 000000000..ea0703112
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/216.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/256.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/256.png
new file mode 100644
index 000000000..f1a3ef352
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/256.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/29.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/29.png
new file mode 100644
index 000000000..1f9ef0678
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/29.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/32.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/32.png
new file mode 100644
index 000000000..d969ed1df
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/32.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/40.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/40.png
new file mode 100644
index 000000000..1f76c0b09
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/40.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/48.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/48.png
new file mode 100644
index 000000000..5279cb807
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/48.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/50.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/50.png
new file mode 100644
index 000000000..8045e514d
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/50.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/512.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/512.png
new file mode 100644
index 000000000..c8f3cb758
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/512.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/55.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/55.png
new file mode 100644
index 000000000..c3d8811f6
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/55.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/57.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/57.png
new file mode 100644
index 000000000..5abf4b377
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/57.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/58.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/58.png
new file mode 100644
index 000000000..fc8cf5df5
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/58.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/60.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/60.png
new file mode 100644
index 000000000..ddc66846c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/60.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/64.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/64.png
new file mode 100644
index 000000000..ad87d2af1
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/64.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/72.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/72.png
new file mode 100644
index 000000000..b78c47708
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/72.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/76.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/76.png
new file mode 100644
index 000000000..50bab502d
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/76.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/80.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/80.png
new file mode 100644
index 000000000..6a3a31fa6
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/80.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/87.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/87.png
new file mode 100644
index 000000000..13fb01fef
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/87.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/88.png b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/88.png
new file mode 100644
index 000000000..8eb955ca8
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/88.png
Binary files differ
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/Contents.json b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 000000000..87ae131b9
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/AppIconSet.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,299 @@
+{
+ "images" : [
+ {
+ "filename" : "40.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "60.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "29.png",
+ "idiom" : "iphone",
+ "scale" : "1x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "58.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "87.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "80.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "120.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "57.png",
+ "idiom" : "iphone",
+ "scale" : "1x",
+ "size" : "57x57"
+ },
+ {
+ "filename" : "114.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "57x57"
+ },
+ {
+ "filename" : "120.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "60x60"
+ },
+ {
+ "filename" : "180.png",
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "60x60"
+ },
+ {
+ "filename" : "20.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "40.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "filename" : "29.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "58.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "40.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "80.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "50.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "50x50"
+ },
+ {
+ "filename" : "100.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "50x50"
+ },
+ {
+ "filename" : "72.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "72x72"
+ },
+ {
+ "filename" : "144.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "72x72"
+ },
+ {
+ "filename" : "76.png",
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "76x76"
+ },
+ {
+ "filename" : "152.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "76x76"
+ },
+ {
+ "filename" : "167.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "83.5x83.5"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "scale" : "1x",
+ "size" : "1024x1024"
+ },
+ {
+ "filename" : "48.png",
+ "idiom" : "watch",
+ "role" : "notificationCenter",
+ "scale" : "2x",
+ "size" : "24x24",
+ "subtype" : "38mm"
+ },
+ {
+ "filename" : "55.png",
+ "idiom" : "watch",
+ "role" : "notificationCenter",
+ "scale" : "2x",
+ "size" : "27.5x27.5",
+ "subtype" : "42mm"
+ },
+ {
+ "filename" : "58.png",
+ "idiom" : "watch",
+ "role" : "companionSettings",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "87.png",
+ "idiom" : "watch",
+ "role" : "companionSettings",
+ "scale" : "3x",
+ "size" : "29x29"
+ },
+ {
+ "filename" : "80.png",
+ "idiom" : "watch",
+ "role" : "appLauncher",
+ "scale" : "2x",
+ "size" : "40x40",
+ "subtype" : "38mm"
+ },
+ {
+ "filename" : "88.png",
+ "idiom" : "watch",
+ "role" : "appLauncher",
+ "scale" : "2x",
+ "size" : "44x44",
+ "subtype" : "40mm"
+ },
+ {
+ "filename" : "100.png",
+ "idiom" : "watch",
+ "role" : "appLauncher",
+ "scale" : "2x",
+ "size" : "50x50",
+ "subtype" : "44mm"
+ },
+ {
+ "filename" : "172.png",
+ "idiom" : "watch",
+ "role" : "quickLook",
+ "scale" : "2x",
+ "size" : "86x86",
+ "subtype" : "38mm"
+ },
+ {
+ "filename" : "196.png",
+ "idiom" : "watch",
+ "role" : "quickLook",
+ "scale" : "2x",
+ "size" : "98x98",
+ "subtype" : "42mm"
+ },
+ {
+ "filename" : "216.png",
+ "idiom" : "watch",
+ "role" : "quickLook",
+ "scale" : "2x",
+ "size" : "108x108",
+ "subtype" : "44mm"
+ },
+ {
+ "idiom" : "watch-marketing",
+ "scale" : "1x",
+ "size" : "1024x1024"
+ },
+ {
+ "filename" : "16.png",
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "16x16"
+ },
+ {
+ "filename" : "32.png",
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "16x16"
+ },
+ {
+ "filename" : "32.png",
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "32x32"
+ },
+ {
+ "filename" : "64.png",
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "32x32"
+ },
+ {
+ "filename" : "128.png",
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "128x128"
+ },
+ {
+ "filename" : "256.png",
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "128x128"
+ },
+ {
+ "filename" : "256.png",
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "256x256"
+ },
+ {
+ "filename" : "512.png",
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "256x256"
+ },
+ {
+ "filename" : "512.png",
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "512x512"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "512x512"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/tests/auto/blackbox/testdata-apple/ib/appiconset/appiconset.qbs b/tests/auto/blackbox/testdata-apple/ib/appiconset/appiconset.qbs
new file mode 100644
index 000000000..2015032ea
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/appiconset.qbs
@@ -0,0 +1,10 @@
+CppApplication {
+ Depends { name: "ib" }
+ Depends { name: "bundle" }
+ property bool isShallow: {
+ console.info("bundle.isShallow: " + bundle.isShallow);
+ return bundle.isShallow;
+ }
+ files: ["main.c", "AppIconSet.xcassets"]
+ ib.appIconName: "AppIcon"
+}
diff --git a/tests/auto/blackbox/testdata/wixDependencies/main.c b/tests/auto/blackbox/testdata-apple/ib/appiconset/main.c
index 76e819701..76e819701 100644
--- a/tests/auto/blackbox/testdata/wixDependencies/main.c
+++ b/tests/auto/blackbox/testdata-apple/ib/appiconset/main.c
diff --git a/tests/auto/blackbox/testdata-apple/ib/assetcatalog/assetcatalogempty.qbs b/tests/auto/blackbox/testdata-apple/ib/assetcatalog/assetcatalogempty.qbs
index 622fa46cb..d06e24eb3 100644
--- a/tests/auto/blackbox/testdata-apple/ib/assetcatalog/assetcatalogempty.qbs
+++ b/tests/auto/blackbox/testdata-apple/ib/assetcatalog/assetcatalogempty.qbs
@@ -1,6 +1,13 @@
+import qbs.Host
import qbs.Utilities
Project {
+ condition: {
+ var result = qbs.targetOS.includes("macos");
+ if (!result)
+ console.info("Skip this test");
+ return result;
+ }
property bool includeIconset
CppApplication {
@@ -11,7 +18,8 @@ Project {
filez.push("empty.xcassets/empty.iconset");
else if (Utilities.versionCompare(xcode.version, "5") >= 0)
filez.push("empty.xcassets");
- if (qbs.hostOSVersionMinor >= 10 // need macOS 10.10 to build SBs
+ if ((Host.osVersionMajor() >= 11
+ || Host.osVersionMinor() >= 10) // need macOS 10.10 or higher to build SBs
&& cpp.minimumMacosVersion !== undefined
&& Utilities.versionCompare(cpp.minimumMacosVersion, "10.10") >= 0)
filez.push("Storyboard.storyboard");
diff --git a/tests/auto/blackbox/testdata-apple/ib/iconsetapp/iconsetapp.qbs b/tests/auto/blackbox/testdata-apple/ib/iconsetapp/iconsetapp.qbs
index 04e6ce0ce..dd39d1639 100644
--- a/tests/auto/blackbox/testdata-apple/ib/iconsetapp/iconsetapp.qbs
+++ b/tests/auto/blackbox/testdata-apple/ib/iconsetapp/iconsetapp.qbs
@@ -1,4 +1,9 @@
CppApplication {
Depends { name: "ib" }
+ Depends { name: "bundle" }
+ property bool isShallow: {
+ console.info("isShallow: " + bundle.isShallow);
+ return bundle.isShallow;
+ }
files: ["main.c", "white.iconset"]
}
diff --git a/tests/auto/blackbox/testdata-apple/infoPlistVariables/Info.plist b/tests/auto/blackbox/testdata-apple/infoPlistVariables/Info.plist
new file mode 100644
index 000000000..cb879d70c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/infoPlistVariables/Info.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Curly</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>Braces</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>At</key>
+ <string>@EXECUTABLE_NAME@</string>
+ <key>CurlyMult</key>
+ <string>${EXECUTABLE_NAME}_${PRODUCT_NAME}</string>
+ <key>BracesMult</key>
+ <string>$(EXECUTABLE_NAME)_$(PRODUCT_NAME)</string>
+ <key>AtMult</key>
+ <string>@EXECUTABLE_NAME@_@PRODUCT_NAME@</string>
+ <key>CurlyNested</key>
+ <string>${${EXE}_NAME}</string>
+ <key>BracesNested</key>
+ <string>${${EXE}_NAME}</string>
+ <key>WithDefault</key>
+ <string>${NON_EXISTING:default=DEFAULT}</string>
+</dict>
+</plist>
diff --git a/tests/auto/blackbox/testdata-apple/infoPlistVariables/infoPlistVariables.qbs b/tests/auto/blackbox/testdata-apple/infoPlistVariables/infoPlistVariables.qbs
new file mode 100644
index 000000000..47ca80f07
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/infoPlistVariables/infoPlistVariables.qbs
@@ -0,0 +1,16 @@
+CppApplication {
+ Depends { name: "bundle" }
+ cpp.minimumMacosVersion: "10.7"
+ files: ["main.c", "Info.plist"]
+
+ Properties {
+ condition: qbs.targetOS.includes("darwin")
+ bundle.isBundle: true
+ bundle.identifierPrefix: "com.test"
+ bundle.extraEnv: {
+ var result = original;
+ result["EXE"] = "EXECUTABLE";
+ return result;
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-apple/infoPlistVariables/main.c b/tests/auto/blackbox/testdata-apple/infoPlistVariables/main.c
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/infoPlistVariables/main.c
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/tests/auto/blackbox/testdata-apple/multiarch-helpers.js b/tests/auto/blackbox/testdata-apple/multiarch-helpers.js
new file mode 100644
index 000000000..a8054b63c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/multiarch-helpers.js
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://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 Utilities = require("qbs.Utilities");
+
+// Typically, multiple architectures are used for migration from "old" arch to a "new" one
+// For example: x86 -> x86_64 on macOS, armv7 -> arm64 on iOS
+
+function enableOldArch(qbs, xcodeVersion) {
+ return qbs.targetOS.includes("macos")
+ && xcodeVersion
+ && (Utilities.versionCompare(xcodeVersion, "10") < 0
+ || Utilities.versionCompare(xcodeVersion, "12.2") >= 0)
+ || qbs.targetOS.includes("ios")
+}
+
+function getNewArch(qbs, xcodeVersion) {
+ if (qbs.targetOS.includes("macos"))
+ return xcodeVersion
+ && Utilities.versionCompare(xcodeVersion, "12.2") >= 0 ? "arm64" : "x86_64";
+ else if (qbs.targetOS.includes("ios-simulator"))
+ return "x86_64"
+ else if (qbs.targetOS.includes("ios"))
+ return "arm64"
+ else if (qbs.targetOS.includes("tvos"))
+ return "arm64"
+ else if (qbs.targetOS.includes("watchos"))
+ return "armv7k"
+ throw "unsupported targetOS: " + qbs.targetOS;
+}
+
+function getOldArch(qbs, xcodeVersion) {
+ if (qbs.targetOS.includes("macos"))
+ return xcodeVersion
+ && Utilities.versionCompare(xcodeVersion, "12.2") >= 0 ? "x86_64" : "x86";
+ else if (qbs.targetOS.includes("ios-simulator"))
+ return "x86"
+ else if (qbs.targetOS.includes("ios"))
+ return "armv7a"
+ throw "unsupported targetOS: " + qbs.targetOS;
+}
+
+function getArchitectures(qbs, xcodeVersion) {
+ return enableOldArch(qbs, xcodeVersion)
+ ? [getOldArch(qbs, xcodeVersion), getNewArch(qbs, xcodeVersion)]
+ : [getNewArch(qbs, xcodeVersion)];
+}
diff --git a/tests/auto/blackbox/testdata-apple/objc-arc/objc-arc.qbs b/tests/auto/blackbox/testdata-apple/objc-arc/objc-arc.qbs
index 545d5701c..ce128059f 100644
--- a/tests/auto/blackbox/testdata-apple/objc-arc/objc-arc.qbs
+++ b/tests/auto/blackbox/testdata-apple/objc-arc/objc-arc.qbs
@@ -2,7 +2,7 @@ Product {
Depends { name: "cpp" }
consoleApplication: true
type: ["application"]
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
Group {
cpp.automaticReferenceCounting: true
diff --git a/tests/auto/blackbox/testdata-apple/overrideInfoPlist/Override-Info.plist b/tests/auto/blackbox/testdata-apple/overrideInfoPlist/Override-Info.plist
new file mode 100644
index 000000000..f2621e983
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/overrideInfoPlist/Override-Info.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>DefaultValue</key>
+ <string>The default value</string>
+ <key>OverriddenValue</key>
+ <string>The default value</string>
+</dict>
+</plist>
diff --git a/tests/auto/blackbox/testdata-apple/overrideInfoPlist/main.c b/tests/auto/blackbox/testdata-apple/overrideInfoPlist/main.c
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/overrideInfoPlist/main.c
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/tests/auto/blackbox/testdata-apple/overrideInfoPlist/overrideInfoPlist.qbs b/tests/auto/blackbox/testdata-apple/overrideInfoPlist/overrideInfoPlist.qbs
new file mode 100644
index 000000000..270a0792c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-apple/overrideInfoPlist/overrideInfoPlist.qbs
@@ -0,0 +1,16 @@
+CppApplication {
+ Depends { name: "bundle" }
+ cpp.minimumMacosVersion: "10.7"
+ files: ["main.c", "Override-Info.plist"]
+
+ Properties {
+ condition: qbs.targetOS.includes("darwin")
+ bundle.isBundle: true
+ bundle.identifierPrefix: "com.test"
+
+ bundle.infoPlist: ({
+ "CFBundleName": "My Bundle",
+ "OverriddenValue": "The overridden value",
+ })
+ }
+}
diff --git a/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs b/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs
index fbab6d0b1..e7bf4739a 100644
--- a/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs
+++ b/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs
@@ -16,19 +16,19 @@ Project {
console.info("Available SDK versions: " + xcode.availableSdkVersions.join(", "));
var targetOsToKey = function(targetOS) {
- if (targetOS.contains("ios"))
+ if (targetOS.includes("ios"))
return "iphoneos";
- if (targetOS.contains("ios-simulator"))
+ if (targetOS.includes("ios-simulator"))
return "iphonesimulator";
- if (targetOS.contains("macos"))
+ if (targetOS.includes("macos"))
return "macosx";
- if (targetOS.contains("tvos"))
+ if (targetOS.includes("tvos"))
return "appletvos";
- if (targetOS.contains("tvos-simulator"))
+ if (targetOS.includes("tvos-simulator"))
return "appletvsimulator";
- if (targetOS.contains("watchos"))
+ if (targetOS.includes("watchos"))
return "watchos";
- if (targetOS.contains("watchos-simulator"))
+ if (targetOS.includes("watchos-simulator"))
return "watchossimulator";
throw "Unsupported OS" + targetOS;
}
@@ -43,8 +43,11 @@ Project {
}
for (var i = 0; i < a.length; ++i) {
- if (a[i] !== b[i]) {
- throw msg;
+ var version1 = a[i].split('.');
+ var version2 = b[i].split('.');
+ for (var j = 0; j < version1.length; ++j) {
+ if (version1[j] !== version2[j])
+ throw msg;
}
}
}
diff --git a/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs b/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs
new file mode 100644
index 000000000..7a35e4e13
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/BareMetalApplication.qbs
@@ -0,0 +1,29 @@
+import qbs.Host
+
+BareMetalProduct {
+ type: "application"
+ consoleApplication: true
+
+ property bool dummy: {
+ if (qbs.targetPlatform !== Host.platform()
+ || qbs.architecture !== Host.architecture()) {
+
+ function supportsCrossRun() {
+ // We can run 32 bit applications on 64 bit Windows.
+ if (Host.platform() === "windows" && Host.architecture() === "x86_64"
+ && qbs.targetPlatform === "windows" && qbs.architecture === "x86") {
+ return true;
+ }
+ }
+
+ if (!supportsCrossRun())
+ console.info("targetPlatform differs from hostPlatform")
+ }
+ }
+
+ Group {
+ condition: qbs.toolchain.includes("cosmic")
+ files: "cosmic.lkf"
+ fileTags: "linkerscript"
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs b/tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs
new file mode 100644
index 000000000..446cfe086
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/BareMetalProduct.qbs
@@ -0,0 +1,158 @@
+Product {
+ Depends { name: "cpp" }
+ cpp.positionIndependentCode: false
+ Properties {
+ condition: qbs.toolchain.includes("iar")
+ && qbs.architecture === "stm8"
+ cpp.driverLinkerFlags: [
+ "--config_def", "_CSTACK_SIZE=0x100",
+ "--config_def", "_HEAP_SIZE=0x100",
+ ]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("iar")
+ && qbs.architecture === "rl78"
+ cpp.driverLinkerFlags: [
+ "--config_def", "_NEAR_HEAP_SIZE=256",
+ "--config_def", "_FAR_HEAP_SIZE=4096",
+ "--config_def", "_HUGE_HEAP_SIZE=0",
+ "--config_def", "_STACK_SIZE=128",
+ "--config_def", "_NEAR_CONST_LOCATION_SIZE=0x6F00",
+ "--config_def", "_NEAR_CONST_LOCATION_START=0x3000",
+ "--define_symbol", "_NEAR_CONST_LOCATION=0",
+ "--config", cpp.toolchainInstallPath + "/../config/lnkrl78_s3.icf"
+ ]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("iar")
+ && qbs.architecture === "rh850"
+ cpp.driverLinkerFlags: [
+ "--config_def", "CSTACK_SIZE=0x1000",
+ "--config_def", "HEAP_SIZE=0x1000",
+ "--config", cpp.toolchainInstallPath + "/../config/lnkrh850_g3m.icf"
+ ]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("iar")
+ && qbs.architecture === "v850"
+ cpp.driverLinkerFlags: [
+ "-D_CSTACK_SIZE=1000",
+ "-D_HEAP_SIZE=1000",
+ "-f", cpp.toolchainInstallPath + "/../config/lnk85.xcl"
+ ]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("iar")
+ && qbs.architecture === "78k"
+ cpp.commonCompilerFlags: [
+ "--core", "78k0",
+ "--code_model", "standard"
+ ]
+ cpp.driverLinkerFlags: [
+ "-D_CSTACK_SIZE=80",
+ "-D_HEAP_SIZE=200",
+ "-D_CODEBANK_START=0",
+ "-D_CODEBANK_END=0",
+ "-D_CODEBANK_BANKS=0",
+ "-f", cpp.toolchainInstallPath + "/../config/lnk.xcl",
+ cpp.toolchainInstallPath + "/../lib/clib/cl78ks1.r26"
+ ]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("iar")
+ && qbs.architecture === "sh"
+ cpp.driverLinkerFlags: [
+ "--config_def", "_CSTACK_SIZE=0x800",
+ "--config_def", "_HEAP_SIZE=0x800",
+ "--config_def", "_INT_TABLE=0x10",
+ "--config", cpp.toolchainInstallPath + "/../config/generic.icf"
+ ]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("iar")
+ && qbs.architecture === "hcs8"
+ cpp.driverLinkerFlags: [
+ "-D_CSTACK_SIZE=200",
+ "-D_HEAP_SIZE=200",
+ "-f", cpp.toolchainInstallPath + "/../config/lnkunspecifieds08.xcl"
+ ]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("iar")
+ && qbs.architecture === "m32c"
+ cpp.driverLinkerFlags: [
+ "-D_CSTACK_SIZE=100",
+ "-D_NEAR_HEAP_SIZE=400",
+ "-D_FAR_HEAP_SIZE=400",
+ "-D_HUGE_HEAP_SIZE=400",
+ "-D_ISTACK_SIZE=40",
+ "-f", cpp.toolchainInstallPath + "/../config/lnkm32c.xcl",
+ cpp.toolchainInstallPath + (qbs.debugInformation ? "/../lib/dlib/dlm32cnf.r48" : "/../lib/clib/clm32cf.r48")
+ ]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("iar")
+ && qbs.architecture === "riscv"
+ cpp.driverLinkerFlags: [
+ "--config_def", "CSTACK_SIZE=0x1000",
+ "--config_def", "HEAP_SIZE=0x1000"
+ ]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("iar")
+ && qbs.architecture === "m68k"
+ cpp.cFlags: [
+ "--no_div"
+ ]
+ cpp.driverLinkerFlags: [
+ "-D__FLASHBEGIN=0",
+ "-D__FLASHEND=1FFFF",
+ "-D__RAMBEGIN=800000",
+ "-D__RAMEND=803FFF",
+ "-D_CSTACK_SIZE=200",
+ "-D_HEAP_SIZE=1000",
+ "-D_VBR_ADDRESS=0",
+ "-f", cpp.toolchainInstallPath + "/../config/lnkm51ac128.xcl",
+ cpp.toolchainInstallPath + "/../lib/dlcfcffdn.r68"
+ ]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("keil")
+ && qbs.architecture.startsWith("arm")
+ && cpp.compilerName.startsWith("armcc")
+ cpp.assemblerFlags: ["--cpu", "cortex-m0"]
+ cpp.commonCompilerFlags: ["--cpu", "cortex-m0"]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("keil")
+ && qbs.architecture.startsWith("arm")
+ && cpp.compilerName.startsWith("armclang")
+ cpp.assemblerFlags: ["--cpu", "cortex-m0"]
+ cpp.commonCompilerFlags: ["-mcpu=cortex-m0", "--target=arm-arm-none-eabi"]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("gcc")
+ && qbs.architecture.startsWith("arm")
+ cpp.driverFlags: ["-specs=nosys.specs"]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("gcc")
+ && qbs.architecture === "xtensa"
+ cpp.driverFlags: ["-nostdlib"]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("gcc")
+ && qbs.architecture === "msp430"
+ cpp.driverFlags: ["-mmcu=msp430f5529", "-nostdlib"]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("gcc")
+ && qbs.architecture === "m32r"
+ cpp.driverFlags: ["-nostdlib"]
+ }
+ Properties {
+ condition: qbs.toolchain.includes("gcc")
+ && qbs.architecture === "riscv"
+ cpp.driverFlags: ["-nostdlib"]
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/BareMetalStaticLibrary.qbs b/tests/auto/blackbox/testdata-baremetal/BareMetalStaticLibrary.qbs
new file mode 100644
index 000000000..7259b1446
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/BareMetalStaticLibrary.qbs
@@ -0,0 +1,3 @@
+BareMetalProduct {
+ type: "staticlibrary"
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/app.c b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/app.c
new file mode 100644
index 000000000..58fe69254
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/app.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/compiler-defines-by-language.qbs b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/compiler-defines-by-language.qbs
new file mode 100644
index 000000000..73365ada4
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/compiler-defines-by-language.qbs
@@ -0,0 +1,73 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+Project {
+ property bool supportsCpp: {
+ if (qbs.toolchain.includes("cosmic"))
+ return false;
+ if (qbs.toolchain.includes("sdcc"))
+ return false;
+ if (qbs.toolchain.includes("keil")) {
+ if (qbs.architecture === "mcs51"
+ || qbs.architecture === "mcs251"
+ || qbs.architecture === "c166") {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ BareMetalApplication {
+ name: "c_language"
+ files: ["app.c", "ctest.c"]
+ cpp.enableCompilerDefinesByLanguage: []
+ property var foo: {
+ if (!cpp.compilerDefinesByLanguage)
+ throw "ASSERT cpp.compilerDefinesByLanguage: "
+ + cpp.compilerDefinesByLanguage;
+ if (!cpp.compilerDefinesByLanguage["c"])
+ throw "ASSERT cpp.compilerDefinesByLanguage[\"c\"]: "
+ + cpp.compilerDefinesByLanguage["c"];
+ if (cpp.compilerDefinesByLanguage["cpp"])
+ throw "ASSERT !cpp.compilerDefinesByLanguage[\"cpp\"]: "
+ + cpp.compilerDefinesByLanguage["cpp"];
+ }
+ }
+
+ BareMetalApplication {
+ condition: supportsCpp
+ name: "cpp_language"
+ files: ["app.c", "cpptest.cpp"]
+ cpp.enableCompilerDefinesByLanguage: ["cpp"]
+ cpp.enableExceptions: false
+ property var foo: {
+ if (!cpp.compilerDefinesByLanguage)
+ throw "ASSERT cpp.compilerDefinesByLanguage: "
+ + cpp.compilerDefinesByLanguage;
+ if (cpp.compilerDefinesByLanguage["c"])
+ throw "ASSERT !cpp.compilerDefinesByLanguage[\"c\"]: "
+ + cpp.compilerDefinesByLanguage["c"];
+ if (!cpp.compilerDefinesByLanguage["cpp"])
+ throw "ASSERT cpp.compilerDefinesByLanguage[\"cpp\"]: "
+ + cpp.compilerDefinesByLanguage["cpp"];
+ }
+ }
+
+ BareMetalApplication {
+ condition: supportsCpp
+ name: "c_and_cpp_language"
+ files: ["app.c", "ctest.c", "cpptest.cpp"]
+ cpp.enableCompilerDefinesByLanguage: ["c", "cpp"]
+ cpp.enableExceptions: false
+ property var foo: {
+ if (!cpp.compilerDefinesByLanguage)
+ throw "ASSERT cpp.compilerDefinesByLanguage: "
+ + cpp.compilerDefinesByLanguage;
+ if (!cpp.compilerDefinesByLanguage["c"])
+ throw "ASSERT cpp.compilerDefinesByLanguage[\"c\"]: "
+ + cpp.compilerDefinesByLanguage["c"];
+ if (!cpp.compilerDefinesByLanguage["cpp"])
+ throw "ASSERT cpp.compilerDefinesByLanguage[\"cpp\"]: "
+ + cpp.compilerDefinesByLanguage["cpp"];
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/cpptest.cpp b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/cpptest.cpp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/cpptest.cpp
diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/ctest.c b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/ctest.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-defines-by-language/ctest.c
diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/compiler-include-paths.qbs b/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/compiler-include-paths.qbs
new file mode 100644
index 000000000..5c73302ad
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/compiler-include-paths.qbs
@@ -0,0 +1,9 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ files: ["main.c"]
+ property bool dummy: {
+ console.info("compilerIncludePaths: %%" + cpp.compilerIncludePaths + "%%");
+ return true;
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/main.c b/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/main.c
new file mode 100644
index 000000000..58fe69254
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-include-paths/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-listing/compiler-listing.qbs b/tests/auto/blackbox/testdata-baremetal/compiler-listing/compiler-listing.qbs
new file mode 100644
index 000000000..6bd51e3bd
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-listing/compiler-listing.qbs
@@ -0,0 +1,14 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ condition: {
+ if (!qbs.toolchain.includes("gcc")) {
+ console.info("compiler listing suffix: %%" + cpp.compilerListingSuffix + "%%");
+ return true;
+ }
+ console.info("unsupported toolset: %%"
+ + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%");
+ return false;
+ }
+ files: ["main.c", "fun.c"]
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-listing/fun.c b/tests/auto/blackbox/testdata-baremetal/compiler-listing/fun.c
new file mode 100644
index 000000000..3b8c8f2f4
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-listing/fun.c
@@ -0,0 +1,4 @@
+int f(void)
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/compiler-listing/main.c b/tests/auto/blackbox/testdata-baremetal/compiler-listing/main.c
new file mode 100644
index 000000000..2c3d7726c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/compiler-listing/main.c
@@ -0,0 +1,6 @@
+extern int f(void);
+
+int main(void)
+{
+ return f();
+}
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/defines/defines.qbs b/tests/auto/blackbox/testdata-baremetal/defines/defines.qbs
new file mode 100644
index 000000000..b257a8a4b
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/defines/defines.qbs
@@ -0,0 +1,6 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ cpp.defines: ["FOO", "BAR"]
+ files: ["main.c"]
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/defines/main.c b/tests/auto/blackbox/testdata-baremetal/defines/main.c
new file mode 100644
index 000000000..d2d4769e4
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/defines/main.c
@@ -0,0 +1,11 @@
+#ifndef FOO
+#error FOO missing!
+#endif
+#ifndef BAR
+#error BAR missing!
+#endif
+
+int main(void)
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/bar/bar.h b/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/bar/bar.h
new file mode 100644
index 000000000..49ffa0b12
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/bar/bar.h
@@ -0,0 +1,6 @@
+#ifndef BAR_H
+#define BAR_H
+
+#define BAR_VALUE 1
+
+#endif // BAR_H
diff --git a/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/distribution-include-paths.qbs b/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/distribution-include-paths.qbs
new file mode 100644
index 000000000..0fded6a46
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/distribution-include-paths.qbs
@@ -0,0 +1,6 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ files: ["main.c"]
+ cpp.distributionIncludePaths: ["foo", "bar"]
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/foo/foo.h b/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/foo/foo.h
new file mode 100644
index 000000000..dc510379d
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/foo/foo.h
@@ -0,0 +1,6 @@
+#ifndef FOO_H
+#define FOO_H
+
+#define FOO_VALUE 1
+
+#endif // FOO_H
diff --git a/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/main.c b/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/main.c
new file mode 100644
index 000000000..aabc97a0c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/distribution-include-paths/main.c
@@ -0,0 +1,7 @@
+#include <foo.h>
+#include <bar.h>
+
+int main(void)
+{
+ return FOO_VALUE - BAR_VALUE;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs
new file mode 100644
index 000000000..7336e3970
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/external-static-libraries.qbs
@@ -0,0 +1,34 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+import "../BareMetalStaticLibrary.qbs" as BareMetalStaticLibrary
+
+Project {
+ property string outputLibrariesDirectory: buildDirectory + "/libs"
+ BareMetalStaticLibrary {
+ name: "lib-a"
+ destinationDirectory: project.outputLibrariesDirectory
+ Depends { name: "cpp" }
+ Properties {
+ condition: qbs.targetOS.includes("darwin")
+ bundle.isBundle: false
+ }
+ files: ["lib-a.c"]
+ }
+ BareMetalStaticLibrary {
+ name: "lib-b"
+ destinationDirectory: project.outputLibrariesDirectory
+ Depends { name: "cpp" }
+ Depends { name: "lib-a" }
+ Properties {
+ condition: qbs.targetOS.includes("darwin")
+ bundle.isBundle: false
+ }
+ files: ["lib-b.c"]
+ }
+ BareMetalApplication {
+ Depends { name: "lib-a"; cpp.link: false }
+ Depends { name: "lib-b"; cpp.link: false }
+ files: ["main.c"]
+ cpp.libraryPaths: [project.outputLibrariesDirectory]
+ cpp.staticLibraries: ["lib-b", "lib-a"]
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/external-static-libraries/lib-a.c b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/lib-a.c
new file mode 100644
index 000000000..13401861f
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/lib-a.c
@@ -0,0 +1,4 @@
+int a(void)
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/external-static-libraries/lib-b.c b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/lib-b.c
new file mode 100644
index 000000000..5d45b8175
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/lib-b.c
@@ -0,0 +1,6 @@
+extern int a(void);
+
+int b(void)
+{
+ return a();
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/external-static-libraries/main.c b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/main.c
new file mode 100644
index 000000000..84ef5e51e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/external-static-libraries/main.c
@@ -0,0 +1,6 @@
+extern int b();
+
+int main(void)
+{
+ return b();
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs b/tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs
new file mode 100644
index 000000000..fe93ac144
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/linker-map/linker-map.qbs
@@ -0,0 +1,8 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ property bool dummy: {
+ console.info("linker map suffix: %%" + cpp.linkerMapSuffix + "%%");
+ }
+ files: ["main.c"]
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/linker-map/main.c b/tests/auto/blackbox/testdata-baremetal/linker-map/main.c
new file mode 100644
index 000000000..58fe69254
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/linker-map/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-application/main.c b/tests/auto/blackbox/testdata-baremetal/one-object-application/main.c
new file mode 100644
index 000000000..58fe69254
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-application/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-application/one-object-application.qbs b/tests/auto/blackbox/testdata-baremetal/one-object-application/one-object-application.qbs
new file mode 100644
index 000000000..482425b5f
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-application/one-object-application.qbs
@@ -0,0 +1,5 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ files: ["main.c"]
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/78k-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/78k-iar.s
new file mode 100644
index 000000000..25f0e2bbd
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/78k-iar.s
@@ -0,0 +1,6 @@
+ PUBLIC main
+ RSEG CODE:CODE:NOROOT(0)
+main:
+ MOVW AX, #0
+ RET
+ END
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/arm-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-gcc.s
new file mode 100644
index 000000000..c7b894230
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-gcc.s
@@ -0,0 +1,5 @@
+ .global main
+ .type main, %function
+main:
+ mov r0, #0
+ bx lr
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-iar.s
new file mode 100644
index 000000000..0a13a5dc2
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC main
+ SECTION `.text`:CODE:NOROOT(1)
+ THUMB
+main:
+ MOVS R0, #+0
+ BX LR
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-keil.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-keil.s
new file mode 100644
index 000000000..f3fcd50fe
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/arm-keil.s
@@ -0,0 +1,7 @@
+ THUMB
+ AREA ||.text||, CODE, READONLY, ALIGN = 1
+main PROC
+ MOVS r0, #0
+ BX lr
+ ENDP
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr-gcc.s
new file mode 100644
index 000000000..4ba005a47
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr-gcc.s
@@ -0,0 +1,6 @@
+ .global main
+ .type main, %function
+main:
+ ldi r24, 0
+ ldi r25, 0
+ ret
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr-iar.s
new file mode 100644
index 000000000..49e9d476e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC main
+ RSEG CODE:CODE:NOROOT(1)
+main:
+ LDI R16, 0
+ LDI R17, 0
+ RET
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr32-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr32-gcc.s
new file mode 100644
index 000000000..879e54150
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr32-gcc.s
@@ -0,0 +1,8 @@
+ .global main
+ .type main, @function
+main:
+ stm --sp, r7, lr
+ mov r7, sp
+ mov r8, 0
+ mov r12, r8
+ ldm sp++, r7, pc
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr32-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr32-iar.s
new file mode 100644
index 000000000..c5e78896f
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/avr32-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC main
+ RSEG CODE32:CODE:REORDER:NOROOT(2)
+ CODE
+main:
+ MOV R12, 0x0
+ RET R12
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/c166-keil.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/c166-keil.s
new file mode 100644
index 000000000..394bc2ae4
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/c166-keil.s
@@ -0,0 +1,7 @@
+MAIN_SEG SECTION CODE WORD 'NCODE'
+main PROC NEAR
+ MOV R4, #0
+ RET
+main ENDP
+MAIN_SEG ENDS
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/cr16-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/cr16-iar.s
new file mode 100644
index 000000000..4a14de6a1
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/cr16-iar.s
@@ -0,0 +1,6 @@
+ PUBLIC main
+ RSEG CODE:CODE:NOROOT(0)
+main:
+ MOVW $0, R0
+ JUMP (RA)
+ 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/hcs12-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs12-iar.s
new file mode 100644
index 000000000..4344e757f
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs12-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC main
+ RSEG CODE:CODE:REORDER:NOROOT(0)
+main:
+ CLRB
+ CLRA
+ RTS
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-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/hcs8-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-iar.s
new file mode 100644
index 000000000..883dfdcad
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-iar.s
@@ -0,0 +1,6 @@
+ PUBLIC main
+ RSEG CODE:CODE:REORDER:NOROOT(0)
+main:
+ LDHX #0x0000
+ RTS
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-sdcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-sdcc.s
new file mode 100644
index 000000000..f47fed1be
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/hcs8-sdcc.s
@@ -0,0 +1,6 @@
+ .globl main
+ .area DSEG (PAG)
+ .area HOME (CODE)
+main:
+ clra
+ tax
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m16c-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m16c-iar.s
new file mode 100644
index 000000000..4153f290e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m16c-iar.s
@@ -0,0 +1,6 @@
+ PUBLIC main
+ RSEG CODE:CODE:REORDER:NOROOT(0)
+main:
+ MOV.W #0x0, R0
+ RTS
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-gcc.s
new file mode 100644
index 000000000..173c04c39
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-gcc.s
@@ -0,0 +1,5 @@
+ .global _main
+ .type _main, @function
+_main:
+ mov.w #0, r0
+ rts
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-iar.s
new file mode 100644
index 000000000..4153f290e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32c-iar.s
@@ -0,0 +1,6 @@
+ PUBLIC main
+ RSEG CODE:CODE:REORDER:NOROOT(0)
+main:
+ MOV.W #0x0, R0
+ RTS
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32r-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32r-gcc.s
new file mode 100644
index 000000000..dfcf42ca1
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m32r-gcc.s
@@ -0,0 +1,9 @@
+ .global main
+ .type main, @function
+main:
+ push fp
+ mv fp, sp
+ ldi r4, #0
+ mv r0, r4
+ pop fp
+ jmp lr
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/m68k-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-gcc.s
new file mode 100644
index 000000000..fdde81dae
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-gcc.s
@@ -0,0 +1,7 @@
+ .global main
+ .type main, @function
+main:
+ link.w %fp, #0
+ clr.l %d0
+ unlk %fp
+ rts
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-iar.s
new file mode 100644
index 000000000..9811be134
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/m68k-iar.s
@@ -0,0 +1,6 @@
+ PUBLIC main
+ RSEG FCODE:CODE:NOROOT(1)
+main:
+ CLR.L D0
+ RTS
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs251-keil.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs251-keil.s
new file mode 100644
index 000000000..312cc9680
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs251-keil.s
@@ -0,0 +1,8 @@
+PUBLIC main
+MAIN_SEG SEGMENT CODE
+ RSEG MAIN_SEG
+main PROC
+ XRL WR6,WR6
+ RET
+ ENDP
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-iar.s
new file mode 100644
index 000000000..09cc64613
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC main
+ RSEG NEAR_CODE:CODE:NOROOT(0)
+main:
+ MOV R2, #0x0
+ MOV R3, #0x0
+ RET
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-keil.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-keil.s
new file mode 100644
index 000000000..28174d0e2
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-keil.s
@@ -0,0 +1,8 @@
+PUBLIC main
+MAIN_SEG SEGMENT CODE
+ RSEG MAIN_SEG
+main:
+ MOV R6, #0x0
+ MOV R7, #0x0
+ RET
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-sdcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-sdcc.s
new file mode 100644
index 000000000..eaa6467e3
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/mcs51-sdcc.s
@@ -0,0 +1,7 @@
+ .globl main
+ .area PSEG (PAG,XDATA)
+ .area XSEG (XDATA)
+ .area HOME (CODE)
+main:
+ mov dptr, #0x0000
+ ret
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/msp430-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/msp430-gcc.s
new file mode 100644
index 000000000..8e8a24980
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/msp430-gcc.s
@@ -0,0 +1,5 @@
+ .global main
+ .type main, %function
+main:
+ mov #0, r15
+ .LIRD0:
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/msp430-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/msp430-iar.s
new file mode 100644
index 000000000..fbabe3ba8
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/msp430-iar.s
@@ -0,0 +1,6 @@
+ PUBLIC main
+ RSEG `CODE`:CODE:REORDER:NOROOT(1)
+main:
+ MOV.W #0x0, R12
+ RET
+ 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
new file mode 100644
index 000000000..e8805225c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/one-object-asm-application.qbs
@@ -0,0 +1,122 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ condition: {
+ 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")
+ return true;
+ if (qbs.architecture === "mcs251")
+ return true;
+ if (qbs.architecture === "c166")
+ return true;
+ } else if (qbs.toolchainType === "iar") {
+ if (qbs.architecture.startsWith("arm"))
+ return true;
+ if (qbs.architecture === "mcs51")
+ return true;
+ if (qbs.architecture === "stm8")
+ return true;
+ if (qbs.architecture === "avr")
+ return true;
+ if (qbs.architecture === "avr32")
+ return true;
+ if (qbs.architecture === "msp430")
+ return true;
+ if (qbs.architecture === "rl78")
+ return true;
+ if (qbs.architecture === "rh850")
+ return true;
+ if (qbs.architecture === "v850")
+ return true;
+ if (qbs.architecture === "78k")
+ return true;
+ if (qbs.architecture === "r32c")
+ return true;
+ if (qbs.architecture === "sh")
+ return true;
+ if (qbs.architecture === "cr16")
+ return true;
+ if (qbs.architecture === "m16c")
+ return true;
+ if (qbs.architecture === "hcs8")
+ return true;
+ if (qbs.architecture === "hcs12")
+ return true;
+ if (qbs.architecture === "rx")
+ return true;
+ if (qbs.architecture === "m32c")
+ return true;
+ if (qbs.architecture === "riscv")
+ return true;
+ if (qbs.architecture === "m68k")
+ return true;
+ } else if (qbs.toolchainType === "sdcc") {
+ if (qbs.architecture === "mcs51")
+ return true;
+ if (qbs.architecture === "stm8")
+ return true;
+ if (qbs.architecture === "hcs8")
+ return true;
+ } else if (qbs.toolchainType === "gcc") {
+ if (qbs.architecture.startsWith("arm"))
+ return true;
+ if (qbs.architecture === "avr")
+ return true;
+ if (qbs.architecture === "avr32")
+ return true;
+ if (qbs.architecture === "msp430")
+ return true;
+ if (qbs.architecture === "xtensa")
+ return true;
+ if (qbs.architecture === "rl78")
+ return true;
+ if (qbs.architecture === "m32c")
+ return true;
+ if (qbs.architecture === "m32r")
+ return true;
+ if (qbs.architecture === "m68k")
+ return true;
+ if (qbs.architecture === "v850")
+ return true;
+ if (qbs.architecture === "riscv")
+ return true;
+ if (qbs.architecture === "rx")
+ return true;
+ }
+ console.info("unsupported toolset: %%"
+ + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%");
+ return false;
+ }
+
+ Properties {
+ condition: qbs.toolchainType === "gcc"
+ && qbs.architecture === "msp430"
+ // We need to use this workaround to enable
+ // the cpp.driverFlags property.
+ cpp.linkerPath: cpp.compilerPathByLanguage["c"]
+ }
+
+ Properties {
+ condition: qbs.toolchainType === "iar"
+ && qbs.architecture.startsWith("arm")
+ cpp.entryPoint: "main"
+ }
+
+ cpp.linkerPath: original
+
+ files: [(qbs.architecture.startsWith("arm") ? "arm" : qbs.architecture)
+ + "-" + qbs.toolchainType + ".s"]
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/r32c-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/r32c-iar.s
new file mode 100644
index 000000000..844306811
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/r32c-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC main
+ RSEG CODE24:CODE:REORDER:NOROOT(0)
+main:
+ MOV.L:Z #0x0, R2R0
+ RTS
+ RSEG SBREF:DATA:NOROOT(0)
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rh850-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rh850-iar.s
new file mode 100644
index 000000000..8901027aa
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rh850-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC _main
+ SECTION `.text`:CODE:NOROOT(2)
+ CODE
+_main:
+ MOV r0, r10
+ JMP [lp]
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-gcc.s
new file mode 100644
index 000000000..d09097804
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-gcc.s
@@ -0,0 +1,11 @@
+ .globl main
+ .type main, @function
+main:
+ add sp, sp, -16
+ sd s0, 8(sp)
+ add s0, sp, 16
+ li a5, 0
+ mv a0, a5
+ ld s0, 8(sp)
+ add sp, sp, 16
+ jr ra
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-iar.s
new file mode 100644
index 000000000..e19fdfddb
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/riscv-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC main
+ SECTION `.text`:CODE:REORDER:NOROOT(2)
+ CODE
+main:
+ MV A0, ZERO
+ RET
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rl78-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rl78-gcc.s
new file mode 100644
index 000000000..59510bd01
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rl78-gcc.s
@@ -0,0 +1,11 @@
+r8 = 0xffef0
+.text
+ .global _main
+ .type _main, @function
+_main:
+ subw sp, #2
+ clrw ax
+ movw [sp], ax
+ movw r8, ax
+ addw sp, #2
+ ret
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rl78-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rl78-iar.s
new file mode 100644
index 000000000..1f00996cc
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rl78-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC _main
+ SECTION `.text`:CODE:NOROOT(0)
+ CODE
+_main:
+ CLRW AX
+ RET
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-gcc.s
new file mode 100644
index 000000000..501d4cd7e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-gcc.s
@@ -0,0 +1,8 @@
+ .global _main
+ .type _main, @function
+_main:
+ push.l r10
+ mov.L r0, r10
+ mov.L #0, r5
+ mov.L r5, r1
+ rtsd #4, r10-r10
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-iar.s
new file mode 100644
index 000000000..cc1573431
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/rx-iar.s
@@ -0,0 +1,5 @@
+ PUBLIC _main
+ SECTION CODE:CODE:ROOT(2)
+_main:
+ BRA _main
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/sh-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/sh-iar.s
new file mode 100644
index 000000000..d86780310
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/sh-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC _main
+ SECTION `.code32.text`:CODE:NOROOT(2)
+_main:
+ CODE
+ MOV #0, R0
+ RTS/N
+ END
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/one-object-asm-application/stm8-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-iar.s
new file mode 100644
index 000000000..674e20de6
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC main
+ SECTION `.near_func.text`:CODE:REORDER:NOROOT(0)
+ CODE
+main:
+ CLRW X
+ RET
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-sdcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-sdcc.s
new file mode 100644
index 000000000..1a552f4a4
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/stm8-sdcc.s
@@ -0,0 +1,7 @@
+ .globl main
+ .area DATA
+ .area SSEG
+ .area HOME
+main:
+ clrw x
+ ret
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/v850-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/v850-gcc.s
new file mode 100644
index 000000000..3599a1fb1
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/v850-gcc.s
@@ -0,0 +1,11 @@
+ .global _main
+ .type _main, @function
+_main:
+ add -4, sp
+ st.w r29, 0[sp]
+ mov sp, r29
+ mov 0, r10
+ mov r29, sp
+ ld.w 0[sp], r29
+ add 4, sp
+ jmp [r31]
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/v850-iar.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/v850-iar.s
new file mode 100644
index 000000000..4ccfacd64
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/v850-iar.s
@@ -0,0 +1,7 @@
+ PUBLIC _main
+ RSEG `CODE`:CODE:NOROOT(2)
+ CODE
+_main:
+ MOV zero, r1
+ JMP [lp]
+ END
diff --git a/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/xtensa-gcc.s b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/xtensa-gcc.s
new file mode 100644
index 000000000..c21000905
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/one-object-asm-application/xtensa-gcc.s
@@ -0,0 +1,11 @@
+ .global main
+ .type main, @function
+main:
+ addi sp, sp, -16
+ s32i.n a15, sp, 12
+ mov.n a15, sp
+ movi.n a2, 0
+ mov.n sp, a15
+ l32i.n a15, sp, 12
+ addi sp, sp, 16
+ ret.n
diff --git a/tests/auto/blackbox/testdata-baremetal/preinclude-headers/main.c b/tests/auto/blackbox/testdata-baremetal/preinclude-headers/main.c
new file mode 100644
index 000000000..755192287
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/preinclude-headers/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return PREINCLUDE_VALUE;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/preinclude-headers/preinclude-headers.qbs b/tests/auto/blackbox/testdata-baremetal/preinclude-headers/preinclude-headers.qbs
new file mode 100644
index 000000000..0ded6ff15
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/preinclude-headers/preinclude-headers.qbs
@@ -0,0 +1,18 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ condition: {
+ if (qbs.toolchainType === "keil") {
+ if (qbs.architecture === "mcs51"
+ || qbs.architecture === "mcs251"
+ || qbs.architecture === "c166") {
+ console.info("unsupported toolset: %%"
+ + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%");
+ return false;
+ }
+ }
+ return true;
+ }
+ cpp.prefixHeaders: ["preinclude.h"]
+ files: ["main.c"]
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/preinclude-headers/preinclude.h b/tests/auto/blackbox/testdata-baremetal/preinclude-headers/preinclude.h
new file mode 100644
index 000000000..6b68e4826
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/preinclude-headers/preinclude.h
@@ -0,0 +1,6 @@
+#ifndef PREINCLUDE_H
+#define PREINCLUDE_H
+
+#define PREINCLUDE_VALUE 0
+
+#endif // PREINCLUDE_H
diff --git a/tests/auto/blackbox/testdata-baremetal/shared-libraries/app.c b/tests/auto/blackbox/testdata-baremetal/shared-libraries/app.c
new file mode 100644
index 000000000..f2ecb5f55
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/shared-libraries/app.c
@@ -0,0 +1,12 @@
+#include "../dllexport.h"
+
+#include <stdio.h>
+
+DLL_IMPORT void foo(void);
+
+int main(void)
+{
+ printf("Hello from app\n");
+ foo();
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared-libraries.qbs b/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared-libraries.qbs
new file mode 100644
index 000000000..fded553f6
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared-libraries.qbs
@@ -0,0 +1,32 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+Project {
+ condition: {
+ if (qbs.targetPlatform === "windows" && qbs.architecture === "x86") {
+ if (qbs.toolchainType === "watcom")
+ return true;
+ if (qbs.toolchainType === "dmc")
+ return true;
+ }
+
+ if (qbs.toolchainType === "msvc")
+ return true;
+
+ console.info("unsupported toolset: %%"
+ + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%");
+ return false;
+ }
+
+ DynamicLibrary {
+ Depends { name: "cpp" }
+ destinationDirectory: "bin"
+ name: "shared"
+ files: ["shared.c"]
+ }
+ BareMetalApplication {
+ Depends { name: "shared" }
+ destinationDirectory: "bin"
+ name: "app"
+ files: ["app.c"]
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared.c b/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared.c
new file mode 100644
index 000000000..ab0c110fb
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/shared-libraries/shared.c
@@ -0,0 +1,19 @@
+#include "../dllexport.h"
+
+#include <stdio.h>
+
+#ifdef __DMC__
+#include <windows.h>
+#define EXPORT_FUN _export
+BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+{
+ return TRUE;
+}
+#else
+#define EXPORT_FUN
+#endif // __DMC__
+
+DLL_EXPORT void EXPORT_FUN foo(void)
+{
+ printf("Hello from lib\n");
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/a1.c b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/a1.c
new file mode 100644
index 000000000..b593e95d8
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/a1.c
@@ -0,0 +1,4 @@
+int a1(void)
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/a2.c b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/a2.c
new file mode 100644
index 000000000..35ab7feb3
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/a2.c
@@ -0,0 +1,4 @@
+int a2(void)
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/app.c b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/app.c
new file mode 100644
index 000000000..9814bfd9c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/app.c
@@ -0,0 +1,6 @@
+extern int e(void);
+
+int main(void)
+{
+ return e();
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/b.c b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/b.c
new file mode 100644
index 000000000..92df418d1
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/b.c
@@ -0,0 +1,6 @@
+extern int a1(void);
+
+int b(void)
+{
+ return a1();
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/c.c b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/c.c
new file mode 100644
index 000000000..0c0e350f2
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/c.c
@@ -0,0 +1,6 @@
+extern int a2(void);
+
+int c(void)
+{
+ return a2();
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/d.c b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/d.c
new file mode 100644
index 000000000..a3fc084f5
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/d.c
@@ -0,0 +1,7 @@
+extern int b(void);
+extern int c(void);
+
+int d(void)
+{
+ return b() + c();
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/e.c b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/e.c
new file mode 100644
index 000000000..9381e845c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/e.c
@@ -0,0 +1,7 @@
+extern int d(void);
+
+int e(void)
+{
+ return d();
+}
+
diff --git a/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/static-library-dependencies.qbs b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/static-library-dependencies.qbs
new file mode 100644
index 000000000..7184f47ea
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/static-library-dependencies/static-library-dependencies.qbs
@@ -0,0 +1,40 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+import "../BareMetalStaticLibrary.qbs" as BareMetalStaticLibrary
+
+Project {
+ BareMetalStaticLibrary {
+ name: "lib-a"
+ Depends { name: "cpp" }
+ files: ["a1.c", "a2.c"]
+ }
+ BareMetalStaticLibrary {
+ name: "lib-b"
+ Depends { name: "cpp" }
+ Depends { name: "lib-a" }
+ files: ["b.c"]
+ }
+ BareMetalStaticLibrary {
+ name: "lib-c"
+ Depends { name: "cpp" }
+ Depends { name: "lib-a" }
+ files: ["c.c"]
+ }
+ BareMetalStaticLibrary {
+ name: "lib-d"
+ Depends { name: "cpp" }
+ Depends { name: "lib-b" }
+ Depends { name: "lib-c" }
+ files: ["d.c"]
+ }
+ BareMetalStaticLibrary {
+ name: "lib-e"
+ Depends { name: "cpp" }
+ Depends { name: "lib-d" }
+ files: ["e.c"]
+ }
+ BareMetalApplication {
+ name: "app"
+ Depends { name: "lib-e" }
+ files: ["app.c"]
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/system-include-paths/bar/bar.h b/tests/auto/blackbox/testdata-baremetal/system-include-paths/bar/bar.h
new file mode 100644
index 000000000..49ffa0b12
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/system-include-paths/bar/bar.h
@@ -0,0 +1,6 @@
+#ifndef BAR_H
+#define BAR_H
+
+#define BAR_VALUE 1
+
+#endif // BAR_H
diff --git a/tests/auto/blackbox/testdata-baremetal/system-include-paths/foo/foo.h b/tests/auto/blackbox/testdata-baremetal/system-include-paths/foo/foo.h
new file mode 100644
index 000000000..dc510379d
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/system-include-paths/foo/foo.h
@@ -0,0 +1,6 @@
+#ifndef FOO_H
+#define FOO_H
+
+#define FOO_VALUE 1
+
+#endif // FOO_H
diff --git a/tests/auto/blackbox/testdata-baremetal/system-include-paths/main.c b/tests/auto/blackbox/testdata-baremetal/system-include-paths/main.c
new file mode 100644
index 000000000..aabc97a0c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/system-include-paths/main.c
@@ -0,0 +1,7 @@
+#include <foo.h>
+#include <bar.h>
+
+int main(void)
+{
+ return FOO_VALUE - BAR_VALUE;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/system-include-paths/system-include-paths.qbs b/tests/auto/blackbox/testdata-baremetal/system-include-paths/system-include-paths.qbs
new file mode 100644
index 000000000..1f9fd1231
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/system-include-paths/system-include-paths.qbs
@@ -0,0 +1,6 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ files: ["main.c"]
+ cpp.systemIncludePaths: ["foo", "bar"]
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/target-platform/target-platform.qbs b/tests/auto/blackbox/testdata-baremetal/target-platform/target-platform.qbs
new file mode 100644
index 000000000..d29e7e619
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/target-platform/target-platform.qbs
@@ -0,0 +1,19 @@
+Product {
+ Depends { name: "cpp" }
+ condition: {
+ if (qbs.toolchainType === "keil"
+ || qbs.toolchainType === "iar"
+ || 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);
+ console.info("has no os: " + hasNoOS);
+ } else {
+ console.info("unsupported toolset: %%"
+ + qbs.toolchainType + "%%, %%" + qbs.architecture + "%%");
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/dmc.qbs b/tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/dmc.qbs
new file mode 100644
index 000000000..13f751669
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/dmc.qbs
@@ -0,0 +1,31 @@
+import qbs.Probes
+
+Product {
+ id: product
+ condition: qbs.toolchainType === "dmc"
+
+ Depends { name: "cpp" }
+
+ Probes.DmcProbe {
+ id: probe
+ compilerFilePath: cpp.compilerPath
+ enableDefinesByLanguage: cpp.enableCompilerDefinesByLanguage
+ _targetPlatform: qbs.targetPlatform
+ _targetArchitecture: qbs.architecture
+ _targetExtender: cpp.extenderName
+ }
+
+ property bool dummy: {
+ if (!product.condition)
+ return;
+ if (!probe.found
+ || !probe.compilerDefinesByLanguage
+ || !probe.includePaths
+ || (probe.includePaths.length === 0)
+ || (qbs.architecture !== probe.architecture)
+ || (qbs.targetPlatform !== probe.targetPlatform)) {
+ console.info("broken probe: %%" + qbs.toolchainType + "%%, %%"
+ + qbs.architecture + "%%");
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/sdcc.qbs b/tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/sdcc.qbs
new file mode 100644
index 000000000..fa5f519a9
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/sdcc.qbs
@@ -0,0 +1,29 @@
+import qbs.Probes
+
+Product {
+ id: product
+ condition: qbs.toolchainType === "sdcc"
+
+ Depends { name: "cpp" }
+
+ Probes.SdccProbe {
+ id: probe
+ compilerFilePath: cpp.compilerPath
+ enableDefinesByLanguage: cpp.enableCompilerDefinesByLanguage
+ preferredArchitecture: qbs.architecture
+ }
+
+ property bool dummy: {
+ if (!product.condition)
+ return;
+ if (!probe.found
+ || !probe.endianness
+ || !probe.compilerDefinesByLanguage
+ || !probe.includePaths
+ || (probe.includePaths.length === 0)
+ || (qbs.architecture !== probe.architecture)) {
+ console.info("broken probe: %%" + qbs.toolchainType + "%%, %%"
+ + qbs.architecture + "%%");
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/watcom.qbs b/tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/watcom.qbs
new file mode 100644
index 000000000..b7c92dc21
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/toolchain-probe/probes/watcom.qbs
@@ -0,0 +1,34 @@
+import qbs.Probes
+
+Product {
+ id: product
+ condition: qbs.toolchainType === "watcom"
+
+ Depends { name: "cpp" }
+
+ Probes.WatcomProbe {
+ id: probe
+ compilerFilePath: cpp.compilerPath
+ enableDefinesByLanguage: cpp.enableCompilerDefinesByLanguage
+ _pathListSeparator: qbs.pathListSeparator
+ _toolchainInstallPath: cpp.toolchainInstallPath
+ _targetPlatform: qbs.targetPlatform
+ _targetArchitecture: qbs.architecture
+ }
+
+ property bool dummy: {
+ if (!product.condition)
+ return;
+ if (!probe.found
+ || !probe.endianness
+ || !probe.compilerDefinesByLanguage
+ || !probe.environment
+ || !probe.includePaths
+ || (probe.includePaths.length === 0)
+ || (qbs.architecture !== probe.architecture)
+ || (qbs.targetPlatform !== probe.targetPlatform)) {
+ console.info("broken probe: %%" + qbs.toolchainType + "%%, %%"
+ + qbs.architecture + "%%");
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/toolchain-probe/toolchain-probe.qbs b/tests/auto/blackbox/testdata-baremetal/toolchain-probe/toolchain-probe.qbs
new file mode 100644
index 000000000..36725cfde
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/toolchain-probe/toolchain-probe.qbs
@@ -0,0 +1,7 @@
+Project {
+ references: [
+ "probes/dmc.qbs",
+ "probes/sdcc.qbs",
+ "probes/watcom.qbs",
+ ]
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/two-object-application/fun.c b/tests/auto/blackbox/testdata-baremetal/two-object-application/fun.c
new file mode 100644
index 000000000..3b8c8f2f4
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/two-object-application/fun.c
@@ -0,0 +1,4 @@
+int f(void)
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/two-object-application/main.c b/tests/auto/blackbox/testdata-baremetal/two-object-application/main.c
new file mode 100644
index 000000000..2c3d7726c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/two-object-application/main.c
@@ -0,0 +1,6 @@
+extern int f(void);
+
+int main(void)
+{
+ return f();
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/two-object-application/two-object-application.qbs b/tests/auto/blackbox/testdata-baremetal/two-object-application/two-object-application.qbs
new file mode 100644
index 000000000..2947975ca
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/two-object-application/two-object-application.qbs
@@ -0,0 +1,5 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ files: ["main.c", "fun.c"]
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/user-include-paths/bar/bar.h b/tests/auto/blackbox/testdata-baremetal/user-include-paths/bar/bar.h
new file mode 100644
index 000000000..49ffa0b12
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/user-include-paths/bar/bar.h
@@ -0,0 +1,6 @@
+#ifndef BAR_H
+#define BAR_H
+
+#define BAR_VALUE 1
+
+#endif // BAR_H
diff --git a/tests/auto/blackbox/testdata-baremetal/user-include-paths/foo/foo.h b/tests/auto/blackbox/testdata-baremetal/user-include-paths/foo/foo.h
new file mode 100644
index 000000000..dc510379d
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/user-include-paths/foo/foo.h
@@ -0,0 +1,6 @@
+#ifndef FOO_H
+#define FOO_H
+
+#define FOO_VALUE 1
+
+#endif // FOO_H
diff --git a/tests/auto/blackbox/testdata-baremetal/user-include-paths/main.c b/tests/auto/blackbox/testdata-baremetal/user-include-paths/main.c
new file mode 100644
index 000000000..e76e08cbe
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/user-include-paths/main.c
@@ -0,0 +1,7 @@
+#include "foo.h"
+#include "bar.h"
+
+int main(void)
+{
+ return FOO_VALUE - BAR_VALUE;
+}
diff --git a/tests/auto/blackbox/testdata-baremetal/user-include-paths/user-include-paths.qbs b/tests/auto/blackbox/testdata-baremetal/user-include-paths/user-include-paths.qbs
new file mode 100644
index 000000000..23d5dbced
--- /dev/null
+++ b/tests/auto/blackbox/testdata-baremetal/user-include-paths/user-include-paths.qbs
@@ -0,0 +1,6 @@
+import "../BareMetalApplication.qbs" as BareMetalApplication
+
+BareMetalApplication {
+ files: ["main.c"]
+ cpp.includePaths: ["foo", "bar"]
+}
diff --git a/tests/auto/blackbox/testdata-clangdb/project1/project.qbs b/tests/auto/blackbox/testdata-clangdb/project1/project.qbs
index ecfc562b0..313f33ead 100644
--- a/tests/auto/blackbox/testdata-clangdb/project1/project.qbs
+++ b/tests/auto/blackbox/testdata-clangdb/project1/project.qbs
@@ -7,8 +7,8 @@ Project {
Application {
Probe {
id: dummy
- property bool isMingw: qbs.toolchain.contains("mingw")
- property bool isMsvc: qbs.toolchain.contains("msvc")
+ property bool isMingw: qbs.toolchain.includes("mingw")
+ property bool isMsvc: qbs.toolchain.includes("msvc")
property var buildEnv: cpp.buildEnv
configure: {
if (!buildEnv)
diff --git a/tests/auto/blackbox/testdata-java/java/vehicles.qbs b/tests/auto/blackbox/testdata-java/java/vehicles.qbs
index 8153efe00..8a4bb732f 100644
--- a/tests/auto/blackbox/testdata-java/java/vehicles.qbs
+++ b/tests/auto/blackbox/testdata-java/java/vehicles.qbs
@@ -1,4 +1,5 @@
import qbs.FileInfo
+import qbs.Host
import qbs.Utilities
Project {
@@ -6,10 +7,17 @@ Project {
Depends { name: "cpp" }
Depends { name: "car_jar" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
+ property bool _testPlatform: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
+
name: "native"
files: ["engine.c"]
@@ -34,7 +42,7 @@ Project {
Export {
Depends { name: "java" }
- java.manifestClassPath: [product.targetName + ".jar"]
+ java.manifestClassPath: [exportingProduct.targetName + ".jar"]
}
}
@@ -50,7 +58,7 @@ Project {
Export {
Depends { name: "java" }
- java.manifestClassPath: [product.targetName + ".jar"]
+ java.manifestClassPath: [exportingProduct.targetName + ".jar"]
}
}
@@ -68,13 +76,13 @@ Project {
cpp.systemIncludePaths: {
var paths = importingProduct.java.jdkIncludePaths;
if (Utilities.versionCompare(importingProduct.java.version, "1.8") >= 0) {
- paths.push(product.buildDirectory); // generated JNI headers
+ paths.push(exportingProduct.buildDirectory); // generated JNI headers
}
return paths;
}
Depends { name: "java" }
- java.manifestClassPath: [product.targetName + ".jar"]
+ java.manifestClassPath: [exportingProduct.targetName + ".jar"]
}
qbs.installPrefix: ""
diff --git a/tests/auto/blackbox/testdata-joblimits/job-limits-init/job-limits-init.qbs b/tests/auto/blackbox/testdata-joblimits/job-limits-init/job-limits-init.qbs
new file mode 100644
index 000000000..3a0075530
--- /dev/null
+++ b/tests/auto/blackbox/testdata-joblimits/job-limits-init/job-limits-init.qbs
@@ -0,0 +1,10 @@
+import qbs.Host
+
+Product {
+ property bool _testPlatform: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
+}
diff --git a/tests/auto/blackbox/testdata-joblimits/job-limits/job-limits.qbs b/tests/auto/blackbox/testdata-joblimits/job-limits/job-limits.qbs
index 221105a64..76f54807a 100644
--- a/tests/auto/blackbox/testdata-joblimits/job-limits/job-limits.qbs
+++ b/tests/auto/blackbox/testdata-joblimits/job-limits/job-limits.qbs
@@ -19,7 +19,7 @@ Project {
consoleApplication: true
cpp.cxxLanguageVersion: "c++14"
Properties {
- condition: qbs.targetOS.contains("macos")
+ condition: qbs.targetOS.includes("macos")
cpp.minimumMacosVersion: "10.9"
}
files: "main.cpp"
@@ -37,7 +37,7 @@ Project {
var cmd = new Command(explicitlyDependsOn.tool_tag[0].filePath,
[output.filePath]);
cmd.workingDirectory = product.buildDirectory;
- cmd.description = "Running tool";
+ cmd.description = "running tool";
cmd.jobPool = "singleton";
return cmd;
}
diff --git a/tests/auto/blackbox/testdata-joblimits/job-limits/main.cpp b/tests/auto/blackbox/testdata-joblimits/job-limits/main.cpp
index ec9acba80..5f436b0e9 100644
--- a/tests/auto/blackbox/testdata-joblimits/job-limits/main.cpp
+++ b/tests/auto/blackbox/testdata-joblimits/job-limits/main.cpp
@@ -63,7 +63,7 @@ int main(int argc, char *argv[])
const std::string lockFilePath = std::string(argv[0]) + ".lock";
std::FILE * const lockFile = std::fopen(lockFilePath.c_str(), "w");
if (!lockFile) {
- std::cerr << "cannot open lock file: " << strerror(errno) << std::endl;
+ std::cerr << "cannot open lock file: " << std::strerror(errno) << std::endl;
return 2;
}
if (!tryLock(lockFile)) {
@@ -71,17 +71,17 @@ int main(int argc, char *argv[])
std::cerr << "tool is exclusive" << std::endl;
return 3;
} else {
- std::cerr << "unexpected lock failure: " << strerror(errno) << std::endl;
- fclose(lockFile);
+ std::cerr << "unexpected lock failure: " << std::strerror(errno) << std::endl;
+ std::fclose(lockFile);
return 4;
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
- fclose(lockFile);
+ std::fclose(lockFile);
std::FILE * const output = std::fopen(argv[1], "w");
if (!output) {
- std::cerr << "cannot create output file: " << strerror(errno) << std::endl;
+ std::cerr << "cannot create output file: " << std::strerror(errno) << std::endl;
return 5;
}
- fclose(output);
+ std::fclose(output);
}
diff --git a/tests/auto/blackbox/testdata-providers/allowed-values/allowed-values.qbs b/tests/auto/blackbox/testdata-providers/allowed-values/allowed-values.qbs
new file mode 100644
index 000000000..e6dbaddde
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/allowed-values/allowed-values.qbs
@@ -0,0 +1,4 @@
+Product {
+ Depends { name: "qbsmetatestmodule" }
+ qbsModuleProviders: "provider"
+}
diff --git a/tests/auto/blackbox/testdata-providers/allowed-values/module-providers/provider.qbs b/tests/auto/blackbox/testdata-providers/allowed-values/module-providers/provider.qbs
new file mode 100644
index 000000000..c0e426c96
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/allowed-values/module-providers/provider.qbs
@@ -0,0 +1,14 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ isEager: false
+ property stringList aProperty: "zero"
+ PropertyOptions {
+ name: "aProperty"
+ allowedValues: ["one", "two"]
+ }
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, moduleName, "from_provider");
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/broken-provider/broken-provider.qbs b/tests/auto/blackbox/testdata-providers/broken-provider/broken-provider.qbs
new file mode 100644
index 000000000..461c7e30e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/broken-provider/broken-provider.qbs
@@ -0,0 +1,13 @@
+Project {
+ qbsModuleProviders: "provider_a"
+ name: "project"
+ Project {
+ name: "innerProject"
+ Product {
+ name: "p1"
+ Depends { name: "qbsothermodule"; required: false }
+ Depends { name: "qbsmetatestmodule" }
+ }
+ }
+
+}
diff --git a/tests/auto/blackbox/testdata-providers/broken-provider/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/broken-provider/module-providers/provider_a.qbs
new file mode 100644
index 000000000..f446d2d13
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/broken-provider/module-providers/provider_a.qbs
@@ -0,0 +1,5 @@
+ModuleProvider {
+ relativeSearchPaths: {
+ throw "This provider is broken";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/conan-module-provider.qbs b/tests/auto/blackbox/testdata-providers/conan-provider/conan-module-provider.qbs
new file mode 100644
index 000000000..e8880fc96
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/conan-module-provider.qbs
@@ -0,0 +1,11 @@
+CppApplication {
+ consoleApplication: true
+ name: "p"
+ files: "main.cpp"
+ qbsModuleProviders: "conan"
+ qbs.buildVariant: "release"
+ qbs.installPrefix: ""
+ install: true
+ Depends { name: "conanmoduleprovider.testlib" }
+ Depends { name: "conanmoduleprovider.testlibheader" }
+}
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/conanfile.txt b/tests/auto/blackbox/testdata-providers/conan-provider/conanfile.txt
new file mode 100644
index 000000000..7c40ff7d6
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/conanfile.txt
@@ -0,0 +1,3 @@
+[requires]
+conanmoduleprovider.testlib/1.2.3
+conanmoduleprovider.testlibheader/0.1.0
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/main.cpp b/tests/auto/blackbox/testdata-providers/conan-provider/main.cpp
new file mode 100644
index 000000000..6250927b3
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/main.cpp
@@ -0,0 +1,8 @@
+#include <testlib.h>
+
+#include <header.h>
+
+int main()
+{
+ HelloWorld h(42 + hello());
+}
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlib/CMakeLists.txt b/tests/auto/blackbox/testdata-providers/conan-provider/testlib/CMakeLists.txt
new file mode 100644
index 000000000..d186d1906
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlib/CMakeLists.txt
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.15)
+project(conanmoduleprovider.testlib)
+
+find_package(conanmoduleprovider.testlibdep REQUIRED)
+
+add_library(${PROJECT_NAME} STATIC testlib.cpp)
+set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "testlib.h")
+target_link_libraries(${PROJECT_NAME} conanmoduleprovider.testlibdep::conanmoduleprovider.testlibdep)
+install(TARGETS ${PROJECT_NAME})
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlib/conanfile.py b/tests/auto/blackbox/testdata-providers/conan-provider/testlib/conanfile.py
new file mode 100644
index 000000000..7cb91f9ef
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlib/conanfile.py
@@ -0,0 +1,36 @@
+from conan import ConanFile
+from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
+from conan.tools.files import collect_libs
+import os
+
+class ConanModuleProviderTestlib(ConanFile):
+ name = "conanmoduleprovider.testlib"
+ license = "none"
+ version = "1.2.3"
+
+ exports_sources = "*.cpp", "*.h", "CMakeLists.txt"
+ settings = "os", "compiler", "build_type", "arch"
+
+ def requirements(self):
+ self.requires("conanmoduleprovider.testlibdep/1.2.3")
+
+ def layout(self):
+ cmake_layout(self)
+
+ def generate(self):
+ deps = CMakeDeps(self)
+ deps.generate()
+ tc = CMakeToolchain(self, generator="Ninja")
+ tc.generate()
+
+ def build(self):
+ cmake = CMake(self)
+ cmake.configure()
+ cmake.build()
+
+ def package(self):
+ cmake = CMake(self)
+ cmake.install()
+
+ def package_info(self):
+ self.cpp_info.libs = collect_libs(self)
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlib/testlib.cpp b/tests/auto/blackbox/testdata-providers/conan-provider/testlib/testlib.cpp
new file mode 100644
index 000000000..7118dfda9
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlib/testlib.cpp
@@ -0,0 +1,7 @@
+#include "testlib.h"
+
+#include <testlibdep.h>
+
+HelloWorld::HelloWorld(int x)
+ : m_x(foo(x))
+{}
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlib/testlib.h b/tests/auto/blackbox/testdata-providers/conan-provider/testlib/testlib.h
new file mode 100644
index 000000000..11a354b70
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlib/testlib.h
@@ -0,0 +1,10 @@
+#pragma once
+
+class HelloWorld
+{
+public:
+ explicit HelloWorld(int x);
+
+private:
+ int m_x;
+};
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/CMakeLists.txt b/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/CMakeLists.txt
new file mode 100644
index 000000000..5510a9250
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.15)
+project(conanmoduleprovider.testlibdep)
+
+add_library(${PROJECT_NAME} STATIC testlibdep.cpp)
+set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "testlibdep.h")
+install(TARGETS ${PROJECT_NAME})
+install(FILES lorem_ipsum.txt DESTINATION share) \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/conanfile.py b/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/conanfile.py
new file mode 100644
index 000000000..f2c577c5e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/conanfile.py
@@ -0,0 +1,35 @@
+from conan import ConanFile
+from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
+from conan.tools.files import collect_libs, copy
+import os
+
+class ConanModuleProviderTestlib(ConanFile):
+ name = "conanmoduleprovider.testlibdep"
+ license = "none"
+ version = "1.2.3"
+
+ exports_sources = "*.cpp", "*.h", "*.txt"
+ settings = "os", "compiler", "build_type", "arch"
+
+ def layout(self):
+ cmake_layout(self)
+
+ def generate(self):
+ deps = CMakeDeps(self)
+ deps.generate()
+ tc = CMakeToolchain(self, generator="Ninja")
+ tc.generate()
+
+ def build(self):
+ cmake = CMake(self)
+ cmake.configure()
+ cmake.build()
+
+ def package(self):
+ cmake = CMake(self)
+ cmake.install()
+
+ def package_info(self):
+ self.cpp_info.libs = collect_libs(self)
+ self.cpp_info.resdirs = ['share']
+
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/lorem_ipsum.txt b/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/lorem_ipsum.txt
new file mode 100644
index 000000000..d8634396c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/lorem_ipsum.txt
@@ -0,0 +1 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/testlibdep.cpp b/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/testlibdep.cpp
new file mode 100644
index 000000000..893478c82
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/testlibdep.cpp
@@ -0,0 +1,6 @@
+#include "testlibdep.h"
+
+int foo(int i)
+{
+ return i * i;
+} \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/testlibdep.h b/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/testlibdep.h
new file mode 100644
index 000000000..ca7bd3cbc
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlibdep/testlibdep.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int foo(int i); \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlibheader/conanfile.py b/tests/auto/blackbox/testdata-providers/conan-provider/testlibheader/conanfile.py
new file mode 100644
index 000000000..6078b9750
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlibheader/conanfile.py
@@ -0,0 +1,15 @@
+from conan import ConanFile
+from conan.tools.files import copy
+
+import os
+
+class Recipe(ConanFile):
+ exports_sources = ("header.h")
+ version = '0.1.0'
+ name = 'conanmoduleprovider.testlibheader'
+
+ def package(self):
+ copy(self,
+ "header.h",
+ src=self.source_folder,
+ dst=os.path.join(self.package_folder, "include")) \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata-providers/conan-provider/testlibheader/header.h b/tests/auto/blackbox/testdata-providers/conan-provider/testlibheader/header.h
new file mode 100644
index 000000000..66bd50d57
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/conan-provider/testlibheader/header.h
@@ -0,0 +1,6 @@
+#pragma once
+
+inline int hello()
+{
+ return 0;
+} \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata/fallback-module-provider/fallback-module-provider.qbs b/tests/auto/blackbox/testdata-providers/fallback-module-provider/fallback-module-provider.qbs
index a798e15b3..a798e15b3 100644
--- a/tests/auto/blackbox/testdata/fallback-module-provider/fallback-module-provider.qbs
+++ b/tests/auto/blackbox/testdata-providers/fallback-module-provider/fallback-module-provider.qbs
diff --git a/tests/auto/blackbox/testdata/fallback-module-provider/libdir/qbsmetatestmodule.pc b/tests/auto/blackbox/testdata-providers/fallback-module-provider/libdir/qbsmetatestmodule.pc
index ae4daba89..ae4daba89 100644
--- a/tests/auto/blackbox/testdata/fallback-module-provider/libdir/qbsmetatestmodule.pc
+++ b/tests/auto/blackbox/testdata-providers/fallback-module-provider/libdir/qbsmetatestmodule.pc
diff --git a/tests/auto/blackbox/testdata/fallback-module-provider/main.cpp b/tests/auto/blackbox/testdata-providers/fallback-module-provider/main.cpp
index 442b755bf..442b755bf 100644
--- a/tests/auto/blackbox/testdata/fallback-module-provider/main.cpp
+++ b/tests/auto/blackbox/testdata-providers/fallback-module-provider/main.cpp
diff --git a/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers-cache.qbs b/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers-cache.qbs
new file mode 100644
index 000000000..508ed84d2
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers-cache.qbs
@@ -0,0 +1,11 @@
+Project {
+ qbsModuleProviders: ["provider_a"]
+ name: "project"
+ property string dummyProp
+
+ Product {
+ name: "p1"
+ Depends { name: "qbsothermodule" }
+ Depends { name: "qbsmetatestmodule" }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers/provider_a.qbs
new file mode 100644
index 000000000..782cf7d25
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers/provider_a.qbs
@@ -0,0 +1,9 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", "from_provider_a");
+ Helpers.writeModule(outputBaseDir, "qbsothermodule", "from_provider_a");
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata/module-providers/main.cpp b/tests/auto/blackbox/testdata-providers/module-providers/main.cpp
index 9cd29b1fe..85a4f551c 100644
--- a/tests/auto/blackbox/testdata/module-providers/main.cpp
+++ b/tests/auto/blackbox/testdata-providers/module-providers/main.cpp
@@ -3,4 +3,6 @@
int main()
{
std::cout << "The letters are " << LETTER1 << " and " << LETTER2 << std::endl;
+ std::cout << "The MY_DEFINE is " << MY_DEFINE << std::endl;
+ return 0;
}
diff --git a/tests/auto/blackbox/testdata-providers/module-providers/module-providers.qbs b/tests/auto/blackbox/testdata-providers/module-providers/module-providers.qbs
new file mode 100644
index 000000000..89bd1a11d
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/module-providers/module-providers.qbs
@@ -0,0 +1,36 @@
+import qbs.Host
+
+Project {
+ property bool enabled: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
+ readonly property string beginning: "beginning"
+ CppApplication {
+ name: "app1"
+ property string chooseLettersFrom: project.beginning // This indirection tests QBS-1747.
+ Depends { name: "mygenerator.module1" }
+ Depends { name: "mygenerator.module2" }
+ Depends { name: "othergenerator" }
+ moduleProviders.mygenerator.chooseLettersFrom: chooseLettersFrom
+ moduleProviders.othergenerator.someDefines: name
+ files: "main.cpp"
+ }
+ CppApplication {
+ readonly property string end: "end"
+ name: "app2"
+ Depends { name: "mygenerator.module1" }
+ Depends { name: "mygenerator.module2" }
+ Depends { name: "othergenerator" }
+ Profile {
+ name: "myProfile"
+ baseProfile: project.profile
+ moduleProviders.mygenerator.chooseLettersFrom: product.end
+ moduleProviders.othergenerator.someDefines: "app2"
+ }
+ qbs.profile: "myProfile"
+ files: "main.cpp"
+ }
+}
diff --git a/tests/auto/blackbox/testdata/module-providers/module-providers/mygenerator/provider.qbs b/tests/auto/blackbox/testdata-providers/module-providers/module-providers/mygenerator/provider.qbs
index dae02c03a..dae02c03a 100644
--- a/tests/auto/blackbox/testdata/module-providers/module-providers/mygenerator/provider.qbs
+++ b/tests/auto/blackbox/testdata-providers/module-providers/module-providers/mygenerator/provider.qbs
diff --git a/tests/auto/blackbox/testdata-providers/module-providers/module-providers/othergenerator/provider.qbs b/tests/auto/blackbox/testdata-providers/module-providers/module-providers/othergenerator/provider.qbs
new file mode 100644
index 000000000..66557037c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/module-providers/module-providers/othergenerator/provider.qbs
@@ -0,0 +1,19 @@
+import qbs.File;
+import qbs.FileInfo;
+import qbs.TextFile;
+
+ModuleProvider {
+ property string someDefines
+ relativeSearchPaths: {
+ console.info("Running setup script for " + name);
+ var moduleDir = FileInfo.joinPaths(outputBaseDir, "modules", "othergenerator");
+ File.makePath(moduleDir);
+ var module = new TextFile(FileInfo.joinPaths(moduleDir, "module.qbs"), TextFile.WriteOnly);
+ module.writeLine("Module {");
+ module.writeLine(" Depends { name: 'cpp' }");
+ module.writeLine(" cpp.defines: 'MY_DEFINE=\"" + someDefines + "\"'");
+ module.writeLine("}");
+ module.close();
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/non-eager-provider/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/non-eager-provider/module-providers/provider_a.qbs
new file mode 100644
index 000000000..6cd9177db
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/non-eager-provider/module-providers/provider_a.qbs
@@ -0,0 +1,11 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ isEager: false
+ relativeSearchPaths: {
+ if (moduleName === "nonexistentmodule")
+ return undefined;
+ Helpers.writeModule(outputBaseDir, moduleName, "from_provider_a");
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/non-eager-provider/non-eager-provider.qbs b/tests/auto/blackbox/testdata-providers/non-eager-provider/non-eager-provider.qbs
new file mode 100644
index 000000000..bd3662de3
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/non-eager-provider/non-eager-provider.qbs
@@ -0,0 +1,13 @@
+Project {
+ Product {
+ name: "p1"
+ Depends { name: "qbsmetatestmodule" }
+ Depends { name: "qbsothermodule" }
+ Depends { name: "nonexistentmodule"; required: false }
+ property bool dummy: {
+ console.info("p1.qbsmetatestmodule.prop: " + qbsmetatestmodule.prop);
+ console.info("p1.qbsothermodule.prop: " + qbsothermodule.prop);
+ }
+ qbsModuleProviders: "provider_a"
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/probe-in-module-provider/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/probe-in-module-provider/module-providers/provider_a.qbs
new file mode 100644
index 000000000..476a83143
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/probe-in-module-provider/module-providers/provider_a.qbs
@@ -0,0 +1,23 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ property string sysroot: qbs.sysroot
+ Probe {
+ id: theProbe
+ property string theValue: "value"
+ property string dummy: sysroot
+ configure: {
+ console.info("Running probe with irrelevant value '" + dummy + "'");
+ found = true;
+ }
+ }
+ isEager: false
+ property bool found: theProbe.found
+ property string theValue: theProbe.theValue
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", theValue, undefined, found);
+ if (sysroot !== qbs.sysroot)
+ throw "this is unexpected";
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/probe-in-module-provider/probe-in-module-provider.qbs b/tests/auto/blackbox/testdata-providers/probe-in-module-provider/probe-in-module-provider.qbs
new file mode 100644
index 000000000..1f2b3d387
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/probe-in-module-provider/probe-in-module-provider.qbs
@@ -0,0 +1,9 @@
+Product {
+ qbsModuleProviders: ["provider_a"]
+ name: "p"
+ Depends { name: "qbsmetatestmodule" }
+ property bool dummy: {
+ console.info("p.qbsmetatestmodule.boolProp: " + JSON.stringify(qbsmetatestmodule.boolProp));
+ console.info("p.qbsmetatestmodule.prop: " + JSON.stringify(qbsmetatestmodule.prop));
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_a.qbs
new file mode 100644
index 000000000..ab9d475d8
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_a.qbs
@@ -0,0 +1,9 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ property stringList someProp: "provider_a"
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", undefined, someProp);
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_b.qbs b/tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_b.qbs
new file mode 100644
index 000000000..1b2a79979
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_b.qbs
@@ -0,0 +1,9 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ property stringList someProp: "provider_b"
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsothermodule", undefined, someProp);
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/providers-properties/providers-properties.qbs b/tests/auto/blackbox/testdata-providers/providers-properties/providers-properties.qbs
new file mode 100644
index 000000000..258a973fa
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/providers-properties/providers-properties.qbs
@@ -0,0 +1,12 @@
+Product {
+ qbsModuleProviders: ["provider_a", "provider_b"]
+ name: "p"
+ Depends { name: "qbsmetatestmodule" }
+ Depends { name: "qbsothermodule" }
+ moduleProviders.provider_a.someProp: "someValue"
+ property bool dummy: {
+ console.info("p.qbsmetatestmodule.listProp: "
+ + JSON.stringify(qbsmetatestmodule.listProp));
+ console.info("p.qbsothermodule.listProp: " + JSON.stringify(qbsothermodule.listProp));
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/module-providers/provider_a.qbs
new file mode 100644
index 000000000..95c89cd1c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/module-providers/provider_a.qbs
@@ -0,0 +1,9 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ property string sysroot: qbs.sysroot
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", sysroot);
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/qbs-module-properties-in-providers.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/qbs-module-properties-in-providers.qbs
new file mode 100644
index 000000000..c2fc58299
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/qbs-module-properties-in-providers.qbs
@@ -0,0 +1,34 @@
+Project {
+ qbsModuleProviders: "provider_a"
+ name: "project"
+
+ Profile {
+ name: "profile1"
+ qbs.sysroot: "/sysroot1"
+ }
+
+ Profile {
+ name: "profile2"
+ qbs.sysroot: "/sysroot2"
+ }
+
+ Product {
+ name: "product1"
+ Depends { name: "qbsmetatestmodule" }
+ property bool dummy: {
+ console.info("product1.qbsmetatestmodule.prop: " + qbsmetatestmodule.prop);
+ }
+ // multiplex over profiles, sysroot should not be cached
+ qbs.profiles: ["profile1", "profile2"]
+ }
+
+ Product {
+ name: "product2"
+ Depends { name: "qbsmetatestmodule" }
+ property bool dummy: {
+ console.info("product2.qbsmetatestmodule.prop: " + qbsmetatestmodule.prop);
+ }
+ // multiplex over profiles, sysroot should not be cached
+ qbs.profiles: ["profile1", "profile2"]
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_a.qbs
new file mode 100644
index 000000000..d34d1cac5
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_a.qbs
@@ -0,0 +1,8 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", "from_provider_a");
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_b.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_b.qbs
new file mode 100644
index 000000000..767e30923
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_b.qbs
@@ -0,0 +1,9 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", "from_provider_b");
+ Helpers.writeModule(outputBaseDir, "qbsothermodule", "from_provider_b");
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/qbs-module-providers-cli-override.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/qbs-module-providers-cli-override.qbs
new file mode 100644
index 000000000..6f94ab207
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/qbs-module-providers-cli-override.qbs
@@ -0,0 +1,13 @@
+Project {
+ name: "project"
+ Project {
+ name: "innerProject"
+ Product {
+ name: "product"
+ Depends { name: "qbsmetatestmodule"; required: false }
+ property bool dummy: {
+ console.info("qbsmetatestmodule.prop: " + qbsmetatestmodule.prop);
+ }
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/named_provider.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/named_provider.qbs
new file mode 100644
index 000000000..07114b5ef
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/named_provider.qbs
@@ -0,0 +1,8 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", "from_named_provider");
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/qbsmetatestmodule/provider.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/qbsmetatestmodule/provider.qbs
new file mode 100644
index 000000000..b04a52261
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/qbsmetatestmodule/provider.qbs
@@ -0,0 +1,8 @@
+import "../../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", "from_scoped_provider");
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/qbs-module-providers-compatibility.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/qbs-module-providers-compatibility.qbs
new file mode 100644
index 000000000..7885b540a
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/qbs-module-providers-compatibility.qbs
@@ -0,0 +1,7 @@
+Product {
+ name: "p"
+ Depends { name: "qbsmetatestmodule" }
+ property bool dummy: {
+ console.info("qbsmetatestmodule.prop: " + qbsmetatestmodule.prop);
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-providers-helpers.js b/tests/auto/blackbox/testdata-providers/qbs-module-providers-helpers.js
new file mode 100644
index 000000000..8b6d9e275
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-helpers.js
@@ -0,0 +1,23 @@
+var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+var TextFile = require("qbs.TextFile");
+var ModUtils = require("qbs.ModUtils");
+
+function writeModule(outputBaseDir, name, prop, listProp, boolProp) {
+ console.info("Running setup script for " + name);
+ var moduleDir = FileInfo.joinPaths(outputBaseDir, "modules", name);
+ File.makePath(moduleDir);
+ var module = new TextFile(FileInfo.joinPaths(moduleDir, "module.qbs"), TextFile.WriteOnly);
+ module.writeLine("Module {");
+ module.writeLine(" property string prop: " + ModUtils.toJSLiteral(prop));
+ if (listProp) {
+ module.writeLine(" property stringList listProp: "
+ + ModUtils.toJSLiteral(listProp));
+ }
+ if (boolProp) {
+ module.writeLine(" property bool boolProp: "
+ + ModUtils.toJSLiteral(boolProp));
+ }
+ module.writeLine("}");
+ module.close();
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_a.qbs
new file mode 100644
index 000000000..d34d1cac5
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_a.qbs
@@ -0,0 +1,8 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", "from_provider_a");
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_b.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_b.qbs
new file mode 100644
index 000000000..767e30923
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_b.qbs
@@ -0,0 +1,9 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", "from_provider_b");
+ Helpers.writeModule(outputBaseDir, "qbsothermodule", "from_provider_b");
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbs-module-providers/qbs-module-providers.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers/qbs-module-providers.qbs
new file mode 100644
index 000000000..00776a62e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers/qbs-module-providers.qbs
@@ -0,0 +1,28 @@
+Project {
+ qbsModuleProviders: "provider_a"
+ property stringList wantedProviders: qbsModuleProviders
+ name: "project"
+ Project {
+ name: "innerProject"
+ qbsModuleProviders: project.wantedProviders
+ Product {
+ name: "p1"
+ Depends { name: "qbsmetatestmodule" }
+ Depends { name: "qbsothermodule"; required: false }
+ property bool dummy: {
+ console.info("p1.qbsmetatestmodule.prop: " + qbsmetatestmodule.prop);
+ console.info("p1.qbsothermodule.prop: " + qbsothermodule.prop);
+ }
+ }
+ }
+
+ Product {
+ name: "p2"
+ Depends { name: "qbsmetatestmodule" }
+ Depends { name: "qbsothermodule"; required: false }
+ property bool dummy: {
+ console.info("p2.qbsmetatestmodule.prop: " + qbsmetatestmodule.prop);
+ console.info("p2.qbsothermodule.prop: " + qbsothermodule.prop);
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.cpp b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.cpp
new file mode 100644
index 000000000..0c5274415
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.cpp
@@ -0,0 +1,14 @@
+#include "libA.h"
+
+#include <iostream>
+
+void foo()
+{
+ std::cout << "hello from foo: ";
+#ifdef MYLIB_FRAMEWORK
+ std::cout << "bundled: yes";
+#else
+ std::cout << "bundled: no";
+#endif
+ std::cout << std::endl;
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.h b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.h
new file mode 100644
index 000000000..ddaaf1609
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#if defined(_WIN32) || defined(WIN32)
+# define DECL_EXPORT __declspec(dllexport)
+# define DECL_IMPORT __declspec(dllimport)
+#else
+# define DECL_EXPORT __attribute__((visibility("default")))
+# define DECL_IMPORT __attribute__((visibility("default")))
+# endif
+
+#if defined(LIBA_STATIC_LIBRARY)
+# define LIBA_EXPORT
+#else
+# if defined(MYLIB_LIBRARY)
+# define LIBA_EXPORT DECL_EXPORT
+# else
+# define LIBA_EXPORT DECL_IMPORT
+# endif
+#endif
+
+LIBA_EXPORT void foo();
diff --git a/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libs.qbs b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libs.qbs
new file mode 100644
index 000000000..b473083c6
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libs.qbs
@@ -0,0 +1,42 @@
+import qbs.FileInfo
+
+Project {
+ property bool isBundle: false
+
+ DynamicLibrary {
+ Depends { name: "cpp" }
+ Depends { name: "bundle" }
+ Depends { name: "Exporter.pkgconfig" }
+ Exporter.pkgconfig.versionEntry: "1.0"
+ name: "libA"
+ bundle.isBundle: project.isBundle
+ bundle.publicHeaders: ["libA.h"]
+ files: "libA.cpp"
+ cpp.defines: {
+ var result = [];
+ if (project.isBundle)
+ result.push("MYLIB_FRAMEWORK");
+ return result;
+ }
+ qbs.installPrefix: "/usr"
+ install: true
+ installImportLib: true
+ installDir: "lib"
+ Group {
+ files: ["libA.h"]
+ qbs.install: !project.isBundle
+ qbs.installDir: FileInfo.joinPaths("include", product.name)
+ }
+ Group {
+ fileTagsFilter: ["Exporter.pkgconfig.pc"]
+ qbs.install: !project.isBundle
+ qbs.installDir: FileInfo.joinPaths("share", "pkgconfig")
+ }
+ Export {
+ Depends { name: "cpp" }
+ cpp.defines: ["THE_MAGIC_DEFINE"]
+ cpp.includePaths: [FileInfo.joinPaths(exportingProduct.qbs.installPrefix, "include")]
+ cpp.libraryPaths: [FileInfo.joinPaths(exportingProduct.qbs.installPrefix, "lib")]
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/main.cpp b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/main.cpp
new file mode 100644
index 000000000..5fa0f7eed
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/main.cpp
@@ -0,0 +1,11 @@
+#include <libA/libA.h>
+
+#ifndef THE_MAGIC_DEFINE
+#error "missing the magic define"
+#endif
+
+int main()
+{
+ foo();
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/qbspkgconfig-module-provider.qbs b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/qbspkgconfig-module-provider.qbs
new file mode 100644
index 000000000..d2b3654ae
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/qbspkgconfig-module-provider.qbs
@@ -0,0 +1,6 @@
+CppApplication {
+ name: "p"
+ Depends { name: "libA" }
+ files: "main.cpp"
+ qbsModuleProviders: "qbspkgconfig"
+}
diff --git a/tests/auto/blackbox/testdata-providers/removal-version/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/removal-version/module-providers/provider_a.qbs
new file mode 100644
index 000000000..7f358acbc
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/removal-version/module-providers/provider_a.qbs
@@ -0,0 +1,14 @@
+import "../../qbs-module-providers-helpers.js" as Helpers
+
+ModuleProvider {
+ isEager: false
+ property bool deprecated: false
+ PropertyOptions {
+ name: "deprecated"
+ removalVersion: "2.2.0"
+ }
+ relativeSearchPaths: {
+ Helpers.writeModule(outputBaseDir, moduleName, "from_provider_a");
+ return "";
+ }
+}
diff --git a/tests/auto/blackbox/testdata-providers/removal-version/removal-version.qbs b/tests/auto/blackbox/testdata-providers/removal-version/removal-version.qbs
new file mode 100644
index 000000000..1aa5e2ce9
--- /dev/null
+++ b/tests/auto/blackbox/testdata-providers/removal-version/removal-version.qbs
@@ -0,0 +1,12 @@
+Project {
+ qbsModuleProviders: "provider_a"
+ name: "project"
+ Project {
+ name: "innerProject"
+ Product {
+ name: "p1"
+ Depends { name: "qbsmetatestmodule" }
+ }
+ }
+
+}
diff --git a/tests/auto/blackbox/testdata-qt/auto-qrc/auto-qrc.qbs b/tests/auto/blackbox/testdata-qt/auto-qrc/auto-qrc.qbs
index e08f89032..bdbf8b2a1 100644
--- a/tests/auto/blackbox/testdata-qt/auto-qrc/auto-qrc.qbs
+++ b/tests/auto/blackbox/testdata-qt/auto-qrc/auto-qrc.qbs
@@ -1,5 +1,14 @@
+import qbs.Host
+
Project {
QtApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
+
name: "app"
files: ["main.cpp"]
diff --git a/tests/auto/blackbox/testdata-qt/dbus-adaptors/car.cpp b/tests/auto/blackbox/testdata-qt/dbus-adaptors/car.cpp
index 5e4f348d2..ce1d33ed6 100644
--- a/tests/auto/blackbox/testdata-qt/dbus-adaptors/car.cpp
+++ b/tests/auto/blackbox/testdata-qt/dbus-adaptors/car.cpp
@@ -49,7 +49,9 @@
****************************************************************************/
#include "car.h"
-#include <QtWidgets/QtWidgets>
+
+#include <QtGui/QPainter>
+
#include <math.h>
static const double Pi = 3.14159265358979323846264338327950288419717;
diff --git a/tests/auto/blackbox/testdata-qt/dbus-adaptors/main.cpp b/tests/auto/blackbox/testdata-qt/dbus-adaptors/main.cpp
index 0491719d7..197005215 100644
--- a/tests/auto/blackbox/testdata-qt/dbus-adaptors/main.cpp
+++ b/tests/auto/blackbox/testdata-qt/dbus-adaptors/main.cpp
@@ -50,9 +50,15 @@
#include "car.h"
#include "car_adaptor.h"
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
#include <QtWidgets/QApplication>
#include <QtWidgets/QGraphicsView>
#include <QtWidgets/QGraphicsScene>
+#else
+#include <QApplication>
+#include <QGraphicsView>
+#include <QGraphicsScene>
+#endif
#include <QtDBus/QDBusConnection>
int main(int argc, char *argv[])
diff --git a/tests/auto/blackbox/testdata-qt/dbus-interfaces/controller.cpp b/tests/auto/blackbox/testdata-qt/dbus-interfaces/controller.cpp
index eaff5c775..0f7a77efa 100644
--- a/tests/auto/blackbox/testdata-qt/dbus-interfaces/controller.cpp
+++ b/tests/auto/blackbox/testdata-qt/dbus-interfaces/controller.cpp
@@ -48,7 +48,8 @@
**
****************************************************************************/
-#include <QtWidgets>
+#include <QtGlobal>
+#include <QtDBus/QDBusConnection>
#include "controller.h"
#include "car_interface.h"
diff --git a/tests/auto/blackbox/testdata-qt/dbus-interfaces/main.cpp b/tests/auto/blackbox/testdata-qt/dbus-interfaces/main.cpp
index fdd9fc590..c4e6ee485 100644
--- a/tests/auto/blackbox/testdata-qt/dbus-interfaces/main.cpp
+++ b/tests/auto/blackbox/testdata-qt/dbus-interfaces/main.cpp
@@ -48,7 +48,12 @@
**
****************************************************************************/
-#include <QtWidgets>
+#include <QtGlobal>
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+#include <QtWidgets/QApplication>
+#else
+#include <QtGui/QApplication>>
+#endif
#include <QtDBus>
#include "controller.h"
diff --git a/tests/auto/blackbox/testdata-qt/forced-moc/forced-moc.qbs b/tests/auto/blackbox/testdata-qt/forced-moc/forced-moc.qbs
index a59aaa28e..064470a79 100644
--- a/tests/auto/blackbox/testdata-qt/forced-moc/forced-moc.qbs
+++ b/tests/auto/blackbox/testdata-qt/forced-moc/forced-moc.qbs
@@ -1,4 +1,17 @@
+import qbs.Host
+import qbs.Utilities
+
QtApplication {
+ condition: {
+ if (Utilities.versionCompare(Qt.core.version, "5.0") < 0) {
+ console.info("using qt4");
+ return false;
+ }
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
files: "main.cpp"
Group {
name: "QObject service provider"
diff --git a/tests/auto/blackbox/testdata-qt/included-moc-cpp/included-moc-cpp.qbs b/tests/auto/blackbox/testdata-qt/included-moc-cpp/included-moc-cpp.qbs
index 1ed85ccdd..265b0c9e3 100644
--- a/tests/auto/blackbox/testdata-qt/included-moc-cpp/included-moc-cpp.qbs
+++ b/tests/auto/blackbox/testdata-qt/included-moc-cpp/included-moc-cpp.qbs
@@ -1,6 +1,13 @@
-import qbs
+import qbs.Utilities
QtApplication {
+ condition: {
+ if (Utilities.versionCompare(Qt.core.version, "5.0") < 0) {
+ console.info("using qt4");
+ return false;
+ }
+ return true;
+ }
files: [
"main.cpp",
"myobject.cpp",
diff --git a/tests/auto/blackbox/testdata-qt/linker-variant/qt-linker-variant.qbs b/tests/auto/blackbox/testdata-qt/linker-variant/qt-linker-variant.qbs
index ab5889007..c1a77d696 100644
--- a/tests/auto/blackbox/testdata-qt/linker-variant/qt-linker-variant.qbs
+++ b/tests/auto/blackbox/testdata-qt/linker-variant/qt-linker-variant.qbs
@@ -3,7 +3,7 @@ QtApplication {
id: qtConfigProbe
property stringList moduleConfig: Qt.core.moduleConfig
configure: {
- console.info("Qt requires gold: " + moduleConfig.contains("use_gold_linker"));
+ console.info("Qt requires gold: " + moduleConfig.includes("use_gold_linker"));
}
}
files: "main.cpp"
diff --git a/tests/auto/blackbox/testdata-qt/metatypes/metatypes.qbs b/tests/auto/blackbox/testdata-qt/metatypes/metatypes.qbs
new file mode 100644
index 000000000..bbc98c934
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/metatypes/metatypes.qbs
@@ -0,0 +1,28 @@
+import qbs.Utilities
+
+StaticLibrary {
+ name: "mylib"
+
+ Depends { name: "Qt.core" }
+
+ qbs.installPrefix: "some-prefix"
+
+ Probe {
+ id: capabilitiesChecker
+ property string version: Qt.core.version
+ configure: {
+ if (Utilities.versionCompare(version, "5.15") >= 0)
+ console.info("can generate");
+ else
+ console.info("cannot generate");
+ found = true;
+ }
+ }
+
+ files: [
+ "mocableclass1.cpp",
+ "mocableclass1.h",
+ "mocableclass2.cpp",
+ "unmocableclass.cpp",
+ ]
+}
diff --git a/tests/auto/blackbox/testdata-qt/metatypes/mocableclass1.cpp b/tests/auto/blackbox/testdata-qt/metatypes/mocableclass1.cpp
new file mode 100644
index 000000000..06adc8ca5
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/metatypes/mocableclass1.cpp
@@ -0,0 +1,3 @@
+#include "mocableclass1.h"
+
+MocableClass1::MocableClass1(QObject *parent) : QObject(parent) {}
diff --git a/tests/auto/blackbox/testdata-qt/metatypes/mocableclass1.h b/tests/auto/blackbox/testdata-qt/metatypes/mocableclass1.h
new file mode 100644
index 000000000..020c15179
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/metatypes/mocableclass1.h
@@ -0,0 +1,8 @@
+#include <QObject>
+
+class MocableClass1 : public QObject
+{
+ Q_OBJECT
+public:
+ MocableClass1(QObject *parent = nullptr);
+};
diff --git a/tests/auto/blackbox/testdata-qt/metatypes/mocableclass2.cpp b/tests/auto/blackbox/testdata-qt/metatypes/mocableclass2.cpp
new file mode 100644
index 000000000..bf538913a
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/metatypes/mocableclass2.cpp
@@ -0,0 +1,10 @@
+#include <QObject>
+
+class MocableClass2 : public QObject
+{
+ Q_OBJECT
+public:
+ MocableClass2(QObject *parent) : QObject(parent) {}
+};
+
+#include <mocableclass2.moc>
diff --git a/tests/auto/blackbox/testdata-qt/metatypes/unmocableclass.cpp b/tests/auto/blackbox/testdata-qt/metatypes/unmocableclass.cpp
new file mode 100644
index 000000000..34330d189
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/metatypes/unmocableclass.cpp
@@ -0,0 +1,7 @@
+#include <QObject>
+
+class UnmocableClass : public QObject
+{
+public:
+ UnmocableClass(QObject *parent) : QObject(parent) {}
+};
diff --git a/tests/auto/blackbox/testdata-qt/mixed-build-variants/mixed-build-variants.qbs b/tests/auto/blackbox/testdata-qt/mixed-build-variants/mixed-build-variants.qbs
index 7d8ab1b90..dea30eef4 100644
--- a/tests/auto/blackbox/testdata-qt/mixed-build-variants/mixed-build-variants.qbs
+++ b/tests/auto/blackbox/testdata-qt/mixed-build-variants/mixed-build-variants.qbs
@@ -1,6 +1,6 @@
QtApplication {
Properties {
- condition: qbs.toolchain.contains("msvc")
+ condition: qbs.toolchain.includes("msvc")
Qt.core.qtBuildVariant: "release"
}
Qt.core.qtBuildVariant: "dummy"
diff --git a/tests/auto/blackbox/testdata-qt/moc-compiler-defines/main.cpp b/tests/auto/blackbox/testdata-qt/moc-compiler-defines/main.cpp
new file mode 100644
index 000000000..d3b8f310e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/moc-compiler-defines/main.cpp
@@ -0,0 +1,7 @@
+#include "object.h"
+
+int main()
+{
+ QObject o;
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata-qt/moc-compiler-defines/moc-compiler-defines.qbs b/tests/auto/blackbox/testdata-qt/moc-compiler-defines/moc-compiler-defines.qbs
new file mode 100644
index 000000000..e184f554e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/moc-compiler-defines/moc-compiler-defines.qbs
@@ -0,0 +1,3 @@
+QtApplication {
+ files: ["main.cpp", "object.h", "object.cpp"]
+}
diff --git a/tests/auto/blackbox/testdata-qt/moc-compiler-defines/object.cpp b/tests/auto/blackbox/testdata-qt/moc-compiler-defines/object.cpp
new file mode 100644
index 000000000..7ffcf419b
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/moc-compiler-defines/object.cpp
@@ -0,0 +1,6 @@
+#include "object.h"
+
+Object::Object(QObject *parent) : QObject(parent)
+{
+
+}
diff --git a/tests/auto/blackbox/testdata-qt/moc-compiler-defines/object.h b/tests/auto/blackbox/testdata-qt/moc-compiler-defines/object.h
new file mode 100644
index 000000000..3221d1173
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/moc-compiler-defines/object.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OBJECT_H
+#define OBJECT_H
+
+#include <QtCore/QObject>
+
+// These were not defined during the moc run (QBS-1592).
+// Do not use Q_OS_UNIX here as it is a fallback value which is defined when nothing else is.
+#if defined(Q_OS_DARWIN) || defined(Q_OS_LINUX) || defined(Q_OS_WIN)
+
+class Object : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Object(QObject *parent = nullptr);
+};
+
+#endif
+
+#endif // OBJECT_H
diff --git a/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/lib.cpp b/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/lib.cpp
new file mode 100644
index 000000000..675960f2d
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/lib.cpp
@@ -0,0 +1,8 @@
+#include <QtDebug>
+
+#include "lib.h"
+
+SymbolsTest::SymbolsTest()
+{
+ // qDebug() << "hallo";
+}
diff --git a/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/lib.h b/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/lib.h
new file mode 100644
index 000000000..0cb4a23c4
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/lib.h
@@ -0,0 +1,18 @@
+#ifndef SYMBOLSTEST_H
+#define SYMBOLSTEST_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(SYMBOLSTEST_LIBRARY)
+# define SYMBOLSTEST_EXPORT Q_DECL_EXPORT
+#else
+# define SYMBOLSTEST_EXPORT Q_DECL_IMPORT
+#endif
+
+class SYMBOLSTEST_EXPORT SymbolsTest
+{
+ public:
+ SymbolsTest();
+};
+
+#endif // SYMBOLSTEST_H
diff --git a/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/main.cpp b/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/main.cpp
new file mode 100644
index 000000000..5047a34e3
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/main.cpp
@@ -0,0 +1,3 @@
+int main()
+{
+}
diff --git a/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/symbols-test.qbs b/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/symbols-test.qbs
new file mode 100644
index 000000000..a614d96c4
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/no-relink-on-qdebug/symbols-test.qbs
@@ -0,0 +1,27 @@
+Project {
+ CppApplication {
+ name: "app"
+ Depends { name: "lib" }
+ property bool dummy: {
+ console.info("is GCC: " + qbs.toolchain.includes("gcc"));
+ console.info("is MinGW: " + qbs.toolchain.includes("mingw"));
+ console.info("is Darwin: " + qbs.targetOS.includes("darwin"));
+ }
+ files: "main.cpp"
+ }
+
+ DynamicLibrary {
+ name: "lib"
+ Depends { name: "Qt.core" }
+
+ cpp.cxxLanguageVersion: "c++11"
+ cpp.defines: "SYMBOLSTEST_LIBRARY"
+
+ files: [
+ "lib.cpp",
+ "lib.h",
+ ]
+
+ Export { Depends { name: "Qt.core" } }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-qt/pkgconfig-qt/dump-libpath.qbs b/tests/auto/blackbox/testdata-qt/pkgconfig-qt/dump-libpath.qbs
new file mode 100644
index 000000000..9aa1c5d17
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/pkgconfig-qt/dump-libpath.qbs
@@ -0,0 +1,6 @@
+QtApplication {
+ files: "main.cpp"
+ property bool test: {
+ console.info("libPath="+Qt.core.libPath)
+ }
+}
diff --git a/tests/auto/blackbox/testdata-qt/pkgconfig-qt/main.cpp b/tests/auto/blackbox/testdata-qt/pkgconfig-qt/main.cpp
new file mode 100644
index 000000000..237c8ce18
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/pkgconfig-qt/main.cpp
@@ -0,0 +1 @@
+int main() {}
diff --git a/tests/auto/blackbox/testdata-qt/pkgconfig-qt/module-providers/dummyProvider.qbs b/tests/auto/blackbox/testdata-qt/pkgconfig-qt/module-providers/dummyProvider.qbs
new file mode 100644
index 000000000..6ed2ca82e
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/pkgconfig-qt/module-providers/dummyProvider.qbs
@@ -0,0 +1,3 @@
+ModuleProvider {
+ relativeSearchPaths: ""
+}
diff --git a/tests/auto/blackbox/testdata-qt/pkgconfig-qt/pkgconfig-qt.qbs b/tests/auto/blackbox/testdata-qt/pkgconfig-qt/pkgconfig-qt.qbs
new file mode 100644
index 000000000..a1d8d8974
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/pkgconfig-qt/pkgconfig-qt.qbs
@@ -0,0 +1,6 @@
+QtApplication {
+ name: "p"
+ files: "main.cpp"
+ qbsSearchPaths: "."
+ qbsModuleProviders: "qbspkgconfig"
+}
diff --git a/tests/auto/blackbox/testdata-qt/pkgconfig/pkgconfig.qbs b/tests/auto/blackbox/testdata-qt/pkgconfig/pkgconfig.qbs
index 04b0097ef..b2d411154 100644
--- a/tests/auto/blackbox/testdata-qt/pkgconfig/pkgconfig.qbs
+++ b/tests/auto/blackbox/testdata-qt/pkgconfig/pkgconfig.qbs
@@ -1,8 +1,15 @@
+import qbs.Host
import qbs.Probes
Project {
property string name: 'pkgconfig'
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: project.name
Probes.PkgConfigProbe {
id: pkgConfig
diff --git a/tests/auto/blackbox/testdata-qt/plugin-meta-data/plugin-meta-data.qbs b/tests/auto/blackbox/testdata-qt/plugin-meta-data/plugin-meta-data.qbs
index f018b34e0..dbe64d5ea 100644
--- a/tests/auto/blackbox/testdata-qt/plugin-meta-data/plugin-meta-data.qbs
+++ b/tests/auto/blackbox/testdata-qt/plugin-meta-data/plugin-meta-data.qbs
@@ -1,5 +1,20 @@
+import qbs.Host
+import qbs.Utilities
+
Project {
QtApplication {
+ condition: {
+ if (Utilities.versionCompare(Qt.core.version, "5.0") < 0) {
+ // qt4 moc can't be used with pluginMetaData
+ console.info("using qt4");
+ return false;
+ }
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
+
name: "app"
consoleApplication: true
@@ -8,7 +23,7 @@ Project {
cpp.cxxLanguageVersion: "c++11"
Properties {
- condition: qbs.targetOS.contains("unix")
+ condition: qbs.targetOS.includes("unix")
cpp.rpaths: [cpp.rpathOrigin]
}
@@ -28,12 +43,12 @@ Project {
Depends { name: "Qt.core" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
cpp.defines: [Qt.core.staticBuild ? "QT_STATICPLUGIN" : "QT_PLUGIN"]
cpp.cxxLanguageVersion: "c++11"
- cpp.sonamePrefix: qbs.targetOS.contains("darwin") ? "@rpath" : undefined
+ cpp.sonamePrefix: qbs.targetOS.includes("darwin") ? "@rpath" : undefined
cpp.includePaths: ["."]
Qt.core.pluginMetaData: ["theKey=theValue"]
diff --git a/tests/auto/blackbox/testdata-qt/plugin-support/plugin-support.qbs b/tests/auto/blackbox/testdata-qt/plugin-support/plugin-support.qbs
index c554a7dc2..8e0923e94 100644
--- a/tests/auto/blackbox/testdata-qt/plugin-support/plugin-support.qbs
+++ b/tests/auto/blackbox/testdata-qt/plugin-support/plugin-support.qbs
@@ -1,4 +1,14 @@
+import qbs.Utilities
+
QtGuiApplication {
+ condition: {
+ // pluginTypes empty for Qt4
+ if (Utilities.versionCompare(Qt.core.version, "5.0") < 0) {
+ console.info("using qt4");
+ return false;
+ }
+ return true;
+ }
Probe {
id: staticProbe
property bool isStaticQt: Qt.gui.isStaticLibrary
diff --git a/tests/auto/blackbox/testdata-qt/qdoc/qdoc.qbs b/tests/auto/blackbox/testdata-qt/qdoc/qdoc.qbs
new file mode 100644
index 000000000..4b82bc405
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/qdoc/qdoc.qbs
@@ -0,0 +1,22 @@
+import qbs.Utilities
+
+Product {
+ condition: {
+ var ok = Utilities.versionCompare(Qt.core.version, "5.0.0") >= 0;
+ if (!ok)
+ console.info("Qt is too old");
+ return ok;
+ }
+ name: "QDoc Test"
+ type: ["qdoc-html", "qch"]
+
+ Depends { name: "Qt.core" }
+
+ files: ["qdoc.qdoc"]
+
+ Group {
+ name: "main qdocconf file"
+ files: "qdoc.qdocconf"
+ fileTags: "qdocconf-main"
+ }
+}
diff --git a/tests/auto/blackbox/testdata-qt/qdoc/qdoc.qdoc b/tests/auto/blackbox/testdata-qt/qdoc/qdoc.qdoc
new file mode 100644
index 000000000..9e44e0948
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/qdoc/qdoc.qdoc
@@ -0,0 +1,7 @@
+/*!
+ \page index.html
+
+ \title QDoc Test
+
+ QDoc Test is a test for QDoc.
+*/ \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata-qt/qdoc/qdoc.qdocconf b/tests/auto/blackbox/testdata-qt/qdoc/qdoc.qdocconf
new file mode 100644
index 000000000..8c82bb575
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/qdoc/qdoc.qdocconf
@@ -0,0 +1,13 @@
+project = QDoc Test
+description = QDoc Test
+
+headerdirs = .
+sourcedirs = .
+exampledirs = .
+
+outputdir = doc/html
+
+qhp.projects = QDocTest
+qhp.QDocTest.file = qdoctest.qhp
+qhp.QDocTest.namespace = org.qt-project.QDocTest
+qhp.QDocTest.virtualFolder = doc
diff --git a/tests/auto/blackbox/testdata-qt/qml-debugging/qml-debugging.qbs b/tests/auto/blackbox/testdata-qt/qml-debugging/qml-debugging.qbs
index 8176a7c3e..0885e6b0b 100644
--- a/tests/auto/blackbox/testdata-qt/qml-debugging/qml-debugging.qbs
+++ b/tests/auto/blackbox/testdata-qt/qml-debugging/qml-debugging.qbs
@@ -4,4 +4,9 @@ QtApplication {
Depends { name: "Qt.quick" }
Qt.quick.qmlDebugging: true
files: "main.cpp"
+ Probe {
+ id: checker
+ property bool isGcc: qbs.toolchain.contains("gcc")
+ configure: { console.info("is gcc: " + isGcc); }
+ }
}
diff --git a/tests/auto/blackbox/testdata-qt/qmltyperegistrar/example.qml b/tests/auto/blackbox/testdata-qt/qmltyperegistrar/example.qml
new file mode 100644
index 000000000..ef97df12d
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/qmltyperegistrar/example.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// ![0]
+import People 1.0
+
+Person {
+ name: "Bob Jones"
+ shoeSize: 12
+}
+// ![0]
diff --git a/tests/auto/blackbox/testdata-qt/qmltyperegistrar/main.cpp b/tests/auto/blackbox/testdata-qt/qmltyperegistrar/main.cpp
new file mode 100644
index 000000000..6c3920f04
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/qmltyperegistrar/main.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QCoreApplication>
+#include <QQmlEngine>
+#include <QQmlComponent>
+#include <QDebug>
+#include "person.h"
+
+int main(int argc, char ** argv)
+{
+ QCoreApplication app(argc, argv);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine, QUrl("qrc:example.qml"));
+ auto *person = qobject_cast<Person *>(component.create());
+ if (person) {
+ qWarning() << "The person's name is" << person->name();
+ qWarning() << "They wear a" << person->shoeSize() << "sized shoe";
+ } else {
+ qWarning() << component.errors();
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/tests/auto/blackbox/testdata-qt/qmltyperegistrar/person.cpp b/tests/auto/blackbox/testdata-qt/qmltyperegistrar/person.cpp
new file mode 100644
index 000000000..de4a33dd0
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/qmltyperegistrar/person.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "person.h"
+
+// ![0]
+Person::Person(QObject *parent)
+: QObject(parent), m_shoeSize(0)
+{
+}
+
+QString Person::name() const
+{
+ return m_name;
+}
+
+void Person::setName(const QString &n)
+{
+ m_name = n;
+}
+
+int Person::shoeSize() const
+{
+ return m_shoeSize;
+}
+
+void Person::setShoeSize(int s)
+{
+ m_shoeSize = s;
+}
+
+// ![0]
diff --git a/tests/auto/blackbox/testdata-qt/qmltyperegistrar/person.h b/tests/auto/blackbox/testdata-qt/qmltyperegistrar/person.h
new file mode 100644
index 000000000..530c335de
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/qmltyperegistrar/person.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef PERSON_H
+#define PERSON_H
+
+#include <QObject>
+#include <QtQml/qqml.h>
+
+//![0]
+class Person : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString name READ name WRITE setName)
+ Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
+ QML_ELEMENT
+public:
+ Person(QObject *parent = nullptr);
+
+ QString name() const;
+ void setName(const QString &);
+
+ int shoeSize() const;
+ void setShoeSize(int);
+
+private:
+ QString m_name;
+ int m_shoeSize;
+};
+//![0]
+
+#endif // PERSON_H
diff --git a/tests/auto/blackbox/testdata-qt/qmltyperegistrar/qmltyperegistrar.qbs b/tests/auto/blackbox/testdata-qt/qmltyperegistrar/qmltyperegistrar.qbs
new file mode 100644
index 000000000..68dc83743
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/qmltyperegistrar/qmltyperegistrar.qbs
@@ -0,0 +1,33 @@
+import qbs.Utilities
+
+CppApplication {
+ name: "myapp"
+ Depends { name: "Qt.qml" }
+
+ Qt.qml.importVersion: "1"
+ cpp.includePaths: sourceDirectory
+ qbs.installPrefix: ""
+
+ files: [
+ "main.cpp",
+ "person.cpp",
+ "person.h",
+ ]
+
+ Group {
+ files: "example.qml"
+ fileTags: "qt.core.resource_data"
+ }
+
+ Probe {
+ id: versionProbe
+ property string version: Qt.core.version
+ configure: {
+ if (Utilities.versionCompare(version, "5.15") >= 0)
+ console.info("has registrar");
+ else
+ console.info("does not have registrar");
+ found = true;
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-qt/qrc/i.qbs b/tests/auto/blackbox/testdata-qt/qrc/i.qbs
index c005490c4..45275106d 100644
--- a/tests/auto/blackbox/testdata-qt/qrc/i.qbs
+++ b/tests/auto/blackbox/testdata-qt/qrc/i.qbs
@@ -1,5 +1,18 @@
+import qbs.Host
+import qbs.Utilities
+
Project {
Product {
+ condition: {
+ if (Utilities.versionCompare(Qt.core.version, "5.0") < 0) {
+ console.info("using qt4");
+ return false;
+ }
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
consoleApplication: true
type: "application"
name: "i"
diff --git a/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs b/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs
index 991e4ddcb..6fee91479 100644
--- a/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs
+++ b/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs
@@ -1,5 +1,6 @@
import qbs.Environment
import qbs.FileInfo
+import qbs.Host
import qbs.Utilities
Project {
@@ -24,6 +25,12 @@ Project {
}
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "runner"
type: ["runner"]
Depends { name: "app" }
@@ -33,18 +40,22 @@ Project {
prepare: {
var cmd = new Command(input.filePath);
cmd.description = "running " + input.filePath;
- var pathVar;
- var pathValue;
- if (product.qbs.hostOS.contains("windows")) {
- pathVar = "PATH";
- pathValue = FileInfo.toWindowsSeparators(input["Qt.core"].binPath);
+
+ var envVars = {};
+ if (Host.os().includes("windows")) {
+ envVars["PATH"] = FileInfo.toWindowsSeparators(input["Qt.core"].binPath);
+ } else if (Host.os().includes("macos")) {
+ envVars["DYLD_LIBRARY_PATH"] = input["Qt.core"].libPath;
+ envVars["DYLD_FRAMEWORK_PATH"] = input["Qt.core"].libPath;
} else {
- pathVar = "LD_LIBRARY_PATH";
- pathValue = input["Qt.core"].libPath;
+ envVars["LD_LIBRARY_PATH"] = input["Qt.core"].libPath;
}
- var oldValue = Environment.getEnv(pathVar) || "";
- var newValue = pathValue + product.qbs.pathListSeparator + oldValue;
- cmd.environment = [pathVar + '=' + newValue];
+ for (var varName in envVars) {
+ var oldValue = Environment.getEnv(varName) || "";
+ var newValue = envVars[varName] + FileInfo.pathListSeparator() + oldValue;
+ cmd.environment.push(varName + '=' + newValue);
+ }
+
return [cmd];
}
}
diff --git a/tests/auto/blackbox/testdata-qt/quick-compiler/quick-compiler.qbs b/tests/auto/blackbox/testdata-qt/quick-compiler/quick-compiler.qbs
index b141c8672..793d261e9 100644
--- a/tests/auto/blackbox/testdata-qt/quick-compiler/quick-compiler.qbs
+++ b/tests/auto/blackbox/testdata-qt/quick-compiler/quick-compiler.qbs
@@ -1,5 +1,9 @@
CppApplication {
- Depends { name: "Qt.quick" }
+ Depends {
+ name: "Qt.quick"
+ // Must fail when using Qt4
+ versionAtLeast: "5"
+ }
Qt.quick.useCompiler: Qt.quick.compilerAvailable
cpp.cxxLanguageVersion: "c++11"
diff --git a/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/lib.cpp b/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/lib.cpp
new file mode 100644
index 000000000..dd79cbe6c
--- /dev/null
+++ b/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/lib.cpp
@@ -0,0 +1 @@
+void function() {}
diff --git a/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/static-qt-plugin-linking.qbs b/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/static-qt-plugin-linking.qbs
index 745fe5527..e4e56bb4b 100644
--- a/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/static-qt-plugin-linking.qbs
+++ b/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/static-qt-plugin-linking.qbs
@@ -11,11 +11,16 @@ Product {
}
Group {
- condition: type.contains("application")
+ condition: type.includes("application")
files: "main.cpp"
}
+ Group {
+ condition: type.includes("staticlibrary")
+ files: "lib.cpp"
+ }
+
Depends { name: "Qt.core" }
Depends { name: "Qt.gui" }
- Depends { name: "Qt.qminimal"; condition: Qt.core.staticBuild; }
+ Depends { name: "Qt.qminimal"; condition: Qt.core.staticBuild }
}
diff --git a/tests/auto/blackbox/testdata-windows/codesign/app.cpp b/tests/auto/blackbox/testdata-windows/codesign/app.cpp
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata-windows/codesign/app.cpp
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/tests/auto/blackbox/testdata-windows/codesign/codesign.qbs b/tests/auto/blackbox/testdata-windows/codesign/codesign.qbs
new file mode 100644
index 000000000..1963f6926
--- /dev/null
+++ b/tests/auto/blackbox/testdata-windows/codesign/codesign.qbs
@@ -0,0 +1,43 @@
+Project {
+ name: "p"
+
+ property bool enableSigning: true
+ property string hashAlgorithm
+ property string subjectName
+ property string signingTimestamp
+
+ CppApplication {
+ name: "A"
+ files: "app.cpp"
+ condition: qbs.toolchain.includes("msvc")
+ codesign.enableCodeSigning: project.enableSigning
+ codesign.hashAlgorithm: project.hashAlgorithm
+ codesign.subjectName: project.subjectName
+ codesign.signingTimestamp: project.signingTimestamp
+ codesign.timestampAlgorithm: "sha256"
+ install: true
+ installDir: ""
+ property bool dummy: {
+ if (codesign.codesignPath)
+ console.info("signtool path: %%" + codesign.codesignPath + "%%");
+ }
+ }
+
+ DynamicLibrary {
+ Depends { name: "cpp" }
+ name: "B"
+ files: "app.cpp"
+ condition: qbs.toolchain.includes("msvc")
+ codesign.enableCodeSigning: project.enableSigning
+ codesign.hashAlgorithm: project.hashAlgorithm
+ codesign.subjectName: project.subjectName
+ codesign.signingTimestamp: project.signingTimestamp
+ codesign.timestampAlgorithm: "sha256"
+ install: true
+ installDir: ""
+ property bool dummy: {
+ if (codesign.codesignPath)
+ console.info("signtool path: %%" + codesign.codesignPath + "%%");
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata-windows/innosetup/inc/qbsinc.iss b/tests/auto/blackbox/testdata-windows/innosetup/inc/qbsinc.iss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ 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 c9f6a22e8..fd8868900 100644
--- a/tests/auto/blackbox/testdata/innosetup/innosetup.qbs
+++ b/tests/auto/blackbox/testdata-windows/innosetup/innosetup.qbs
@@ -2,6 +2,11 @@ import qbs.FileInfo
Project {
InnoSetup {
+ property bool _test: {
+ var present = qbs.targetOS.includes("windows") && innosetup.present;
+ console.info("has innosetup: " + present);
+ }
+
name: "QbsSetup"
targetName: "qbs.setup.test"
version: "1.5"
@@ -12,11 +17,9 @@ Project {
innosetup.includePaths: ["inc"]
innosetup.defines: ["MyProgram=" + name, "MyProgramVersion=" + version]
innosetup.compilerFlags: ["/V9"]
- qbs.targetPlatform: "windows"
}
InnoSetup {
name: "Example1"
files: [FileInfo.joinPaths(innosetup.toolchainInstallPath, "Examples", name + ".iss")]
- qbs.targetPlatform: "windows"
}
}
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 db65e127f..3ef8c30e7 100644
--- a/tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs
+++ b/tests/auto/blackbox/testdata-windows/innosetupDependencies/innosetupDependencies.qbs
@@ -2,6 +2,10 @@ import qbs.TextFile
Project {
InnoSetup {
+ property bool _test: {
+ var present = qbs.targetOS.includes("windows") && innosetup.present;
+ console.info("has innosetup: " + present);
+ }
Depends { name: "app" }
Depends { name: "lib" }
name: "QbsSetup"
diff --git a/tests/auto/blackbox/testdata-windows/innosetupDependencies/main.c b/tests/auto/blackbox/testdata-windows/innosetupDependencies/main.c
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata-windows/innosetupDependencies/main.c
@@ -0,0 +1 @@
+int main() { return 0; }
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..acc7cf7b3 100644
--- a/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs
+++ b/tests/auto/blackbox/testdata-windows/wix/WiXInstallers.qbs
@@ -1,4 +1,5 @@
import qbs.FileInfo
+import qbs.Host
Project {
WindowsInstallerPackage {
@@ -12,14 +13,14 @@ 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)])
}
}
WindowsSetupPackage {
Depends { name: "QbsSetup" }
- condition: qbs.hostOS.contains("windows") // currently does not work in Wine with WiX 3.9
+ condition: Host.os().includes("windows") // currently does not work in Wine with WiX 3.9
name: "QbsBootstrapper"
targetName: "qbs-setup-" + qbs.architecture
files: ["QbsBootstrapper.wxs"]
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-windows/wixDependencies/main.c b/tests/auto/blackbox/testdata-windows/wixDependencies/main.c
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata-windows/wixDependencies/main.c
@@ -0,0 +1 @@
+int main() { return 0; }
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/allowed-values/allowed-values.qbs b/tests/auto/blackbox/testdata/allowed-values/allowed-values.qbs
new file mode 100644
index 000000000..699713770
--- /dev/null
+++ b/tests/auto/blackbox/testdata/allowed-values/allowed-values.qbs
@@ -0,0 +1,19 @@
+Product {
+ Depends { name: "a" }
+ // tests VariantValue
+ property string prop
+ PropertyOptions {
+ name: "prop"
+ description: "Some prop"
+ allowedValues: "foo"
+ }
+ // tests JSValue
+ property string prop2 // setter for otherProp
+ property string otherProp: prop2
+ PropertyOptions {
+ name: "otherProp"
+ description: "Some other prop"
+ allowedValues: "foo"
+ }
+ name: "p"
+}
diff --git a/tests/auto/blackbox/testdata/allowed-values/modules/a/a.qbs b/tests/auto/blackbox/testdata/allowed-values/modules/a/a.qbs
new file mode 100644
index 000000000..2bbcde525
--- /dev/null
+++ b/tests/auto/blackbox/testdata/allowed-values/modules/a/a.qbs
@@ -0,0 +1,18 @@
+Module {
+ // tests VariantValue
+ property stringList prop
+ PropertyOptions {
+ name: "prop"
+ description: "Some prop"
+ allowedValues: ["foo", "bar"]
+ }
+ // tests JSValue
+ property stringList prop2 // setter for otherProp
+ property stringList otherProp: prop2
+ PropertyOptions {
+ name: "otherProp"
+ description: "Some other prop"
+ allowedValues: ["foo", "bar"]
+ }
+}
+
diff --git a/tests/auto/blackbox/testdata/assembly/assembly.qbs b/tests/auto/blackbox/testdata/assembly/assembly.qbs
index f7bd4ecad..9d5584af5 100644
--- a/tests/auto/blackbox/testdata/assembly/assembly.qbs
+++ b/tests/auto/blackbox/testdata/assembly/assembly.qbs
@@ -30,9 +30,9 @@ Project {
name : "testa"
files : [ "testa.s" ]
Depends { name: "cpp" }
- condition: qbs.toolchain.contains("gcc")
+ condition: qbs.toolchain.includes("gcc")
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -40,9 +40,9 @@ Project {
name : "testb"
files : [ "testb.S" ]
Depends { name: "cpp" }
- condition: qbs.toolchain.contains("gcc")
+ condition: qbs.toolchain.includes("gcc")
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -50,9 +50,9 @@ Project {
name : "testc"
files : [ "testc.sx" ]
Depends { name: "cpp" }
- condition: qbs.toolchain.contains("gcc")
+ condition: qbs.toolchain.includes("gcc")
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -63,10 +63,10 @@ Project {
files: ["testd_" + qbs.architecture + ".asm"]
}
Depends { name: "cpp" }
- condition: qbs.toolchain.contains("msvc")
+ condition: qbs.toolchain.includes("msvc")
&& (qbs.architecture === "x86" || qbs.architecture === "x86_64")
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
diff --git a/tests/auto/blackbox/testdata/autotest-timeout/autotests-timeout.qbs b/tests/auto/blackbox/testdata/autotest-timeout/autotests-timeout.qbs
index 49ee35d3a..b6094ed22 100644
--- a/tests/auto/blackbox/testdata/autotest-timeout/autotests-timeout.qbs
+++ b/tests/auto/blackbox/testdata/autotest-timeout/autotests-timeout.qbs
@@ -1,12 +1,20 @@
+import qbs.Host
+
Project {
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "testApp"
type: ["application", "autotest"]
Depends { name: "autotest" }
cpp.cxxLanguageVersion: "c++11"
cpp.minimumOsxVersion: "10.8" // For <chrono>
Properties {
- condition: qbs.toolchain.contains("gcc")
+ condition: qbs.toolchain.includes("gcc")
cpp.driverFlags: "-pthread"
}
files: "test-main.cpp"
@@ -14,7 +22,7 @@ Project {
AutotestRunner {
Depends {
name: "cpp" // Make sure build environment is set up properly.
- condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("gcc")
+ condition: Host.os().includes("windows") && qbs.toolchain.includes("gcc")
}
}
}
diff --git a/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs b/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs
index 7ae6cef73..bea74796a 100644
--- a/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs
+++ b/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs
@@ -1,7 +1,14 @@
import qbs.FileInfo
+import qbs.Host
Project {
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "helper-app"
type: ["application", "test-helper"]
consoleApplication: true
@@ -23,7 +30,7 @@ Project {
AutotestRunner {
Depends {
name: "cpp" // Make sure build environment is set up properly.
- condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("gcc")
+ condition: Host.os().includes("windows") && qbs.toolchain.includes("gcc")
}
arguments: FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix, "bin")
auxiliaryInputs: "test-helper"
diff --git a/tests/auto/blackbox/testdata/autotests/autotests.qbs b/tests/auto/blackbox/testdata/autotests/autotests.qbs
index 10334156e..cfb7fc560 100644
--- a/tests/auto/blackbox/testdata/autotests/autotests.qbs
+++ b/tests/auto/blackbox/testdata/autotests/autotests.qbs
@@ -1,9 +1,17 @@
+import qbs.Host
+
Project {
references: ["test1", "test2", "test3"]
AutotestRunner {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
Depends {
name: "cpp" // Make sure build environment is set up properly.
- condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("gcc")
+ condition: Host.os().includes("windows") && qbs.toolchain.includes("gcc")
}
}
}
diff --git a/tests/auto/blackbox/testdata/badInterpreter/badInterpreter.qbs b/tests/auto/blackbox/testdata/badInterpreter/badInterpreter.qbs
index bef82a003..3c8f64c6c 100644
--- a/tests/auto/blackbox/testdata/badInterpreter/badInterpreter.qbs
+++ b/tests/auto/blackbox/testdata/badInterpreter/badInterpreter.qbs
@@ -1,4 +1,13 @@
+import qbs.Host
+
Project {
+ property bool enabled: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
+
qbsSearchPaths: base.concat(["qbs"])
Product {
diff --git a/tests/auto/blackbox/testdata/build-variant-defaults/build-variant-defaults.qbs b/tests/auto/blackbox/testdata/build-variant-defaults/build-variant-defaults.qbs
new file mode 100644
index 000000000..4015817ca
--- /dev/null
+++ b/tests/auto/blackbox/testdata/build-variant-defaults/build-variant-defaults.qbs
@@ -0,0 +1,16 @@
+CppApplication {
+ property bool validate: {
+ var valid = true;
+ if (qbs.buildVariant === "release") {
+ valid = !qbs.enableDebugCode && !qbs.debugInformation && qbs.optimization === "fast";
+ } else if (qbs.buildVariant === "debug") {
+ valid = qbs.enableDebugCode && qbs.debugInformation && qbs.optimization === "none";
+ } else if (qbs.buildVariant === "profiling") {
+ valid = !qbs.enableDebugCode && qbs.debugInformation && qbs.optimization === "fast";
+ }
+
+ if (!valid)
+ throw "Invalid defaults";
+ return valid;
+ }
+}
diff --git a/tests/auto/blackbox/testdata/build-variant-defaults/main.cpp b/tests/auto/blackbox/testdata/build-variant-defaults/main.cpp
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata/build-variant-defaults/main.cpp
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/tests/auto/blackbox/testdata/buildenv-change/buildenv-change.qbs b/tests/auto/blackbox/testdata/buildenv-change/buildenv-change.qbs
index 6c0bcc73e..54005e76a 100644
--- a/tests/auto/blackbox/testdata/buildenv-change/buildenv-change.qbs
+++ b/tests/auto/blackbox/testdata/buildenv-change/buildenv-change.qbs
@@ -3,7 +3,7 @@ CppApplication {
id: dummy
property stringList toolchain: qbs.toolchain
configure: {
- if (toolchain.contains("msvc"))
+ if (toolchain.includes("msvc"))
console.info("msvc");
}
}
diff --git a/tests/auto/blackbox/testdata/capnproto/bar.capnp b/tests/auto/blackbox/testdata/capnproto/bar.capnp
new file mode 100644
index 000000000..a0e8a0f8c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/bar.capnp
@@ -0,0 +1,8 @@
+@0xc967c84bcca70a1d;
+
+using Foo = import "foo.capnp";
+
+struct Bar {
+ foo @0 :Foo.Foo;
+ # Use type "Foo" defined in foo.capnp.
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/baz.capnp b/tests/auto/blackbox/testdata/capnproto/baz.capnp
new file mode 100644
index 000000000..8b2fe4faf
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/baz.capnp
@@ -0,0 +1,8 @@
+@0xc967c84bcca70a1d;
+
+using Foo = import "/imports/foo.capnp";
+
+struct Baz {
+ foo @0 :Foo.Foo;
+ # Use type "Foo" defined in foo.capnp.
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/capnproto_absolute_import.cpp b/tests/auto/blackbox/testdata/capnproto/capnproto_absolute_import.cpp
new file mode 100644
index 000000000..0e8979eec
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/capnproto_absolute_import.cpp
@@ -0,0 +1,14 @@
+#include "baz.capnp.h"
+
+#include <capnp/message.h>
+
+int main()
+{
+ ::capnp::MallocMessageBuilder message;
+
+ auto baz = message.initRoot<Baz>();
+ auto foo = baz.initFoo();
+ foo.setStr("hello");
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/capnproto_absolute_import.qbs b/tests/auto/blackbox/testdata/capnproto/capnproto_absolute_import.qbs
new file mode 100644
index 000000000..4674d6a6a
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/capnproto_absolute_import.qbs
@@ -0,0 +1,21 @@
+import qbs.Host
+
+CppApplication {
+ Depends { name: "capnproto.cpp"; required: false }
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ if (!capnproto.cpp.present)
+ console.info("capnproto is not present");
+ return result && capnproto.cpp.present;
+ }
+ cpp.minimumMacosVersion: "10.8"
+ capnproto.cpp.importPaths: "."
+ files: [
+ "baz.capnp",
+ "capnproto_absolute_import.cpp",
+ "imports/foo.capnp",
+ ]
+ qbs.buildVariant: "release"
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/capnproto_cpp.cpp b/tests/auto/blackbox/testdata/capnproto/capnproto_cpp.cpp
new file mode 100644
index 000000000..b9f729955
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/capnproto_cpp.cpp
@@ -0,0 +1,13 @@
+#include "foo.capnp.h"
+
+#include <capnp/message.h>
+
+int main()
+{
+ ::capnp::MallocMessageBuilder message;
+
+ auto foo = message.initRoot<Foo>();
+ foo.setStr("hello");
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/capnproto_cpp.qbs b/tests/auto/blackbox/testdata/capnproto/capnproto_cpp.qbs
new file mode 100644
index 000000000..9f287e906
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/capnproto_cpp.qbs
@@ -0,0 +1,19 @@
+import qbs.Host
+
+CppApplication {
+ Depends { name: "capnproto.cpp"; required: false }
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ if (!capnproto.cpp.present)
+ console.info("capnproto is not present");
+ return result && capnproto.cpp.present;
+ }
+ cpp.minimumMacosVersion: "10.8"
+ files: [
+ "capnproto_cpp.cpp",
+ "foo.capnp"
+ ]
+ qbs.buildVariant: "release"
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/capnproto_relative_import.cpp b/tests/auto/blackbox/testdata/capnproto/capnproto_relative_import.cpp
new file mode 100644
index 000000000..5116bd3d6
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/capnproto_relative_import.cpp
@@ -0,0 +1,14 @@
+#include "bar.capnp.h"
+
+#include <capnp/message.h>
+
+int main()
+{
+ ::capnp::MallocMessageBuilder message;
+
+ auto bar = message.initRoot<Bar>();
+ auto foo = bar.initFoo();
+ foo.setStr("hello");
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/capnproto_relative_import.qbs b/tests/auto/blackbox/testdata/capnproto/capnproto_relative_import.qbs
new file mode 100644
index 000000000..333a3cdb9
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/capnproto_relative_import.qbs
@@ -0,0 +1,19 @@
+import qbs.Host
+
+CppApplication {
+ Depends { name: "capnproto.cpp"; required: false }
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ if (!capnproto.cpp.present)
+ console.info("capnproto is not present");
+ return result && capnproto.cpp.present;
+ }
+ cpp.minimumMacosVersion: "10.8"
+ files: [
+ "bar.capnp",
+ "capnproto_relative_import.cpp",
+ "foo.capnp",
+ ]
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/conanfile.txt b/tests/auto/blackbox/testdata/capnproto/conanfile.txt
new file mode 100644
index 000000000..7313bb82e
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/conanfile.txt
@@ -0,0 +1,6 @@
+[requires]
+capnproto/1.0.2
+[tool_requires]
+capnproto/1.0.2
+[generators]
+QbsDeps
diff --git a/tests/auto/blackbox/testdata/capnproto/foo.capnp b/tests/auto/blackbox/testdata/capnproto/foo.capnp
new file mode 100644
index 000000000..146a2969f
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/foo.capnp
@@ -0,0 +1,6 @@
+@0x8a2efe67220790be;
+
+struct Foo {
+ num @0 :UInt32;
+ str @1 :Text;
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/greeter-client.cpp b/tests/auto/blackbox/testdata/capnproto/greeter-client.cpp
new file mode 100644
index 000000000..d3fcdb4e3
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/greeter-client.cpp
@@ -0,0 +1,25 @@
+#include "greeter.capnp.h"
+
+#include <capnp/ez-rpc.h>
+
+#include <iostream>
+
+int main(int argc, char *argv[])
+{
+ const char address[] = "localhost:5050";
+ capnp::EzRpcClient client(address);
+ Greeter::Client greeter = client.getMain<Greeter>();
+
+ auto& waitScope = client.getWaitScope();
+
+ for (int i = 0; i < 2; ++i) {
+ auto request = greeter.sayHelloRequest();
+ request.initRequest().setName("hello workd");
+ auto promise = request.send();
+
+ auto response = promise.wait(waitScope);
+ std::cout << response.getResponse().getName().cStr() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/greeter-server.cpp b/tests/auto/blackbox/testdata/capnproto/greeter-server.cpp
new file mode 100644
index 000000000..a7f482cc8
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/greeter-server.cpp
@@ -0,0 +1,27 @@
+#include "greeter.capnp.h"
+
+#include <capnp/ez-rpc.h>
+#include <capnp/message.h>
+
+#include <iostream>
+
+class GreeterImpl final: public Greeter::Server
+{
+public:
+ ::kj::Promise<void> sayHello(SayHelloContext context) override
+ {
+ auto response = context.getResults().initResponse();
+ response.setName(context.getParams().getRequest().getName());
+ return kj::READY_NOW;
+ };
+};
+
+int main(int argc, char *argv[])
+{
+ const char address[] = "localhost:5050";
+ capnp::EzRpcServer server(kj::heap<GreeterImpl>(), address);
+
+ auto& waitScope = server.getWaitScope();
+ // Run forever, accepting connections and handling requests.
+ kj::NEVER_DONE.wait(waitScope);
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/greeter.capnp b/tests/auto/blackbox/testdata/capnproto/greeter.capnp
new file mode 100644
index 000000000..b9188f634
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/greeter.capnp
@@ -0,0 +1,13 @@
+@0x85150b117366d14b;
+
+struct HelloRequest {
+ name @0 :Text;
+}
+
+struct HelloResponse {
+ name @0 :Text;
+}
+
+interface Greeter {
+ sayHello @0 (request: HelloRequest) -> (response: HelloResponse);
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/greeter_cpp.qbs b/tests/auto/blackbox/testdata/capnproto/greeter_cpp.qbs
new file mode 100644
index 000000000..5fc5464b1
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/greeter_cpp.qbs
@@ -0,0 +1,39 @@
+import qbs.Host
+
+Project {
+ CppApplication {
+ Depends { name: "capnproto.cpp"; required: false }
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ if (!capnproto.cpp.present)
+ console.info("capnproto is not present");
+ return result && capnproto.cpp.present;
+ }
+ name: "server"
+ consoleApplication: true
+ cpp.minimumMacosVersion: "10.8"
+ // workaround for broken capnproto
+ cpp.staticLibraries: qbs.targetOS.contains("windows") ? "Advapi32" : []
+ capnproto.cpp.useRpc: true
+ files: [
+ "greeter.capnp",
+ "greeter-server.cpp"
+ ]
+ qbs.buildVariant: "release"
+ }
+ CppApplication {
+ Depends { name: "capnproto.cpp"; required: false }
+ name: "client"
+ consoleApplication: true
+ capnproto.cpp.useRpc: true
+ cpp.minimumMacosVersion: "10.8"
+ cpp.staticLibraries: qbs.targetOS.contains("windows") ? "Advapi32" : []
+ files: [
+ "greeter.capnp",
+ "greeter-client.cpp"
+ ]
+ qbs.buildVariant: "release"
+ }
+}
diff --git a/tests/auto/blackbox/testdata/capnproto/imports/foo.capnp b/tests/auto/blackbox/testdata/capnproto/imports/foo.capnp
new file mode 100644
index 000000000..146a2969f
--- /dev/null
+++ b/tests/auto/blackbox/testdata/capnproto/imports/foo.capnp
@@ -0,0 +1,6 @@
+@0x8a2efe67220790be;
+
+struct Foo {
+ num @0 :UInt32;
+ str @1 :Text;
+}
diff --git a/tests/auto/blackbox/testdata/change-in-imported-file/change-in-imported-file.qbs b/tests/auto/blackbox/testdata/change-in-imported-file/change-in-imported-file.qbs
index cf5354268..011eedc91 100644
--- a/tests/auto/blackbox/testdata/change-in-imported-file/change-in-imported-file.qbs
+++ b/tests/auto/blackbox/testdata/change-in-imported-file/change-in-imported-file.qbs
@@ -15,7 +15,7 @@ Product {
prepare: {
var cmd = new JavaScriptCommand();
PrepareHelper.prepare(cmd);
- cmd.description = "Creating output";
+ cmd.description = "creating output";
return [cmd];
}
}
diff --git a/tests/auto/blackbox/testdata/change-tracking-and-multiplexing/change-tracking-and-multiplexing.qbs b/tests/auto/blackbox/testdata/change-tracking-and-multiplexing/change-tracking-and-multiplexing.qbs
index d1215355c..096778cd3 100644
--- a/tests/auto/blackbox/testdata/change-tracking-and-multiplexing/change-tracking-and-multiplexing.qbs
+++ b/tests/auto/blackbox/testdata/change-tracking-and-multiplexing/change-tracking-and-multiplexing.qbs
@@ -1,8 +1,8 @@
StaticLibrary {
name: "l"
- Depends { condition: qbs.targetOS.contains("darwin"); name: "bundle" }
- Properties { condition: qbs.targetOS.contains("darwin"); bundle.isBundle: false }
+ Depends { condition: qbs.targetOS.includes("darwin"); name: "bundle" }
+ Properties { condition: qbs.targetOS.includes("darwin"); bundle.isBundle: false }
multiplexByQbsProperties: ["buildVariants"]
qbs.buildVariants: ["debug", "release"]
diff --git a/tests/auto/blackbox/testdata/choose-module-instance/other-searchpath/modules/limerick/generic.qbs b/tests/auto/blackbox/testdata/choose-module-instance/other-searchpath/modules/limerick/generic.qbs
index 2ebaaac11..bd8e901c7 100644
--- a/tests/auto/blackbox/testdata/choose-module-instance/other-searchpath/modules/limerick/generic.qbs
+++ b/tests/auto/blackbox/testdata/choose-module-instance/other-searchpath/modules/limerick/generic.qbs
@@ -1,3 +1,3 @@
Module {
- condition: !qbs.targetOS.contains("Beatles")
+ condition: !qbs.targetOS.includes("Beatles")
}
diff --git a/tests/auto/blackbox/testdata/clean/clean.qbs b/tests/auto/blackbox/testdata/clean/clean.qbs
index ce3a8eb12..10eca2d41 100644
--- a/tests/auto/blackbox/testdata/clean/clean.qbs
+++ b/tests/auto/blackbox/testdata/clean/clean.qbs
@@ -5,7 +5,7 @@ Project {
name: "dep"
files: "dep.cpp"
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
diff --git a/tests/auto/blackbox/testdata/cli/dotnettest.qbs b/tests/auto/blackbox/testdata/cli/dotnettest.qbs
index 9a10b8068..5685be8c4 100644
--- a/tests/auto/blackbox/testdata/cli/dotnettest.qbs
+++ b/tests/auto/blackbox/testdata/cli/dotnettest.qbs
@@ -1,7 +1,7 @@
Project {
Application {
Depends { name: "cli" }
- Depends { name: "HelloWorldModule"; condition: !qbs.toolchain.contains("mono") }
+ Depends { name: "HelloWorldModule"; condition: !qbs.toolchain.includes("mono") }
Depends { name: "NetLib" }
type: "application"
@@ -16,7 +16,7 @@ Project {
// Mono's VB compiler doesn't support modules yet, and if we try with C#, it crashes anyways
NetModule {
- condition: !qbs.toolchain.contains("mono")
+ condition: !qbs.toolchain.includes("mono")
Depends { name: "cli" }
name: "HelloWorldModule"
@@ -37,7 +37,7 @@ Project {
// fill-in for missing NetModule
Group {
- condition: qbs.toolchain.contains("mono")
+ condition: qbs.toolchain.includes("mono")
files: ["Module.cs"]
}
diff --git a/tests/auto/blackbox/testdata/command-file/command-file.qbs b/tests/auto/blackbox/testdata/command-file/command-file.qbs
index 8e25221c5..87dd0e054 100644
--- a/tests/auto/blackbox/testdata/command-file/command-file.qbs
+++ b/tests/auto/blackbox/testdata/command-file/command-file.qbs
@@ -4,7 +4,7 @@ Project {
destinationDirectory: project.buildDirectory
Depends { name: "cpp" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
files: ["lib.cpp"]
@@ -14,6 +14,6 @@ Project {
cpp.libraryPaths: project.buildDirectory
files: ["main.cpp"]
cpp.staticLibraries: ['@' + sourceDirectory + '/'
- + (qbs.toolchain.contains("msvc") ? "list.msvc" : "list.gcc")]
+ + (qbs.toolchain.includes("msvc") ? "list.msvc" : "list.gcc")]
}
}
diff --git a/tests/auto/blackbox/testdata/compilerDefinesByLanguage/CppDefinesApp.qbs b/tests/auto/blackbox/testdata/compilerDefinesByLanguage/CppDefinesApp.qbs
index b205ef2a7..f2da212f6 100644
--- a/tests/auto/blackbox/testdata/compilerDefinesByLanguage/CppDefinesApp.qbs
+++ b/tests/auto/blackbox/testdata/compilerDefinesByLanguage/CppDefinesApp.qbs
@@ -1,7 +1,7 @@
CppApplication {
files: ["app.c"]
- property bool enableObjectiveC: qbs.targetOS.contains("darwin")
+ property bool enableObjectiveC: qbs.targetOS.includes("darwin")
Group {
name: "C/C++"
diff --git a/tests/auto/blackbox/testdata/conanfile-probe/testapp/conanfile-probe-project.qbs b/tests/auto/blackbox/testdata/conanfile-probe/testapp/conanfile-probe-project.qbs
new file mode 100644
index 000000000..adcb2bd9c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/conanfile-probe/testapp/conanfile-probe-project.qbs
@@ -0,0 +1,23 @@
+import qbs.Probes
+import qbs.TextFile
+
+Project {
+ readonly property bool forceFailure: false
+
+ Probes.ConanfileProbe {
+ id: conan
+ conanfilePath: path + "/conanfile.py"
+ options: ({opt: "True", forceFailure: (project.forceFailure ? "True" : "False")})
+ settings: ({os: "AIX"})
+ }
+
+ property var check: {
+ var tf = new TextFile(buildDirectory + "/results.json", TextFile.WriteOnly);
+ var o = {
+ json: conan.json.deps_env_info["ENV_VAR"],
+ dependencies: conan.dependencies["testlib"].libs,
+ generatedFilesPath: conan.generatedFilesPath
+ };
+ tf.write(JSON.stringify(o));
+ }
+}
diff --git a/tests/auto/blackbox/testdata/conanfile-probe/testapp/conanfile.py b/tests/auto/blackbox/testdata/conanfile-probe/testapp/conanfile.py
new file mode 100644
index 000000000..59e40cc80
--- /dev/null
+++ b/tests/auto/blackbox/testdata/conanfile-probe/testapp/conanfile.py
@@ -0,0 +1,26 @@
+from conans import ConanFile
+
+class TestApp(ConanFile):
+ name = "testapp"
+ description = "Our project package, to be inspected by the Qbs ConanfileProbe"
+ license = "none"
+ version = "6.6.6"
+
+ settings = "os"
+ options = {"opt": [True, False], "forceFailure": [True, False]}
+ default_options = {"opt": False, "forceFailure": False}
+
+ requires = "testlib/1.2.3@qbs/testing"
+
+ def configure(self):
+ assert(not self.options.forceFailure)
+ self.options["testlib"].opt = self.options.opt
+
+ def source(self):
+ pass
+
+ def build(self):
+ pass
+
+ def package(self):
+ pass
diff --git a/tests/auto/blackbox/testdata/conanfile-probe/testlib/conanfile.py b/tests/auto/blackbox/testdata/conanfile-probe/testlib/conanfile.py
new file mode 100644
index 000000000..983c22599
--- /dev/null
+++ b/tests/auto/blackbox/testdata/conanfile-probe/testlib/conanfile.py
@@ -0,0 +1,25 @@
+from conans import ConanFile
+
+class Testlib(ConanFile):
+ name = "testlib"
+ description = "Represents an arbitrary package, for instance on bintray"
+ license = "none"
+ version = "1.2.3"
+
+ settings = "os"
+ options = {"opt": [True, False]}
+ default_options = {"opt": False}
+
+ def source(self):
+ pass
+
+ def build(self):
+ pass
+
+ def package(self):
+ pass
+
+ def package_info(self):
+ self.cpp_info.libs = ["testlib1","testlib2"]
+ self.env_info.ENV_VAR = "TESTLIB_ENV_VAL"
+ self.user_info.user_var = "testlib_user_val"
diff --git a/tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs b/tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs
deleted file mode 100644
index 802aa1450..000000000
--- a/tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs
+++ /dev/null
@@ -1,67 +0,0 @@
-import qbs.File
-import qbs.TextFile
-import "util.js" as Utils
-
-Product {
- type: ["final1", "final2"]
- Group {
- files: ["dummy1.input"]
- fileTags: ["input1"]
- }
- Group {
- files: ["dummy2.input"]
- fileTags: ["input2"]
- }
- Rule {
- inputs: ["input1"]
- Artifact {
- filePath: project.buildDirectory + "/dummy1.final"
- fileTags: ["final1"]
- }
- prepare: {
- var cmds = [];
- for (var i = 0; i < 10; ++i) {
- var cmd = new JavaScriptCommand();
- cmd.silent = true;
- cmd.createFile = i == 9;
- cmd.sourceCode = function() {
- if (createFile) {
- console.info("Creating file");
- var file = new TextFile(output.filePath, TextFile.WriteOnly);
- file.close();
- }
- };
- cmds.push(cmd);
- }
- return cmds;
- }
- }
- Rule {
- inputs: ["input2"]
- Artifact {
- filePath: "dummy.intermediate"
- fileTags: ["intermediate"]
- }
- prepare: {
- var cmd = new JavaScriptCommand();
- cmd.silent = true;
- cmd.sourceCode = function() { };
- return [cmd];
- }
- }
- Rule {
- inputs: ["intermediate"]
- outputFileTags: "final2"
- prepare: {
- do
- Utils.sleep(6000);
- while (!File.exists(project.buildDirectory + "/dummy1.final"));
- var cmd = new JavaScriptCommand();
- cmd.silent = true;
- cmd.sourceCode = function() { };
- return [cmd];
- }
- }
-}
-
-
diff --git a/tests/auto/blackbox/testdata/concurrent-executor/util.js b/tests/auto/blackbox/testdata/concurrent-executor/util.js
deleted file mode 100644
index a37a8cbb1..000000000
--- a/tests/auto/blackbox/testdata/concurrent-executor/util.js
+++ /dev/null
@@ -1,8 +0,0 @@
-function sleep(timeInMs)
-{
- var referenceTime = new Date();
- var time = null;
- do {
- time = new Date();
- } while (time - referenceTime < timeInMs);
-}
diff --git a/tests/auto/blackbox/testdata/conditional-filetagger/conditional-filetagger.qbs b/tests/auto/blackbox/testdata/conditional-filetagger/conditional-filetagger.qbs
index 5f0c93e46..f5d7ad676 100644
--- a/tests/auto/blackbox/testdata/conditional-filetagger/conditional-filetagger.qbs
+++ b/tests/auto/blackbox/testdata/conditional-filetagger/conditional-filetagger.qbs
@@ -1,7 +1,7 @@
CppApplication {
name: "theApp"
property bool enableTagger
- files: ["main.custom"];
+ files: ["main.custom"]
FileTagger {
condition: enableTagger
patterns: ["*.custom"]
diff --git a/tests/auto/blackbox/testdata/configure/configure.qbs b/tests/auto/blackbox/testdata/configure/configure.qbs
index af5638dde..be0e65247 100644
--- a/tests/auto/blackbox/testdata/configure/configure.qbs
+++ b/tests/auto/blackbox/testdata/configure/configure.qbs
@@ -1,6 +1,13 @@
import qbs.FileInfo
+import qbs.Host
Project {
+ property bool enabled: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
property string name: 'configure'
qbsSearchPaths: '.'
Product {
diff --git a/tests/auto/blackbox/testdata/configure/main.cpp b/tests/auto/blackbox/testdata/configure/main.cpp
index c7213c768..a91914f73 100644
--- a/tests/auto/blackbox/testdata/configure/main.cpp
+++ b/tests/auto/blackbox/testdata/configure/main.cpp
@@ -30,7 +30,7 @@
int main()
{
- printf("%s..\n", TEXT);
+ std::printf("%s..\n", TEXT);
return 0;
}
diff --git a/tests/auto/blackbox/testdata/configure/modules/definition/module.qbs b/tests/auto/blackbox/testdata/configure/modules/definition/module.qbs
index 1d647faa2..6a1dbe67d 100644
--- a/tests/auto/blackbox/testdata/configure/modules/definition/module.qbs
+++ b/tests/auto/blackbox/testdata/configure/modules/definition/module.qbs
@@ -12,7 +12,7 @@ Module {
var cmd;
var args;
var p = path;
- if (targetOS.contains("windows")) {
+ if (targetOS.includes("windows")) {
cmd = windowsShellPath;
args = ["/c", "date", "/t"];
} else {
diff --git a/tests/auto/blackbox/testdata/conflicting-property-values/conflicting-property-values.qbs b/tests/auto/blackbox/testdata/conflicting-property-values/conflicting-property-values.qbs
new file mode 100644
index 000000000..23b6ee5a3
--- /dev/null
+++ b/tests/auto/blackbox/testdata/conflicting-property-values/conflicting-property-values.qbs
@@ -0,0 +1,41 @@
+Project {
+ Product {
+ name: "low"
+ Export { property string prop: "low"; property string prop2: "low" }
+ }
+ Product {
+ name: "higher1"
+ Export { Depends { name: "low" } low.prop: "higher1" }
+ }
+ Product {
+ name: "higher2"
+ Export { Depends { name: "low" } low.prop: "higher2" }
+ }
+ Product {
+ name: "highest1"
+ Export {
+ Depends { name: "low" }
+ Depends { name: "higher1" }
+ Depends { name: "higher2" }
+ low.prop: "highest1"
+ low.prop2: "highest"
+ }
+ }
+ Product {
+ name: "highest2"
+ Export {
+ Depends { name: "low" }
+ Depends { name: "higher1" }
+ Depends { name: "higher2" }
+ low.prop: "highest2"
+ low.prop2: "highest"
+ }
+ }
+ Product {
+ name: "toplevel"
+ Depends { name: "highest1" }
+ Depends { name: "highest2" }
+ low.prop: name
+ property bool dummy: { console.info("final prop value: " + low.prop); }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/cpu-features/cpu-features.qbs b/tests/auto/blackbox/testdata/cpu-features/cpu-features.qbs
index 0bfdaceba..36e805516 100644
--- a/tests/auto/blackbox/testdata/cpu-features/cpu-features.qbs
+++ b/tests/auto/blackbox/testdata/cpu-features/cpu-features.qbs
@@ -8,7 +8,7 @@ CppApplication {
property bool dummy: {
console.info("is x86: " + (qbs.architecture === "x86"));
console.info("is x64: " + (qbs.architecture === "x86_64"));
- console.info("is gcc: " + qbs.toolchain.contains("gcc"));
- console.info("is msvc: " + qbs.toolchain.contains("msvc"));
+ console.info("is gcc: " + qbs.toolchain.includes("gcc"));
+ console.info("is msvc: " + qbs.toolchain.includes("msvc"));
}
}
diff --git a/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs b/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs
index 322ded85c..24c37951c 100644
--- a/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs
+++ b/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs
@@ -13,10 +13,10 @@ CppApplication {
var isEvenNewerMsvc;
var isOlderMsvc;
var isGcc;
- if (toolchain.contains("clang-cl")) {
+ if (toolchain.includes("clang-cl")) {
isEvenNewerMsvc = true;
isNewerMsvc = true;
- } else if (toolchain.contains("msvc")) {
+ } else if (toolchain.includes("msvc")) {
if (compilerVersion >= "19.12.25831")
isEvenNewerMsvc = true;
if (compilerVersion >= "18.00.30723")
diff --git a/tests/auto/blackbox/testdata/date-property/date-property.qbs b/tests/auto/blackbox/testdata/date-property/date-property.qbs
new file mode 100644
index 000000000..ffd584802
--- /dev/null
+++ b/tests/auto/blackbox/testdata/date-property/date-property.qbs
@@ -0,0 +1,18 @@
+Product {
+ type: "date"
+ property var theDate: new Date(1999, 11, 31);
+ Rule {
+ multiplex: true
+ Artifact { filePath: "dummy"; fileTags: "date" }
+ prepare: {
+ var cmd = new JavaScriptCommand;
+ cmd.silent = true;
+ cmd.sourceCode = function() {
+ var d = product.theDate;
+ console.info("The stored date was " + d.getFullYear() + '-' + (d.getMonth() + 1) + '-'
+ + d.getDate());
+ };
+ return cmd;
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs b/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs
index 735bfffbc..681ffeab0 100644
--- a/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs
+++ b/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs
@@ -18,7 +18,7 @@ Project {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = 'generate ' + FileInfo.fileName(output.filePath);
+ cmd.description = 'generating ' + FileInfo.fileName(output.filePath);
cmd.highlight = 'codegen';
cmd.sourceCode = function() {
file = new TextFile(output.filePath, TextFile.WriteOnly);
diff --git a/tests/auto/blackbox/testdata/dependency-profile-mismatch/dependency-profile-mismatch.qbs b/tests/auto/blackbox/testdata/dependency-profile-mismatch/dependency-profile-mismatch.qbs
deleted file mode 100644
index 8a6f733c0..000000000
--- a/tests/auto/blackbox/testdata/dependency-profile-mismatch/dependency-profile-mismatch.qbs
+++ /dev/null
@@ -1,12 +0,0 @@
-Project {
- property string mainProfile
- property string depProfile
- Product {
- name: "dep"
- qbs.profiles: [project.depProfile]
- }
- Product {
- name: "main"
- Depends { name: "dep"; profiles: [project.mainProfile]; }
- }
-}
diff --git a/tests/auto/blackbox/testdata/dependency-scanning-loop/dependency-scanning-loop.qbs b/tests/auto/blackbox/testdata/dependency-scanning-loop/dependency-scanning-loop.qbs
new file mode 100644
index 000000000..ac8e7258c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/dependency-scanning-loop/dependency-scanning-loop.qbs
@@ -0,0 +1,34 @@
+import qbs.FileInfo
+import qbs.TextFile
+
+CppApplication {
+ name: "app"
+ cpp.includePaths: buildDirectory
+ Group {
+ files: "main.cpp"
+ fileTags: ["cpp", "custom.in"]
+ }
+ Rule {
+ inputs: "custom.in"
+ Artifact {
+ filePath: FileInfo.completeBaseName(input.filePath) + ".h"
+ fileTags: "hpp"
+ }
+ Artifact {
+ filePath: "custom.txt"
+ fileTags: "whatever"
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "generating " + outputs.hpp[0].fileName;
+ cmd.sourceCode = function() {
+ var f = new TextFile(outputs.hpp[0].filePath, TextFile.WriteOnly);
+ f.writeLine("int main() {}");
+ f.close();
+ f = new TextFile(outputs.whatever[0].filePath, TextFile.WriteOnly);
+ f.close();
+ }
+ return cmd;
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/dependency-scanning-loop/main.cpp b/tests/auto/blackbox/testdata/dependency-scanning-loop/main.cpp
new file mode 100644
index 000000000..5e8dda41b
--- /dev/null
+++ b/tests/auto/blackbox/testdata/dependency-scanning-loop/main.cpp
@@ -0,0 +1 @@
+#include <main.h>
diff --git a/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs b/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs
index a8efb97b5..7d1550312 100644
--- a/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs
+++ b/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs
@@ -1,8 +1,6 @@
-import qbs
-
Product {
Depends { name: "themodule" }
themodule.newProp: true
- themodule.oldProp: false
+ themodule.expiringProp: false
themodule.veryOldProp: false
}
diff --git a/tests/auto/blackbox/testdata/deprecated-property/modules/themodule/m.qbs b/tests/auto/blackbox/testdata/deprecated-property/modules/themodule/m.qbs
index 106ed4135..58164e918 100644
--- a/tests/auto/blackbox/testdata/deprecated-property/modules/themodule/m.qbs
+++ b/tests/auto/blackbox/testdata/deprecated-property/modules/themodule/m.qbs
@@ -1,8 +1,8 @@
-import qbs
+import qbs.Environment
Module {
property bool newProp
- property bool oldProp
+ property bool expiringProp
property bool forgottenProp
PropertyOptions {
@@ -10,9 +10,9 @@ Module {
description: "Use this, it's good!"
}
PropertyOptions {
- name: "oldProp"
+ name: "expiringProp"
description: "Use newProp instead."
- removalVersion: "99.9"
+ removalVersion: Environment.getEnv("REMOVAL_VERSION")
}
PropertyOptions {
name: "veryOldProp"
diff --git a/tests/auto/blackbox/testdata/disappeared-profile/modules-dir/modules/m/m.qbs b/tests/auto/blackbox/testdata/disappeared-profile/modules-dir/modules/m/m.qbs
index 3e1747ade..fd755ce86 100644
--- a/tests/auto/blackbox/testdata/disappeared-profile/modules-dir/modules/m/m.qbs
+++ b/tests/auto/blackbox/testdata/disappeared-profile/modules-dir/modules/m/m.qbs
@@ -10,7 +10,7 @@ Module {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName + " with " + product.m.p1;
+ cmd.description = "creating " + output.fileName + " with " + product.m.p1;
cmd.sourceCode = function() {};
return [cmd];
}
@@ -24,7 +24,7 @@ Module {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName + " with " + product.m.p2;
+ cmd.description = "creating " + output.fileName + " with " + product.m.p2;
cmd.sourceCode = function() {};
return [cmd];
}
diff --git a/tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs b/tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs
index fdd3aa1f7..367bb665c 100644
--- a/tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs
+++ b/tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs
@@ -4,9 +4,9 @@ CppApplication {
files: "main.cpp"
- Depends { name: "bundle"; condition: qbs.targetOS.contains("darwin") }
+ Depends { name: "bundle"; condition: qbs.targetOS.includes("darwin") }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
@@ -17,7 +17,7 @@ CppApplication {
var cmd = new JavaScriptCommand();
cmd.silent = true;
cmd.sourceCode = function() {
- console.info("is Darwin: " + product.qbs.targetOS.contains("darwin"));
+ console.info("is Darwin: " + product.qbs.targetOS.includes("darwin"));
console.info("---" + product.cpp.nmPath + "---");
}
return [cmd];
diff --git a/tests/auto/blackbox/testdata/distribution-include-paths/distribution-include-paths.qbs b/tests/auto/blackbox/testdata/distribution-include-paths/distribution-include-paths.qbs
new file mode 100644
index 000000000..3e6fb9b00
--- /dev/null
+++ b/tests/auto/blackbox/testdata/distribution-include-paths/distribution-include-paths.qbs
@@ -0,0 +1,4 @@
+CppApplication {
+ files: ["main.cpp"]
+ cpp.distributionIncludePaths: ["subdir"]
+}
diff --git a/tests/auto/blackbox/testdata/distribution-include-paths/main.cpp b/tests/auto/blackbox/testdata/distribution-include-paths/main.cpp
new file mode 100644
index 000000000..10d376a31
--- /dev/null
+++ b/tests/auto/blackbox/testdata/distribution-include-paths/main.cpp
@@ -0,0 +1,8 @@
+#include <cstdio>
+#include <gagagugu.h>
+
+int main()
+{
+ printStuff();
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/distribution-include-paths/subdir/gagagugu.h b/tests/auto/blackbox/testdata/distribution-include-paths/subdir/gagagugu.h
new file mode 100644
index 000000000..b951d8855
--- /dev/null
+++ b/tests/auto/blackbox/testdata/distribution-include-paths/subdir/gagagugu.h
@@ -0,0 +1,4 @@
+void printStuff()
+{
+ puts("alalalalonglonglilonglonglong");
+}
diff --git a/tests/auto/blackbox/testdata/dot-dot-pc-file/dot-dot-pc-file.qbs b/tests/auto/blackbox/testdata/dot-dot-pc-file/dot-dot-pc-file.qbs
new file mode 100644
index 000000000..60c4ea2bc
--- /dev/null
+++ b/tests/auto/blackbox/testdata/dot-dot-pc-file/dot-dot-pc-file.qbs
@@ -0,0 +1,7 @@
+CppApplication {
+ name: "p"
+ Depends { name: "qbs-metatest-module"; }
+ files: "main.cpp"
+ moduleProviders.qbspkgconfig.libDirs: "libdir"
+ qbsModuleProviders: "qbspkgconfig"
+}
diff --git a/tests/auto/blackbox/testdata/dot-dot-pc-file/libdir/qbs.metatest.module.pc b/tests/auto/blackbox/testdata/dot-dot-pc-file/libdir/qbs.metatest.module.pc
new file mode 100644
index 000000000..c00fd26d6
--- /dev/null
+++ b/tests/auto/blackbox/testdata/dot-dot-pc-file/libdir/qbs.metatest.module.pc
@@ -0,0 +1,5 @@
+Name: qbs.metatest.module
+Description: just a test
+Version: 0.0.1
+
+Cflags: -DTHE_MAGIC_DEFINE
diff --git a/tests/auto/blackbox/testdata/dot-dot-pc-file/main.cpp b/tests/auto/blackbox/testdata/dot-dot-pc-file/main.cpp
new file mode 100644
index 000000000..442b755bf
--- /dev/null
+++ b/tests/auto/blackbox/testdata/dot-dot-pc-file/main.cpp
@@ -0,0 +1,5 @@
+#ifndef THE_MAGIC_DEFINE
+#error "missing the magic define"
+#endif
+
+int main() {}
diff --git a/tests/auto/blackbox/testdata/driver-linker-flags/driver-linker-flags.qbs b/tests/auto/blackbox/testdata/driver-linker-flags/driver-linker-flags.qbs
index 5de0fe053..57f096494 100644
--- a/tests/auto/blackbox/testdata/driver-linker-flags/driver-linker-flags.qbs
+++ b/tests/auto/blackbox/testdata/driver-linker-flags/driver-linker-flags.qbs
@@ -8,7 +8,7 @@ CppApplication {
Probe {
id: toolchainProbe
- condition: qbs.toolchain.contains("gcc")
+ condition: qbs.toolchain.includes("gcc")
configure: {
console.info("toolchain is GCC-like");
found = true;
diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs
index 1acf606dc..c95d88052 100644
--- a/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs
+++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs
@@ -1,8 +1,8 @@
DynamicLibrary {
Depends { name: "cpp" }
- Depends { name: "bundle"; condition: qbs.targetOS.contains("darwin") }
+ Depends { name: "bundle"; condition: qbs.targetOS.includes("darwin") }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
cpp.minimumMacosVersion: "10.7" // For -rpath
}
diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thelib/thelib.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thelib/thelib.qbs
index 30f87337d..3059fa5e9 100644
--- a/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thelib/thelib.qbs
+++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thelib/thelib.qbs
@@ -13,7 +13,7 @@ Module {
}
Group {
name: "thelib dll import"
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
files: FileInfo.joinPaths(product.thelib.baseDir, "thelib.lib")
fileTags: ["dynamiclibrary_import"]
filesAreTargets: true
diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/theotherlib/theotherlib.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/theotherlib/theotherlib.qbs
index 1eb1e01a5..f387feb80 100644
--- a/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/theotherlib/theotherlib.qbs
+++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/theotherlib/theotherlib.qbs
@@ -13,7 +13,7 @@ Module {
}
Group {
name: "theotherlib dll import"
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
files: FileInfo.joinPaths(product.theotherlib.baseDir, "theotherlib.lib")
fileTags: ["dynamiclibrary_import"]
filesAreTargets: true
diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs
index b9149d091..5ea8cef23 100644
--- a/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs
+++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs
@@ -1,5 +1,13 @@
+import qbs.Host
+
Project {
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "theapp"
cpp.minimumMacosVersion: "10.7" // For -rpath
Depends { name: "theotherlib" }
diff --git a/tests/auto/blackbox/testdata/dynamic-project/dynamic-project.qbs b/tests/auto/blackbox/testdata/dynamic-project/dynamic-project.qbs
index 166648c80..5acdb8892 100644
--- a/tests/auto/blackbox/testdata/dynamic-project/dynamic-project.qbs
+++ b/tests/auto/blackbox/testdata/dynamic-project/dynamic-project.qbs
@@ -17,13 +17,12 @@ Project
var srcDir = FileInfo.joinPaths(sourceDir, "src");
var projectDirs = File.directoryEntries(srcDir, File.Dirs | File.NoDotAndDotDot);
var list = [];
- for (it in projectDirs) {
+ for (var it = 0; it < projectDirs.length; ++it) {
var name = projectDirs[it];
var productSrcDir = FileInfo.joinPaths(srcDir, name);
var productFilePath = FileInfo.joinPaths(tempDir, name + ".qbs");
var file = new TextFile(productFilePath, TextFile.WriteOnly);
try {
- file.writeLine("import qbs");
file.writeLine("CppApplication");
file.writeLine("{");
file.writeLine("\tfiles: [ \"" + productSrcDir + "/*.cpp\" ]");
diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js
index bd596fbca..b925effcf 100644
--- a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js
+++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js
@@ -35,7 +35,7 @@
**
****************************************************************************/
-// needs import qbs.TextFile
+var TextFile = require("qbs.TextFile");
function readFlexOptions(filePath)
{
@@ -82,7 +82,7 @@ function readFlexOptions(filePath)
}
}
- var tf = new TextFile(input.filePath);
+ var tf = new TextFile(filePath);
var line;
var optrex = /^%option\s+(.*$)/;
var res;
diff --git a/tests/auto/blackbox/testdata/empty-profile/empty-profile.qbs b/tests/auto/blackbox/testdata/empty-profile/empty-profile.qbs
new file mode 100644
index 000000000..da7536315
--- /dev/null
+++ b/tests/auto/blackbox/testdata/empty-profile/empty-profile.qbs
@@ -0,0 +1,3 @@
+CppApplication {
+ files: ["main.cpp"]
+}
diff --git a/tests/auto/blackbox/testdata/empty-profile/main.cpp b/tests/auto/blackbox/testdata/empty-profile/main.cpp
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata/empty-profile/main.cpp
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/tests/auto/blackbox/testdata/enableExceptions/exceptions.qbs b/tests/auto/blackbox/testdata/enableExceptions/exceptions.qbs
index 9a75043a8..e1d09f7e0 100644
--- a/tests/auto/blackbox/testdata/enableExceptions/exceptions.qbs
+++ b/tests/auto/blackbox/testdata/enableExceptions/exceptions.qbs
@@ -1,5 +1,5 @@
CppApplication {
files: ["main.cpp"]
cpp.treatWarningsAsErrors: true
- cpp.defines: qbs.toolchain.contains("msvc") && !cpp.enableExceptions ? ["FORCE_FAIL_VS"] : []
+ cpp.defines: qbs.toolchain.includes("msvc") && !cpp.enableExceptions ? ["FORCE_FAIL_VS"] : []
}
diff --git a/tests/auto/blackbox/testdata/enableExceptions/none.qbs b/tests/auto/blackbox/testdata/enableExceptions/none.qbs
index 8fb052476..439ea3037 100644
--- a/tests/auto/blackbox/testdata/enableExceptions/none.qbs
+++ b/tests/auto/blackbox/testdata/enableExceptions/none.qbs
@@ -2,7 +2,7 @@ CppApplication {
files: ["emptymain.cpp"]
Group {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
files: ["empty.m", "empty.mm"]
}
}
diff --git a/tests/auto/blackbox/testdata/env-merging/env-merging.qbs b/tests/auto/blackbox/testdata/env-merging/env-merging.qbs
index 6edeca444..eb681f36b 100644
--- a/tests/auto/blackbox/testdata/env-merging/env-merging.qbs
+++ b/tests/auto/blackbox/testdata/env-merging/env-merging.qbs
@@ -1,3 +1,5 @@
+import qbs.Host
+
Project {
CppApplication {
name: "tool"
@@ -5,6 +7,12 @@ Project {
}
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "p"
type: "custom"
Depends { name: "tool" }
diff --git a/tests/auto/blackbox/testdata/escaped-linker-flags/escaped-linker-flags.qbs b/tests/auto/blackbox/testdata/escaped-linker-flags/escaped-linker-flags.qbs
index f48bf8d1f..b4fb0df4d 100644
--- a/tests/auto/blackbox/testdata/escaped-linker-flags/escaped-linker-flags.qbs
+++ b/tests/auto/blackbox/testdata/escaped-linker-flags/escaped-linker-flags.qbs
@@ -10,4 +10,9 @@ CppApplication {
cpp.linkerFlags: ["-s"]
}
files: ["main.cpp"]
+ Probe {
+ id: checker
+ property bool isUnixGcc: qbs.toolchain.contains("gcc") && !qbs.targetOS.contains("macos")
+ configure: { console.info("is gcc: " + isUnixGcc); }
+ }
}
diff --git a/tests/auto/blackbox/testdata/export-rule/export-rule.qbs b/tests/auto/blackbox/testdata/export-rule/export-rule.qbs
index 29899e728..455ccba0d 100644
--- a/tests/auto/blackbox/testdata/export-rule/export-rule.qbs
+++ b/tests/auto/blackbox/testdata/export-rule/export-rule.qbs
@@ -13,7 +13,7 @@ Project {
Export {
Depends { name: "cpp" }
property bool enableTagger
- property string description: "Creating C++ source file.";
+ property string description: "creating C++ source file.";
FileTagger {
condition: enableTagger
patterns: ["*.blubb"]
diff --git a/tests/auto/blackbox/testdata/exports-cmake/Foo.cpp b/tests/auto/blackbox/testdata/exports-cmake/Foo.cpp
new file mode 100644
index 000000000..ea334f9af
--- /dev/null
+++ b/tests/auto/blackbox/testdata/exports-cmake/Foo.cpp
@@ -0,0 +1,5 @@
+#include "Foo.h"
+int someFooWork()
+{
+ return 42;
+}
diff --git a/tests/auto/blackbox/testdata/exports-cmake/Foo.h b/tests/auto/blackbox/testdata/exports-cmake/Foo.h
new file mode 100644
index 000000000..2f279f577
--- /dev/null
+++ b/tests/auto/blackbox/testdata/exports-cmake/Foo.h
@@ -0,0 +1,16 @@
+#ifndef FOO_H
+#define FOO_H
+#include <dllexport.h>
+
+#ifdef FOO_LIB_STATIC
+#define FOO_LIB_EXPORT
+#else
+#ifdef FOO_LIB
+#define FOO_LIB_EXPORT DLL_EXPORT
+#else
+#define FOO_LIB_EXPORT DLL_IMPORT
+#endif
+#endif
+
+FOO_LIB_EXPORT int someFooWork();
+#endif // FOO_H
diff --git a/tests/auto/blackbox/testdata/exports-cmake/cmake/CMakeLists.txt b/tests/auto/blackbox/testdata/exports-cmake/cmake/CMakeLists.txt
new file mode 100644
index 000000000..d874e0e92
--- /dev/null
+++ b/tests/auto/blackbox/testdata/exports-cmake/cmake/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.10)
+
+project(qbs_import)
+
+find_package(Bar PATHS REQUIRED)
+add_executable(Consumer main.cpp)
+target_link_libraries(Consumer Bar)
diff --git a/tests/auto/blackbox/testdata/exports-cmake/cmake/main.cpp b/tests/auto/blackbox/testdata/exports-cmake/cmake/main.cpp
new file mode 100644
index 000000000..1a1fa90ec
--- /dev/null
+++ b/tests/auto/blackbox/testdata/exports-cmake/cmake/main.cpp
@@ -0,0 +1,6 @@
+#include <Foo.h>
+
+int main()
+{
+ return someFooWork();
+}
diff --git a/tests/auto/blackbox/testdata/exports-cmake/exports-cmake.qbs b/tests/auto/blackbox/testdata/exports-cmake/exports-cmake.qbs
new file mode 100644
index 000000000..6464af705
--- /dev/null
+++ b/tests/auto/blackbox/testdata/exports-cmake/exports-cmake.qbs
@@ -0,0 +1,70 @@
+import qbs.FileInfo
+
+Project {
+ property bool isStatic: false
+ property bool isBundle: false
+
+ property string headersInstallDir: "include"
+
+ Product {
+ name: "DllExport"
+ Depends { name: "Exporter.cmake" }
+ Group {
+ name: "API headers"
+ files: ["../dllexport.h"]
+ qbs.install: true
+ qbs.installDir: project.headersInstallDir
+ }
+ Group {
+ fileTagsFilter: ["Exporter.cmake.package"]
+ qbs.install: true
+ qbs.installDir: "/lib/cmake/DllExport"
+ }
+ Export {
+ Depends { name: "cpp" }
+ cpp.includePaths: FileInfo.joinPaths(
+ exportingProduct.qbs.installRoot,
+ exportingProduct.qbs.installPrefix,
+ project.headersInstallDir)
+ }
+ }
+
+ Library {
+ type: project.isStatic ? "staticlibrary" : "dynamiclibrary"
+ Depends { name: "cpp" }
+ Depends { name: "DllExport" }
+ Depends { name: "Exporter.cmake" }
+ Exporter.cmake.packageName: "Bar"
+ name: "Foo"
+ files: ["Foo.cpp"]
+ version: "1.2.3"
+ cpp.includePaths: "."
+ cpp.defines: "FOO_LIB"
+ Group {
+ name: "API headers"
+ files: ["Foo.h"]
+ qbs.install: true
+ qbs.installDir: project.headersInstallDir
+ }
+ install: true
+ installImportLib: true
+ Group {
+ fileTagsFilter: ["Exporter.cmake.package"]
+ qbs.install: true
+ qbs.installDir: "/lib/cmake/Bar"
+ }
+ Export {
+ Depends { name: "cpp" }
+ cpp.includePaths: FileInfo.joinPaths(
+ exportingProduct.qbs.installRoot,
+ exportingProduct.qbs.installPrefix,
+ project.headersInstallDir)
+ cpp.defines: ["FOO=1"].concat(project.isStatic ? ["FOO_LIB_STATIC"] : [])
+ cpp.commonCompilerFlags: "-DOTHER_DEF=1"
+ cpp.linkerFlags: exportingProduct.qbs.toolchain.contains("gcc") ? ["-s"] : []
+ }
+
+ Depends { name: 'bundle' }
+ bundle.isBundle: qbs.targetOS.includes("darwin") && project.isBundle
+ }
+}
diff --git a/tests/auto/blackbox/testdata/exports-cmake/find-cmake.qbs b/tests/auto/blackbox/testdata/exports-cmake/find-cmake.qbs
new file mode 100644
index 000000000..52f388966
--- /dev/null
+++ b/tests/auto/blackbox/testdata/exports-cmake/find-cmake.qbs
@@ -0,0 +1,46 @@
+import qbs.Probes
+
+Product {
+ Depends { name: "cpp" }
+
+ Probes.BinaryProbe {
+ id: cmakeProbe
+ names: "cmake"
+ }
+
+ Probes.BinaryProbe {
+ id: ninjaProbe
+ names: ["ninja"]
+ }
+
+ property bool test: {
+ var data = {
+ cmakeFound: cmakeProbe.found,
+ cmakeFilePath: cmakeProbe.filePath,
+ crossCompiling: qbs.targetPlatform !== qbs.hostPlatform,
+ installPrefix: qbs.installPrefix
+ };
+ data.buildEnv = {}
+ Object.assign(data.buildEnv, cpp.buildEnv); // deep copy buildEnv from a probe
+ if (qbs.toolchain.includes("gcc")) {
+ data.buildEnv["CC"] = cpp.cCompilerName;
+ data.buildEnv["CXX"] = cpp.cxxCompilerName;
+ } else {
+ data.buildEnv["CC"] = cpp.compilerName;
+ data.buildEnv["CXX"] = cpp.compilerName;
+ }
+
+ if (ninjaProbe.found) {
+ data.generator = "Ninja";
+ } else {
+ if (qbs.toolchain.includes("msvc")) {
+ data.generator = "NMake Makefiles"
+ } else if (qbs.toolchain.includes("mingw")) {
+ data.generator = "MinGW Makefiles";
+ } else if (qbs.toolchain.includes("gcc")) {
+ data.generator = "Unix Makefiles";
+ }
+ }
+ console.info("---" + JSON.stringify(data) + "---");
+ }
+}
diff --git a/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs b/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs
index 96d1cabb9..23331f93f 100644
--- a/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs
+++ b/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs
@@ -1,4 +1,5 @@
import qbs.FileInfo
+import qbs.Host
Project {
Product {
@@ -42,14 +43,14 @@ Project {
Depends { name: "Qt.core"; required: false }
Depends { name: "helper1" }
Depends { name: "helper3" }
- property bool someCondition: qbs.hostOS.contains("windows") // hostOS for easier testing
+ property bool someCondition: Host.os().includes("windows") // hostOS for easier testing
property bool someOtherCondition: someCondition
Properties {
condition: !someOtherCondition
cpp.driverFlags: ["-pthread"]
}
- cpp.defines: product.name
- cpp.includePaths: [FileInfo.joinPaths(product.qbs.installPrefix, "include")]
+ cpp.defines: exportingProduct.name
+ cpp.includePaths: [FileInfo.joinPaths(exportingProduct.qbs.installPrefix, "include")]
Qt.core.mocName: "muck"
}
@@ -94,7 +95,7 @@ Project {
Depends { name: "cpp" }
cpp.includePaths: [
"/opt/thesecondlib/include",
- product.sourceDirectory,
+ exportingProduct.sourceDirectory,
importingProduct.buildDirectory
]
property string hurz: importingProduct.name
diff --git a/tests/auto/blackbox/testdata/exports-qbs/consumer.qbs b/tests/auto/blackbox/testdata/exports-qbs/consumer.qbs
index 02affdfe8..073504400 100644
--- a/tests/auto/blackbox/testdata/exports-qbs/consumer.qbs
+++ b/tests/auto/blackbox/testdata/exports-qbs/consumer.qbs
@@ -1,4 +1,12 @@
+import qbs.Host
+
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "consumer"
qbsSearchPaths: "default/install-root/usr/qbs"
property string outTag: "cpp"
diff --git a/tests/auto/blackbox/testdata/exports-qbs/lib.qbs b/tests/auto/blackbox/testdata/exports-qbs/lib.qbs
index 53a472dbb..01f89a221 100644
--- a/tests/auto/blackbox/testdata/exports-qbs/lib.qbs
+++ b/tests/auto/blackbox/testdata/exports-qbs/lib.qbs
@@ -16,7 +16,7 @@ DynamicLibrary {
cpp.defines: ["MYLIB_BUILD"]
cpp.variantSuffix: qbs.buildVariant === "debug" ? "d" : ""
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
files: ["mylib.cpp"]
@@ -38,8 +38,8 @@ DynamicLibrary {
Export {
Depends { name: "cpp" }
- property string includeDir: product.sourceDirectory
- property var config: product.config
+ property string includeDir: exportingProduct.sourceDirectory
+ property var config: exportingProduct.config
Properties {
condition: true
cpp.includePaths: [includeDir]
@@ -52,7 +52,7 @@ DynamicLibrary {
condition: true
prefixMapping: [{
prefix: includeDir,
- replacement: FileInfo.joinPaths(qbs.installPrefix, product.headersInstallDir)
+ replacement: FileInfo.joinPaths(exportingProduct.qbs.installPrefix, exportingProduct.headersInstallDir)
}]
}
}
diff --git a/tests/auto/blackbox/testdata/exports-qbs/tool.qbs b/tests/auto/blackbox/testdata/exports-qbs/tool.qbs
index 655597cf7..d3626bead 100644
--- a/tests/auto/blackbox/testdata/exports-qbs/tool.qbs
+++ b/tests/auto/blackbox/testdata/exports-qbs/tool.qbs
@@ -33,7 +33,7 @@ CppApplication {
}
Export {
- property stringList toolTags: product.toolTags
+ property stringList toolTags: exportingProduct.toolTags
property stringList outTags: [importingProduct.outTag]
property var helper2Obj: Helper2
Rule {
@@ -49,7 +49,7 @@ CppApplication {
prepare: {
var cmd = new Command(explicitlyDependsOn["MyTool.tool"][0].filePath,
[input.filePath, output.filePath]);
- cmd.description = input.fileName + " -> " + output.fileName;
+ cmd.description = "compiling" + input.fileName + " to " + output.fileName;
return [cmd];
}
}
diff --git a/tests/auto/blackbox/testdata/external-libs/external-libs.qbs b/tests/auto/blackbox/testdata/external-libs/external-libs.qbs
index 619f40867..326bf5dae 100644
--- a/tests/auto/blackbox/testdata/external-libs/external-libs.qbs
+++ b/tests/auto/blackbox/testdata/external-libs/external-libs.qbs
@@ -1,13 +1,13 @@
import qbs.TextFile
Project {
- property string libDir: sourceDirectory + "/libs"
+ property string libDir: buildDirectory + "/libs"
StaticLibrary {
name: "lib1"
destinationDirectory: project.libDir
Depends { name: "cpp" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
files: ["lib1.cpp"]
@@ -18,7 +18,7 @@ Project {
Depends { name: "cpp" }
Depends { name: "lib1" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
files: ["lib2.cpp"]
diff --git a/tests/auto/blackbox/testdata/fileDependencies/awesomelib/awesome.h b/tests/auto/blackbox/testdata/fileDependencies/awesomelib/awesome.h
index 4633f9746..8f1f25087 100644
--- a/tests/auto/blackbox/testdata/fileDependencies/awesomelib/awesome.h
+++ b/tests/auto/blackbox/testdata/fileDependencies/awesomelib/awesome.h
@@ -31,6 +31,6 @@
void doAwesomeStuff()
{
- printf(magnificentMessage);
+ std::printf(magnificentMessage);
}
diff --git a/tests/auto/blackbox/testdata/flatbuf/bar.fbs b/tests/auto/blackbox/testdata/flatbuf/bar.fbs
new file mode 100644
index 000000000..47148f800
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/bar.fbs
@@ -0,0 +1,9 @@
+include "foo.fbs";
+
+namespace QbsTest;
+
+table Bar {
+ foo:Foo;
+}
+
+root_type Bar;
diff --git a/tests/auto/blackbox/testdata/flatbuf/baz.fbs b/tests/auto/blackbox/testdata/flatbuf/baz.fbs
new file mode 100644
index 000000000..312183710
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/baz.fbs
@@ -0,0 +1,9 @@
+include "imported_foo/imported_foo.fbs";
+
+namespace QbsTest;
+
+table Baz {
+ foo:Foo;
+}
+
+root_type Baz;
diff --git a/tests/auto/blackbox/testdata/flatbuf/conanfile.txt b/tests/auto/blackbox/testdata/flatbuf/conanfile.txt
new file mode 100644
index 000000000..188da5897
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/conanfile.txt
@@ -0,0 +1,6 @@
+[requires]
+flatbuffers/24.3.25
+[tool_requires]
+flatbuffers/24.3.25
+[generators]
+QbsDeps
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat.c b/tests/auto/blackbox/testdata/flatbuf/flat.c
new file mode 100644
index 000000000..55e25e556
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat.c
@@ -0,0 +1,36 @@
+#include "foo_builder.h"
+
+#include <stdio.h>
+
+#undef ns
+#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(QbsTest, x) // Specified in the schema.
+
+#define test_assert(x) do { if (!(x)) { assert(0); return -1; }} while (0)
+
+int main()
+{
+ void *buffer = NULL;
+ size_t size = 0;
+
+ flatcc_builder_t builder;
+ flatcc_builder_init(&builder);
+
+ flatbuffers_string_ref_t name = flatbuffers_string_create_str(&builder, "John Doe");
+
+ ns(Foo_create_as_root(&builder, name, 42));
+
+ buffer = flatcc_builder_finalize_aligned_buffer(&builder, &size);
+
+ ns(Foo_table_t) foo = ns(Foo_as_root(buffer));
+
+ test_assert(strcmp(ns(Foo_name(foo)), "John Doe") == 0);
+ test_assert(ns(Foo_count(foo)) == 42);
+
+ free(buffer);
+
+ flatcc_builder_clear(&builder);
+
+ printf("The FlatBuffer was successfully created and accessed!\n");
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat.cpp b/tests/auto/blackbox/testdata/flatbuf/flat.cpp
new file mode 100644
index 000000000..56332bacd
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat.cpp
@@ -0,0 +1,22 @@
+#include "foo_generated.h"
+
+#include <iostream>
+
+using namespace QbsTest;
+
+int main()
+{
+ flatbuffers::FlatBufferBuilder builder;
+ auto name = builder.CreateString("John Doe");
+ auto newFoo = QbsTest::CreateFoo(builder, name, 42);
+ builder.Finish(newFoo);
+
+ auto foo = GetFoo(builder.GetBufferPointer());
+
+ assert(foo->name()->str() == "John Doe");
+ assert(foo->count() == 42);
+
+ std::cout << "The FlatBuffer was successfully created and accessed!" << std::endl;
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_absolute_import.cpp b/tests/auto/blackbox/testdata/flatbuf/flat_absolute_import.cpp
new file mode 100644
index 000000000..b7c43d8a5
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_absolute_import.cpp
@@ -0,0 +1,25 @@
+#include "baz_generated.h"
+
+#include <iostream>
+
+using namespace QbsTest;
+
+int main()
+{
+ flatbuffers::FlatBufferBuilder builder;
+
+ auto name = builder.CreateString("John Doe");
+ auto newFoo = QbsTest::CreateFoo(builder, name, 42);
+
+ auto newBaz = QbsTest::CreateBaz(builder, newFoo);
+ builder.Finish(newBaz);
+
+ auto baz = GetBaz(builder.GetBufferPointer());
+
+ assert(baz->foo()->name()->str() == "John Doe");
+ assert(baz->foo()->count() == 42);
+
+ std::cout << "The FlatBuffer was successfully created and accessed!" << std::endl;
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_absolute_import.qbs b/tests/auto/blackbox/testdata/flatbuf/flat_absolute_import.qbs
new file mode 100644
index 000000000..888bfd4e3
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_absolute_import.qbs
@@ -0,0 +1,24 @@
+CppApplication {
+ Depends { name: "flatbuf.cpp"; required: false }
+
+ consoleApplication: true
+ condition: {
+ var result = qbs.targetPlatform === qbs.hostPlatform;
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasFlatbuffers;
+ }
+ property bool hasFlatbuffers: {
+ console.info("has flatbuffers: " + flatbuf.cpp.present);
+ return flatbuf.cpp.present;
+ }
+
+ flatbuf.cpp.importPaths: "imports/"
+
+ files: [
+ "flat_absolute_import.cpp",
+ "baz.fbs",
+ "imports/imported_foo/imported_foo.fbs",
+ ]
+ qbsModuleProviders: "conan"
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_c.qbs b/tests/auto/blackbox/testdata/flatbuf/flat_c.qbs
new file mode 100644
index 000000000..6d365252e
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_c.qbs
@@ -0,0 +1,21 @@
+CppApplication {
+ Depends { name: "flatbuffers.c"; required: false }
+
+ consoleApplication: true
+ condition: {
+ var result = qbs.targetPlatform === qbs.hostPlatform;
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasFlatbuffers;
+ }
+ property bool hasFlatbuffers: {
+ console.info("has flatbuffers: " + flatbuffers.c.present);
+ return flatbuffers.c.present;
+ }
+
+ files: [
+ "flat.c",
+ "foo.fbs",
+ ]
+ qbsModuleProviders: "conan"
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_cpp.qbs b/tests/auto/blackbox/testdata/flatbuf/flat_cpp.qbs
new file mode 100644
index 000000000..99e89a5fa
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_cpp.qbs
@@ -0,0 +1,21 @@
+CppApplication {
+ Depends { name: "flatbuf.cpp"; required: false }
+
+ consoleApplication: true
+ condition: {
+ var result = qbs.targetPlatform === qbs.hostPlatform;
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasFlatbuffers;
+ }
+ property bool hasFlatbuffers: {
+ console.info("has flatbuffers: " + flatbuf.cpp.present);
+ return flatbuf.cpp.present;
+ }
+
+ files: [
+ "flat.cpp",
+ "foo.fbs",
+ ]
+ qbsModuleProviders: "conan"
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_filename_extension.cpp b/tests/auto/blackbox/testdata/flatbuf/flat_filename_extension.cpp
new file mode 100644
index 000000000..77ed64acd
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_filename_extension.cpp
@@ -0,0 +1,22 @@
+#include "foo_generated.hpp"
+
+#include <iostream>
+
+using namespace QbsTest;
+
+int main()
+{
+ flatbuffers::FlatBufferBuilder builder;
+ auto name = builder.CreateString("John Doe");
+ auto newFoo = QbsTest::CreateFoo(builder, name, 42);
+ builder.Finish(newFoo);
+
+ auto foo = GetFoo(builder.GetBufferPointer());
+
+ assert(foo->name()->str() == "John Doe");
+ assert(foo->count() == 42);
+
+ std::cout << "The FlatBuffer was successfully created and accessed!" << std::endl;
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_filename_extension.qbs b/tests/auto/blackbox/testdata/flatbuf/flat_filename_extension.qbs
new file mode 100644
index 000000000..31eec7629
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_filename_extension.qbs
@@ -0,0 +1,23 @@
+CppApplication {
+ Depends { name: "flatbuf.cpp"; required: false }
+
+ consoleApplication: true
+ condition: {
+ var result = qbs.targetPlatform === qbs.hostPlatform;
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasFlatbuffers;
+ }
+ property bool hasFlatbuffers: {
+ console.info("has flatbuffers: " + flatbuf.cpp.present);
+ return flatbuf.cpp.present;
+ }
+
+ flatbuf.cpp.filenameExtension: "hpp"
+
+ files: [
+ "flat_filename_extension.cpp",
+ "foo.fbs",
+ ]
+ qbsModuleProviders: "conan"
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_filename_suffix.cpp b/tests/auto/blackbox/testdata/flatbuf/flat_filename_suffix.cpp
new file mode 100644
index 000000000..630e4aaef
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_filename_suffix.cpp
@@ -0,0 +1,22 @@
+#include "foo.fbs.h"
+
+#include <iostream>
+
+using namespace QbsTest;
+
+int main()
+{
+ flatbuffers::FlatBufferBuilder builder;
+ auto name = builder.CreateString("John Doe");
+ auto newFoo = QbsTest::CreateFoo(builder, name, 42);
+ builder.Finish(newFoo);
+
+ auto foo = GetFoo(builder.GetBufferPointer());
+
+ assert(foo->name()->str() == "John Doe");
+ assert(foo->count() == 42);
+
+ std::cout << "The FlatBuffer was successfully created and accessed!" << std::endl;
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_filename_suffix.qbs b/tests/auto/blackbox/testdata/flatbuf/flat_filename_suffix.qbs
new file mode 100644
index 000000000..5103b041f
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_filename_suffix.qbs
@@ -0,0 +1,23 @@
+CppApplication {
+ Depends { name: "flatbuf.cpp"; required: false }
+
+ consoleApplication: true
+ condition: {
+ var result = qbs.targetPlatform === qbs.hostPlatform;
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasFlatbuffers;
+ }
+ property bool hasFlatbuffers: {
+ console.info("has flatbuffers: " + flatbuf.cpp.present);
+ return flatbuf.cpp.present;
+ }
+
+ flatbuf.cpp.filenameSuffix: ".fbs"
+
+ files: [
+ "flat_filename_suffix.cpp",
+ "foo.fbs",
+ ]
+ qbsModuleProviders: "conan"
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_keep_prefix.cpp b/tests/auto/blackbox/testdata/flatbuf/flat_keep_prefix.cpp
new file mode 100644
index 000000000..5f4b55e96
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_keep_prefix.cpp
@@ -0,0 +1,26 @@
+#include "baz_generated.h"
+#include "imported_foo/imported_foo_generated.h"
+
+#include <iostream>
+
+using namespace QbsTest;
+
+int main()
+{
+ flatbuffers::FlatBufferBuilder builder;
+
+ auto name = builder.CreateString("John Doe");
+ auto newFoo = QbsTest::CreateFoo(builder, name, 42);
+
+ auto newBaz = QbsTest::CreateBaz(builder, newFoo);
+ builder.Finish(newBaz);
+
+ auto baz = GetBaz(builder.GetBufferPointer());
+
+ assert(baz->foo()->name()->str() == "John Doe");
+ assert(baz->foo()->count() == 42);
+
+ std::cout << "The FlatBuffer was successfully created and accessed!" << std::endl;
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_keep_prefix.qbs b/tests/auto/blackbox/testdata/flatbuf/flat_keep_prefix.qbs
new file mode 100644
index 000000000..0ea0d1dac
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_keep_prefix.qbs
@@ -0,0 +1,25 @@
+CppApplication {
+ Depends { name: "flatbuf.cpp"; required: false }
+
+ consoleApplication: true
+ condition: {
+ var result = qbs.targetPlatform === qbs.hostPlatform;
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasFlatbuffers;
+ }
+ property bool hasFlatbuffers: {
+ console.info("has flatbuffers: " + flatbuf.cpp.present);
+ return flatbuf.cpp.present;
+ }
+
+ flatbuf.cpp.importPaths: "imports/"
+ flatbuf.cpp.keepPrefix: true
+
+ files: [
+ "flat_keep_prefix.cpp",
+ "baz.fbs",
+ "imports/imported_foo/imported_foo.fbs",
+ ]
+ qbsModuleProviders: "conan"
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_relative_import.cpp b/tests/auto/blackbox/testdata/flatbuf/flat_relative_import.cpp
new file mode 100644
index 000000000..bec6dadfd
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_relative_import.cpp
@@ -0,0 +1,25 @@
+#include "bar_generated.h"
+
+#include <iostream>
+
+using namespace QbsTest;
+
+int main()
+{
+ flatbuffers::FlatBufferBuilder builder;
+
+ auto name = builder.CreateString("John Doe");
+ auto newFoo = QbsTest::CreateFoo(builder, name, 42);
+
+ auto newBar = QbsTest::CreateBar(builder, newFoo);
+ builder.Finish(newBar);
+
+ auto bar = GetBar(builder.GetBufferPointer());
+
+ assert(bar->foo()->name()->str() == "John Doe");
+ assert(bar->foo()->count() == 42);
+
+ std::cout << "The FlatBuffer was successfully created and accessed!" << std::endl;
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/flat_relative_import.qbs b/tests/auto/blackbox/testdata/flatbuf/flat_relative_import.qbs
new file mode 100644
index 000000000..f5a2c5d0b
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/flat_relative_import.qbs
@@ -0,0 +1,22 @@
+CppApplication {
+ Depends { name: "flatbuf.cpp"; required: false }
+
+ consoleApplication: true
+ condition: {
+ var result = qbs.targetPlatform === qbs.hostPlatform;
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasFlatbuffers;
+ }
+ property bool hasFlatbuffers: {
+ console.info("has flatbuffers: " + flatbuf.cpp.present);
+ return flatbuf.cpp.present;
+ }
+
+ files: [
+ "flat_relative_import.cpp",
+ "bar.fbs",
+ "foo.fbs",
+ ]
+ qbsModuleProviders: "conan"
+}
diff --git a/tests/auto/blackbox/testdata/flatbuf/foo.fbs b/tests/auto/blackbox/testdata/flatbuf/foo.fbs
new file mode 100644
index 000000000..dff3b488f
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/foo.fbs
@@ -0,0 +1,8 @@
+namespace QbsTest;
+
+table Foo {
+ name:string;
+ count:int;
+}
+
+root_type Foo;
diff --git a/tests/auto/blackbox/testdata/flatbuf/imports/imported_foo/imported_foo.fbs b/tests/auto/blackbox/testdata/flatbuf/imports/imported_foo/imported_foo.fbs
new file mode 100644
index 000000000..dff3b488f
--- /dev/null
+++ b/tests/auto/blackbox/testdata/flatbuf/imports/imported_foo/imported_foo.fbs
@@ -0,0 +1,8 @@
+namespace QbsTest;
+
+table Foo {
+ name:string;
+ count:int;
+}
+
+root_type Foo;
diff --git a/tests/auto/blackbox/testdata/freedesktop/freedesktop.qbs b/tests/auto/blackbox/testdata/freedesktop/freedesktop.qbs
new file mode 100644
index 000000000..1efe5c91c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/freedesktop/freedesktop.qbs
@@ -0,0 +1,23 @@
+Project {
+ CppApplication {
+ name: "main"
+ install: true
+ files: [
+ "main.cpp",
+ "myapp.desktop",
+ "myapp.appdata.xml",
+ ]
+
+ Depends { name: "freedesktop" }
+
+ freedesktop.appName: "My App"
+ freedesktop.desktopKeys: ({
+ 'Icon': "myapp.png"
+ })
+
+ Group {
+ files: "myapp.png"
+ fileTags: "freedesktop.appIcon"
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/freedesktop/main.cpp b/tests/auto/blackbox/testdata/freedesktop/main.cpp
new file mode 100644
index 000000000..905869dfa
--- /dev/null
+++ b/tests/auto/blackbox/testdata/freedesktop/main.cpp
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/freedesktop/myapp.appdata.xml b/tests/auto/blackbox/testdata/freedesktop/myapp.appdata.xml
new file mode 100644
index 000000000..3cf0a5641
--- /dev/null
+++ b/tests/auto/blackbox/testdata/freedesktop/myapp.appdata.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component type="desktop">
+ <id>myapp.desktop</id>
+ <metadata_license>CC0</metadata_license>
+ <name>MyApp</name>
+ <summary>The coolest app ever</summary>
+
+ <description>
+ <p>This is a cool application.</p>
+ </description>
+
+ <url type="homepage">https://software.house/myapp</url>
+ <project_license>GPL-2.0+</project_license>
+ <developer_name>Coding Wizard</developer_name>
+</component>
diff --git a/tests/auto/blackbox/testdata/freedesktop/myapp.desktop b/tests/auto/blackbox/testdata/freedesktop/myapp.desktop
new file mode 100644
index 000000000..dac3014c3
--- /dev/null
+++ b/tests/auto/blackbox/testdata/freedesktop/myapp.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+GenericName=Image Editor
+Comment=Create images and edit photographs
+Icon=overridden.png
diff --git a/tests/auto/blackbox/testdata/freedesktop/myapp.png b/tests/auto/blackbox/testdata/freedesktop/myapp.png
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/freedesktop/myapp.png
diff --git a/tests/auto/blackbox/testdata/generate-linker-map-file/generate-linker-map-file.qbs b/tests/auto/blackbox/testdata/generate-linker-map-file/generate-linker-map-file.qbs
index 815e64853..0d67fa54c 100644
--- a/tests/auto/blackbox/testdata/generate-linker-map-file/generate-linker-map-file.qbs
+++ b/tests/auto/blackbox/testdata/generate-linker-map-file/generate-linker-map-file.qbs
@@ -2,11 +2,14 @@ Project {
CppApplication {
name: "app-map"
files: ["main.cpp"]
+ // lld-link has different flag for map files, test it by switching to "lld" linkerVariant
+ Properties { condition: qbs.toolchain.includes("clang-cl"); cpp.linkerVariant: "lld" }
cpp.generateLinkerMapFile: true
}
CppApplication {
name: "app-nomap"
files: ["main.cpp"]
+ Properties { condition: qbs.toolchain.includes("clang-cl"); cpp.linkerVariant: "lld" }
cpp.generateLinkerMapFile: false
}
CppApplication {
@@ -16,8 +19,8 @@ Project {
Probe {
id: toolchainProbe
- property bool isUsed: qbs.toolchain.contains("msvc")
- || qbs.toolchain.contains("gcc")
+ property bool isUsed: qbs.toolchain.includes("msvc")
+ || qbs.toolchain.includes("gcc")
configure: {
console.info("use test: " + isUsed);
}
diff --git a/tests/auto/blackbox/testdata/generator/generator.qbs b/tests/auto/blackbox/testdata/generator/generator.qbs
index d0857beb5..9f6d452e7 100644
--- a/tests/auto/blackbox/testdata/generator/generator.qbs
+++ b/tests/auto/blackbox/testdata/generator/generator.qbs
@@ -18,12 +18,12 @@ CppApplication {
var f = new TextFile(input.filePath, TextFile.ReadOnly);
var content = f.readAll();
f.close();
- if (content.contains("file1")) {
+ if (content.includes("file1")) {
f = new TextFile(outputs.file1[0].filePath, TextFile.WriteOnly);
f.writeLine("void f1() {}");
f.close();
}
- if (content.contains("file2")) {
+ if (content.includes("file2")) {
f = new TextFile(outputs.file2[0].filePath, TextFile.WriteOnly);
f.writeLine("void f2() {}");
f.close();
diff --git a/tests/auto/blackbox/testdata/groups-in-modules/groups-in-modules.qbs b/tests/auto/blackbox/testdata/groups-in-modules/groups-in-modules.qbs
index 7347b1211..47275821f 100644
--- a/tests/auto/blackbox/testdata/groups-in-modules/groups-in-modules.qbs
+++ b/tests/auto/blackbox/testdata/groups-in-modules/groups-in-modules.qbs
@@ -1,11 +1,22 @@
+import qbs.Host
+
Project {
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
Depends { name: "dep" }
Depends { name: "helper" }
Depends {
name: "helper3"
required: false
}
+ Depends { name: "helper7" }
+ helper7.fileName: "helper7.c"
+
type: ["diamond"]
files: [
diff --git a/tests/auto/blackbox/testdata/groups-in-modules/imports/Helper7Base.qbs b/tests/auto/blackbox/testdata/groups-in-modules/imports/Helper7Base.qbs
new file mode 100644
index 000000000..cc55e6351
--- /dev/null
+++ b/tests/auto/blackbox/testdata/groups-in-modules/imports/Helper7Base.qbs
@@ -0,0 +1,8 @@
+Module {
+ property string directory
+ property string fileName
+ Group {
+ prefix: directory + "/"
+ files: fileName
+ }
+}
diff --git a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper/helper.qbs b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper/helper.qbs
index cbd30a35d..9dc903411 100644
--- a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper/helper.qbs
+++ b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper/helper.qbs
@@ -39,7 +39,7 @@ Module {
prepare: {
var cmd = new Command(FileInfo.joinPaths(product.buildDirectory, product.targetName), [input.filePath, output.filePath]);
- cmd.description = "compile " + input.fileName + " => " + output.fileName;
+ cmd.description = "compiling " + input.fileName + " to " + output.fileName;
return [cmd];
}
}
diff --git a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper7/helper7.c b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper7/helper7.c
new file mode 100644
index 000000000..a83f5476e
--- /dev/null
+++ b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper7/helper7.c
@@ -0,0 +1 @@
+void helper7(void) {}
diff --git a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper7/helper7.qbs b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper7/helper7.qbs
new file mode 100644
index 000000000..90e1f11e2
--- /dev/null
+++ b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper7/helper7.qbs
@@ -0,0 +1,3 @@
+Helper7Base {
+ directory: path
+}
diff --git a/tests/auto/blackbox/testdata/grpc/conanfile.txt b/tests/auto/blackbox/testdata/grpc/conanfile.txt
new file mode 100644
index 000000000..f88e6e8d6
--- /dev/null
+++ b/tests/auto/blackbox/testdata/grpc/conanfile.txt
@@ -0,0 +1,7 @@
+[requires]
+grpc/1.54.3
+[tool_requires]
+protobuf/3.21.12
+grpc/1.54.3
+[generators]
+QbsDeps
diff --git a/tests/auto/blackbox/testdata/grpc/grpc.cpp b/tests/auto/blackbox/testdata/grpc/grpc.cpp
index 81995601d..5f85c5b40 100644
--- a/tests/auto/blackbox/testdata/grpc/grpc.cpp
+++ b/tests/auto/blackbox/testdata/grpc/grpc.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2019 Ivan Komissarov
-** Contact: abbapoh@gmail.com
+** Copyright (C) 2019 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
diff --git a/tests/auto/blackbox/testdata/grpc/grpc_cpp.qbs b/tests/auto/blackbox/testdata/grpc/grpc_cpp.qbs
index 8ee3dd9c9..d1bdd5d60 100644
--- a/tests/auto/blackbox/testdata/grpc/grpc_cpp.qbs
+++ b/tests/auto/blackbox/testdata/grpc/grpc_cpp.qbs
@@ -1,20 +1,29 @@
-import qbs
+import qbs.Host
CppApplication {
name: "grpc_cpp"
consoleApplication: true
- condition: hasDependencies
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasDependencies;
+ }
Depends { name: "cpp" }
- cpp.cxxLanguageVersion: "c++11"
+ cpp.cxxLanguageVersion: "c++17"
+ cpp.minimumMacosVersion: "10.15"
cpp.warningLevel: "none"
+ qbs.buildVariant: "release"
Depends { name: "protobuf.cpp"; required: false }
+ Depends { name: "grpc++"; id: grpcpp; required: false }
protobuf.cpp.useGrpc: true
property bool hasDependencies: {
console.info("has grpc: " + protobuf.cpp.present);
- return protobuf.cpp.present;
+ console.info("has modules: " + grpcpp.present);
+ return protobuf.cpp.present && grpcpp.present;
}
files: "grpc.cpp"
diff --git a/tests/auto/blackbox/testdata/host-os-properties/host-os-properties.qbs b/tests/auto/blackbox/testdata/host-os-properties/host-os-properties.qbs
new file mode 100644
index 000000000..9d050e166
--- /dev/null
+++ b/tests/auto/blackbox/testdata/host-os-properties/host-os-properties.qbs
@@ -0,0 +1,16 @@
+import qbs.Host
+
+CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
+ consoleApplication: true
+ cpp.defines: [
+ 'HOST_ARCHITECTURE="' + Host.architecture() + '"',
+ 'HOST_PLATFORM="' + Host.platform() + '"'
+ ]
+ files: "main.cpp"
+}
diff --git a/tests/auto/blackbox/testdata/host-os-properties/main.cpp b/tests/auto/blackbox/testdata/host-os-properties/main.cpp
new file mode 100644
index 000000000..129c16379
--- /dev/null
+++ b/tests/auto/blackbox/testdata/host-os-properties/main.cpp
@@ -0,0 +1,7 @@
+#include <cstdio>
+
+int main() {
+ std::printf("HOST_ARCHITECTURE = %s\n", HOST_ARCHITECTURE);
+ std::printf("HOST_PLATFORM = %s\n", HOST_PLATFORM);
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/importing-product/importing-product.qbs b/tests/auto/blackbox/testdata/importing-product/importing-product.qbs
index dfc4cd65e..54ad727b7 100644
--- a/tests/auto/blackbox/testdata/importing-product/importing-product.qbs
+++ b/tests/auto/blackbox/testdata/importing-product/importing-product.qbs
@@ -16,7 +16,7 @@ Project {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Copying file";
+ cmd.description = "copying file";
cmd.sourceCode = function() {
File.copy(input.filePath, output.filePath);
}
diff --git a/tests/auto/blackbox/testdata/includeLookup/includeLookup.qbs b/tests/auto/blackbox/testdata/includeLookup/includeLookup.qbs
index 182d1e232..903d170d0 100644
--- a/tests/auto/blackbox/testdata/includeLookup/includeLookup.qbs
+++ b/tests/auto/blackbox/testdata/includeLookup/includeLookup.qbs
@@ -1,9 +1,16 @@
import qbs.FileInfo
+import qbs.Host
Project {
property string name: 'includeLookup'
qbsSearchPaths: '.'
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
type: 'application'
consoleApplication: true
name: project.name
diff --git a/tests/auto/blackbox/testdata/includeLookup/main.cpp b/tests/auto/blackbox/testdata/includeLookup/main.cpp
index c7213c768..a91914f73 100644
--- a/tests/auto/blackbox/testdata/includeLookup/main.cpp
+++ b/tests/auto/blackbox/testdata/includeLookup/main.cpp
@@ -30,7 +30,7 @@
int main()
{
- printf("%s..\n", TEXT);
+ std::printf("%s..\n", TEXT);
return 0;
}
diff --git a/tests/auto/blackbox/testdata/input-tags-change-tracking/input-tags-change-tracking.qbs b/tests/auto/blackbox/testdata/input-tags-change-tracking/input-tags-change-tracking.qbs
index ef2c5c55b..1e4248009 100644
--- a/tests/auto/blackbox/testdata/input-tags-change-tracking/input-tags-change-tracking.qbs
+++ b/tests/auto/blackbox/testdata/input-tags-change-tracking/input-tags-change-tracking.qbs
@@ -43,10 +43,10 @@ Product {
inputs: "txt"
outputFileTags: "p_tag"
outputArtifacts: {
- if (input.fileTags.contains("empty"))
+ if (input.fileTags.includes("empty"))
return [];
return [{
- filePath: input.fileTags.contains("y") ? "y.out" : "x.out",
+ filePath: input.fileTags.includes("y") ? "y.out" : "x.out",
fileTags: "p_tag"
}]
}
diff --git a/tests/auto/blackbox/testdata/inputs-from-dependencies/inputs-from-dependencies.qbs b/tests/auto/blackbox/testdata/inputs-from-dependencies/inputs-from-dependencies.qbs
index 919060c73..f9993ecf3 100644
--- a/tests/auto/blackbox/testdata/inputs-from-dependencies/inputs-from-dependencies.qbs
+++ b/tests/auto/blackbox/testdata/inputs-from-dependencies/inputs-from-dependencies.qbs
@@ -37,7 +37,7 @@ Project {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Gathering text files";
+ cmd.description = "gathering text files";
cmd.sourceCode = function() {
for (i in inputs.txt)
console.info(inputs.txt[i].filePath);
diff --git a/tests/auto/blackbox/testdata/install-locations/install-locations.qbs b/tests/auto/blackbox/testdata/install-locations/install-locations.qbs
index 8a97f74a1..ba51c0dc1 100644
--- a/tests/auto/blackbox/testdata/install-locations/install-locations.qbs
+++ b/tests/auto/blackbox/testdata/install-locations/install-locations.qbs
@@ -1,16 +1,24 @@
Project {
property bool dummy: {
- if (qbs.targetOS.contains("windows"))
+ if (qbs.targetOS.includes("windows")) {
console.info("is windows");
- else if (qbs.targetOS.contains("macos"))
- console.info("is mac");
- else
+ } else if (qbs.targetOS.includes("darwin")) {
+ console.info("is darwin");
+ if (qbs.targetOS.includes("macos"))
+ console.info("is mac");
+ } else {
console.info("is unix");
+ }
+
+ if (qbs.toolchain.includes("mingw"))
+ console.info("is mingw");
}
CppApplication {
name: "theapp"
install: true
+ installDebugInformation: true
files: "main.cpp"
+ cpp.separateDebugInformation: true
Group {
fileTagsFilter: "application"
fileTags: "some-tag"
@@ -20,7 +28,17 @@ Project {
name: "thelib"
install: true
installImportLib: true
+ installDebugInformation: true
Depends { name: "cpp" }
+ cpp.separateDebugInformation: true
files: "thelib.cpp"
}
+ LoadableModule {
+ name: "theplugin"
+ install: true
+ installDebugInformation: true
+ Depends { name: "cpp" }
+ cpp.separateDebugInformation: true
+ files: "theplugin.cpp"
+ }
}
diff --git a/tests/auto/blackbox/testdata/install-locations/theplugin.cpp b/tests/auto/blackbox/testdata/install-locations/theplugin.cpp
new file mode 100644
index 000000000..ac1ede090
--- /dev/null
+++ b/tests/auto/blackbox/testdata/install-locations/theplugin.cpp
@@ -0,0 +1,3 @@
+#include "../dllexport.h"
+
+DLL_EXPORT void pluginFunc() {}
diff --git a/tests/auto/blackbox/testdata/installable-as-auxiliary-input/installable-as-auxiliary-input.qbs b/tests/auto/blackbox/testdata/installable-as-auxiliary-input/installable-as-auxiliary-input.qbs
index 2d37e85d6..a445fc35b 100644
--- a/tests/auto/blackbox/testdata/installable-as-auxiliary-input/installable-as-auxiliary-input.qbs
+++ b/tests/auto/blackbox/testdata/installable-as-auxiliary-input/installable-as-auxiliary-input.qbs
@@ -1,10 +1,17 @@
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.TextFile
Project {
name: "p"
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "app"
Depends { name: "installed-header" }
Rule {
@@ -42,7 +49,7 @@ Project {
Export {
Depends { name: "cpp" }
- cpp.includePaths: FileInfo.joinPaths(qbs.installRoot, product.installDir);
+ cpp.includePaths: FileInfo.joinPaths(qbs.installRoot, exportingProduct.installDir);
}
Rule {
@@ -50,7 +57,7 @@ Project {
Artifact { filePath: "theheader.h.in"; fileTags: "header.in" }
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.sourceCode = function() {
for (var i = 0; i < 1000; ++i) { // Artificial delay.
var file = new TextFile(output.filePath, TextFile.WriteOnly);
@@ -69,7 +76,7 @@ Project {
Artifact { filePath: "theheader.h"; fileTags: "header" }
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); };
return [cmd];
}
diff --git a/tests/auto/blackbox/testdata/installable/installable.qbs b/tests/auto/blackbox/testdata/installable/installable.qbs
index 56feb6ec5..de93cf61f 100644
--- a/tests/auto/blackbox/testdata/installable/installable.qbs
+++ b/tests/auto/blackbox/testdata/installable/installable.qbs
@@ -11,6 +11,7 @@ Project {
}
install: true
+ installDebugInformation: false
installDir: ""
}
@@ -27,7 +28,7 @@ Project {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.sourceCode = function() {
var file = new TextFile(output.filePath, TextFile.WriteOnly);
for (var i = 0; i < inputs.installable.length; ++i)
diff --git a/tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs b/tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs
index aa40b7691..6f84206be 100644
--- a/tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs
+++ b/tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs
@@ -18,7 +18,7 @@ Product {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating file:'" + output.fileName + "'";
+ cmd.description = "creating file:'" + output.fileName + "'";
cmd.highlight = "codegen";
cmd.sourceCode = function() {
var file = new TextFile(output.filePath, TextFile.WriteOnly);
diff --git a/tests/auto/blackbox/testdata/installpackage/installpackage.qbs b/tests/auto/blackbox/testdata/installpackage/installpackage.qbs
index a0649a578..3396b79a4 100644
--- a/tests/auto/blackbox/testdata/installpackage/installpackage.qbs
+++ b/tests/auto/blackbox/testdata/installpackage/installpackage.qbs
@@ -2,7 +2,7 @@ Project {
CppApplication {
name: "public_tool"
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
Depends { name: "mylib" }
@@ -20,7 +20,7 @@ Project {
}
DynamicLibrary {
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
Depends { name: "cpp" }
diff --git a/tests/auto/blackbox/testdata/invalid-artifact-path/invalid-artifact-path.qbs b/tests/auto/blackbox/testdata/invalid-artifact-path/invalid-artifact-path.qbs
new file mode 100644
index 000000000..650233d86
--- /dev/null
+++ b/tests/auto/blackbox/testdata/invalid-artifact-path/invalid-artifact-path.qbs
@@ -0,0 +1,18 @@
+Project {
+ property string artifactDir
+ Product {
+ type: "t"
+ Rule {
+ multiplex: true
+ Artifact {
+ filePath: project.artifactDir + "/file.out"
+ fileTags: "t"
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.sourceCode = function() {};
+ return cmd;
+ }
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/invalid-command-property/invalid-command-property.qbs b/tests/auto/blackbox/testdata/invalid-command-property/invalid-command-property.qbs
index b08fcd4a3..a07beda57 100644
--- a/tests/auto/blackbox/testdata/invalid-command-property/invalid-command-property.qbs
+++ b/tests/auto/blackbox/testdata/invalid-command-property/invalid-command-property.qbs
@@ -16,7 +16,7 @@ Product {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating output";
+ cmd.description = "creating output";
if (product.errorType === "qobject")
cmd.dummy = new TextFile(input.filePath, TextFile.ReadOnly);
else if (product.errorType === "input")
diff --git a/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs b/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs
index 1e7426744..5824fe518 100644
--- a/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs
+++ b/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs
@@ -36,6 +36,9 @@ Product {
destination.write(source.atEof() ? [ 0xFF ] : [ 0x00 ]);
source.close();
destination.close();
+ source = new BinaryFile("destination.dat", BinaryFile.ReadOnly);
+ destination = new BinaryFile("destination2.dat", BinaryFile.WriteOnly);
+ destination.write(source.read(8));
};
commands.push(cmd);
return commands;
diff --git a/tests/auto/blackbox/testdata/jsextensions-file/file.qbs b/tests/auto/blackbox/testdata/jsextensions-file/file.qbs
index 6adf714e2..7a47cf3cd 100644
--- a/tests/auto/blackbox/testdata/jsextensions-file/file.qbs
+++ b/tests/auto/blackbox/testdata/jsextensions-file/file.qbs
@@ -33,10 +33,10 @@ Product {
if (!created || !File.exists(zePath))
throw new Error("zePath was not created.");
var entries = File.directoryEntries(product.sourceDirectory, File.AllEntries | File.NoDotAndDotDot);
- if (entries.length < 3 || !entries.contains("file.qbs"))
+ if (entries.length < 3 || !entries.includes("file.qbs"))
throw new Error("Directory did not contain file.qbs");
entries = File.directoryEntries(product.sourceDirectory, File.Dirs | File.NoDotAndDotDot);
- if (entries.length < 1 || !entries.contains("zePath"))
+ if (entries.length < 1 || !entries.includes("zePath"))
throw new Error("Directory did not contain only zePath");
var moveSource = FileInfo.joinPaths(product.sourceDirectory, "tomove.txt");
var moveTarget = FileInfo.joinPaths(product.sourceDirectory, "moved.txt");
diff --git a/tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs b/tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs
index d63ba2962..0e727d04b 100644
--- a/tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs
+++ b/tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs
@@ -39,6 +39,8 @@ Product {
output.writeLine(FileInfo.relativePath("/tmp", "/blubb.tar.gz"));
output.writeLine(FileInfo.toWindowsSeparators("/tmp/blubb.tar.gz"));
output.writeLine(FileInfo.toWindowsSeparators("c:\\tmp\\blubb.tar.gz"));
+ output.writeLine(FileInfo.pathListSeparator());
+ output.writeLine(FileInfo.pathSeparator());
output.close();
};
return [cmd];
diff --git a/tests/auto/blackbox/testdata/jsextensions-host/host.qbs b/tests/auto/blackbox/testdata/jsextensions-host/host.qbs
new file mode 100644
index 000000000..08d13b25d
--- /dev/null
+++ b/tests/auto/blackbox/testdata/jsextensions-host/host.qbs
@@ -0,0 +1,31 @@
+import qbs.FileInfo
+import qbs.Host
+import qbs.TextFile
+
+Product {
+ type: ["dummy"]
+ Rule {
+ multiplex: true
+ outputFileTags: "dummy"
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.silent = true;
+ cmd.sourceCode = function() {
+ var output = new TextFile(FileInfo.joinPaths(product.sourceDirectory, "output.txt"),
+ TextFile.WriteOnly);
+ output.writeLine("architecture: " +Host.architecture());
+ output.writeLine("os: " + Host.os());
+ output.writeLine("platform: " + Host.platform());
+ output.writeLine("osVersion: " + Host.osVersion());
+ output.writeLine("osBuildVersion: " + Host.osBuildVersion());
+ output.writeLine("osVersionParts: " + Host.osVersionParts());
+ output.writeLine("osVersionMajor: " + Host.osVersionMajor());
+ output.writeLine("osVersionMinor: " + Host.osVersionMinor());
+ output.writeLine("osVersionPatch: " + Host.osVersionPatch());
+ output.writeLine("nullDevice: " + Host.nullDevice());
+ output.close();
+ };
+ return [cmd];
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/jsextensions-process/main.cpp b/tests/auto/blackbox/testdata/jsextensions-process/main.cpp
index df769de87..3f28fe091 100644
--- a/tests/auto/blackbox/testdata/jsextensions-process/main.cpp
+++ b/tests/auto/blackbox/testdata/jsextensions-process/main.cpp
@@ -4,17 +4,17 @@
int main(int argc, char *argv[])
{
- if (argc != 2 || strcmp(argv[1], "help") != 0) {
- fprintf(stderr, "First argument to this program must be 'help'.\n");
+ if (argc != 2 || std::strcmp(argv[1], "help") != 0) {
+ std::fprintf(stderr, "First argument to this program must be 'help'.\n");
return 1;
}
const char *env = std::getenv("SOME_ENV");
- if (!env || strcmp(env, "why, hello!") != 0) {
- fprintf(stderr, "The SOME_ENV environment variable must be 'why, hello!'.\n");
+ if (!env || std::strcmp(env, "why, hello!") != 0) {
+ std::fprintf(stderr, "The SOME_ENV environment variable must be 'why, hello!'.\n");
return 1;
}
- printf("qbs jsextensions-process test\n");
+ std::printf("qbs jsextensions-process test\n");
return 0;
}
diff --git a/tests/auto/blackbox/testdata/jsextensions-process/process.qbs b/tests/auto/blackbox/testdata/jsextensions-process/process.qbs
index eba95d005..50f22cdfc 100644
--- a/tests/auto/blackbox/testdata/jsextensions-process/process.qbs
+++ b/tests/auto/blackbox/testdata/jsextensions-process/process.qbs
@@ -1,10 +1,17 @@
import qbs.Environment
import qbs.FileInfo
+import qbs.Host
import qbs.Process
import qbs.TextFile
Project {
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
Depends { name: "cpp" }
type: ["dummy"]
name: "dummy"
@@ -48,7 +55,7 @@ Project {
// closeWriteChannel test
process = new Process();
- if (product.qbs.hostOS.contains("windows"))
+ if (Host.os().includes("windows"))
process.start(product.qbs.windowsShellPath,
["/C", product.qbs.windowsSystemRoot + "\\system32\\sort.exe"]);
else
@@ -69,7 +76,7 @@ Project {
testReadlineFile.close();
process = new Process();
- if (product.qbs.hostOS.contains("windows"))
+ if (Host.os().includes("windows"))
process.exec(product.qbs.windowsShellPath,
["/C", "type", "123.txt"],
true);
diff --git a/tests/auto/blackbox/testdata/last-module-candidate-broken/last-module-candidate-broken.qbs b/tests/auto/blackbox/testdata/last-module-candidate-broken/last-module-candidate-broken.qbs
new file mode 100644
index 000000000..db7dc2265
--- /dev/null
+++ b/tests/auto/blackbox/testdata/last-module-candidate-broken/last-module-candidate-broken.qbs
@@ -0,0 +1,5 @@
+CppApplication {
+ qbsSearchPaths: "qbs"
+ Depends { name: "Foo" }
+ files: "main.cpp"
+}
diff --git a/tests/auto/blackbox/testdata/last-module-candidate-broken/main.cpp b/tests/auto/blackbox/testdata/last-module-candidate-broken/main.cpp
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata/last-module-candidate-broken/main.cpp
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/tests/auto/blackbox/testdata/last-module-candidate-broken/qbs/modules/Foo/Foo1.qbs b/tests/auto/blackbox/testdata/last-module-candidate-broken/qbs/modules/Foo/Foo1.qbs
new file mode 100644
index 000000000..ba08b862b
--- /dev/null
+++ b/tests/auto/blackbox/testdata/last-module-candidate-broken/qbs/modules/Foo/Foo1.qbs
@@ -0,0 +1,3 @@
+Module {
+ condition: false
+}
diff --git a/tests/auto/blackbox/testdata/last-module-candidate-broken/qbs/modules/Foo/Foo2.qbs b/tests/auto/blackbox/testdata/last-module-candidate-broken/qbs/modules/Foo/Foo2.qbs
new file mode 100644
index 000000000..0bc383b86
--- /dev/null
+++ b/tests/auto/blackbox/testdata/last-module-candidate-broken/qbs/modules/Foo/Foo2.qbs
@@ -0,0 +1,2 @@
+Group {
+}
diff --git a/tests/auto/blackbox/testdata/ld/ld.qbs b/tests/auto/blackbox/testdata/ld/ld.qbs
index 25fede1b0..cb04d3d9a 100644
--- a/tests/auto/blackbox/testdata/ld/ld.qbs
+++ b/tests/auto/blackbox/testdata/ld/ld.qbs
@@ -5,7 +5,7 @@ Project {
targetName: "qbs can handle any file paths, even the crazy ones! ;)"
files: ["coreutils.cpp", "coreutils.h"]
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
cpp.sonamePrefix: "@rpath"
}
diff --git a/tests/auto/blackbox/testdata/ld/main.cpp b/tests/auto/blackbox/testdata/ld/main.cpp
index fd6b72f3b..bcf293705 100644
--- a/tests/auto/blackbox/testdata/ld/main.cpp
+++ b/tests/auto/blackbox/testdata/ld/main.cpp
@@ -27,10 +27,11 @@
****************************************************************************/
#include "coreutils.h"
-#include <stdio.h>
+
+#include <cstdio>
int main(int argc, char *argv[])
{
- printf("%d\n", foo());
+ std::printf("%d\n", foo());
return 0;
}
diff --git a/tests/auto/blackbox/testdata/lexyacc/modules/bisonhelper/bisonhelper.qbs b/tests/auto/blackbox/testdata/lexyacc/modules/bisonhelper/bisonhelper.qbs
index 449b130e2..4cce9a1e3 100644
--- a/tests/auto/blackbox/testdata/lexyacc/modules/bisonhelper/bisonhelper.qbs
+++ b/tests/auto/blackbox/testdata/lexyacc/modules/bisonhelper/bisonhelper.qbs
@@ -1,4 +1,3 @@
-import qbs
import qbs.Process
Module {
@@ -8,7 +7,7 @@ Module {
property string yaccBinary: lex_yacc.yaccBinary
configure: {
var p = Process();
- found = p.exec(yaccBinary, ["-V"]) == 0 && p.readStdOut().contains("bison");
+ found = p.exec(yaccBinary, ["-V"]) == 0 && p.readStdOut().includes("bison");
p.close();
}
}
diff --git a/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs b/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs
index 6cd334247..faa5d1fac 100644
--- a/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs
+++ b/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs
@@ -1,4 +1,12 @@
+import qbs.Host
+
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
qbsSearchPaths: ".."
Depends { name: "bisonhelper" }
Depends { name: "lex_yacc" }
@@ -11,10 +19,10 @@ CppApplication {
Probe {
id: pathCheck
property string theDir: {
- if (qbs.targetOS.contains("windows")) {
- if (qbs.toolchain.contains("mingw"))
+ if (qbs.targetOS.includes("windows")) {
+ if (qbs.toolchain.includes("mingw"))
return cpp.toolchainInstallPath;
- if (qbs.toolchain.contains("clang") && qbs.sysroot)
+ if (qbs.toolchain.includes("clang") && qbs.sysroot)
return qbs.sysroot + "/bin";
}
}
diff --git a/tests/auto/blackbox/testdata/lexyacc/two-grammars/two-grammars.qbs b/tests/auto/blackbox/testdata/lexyacc/two-grammars/two-grammars.qbs
index 7b0c1e515..648860d9c 100644
--- a/tests/auto/blackbox/testdata/lexyacc/two-grammars/two-grammars.qbs
+++ b/tests/auto/blackbox/testdata/lexyacc/two-grammars/two-grammars.qbs
@@ -1,7 +1,13 @@
+import qbs.Host
+
CppApplication {
Depends { name: "lex_yacc" }
consoleApplication: true
cpp.includePaths: ".."
+ Properties {
+ condition: Host.os().includes("darwin") && qbs.toolchain.includes("clang")
+ cpp.cFlags: "-Wno-implicit-function-declaration"
+ }
files: [
"g1.l",
"g1.y",
diff --git a/tests/auto/blackbox/testdata/linker-library-duplicates/setup-run-environment.qbs b/tests/auto/blackbox/testdata/linker-library-duplicates/setup-run-environment.qbs
index 9723fd3f5..c41e8f1d7 100644
--- a/tests/auto/blackbox/testdata/linker-library-duplicates/setup-run-environment.qbs
+++ b/tests/auto/blackbox/testdata/linker-library-duplicates/setup-run-environment.qbs
@@ -1,5 +1,3 @@
-import qbs 1.0
-
Project {
DynamicLibrary {
id: idLib1
@@ -8,6 +6,11 @@ Project {
files: ["lib1.cpp"]
Depends { name: "bundle" }
bundle.isBundle: false
+ Probe {
+ id: checker
+ property bool isGcc: qbs.toolchain.contains("gcc")
+ configure: { console.info("is gcc: " + isGcc); }
+ }
}
DynamicLibrary {
diff --git a/tests/auto/blackbox/testdata/linker-module-definition/linker-module-definition.qbs b/tests/auto/blackbox/testdata/linker-module-definition/linker-module-definition.qbs
new file mode 100644
index 000000000..cae80e651
--- /dev/null
+++ b/tests/auto/blackbox/testdata/linker-module-definition/linker-module-definition.qbs
@@ -0,0 +1,20 @@
+import qbs.Host
+
+Project {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
+ DynamicLibrary {
+ name: "testlib"
+ Depends { name: "cpp"}
+ files: ["testlib.cpp", "testlib.def"]
+ }
+ CppApplication {
+ name: "testapp"
+ Depends { name: "testlib"}
+ files: ["testapp.cpp"]
+ }
+}
diff --git a/tests/auto/blackbox/testdata/linker-module-definition/testapp.cpp b/tests/auto/blackbox/testdata/linker-module-definition/testapp.cpp
new file mode 100644
index 000000000..7cb5ee901
--- /dev/null
+++ b/tests/auto/blackbox/testdata/linker-module-definition/testapp.cpp
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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.
+**
+****************************************************************************/
+
+extern void foo();
+extern void bar();
+
+int main()
+{
+ foo();
+ bar();
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/linker-module-definition/testlib.cpp b/tests/auto/blackbox/testdata/linker-module-definition/testlib.cpp
new file mode 100644
index 000000000..4af8dd9bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/linker-module-definition/testlib.cpp
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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.
+**
+****************************************************************************/
+
+#include <cstdio>
+
+void foo()
+{
+ std::printf("foo\n");
+}
+
+void bar()
+{
+ std::printf("bar\n");
+}
diff --git a/tests/auto/blackbox/testdata/linker-module-definition/testlib.def b/tests/auto/blackbox/testdata/linker-module-definition/testlib.def
new file mode 100644
index 000000000..36967ddd5
--- /dev/null
+++ b/tests/auto/blackbox/testdata/linker-module-definition/testlib.def
@@ -0,0 +1,3 @@
+EXPORTS
+foo
+bar
diff --git a/tests/auto/blackbox/testdata/linker-variant/linker-variant.qbs b/tests/auto/blackbox/testdata/linker-variant/linker-variant.qbs
index 57bd4ccba..9256bf767 100644
--- a/tests/auto/blackbox/testdata/linker-variant/linker-variant.qbs
+++ b/tests/auto/blackbox/testdata/linker-variant/linker-variant.qbs
@@ -3,7 +3,7 @@ CppApplication {
property string linkerVariant
Probe {
id: gccProbe
- property bool isGcc: qbs.toolchain.contains("gcc")
+ property bool isGcc: qbs.toolchain.includes("gcc")
configure: {
console.info("is GCC: " + isGcc);
if (isGcc)
diff --git a/tests/auto/blackbox/testdata/linkerMode/darwin.s b/tests/auto/blackbox/testdata/linkerMode/darwin.s
new file mode 100644
index 000000000..fb165114b
--- /dev/null
+++ b/tests/auto/blackbox/testdata/linkerMode/darwin.s
@@ -0,0 +1,6 @@
+.globl _main
+.globl main
+
+_main:
+main:
+ ret
diff --git a/tests/auto/blackbox/testdata/linkerMode/linkerMode.qbs b/tests/auto/blackbox/testdata/linkerMode/linkerMode.qbs
index 1be50c0aa..176730ce0 100644
--- a/tests/auto/blackbox/testdata/linkerMode/linkerMode.qbs
+++ b/tests/auto/blackbox/testdata/linkerMode/linkerMode.qbs
@@ -2,7 +2,7 @@ Project {
CppApplication {
consoleApplication: true
name: "LinkedProduct-Assembly"
- files: ["main.s"]
+ files: qbs.targetOS.includes("darwin") ? "darwin.s" : "main.s"
cpp.linkerPath: cpp.compilerPathByLanguage["c"]
@@ -24,7 +24,7 @@ Project {
}
CppApplication {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
consoleApplication: true
name: "LinkedProduct-Objective-C"
@@ -50,7 +50,7 @@ Project {
}
CppApplication {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
consoleApplication: true
name: "LinkedProduct-Objective-C++"
diff --git a/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs b/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs
index 0b4de0ab9..6d068b6a2 100644
--- a/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs
+++ b/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs
@@ -55,6 +55,13 @@ DynamicLibrary {
}
}
+ Probe {
+ id: checker
+ property bool isGcc: qbs.toolchain.contains("gcc")
+ property bool isLinux: qbs.targetOS.contains("linux")
+ configure: { console.info("is Linux gcc: " + (isGcc && isLinux)) }
+ }
+
qbs.installPrefix: ""
install: true
installDir: ""
diff --git a/tests/auto/blackbox/testdata/list-property-order/modules/lower/lower.qbs b/tests/auto/blackbox/testdata/list-property-order/modules/lower/lower.qbs
index df9181641..c47a40aea 100644
--- a/tests/auto/blackbox/testdata/list-property-order/modules/lower/lower.qbs
+++ b/tests/auto/blackbox/testdata/list-property-order/modules/lower/lower.qbs
@@ -1,5 +1,5 @@
Module {
- property stringList listProp
+ property stringList listProp: [ "lower" ]
Rule {
inputs: ["intype"]
diff --git a/tests/auto/blackbox/testdata/list-property-order/product.qbs b/tests/auto/blackbox/testdata/list-property-order/product.qbs
index e92494693..bec122214 100644
--- a/tests/auto/blackbox/testdata/list-property-order/product.qbs
+++ b/tests/auto/blackbox/testdata/list-property-order/product.qbs
@@ -4,6 +4,7 @@ Product {
Depends { name: "higher1" }
Depends { name: "higher2" }
Depends { name: "higher3" }
+ lower.listProp: ["product"]
Group {
files: ["dummy.txt"]
fileTags: ["intype"]
diff --git a/tests/auto/blackbox/testdata/loadablemodule/loadablemodule.qbs b/tests/auto/blackbox/testdata/loadablemodule/loadablemodule.qbs
index ec5b0b358..8023eed36 100644
--- a/tests/auto/blackbox/testdata/loadablemodule/loadablemodule.qbs
+++ b/tests/auto/blackbox/testdata/loadablemodule/loadablemodule.qbs
@@ -1,8 +1,10 @@
+import qbs.Host
+
Project {
LoadableModule {
Depends { name: "cpp" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
name: "CoolPlugIn"
@@ -15,6 +17,12 @@ Project {
}
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
Depends { name: "cpp" }
Depends { name: "CoolPlugIn"; cpp.link: false }
consoleApplication: true
@@ -22,10 +30,10 @@ Project {
files: ["main.cpp"]
cpp.cxxLanguageVersion: "c++11"
- cpp.dynamicLibraries: [qbs.targetOS.contains("windows") ? "kernel32" : "dl"]
+ cpp.dynamicLibraries: [qbs.targetOS.includes("windows") ? "kernel32" : "dl"]
Properties {
- condition: qbs.targetOS.contains("unix") && !qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("unix") && !qbs.targetOS.includes("darwin")
cpp.rpaths: [cpp.rpathOrigin]
}
diff --git a/tests/auto/blackbox/testdata/localDeployment/localDeployment.qbs b/tests/auto/blackbox/testdata/localDeployment/localDeployment.qbs
index 650f07104..b3fa86d32 100644
--- a/tests/auto/blackbox/testdata/localDeployment/localDeployment.qbs
+++ b/tests/auto/blackbox/testdata/localDeployment/localDeployment.qbs
@@ -1,5 +1,13 @@
+import qbs.Host
+
Project {
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
type: ["application"]
consoleApplication: true
name: "HelloWorld"
diff --git a/tests/auto/blackbox/testdata/lsp/lsp.qbs b/tests/auto/blackbox/testdata/lsp/lsp.qbs
new file mode 100644
index 000000000..24479e0ec
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lsp/lsp.qbs
@@ -0,0 +1,11 @@
+Project {
+ Product {
+ name: "dep"
+ Depends { name: "m" }
+ Depends { name: "Prefix"; submodules: ["m1", "m2", "m3"] }
+
+ }
+ Product {
+ Depends { name: "dep" }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/lsp/modules/Prefix/m1/m1.qbs b/tests/auto/blackbox/testdata/lsp/modules/Prefix/m1/m1.qbs
new file mode 100644
index 000000000..09bac2dc2
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lsp/modules/Prefix/m1/m1.qbs
@@ -0,0 +1,5 @@
+Module {
+ property bool p1
+ property string p2
+ property bool x
+}
diff --git a/tests/auto/language/testdata/erroneous/modules/prefix1/prefix1.qbs b/tests/auto/blackbox/testdata/lsp/modules/Prefix/m2/m2.qbs
index 84957060c..84957060c 100644
--- a/tests/auto/language/testdata/erroneous/modules/prefix1/prefix1.qbs
+++ b/tests/auto/blackbox/testdata/lsp/modules/Prefix/m2/m2.qbs
diff --git a/tests/auto/blackbox/testdata/lsp/modules/Prefix/m3/m3.qbs b/tests/auto/blackbox/testdata/lsp/modules/Prefix/m3/m3.qbs
new file mode 100644
index 000000000..84957060c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lsp/modules/Prefix/m3/m3.qbs
@@ -0,0 +1,2 @@
+Module {
+}
diff --git a/tests/auto/blackbox/testdata/lsp/modules/m/m.qbs b/tests/auto/blackbox/testdata/lsp/modules/m/m.qbs
new file mode 100644
index 000000000..84957060c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lsp/modules/m/m.qbs
@@ -0,0 +1,2 @@
+Module {
+}
diff --git a/tests/auto/blackbox/testdata/makefile-generator/app.qbs b/tests/auto/blackbox/testdata/makefile-generator/app.qbs
index dfd67276e..fd3fbb91b 100644
--- a/tests/auto/blackbox/testdata/makefile-generator/app.qbs
+++ b/tests/auto/blackbox/testdata/makefile-generator/app.qbs
@@ -1,11 +1,19 @@
+import qbs.Host
+
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "the app"
consoleApplication: true
cpp.cxxLanguageVersion: "c++11"
cpp.separateDebugInformation: false
Properties {
- condition: qbs.targetOS.contains("macos")
+ condition: qbs.targetOS.includes("macos")
bundle.embedInfoPlist: false
cpp.minimumMacosVersion: "10.7"
}
diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs b/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs
index 320494d00..9f41570f8 100644
--- a/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs
+++ b/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs
@@ -4,10 +4,13 @@ CppApplication {
Probe {
id: osProbe
- property stringList toolchain: qbs.toolchain
+ property string toolchainType: qbs.toolchainType
+ property string compilerVersion: cpp.compilerVersion
configure: {
- if (toolchain.contains("msvc"))
- console.info("is msvc");
+ console.info("is msvc: " + (toolchainType === "msvc" || toolchainType === "clang-cl"));
+ var isOld = (toolchainType === "msvc" && compilerVersion < "19.29.30138")
+ || (toolchainType === "clang-cl" && compilerVersion < "13");
+ console.info("is old msvc: " + isOld);
found = true;
}
}
diff --git a/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newestmodule/newestmodule.qbs b/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newestmodule/newestmodule.qbs
index f99932b10..305cb29f1 100644
--- a/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newestmodule/newestmodule.qbs
+++ b/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newestmodule/newestmodule.qbs
@@ -1,4 +1,4 @@
Module {
Depends { name: "cpp" }
- cpp.cxxLanguageVersion: "c++17"
+ cpp.cxxLanguageVersion: "c++23"
}
diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/fakewindows.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/fakewindows.qbs
index 1a56e0b7e..da836e609 100644
--- a/tests/auto/blackbox/testdata/minimumSystemVersion/fakewindows.qbs
+++ b/tests/auto/blackbox/testdata/minimumSystemVersion/fakewindows.qbs
@@ -4,7 +4,7 @@ import qbs.Utilities
// (but will still compile and link since we avoid passing a
// bad value to the linker)
CppApplication {
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
files: ["main.cpp"]
consoleApplication: true
cpp.minimumWindowsVersion: "5.3"
diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs
index 8440da779..26a94e132 100644
--- a/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs
+++ b/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs
@@ -1,8 +1,15 @@
// just to make sure three-digit minimum versions work on macOS
// this only affects the value of __MAC_OS_X_VERSION_MIN_REQUIRED,
// not the actual LC_VERSION_MIN_MACOSX command which is limited to two
+import qbs.Host
+
CppApplication {
- condition: qbs.targetOS.contains("macos")
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && qbs.targetOS.includes("macos");
+ }
files: ["main.mm"]
consoleApplication: true
cpp.frameworks: "Foundation"
diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs
index f6ecab418..b2b67642a 100644
--- a/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs
+++ b/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs
@@ -3,22 +3,29 @@ import qbs.Utilities
// a specific version of the operating systems is specified
// when the application is run its output should confirm
// that the given values took effect
+import qbs.Host
+
CppApplication {
- condition: qbs.targetOS.contains("windows") || qbs.targetOS.contains("macos")
- files: [qbs.targetOS.contains("darwin") ? "main.mm" : "main.cpp"]
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && qbs.targetOS.includes("windows") || qbs.targetOS.includes("macos");
+ }
+ files: [qbs.targetOS.includes("darwin") ? "main.mm" : "main.cpp"]
consoleApplication: true
Properties {
- condition: qbs.targetOS.contains("windows")
- cpp.minimumWindowsVersion: "6.0"
+ condition: qbs.targetOS.includes("windows")
+ cpp.minimumWindowsVersion: "6.2"
cpp.defines: [
- "QBS_WINVER=0x600",
+ "QBS_WINVER=0x602",
"TOOLCHAIN_INSTALL_PATH=" + Utilities.cStringQuote(cpp.toolchainInstallPath)
]
}
Properties {
- condition: qbs.targetOS.contains("macos")
+ condition: qbs.targetOS.includes("macos")
cpp.frameworks: "Foundation"
cpp.minimumMacosVersion: "10.7"
}
diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified-forced.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified-forced.qbs
index a5ea620fd..adb61a6d8 100644
--- a/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified-forced.qbs
+++ b/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified-forced.qbs
@@ -2,8 +2,16 @@ import qbs.Utilities
// no minimum versions are specified, and explicitly set to undefined in
// case the profile has set it
+import qbs.Host
+
CppApplication {
- files: [qbs.targetOS.contains("darwin") ? "main.mm" : "main.cpp"]
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
+ files: [qbs.targetOS.includes("darwin") ? "main.mm" : "main.cpp"]
consoleApplication: true
cpp.minimumWindowsVersion: undefined
cpp.minimumMacosVersion: undefined
@@ -11,12 +19,12 @@ CppApplication {
cpp.minimumAndroidVersion: undefined
Properties {
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
cpp.defines: ["TOOLCHAIN_INSTALL_PATH=" + Utilities.cStringQuote(cpp.toolchainInstallPath)]
}
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
cpp.frameworks: "Foundation"
}
}
diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified.qbs
index 0eeb2d547..3c6559c39 100644
--- a/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified.qbs
+++ b/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified.qbs
@@ -1,17 +1,25 @@
import qbs.Utilities
// no minimum versions are specified so the profile defaults will be used
+import qbs.Host
+
CppApplication {
- files: [qbs.targetOS.contains("darwin") ? "main.mm" : "main.cpp"]
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
+ files: [qbs.targetOS.includes("darwin") ? "main.mm" : "main.cpp"]
consoleApplication: true
Properties {
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
cpp.defines: ["TOOLCHAIN_INSTALL_PATH=" + Utilities.cStringQuote(cpp.toolchainInstallPath)]
}
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
cpp.frameworks: "Foundation"
}
}
diff --git a/tests/auto/blackbox/testdata/module-conditions/module-conditions.qbs b/tests/auto/blackbox/testdata/module-conditions/module-conditions.qbs
index dc3768203..207df5ded 100644
--- a/tests/auto/blackbox/testdata/module-conditions/module-conditions.qbs
+++ b/tests/auto/blackbox/testdata/module-conditions/module-conditions.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Project {
Product {
name: "p1"
diff --git a/tests/auto/blackbox/testdata/module-providers/module-providers.qbs b/tests/auto/blackbox/testdata/module-providers/module-providers.qbs
deleted file mode 100644
index d1ff79269..000000000
--- a/tests/auto/blackbox/testdata/module-providers/module-providers.qbs
+++ /dev/null
@@ -1,20 +0,0 @@
-Project {
- CppApplication {
- name: "app1"
- Depends { name: "mygenerator.module1" }
- Depends { name: "mygenerator.module2" }
- moduleProviders.mygenerator.chooseLettersFrom: "beginning"
- files: "main.cpp"
- }
- CppApplication {
- name: "app2"
- Depends { name: "mygenerator.module1" }
- Depends { name: "mygenerator.module2" }
- Profile {
- name: "myProfile"
- moduleProviders.mygenerator.chooseLettersFrom: "end"
- }
- qbs.profile: "myProfile"
- files: "main.cpp"
- }
-}
diff --git a/tests/auto/blackbox/testdata/msvc-asm-flags/include/header.inc b/tests/auto/blackbox/testdata/msvc-asm-flags/include/header.inc
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/msvc-asm-flags/include/header.inc
diff --git a/tests/auto/blackbox/testdata/msvc-asm-flags/msvc-asm-flags.asm b/tests/auto/blackbox/testdata/msvc-asm-flags/msvc-asm-flags.asm
new file mode 100644
index 000000000..eddc49131
--- /dev/null
+++ b/tests/auto/blackbox/testdata/msvc-asm-flags/msvc-asm-flags.asm
@@ -0,0 +1,8 @@
+include header.inc
+
+.code
+main proc
+ mov ecx, 16
+main endp
+
+end \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata/msvc-asm-flags/msvc-asm-flags.qbs b/tests/auto/blackbox/testdata/msvc-asm-flags/msvc-asm-flags.qbs
new file mode 100644
index 000000000..d632098c9
--- /dev/null
+++ b/tests/auto/blackbox/testdata/msvc-asm-flags/msvc-asm-flags.qbs
@@ -0,0 +1,6 @@
+StaticLibrary {
+ condition: qbs.toolchain.includes("msvc")
+ Depends { name: "cpp" }
+ files: "msvc-asm-flags.asm"
+ cpp.assemblerFlags: ["/I", "include"]
+}
diff --git a/tests/auto/blackbox/testdata/multiplexed-tool/multiplexed-tool.qbs b/tests/auto/blackbox/testdata/multiplexed-tool/multiplexed-tool.qbs
index 3994bd95f..1ec51c354 100644
--- a/tests/auto/blackbox/testdata/multiplexed-tool/multiplexed-tool.qbs
+++ b/tests/auto/blackbox/testdata/multiplexed-tool/multiplexed-tool.qbs
@@ -1,13 +1,23 @@
+import qbs.Host
+
Project {
CppApplication {
name: "tool"
consoleApplication: true
+ property bool _testPlatform: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
Profile {
name: "debugProfile"
+ baseProfile: project.profile
qbs.buildVariant: "debug"
}
Profile {
name: "releaseProfile"
+ baseProfile: project.profile
qbs.buildVariant: "release"
}
multiplexByQbsProperties: "profiles"
diff --git a/tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs b/tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs
index f8b6a7dc0..a5a6c7d4b 100644
--- a/tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs
+++ b/tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs
@@ -10,7 +10,7 @@ Module {
var cmd = new JavaScriptCommand();
cmd.sourceCode = function() { };
var prop = product.lowerlevel.prop;
- cmd.description = "lowerlevel.prop is '" + prop + "'.";
+ cmd.description = "lowerlevel.prop is '" + prop + "'";
return [cmd];
}
}
diff --git a/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs b/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs
index 346a94e21..9aad3d032 100644
--- a/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs
+++ b/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs
@@ -12,7 +12,7 @@ Project {
id: toolchainProbe
property stringList toolchain: qbs.toolchain
configure: {
- if (toolchain.contains("msvc") && !toolchain.contains("clang-cl"))
+ if (toolchain.includes("msvc") && !toolchain.includes("clang-cl"))
console.info("compiler is MSVC")
else
console.info("compiler is not MSVC")
diff --git a/tests/auto/blackbox/testdata/no-such-profile/no-such-profile.qbs b/tests/auto/blackbox/testdata/no-such-profile/no-such-profile.qbs
index 8e64ba478..1de3a4b10 100644
--- a/tests/auto/blackbox/testdata/no-such-profile/no-such-profile.qbs
+++ b/tests/auto/blackbox/testdata/no-such-profile/no-such-profile.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Product {
name: "theProduct"
property int p
diff --git a/tests/auto/blackbox/testdata/nodejs/hello.qbs b/tests/auto/blackbox/testdata/nodejs/hello.qbs
index c19e455db..849a8789f 100644
--- a/tests/auto/blackbox/testdata/nodejs/hello.qbs
+++ b/tests/auto/blackbox/testdata/nodejs/hello.qbs
@@ -1,4 +1,12 @@
+import qbs.Host
+
NodeJSApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
nodejs.applicationFile: "hello.js"
name: "hello"
}
diff --git a/tests/auto/blackbox/testdata/nsis/hello.qbs b/tests/auto/blackbox/testdata/nsis/hello.qbs
index a161a6998..f70f27e2b 100644
--- a/tests/auto/blackbox/testdata/nsis/hello.qbs
+++ b/tests/auto/blackbox/testdata/nsis/hello.qbs
@@ -1,5 +1,5 @@
NSISSetup {
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
name: "Qbs Hello"
targetName: "qbs-hello-" + qbs.architecture
files: ["hello.nsi", "hello.bat"]
diff --git a/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs b/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs
index d8185aabf..a4ce92067 100644
--- a/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs
+++ b/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs
@@ -2,7 +2,7 @@ import qbs.FileInfo
import qbs.TextFile
Project {
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
NSISSetup {
Depends { name: "app" }
diff --git a/tests/auto/blackbox/testdata/output-redirection/output-redirection.qbs b/tests/auto/blackbox/testdata/output-redirection/output-redirection.qbs
index 3ee443438..d2474cecf 100644
--- a/tests/auto/blackbox/testdata/output-redirection/output-redirection.qbs
+++ b/tests/auto/blackbox/testdata/output-redirection/output-redirection.qbs
@@ -1,4 +1,5 @@
import qbs.FileInfo
+import qbs.Host
Product {
name: "the-product"
@@ -21,7 +22,7 @@ Product {
prepare: {
var binary;
var prefixArgs;
- if (product.qbs.hostOS.contains("windows")) {
+ if (Host.os().includes("windows")) {
binary = product.qbs.windowsShellPath;
prefixArgs = ["/c", "type"];
} else {
diff --git a/tests/auto/blackbox/testdata/overrideProjectProperties/helper_lib.qbs b/tests/auto/blackbox/testdata/overrideProjectProperties/helper_lib.qbs
index b69dd0da8..c7eab99e2 100644
--- a/tests/auto/blackbox/testdata/overrideProjectProperties/helper_lib.qbs
+++ b/tests/auto/blackbox/testdata/overrideProjectProperties/helper_lib.qbs
@@ -3,7 +3,7 @@ DynamicLibrary {
files: "helperlib.cpp"
Depends { name: "cpp" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
diff --git a/tests/auto/blackbox/testdata/path-list-in-probe/main.cpp b/tests/auto/blackbox/testdata/path-list-in-probe/main.cpp
new file mode 100644
index 000000000..5bc549337
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-list-in-probe/main.cpp
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+} \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata/path-list-in-probe/path-list-in-probe.qbs b/tests/auto/blackbox/testdata/path-list-in-probe/path-list-in-probe.qbs
new file mode 100644
index 000000000..3bf36367a
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-list-in-probe/path-list-in-probe.qbs
@@ -0,0 +1,18 @@
+Project {
+ CppApplication {
+ Probe {
+ id: theProbe
+ property pathList result
+ configure: {
+ result = ["main.cpp"]
+ found = true
+ }
+ }
+ property pathList res: theProbe.found ? theProbe.result : []
+
+ Group {
+ name: "files"
+ files: res
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs b/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs
index 84c00c240..62871698e 100644
--- a/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs
@@ -28,9 +28,10 @@
**
****************************************************************************/
+import qbs.FileInfo
import qbs.Probes
-CppApplication {
+Product {
property varList inputSelectors
property varList inputNames
@@ -38,8 +39,10 @@ CppApplication {
property pathList inputSearchPaths
property var inputNameFilter
property var inputCandidateFilter
+ property stringList inputEnvironmentPaths
property stringList outputFilePaths
+ property var outputCandidatePaths
Probes.PathProbe {
id: probe
@@ -49,6 +52,8 @@ CppApplication {
nameFilter: inputNameFilter
candidateFilter: inputCandidateFilter
searchPaths: inputSearchPaths
+ platformSearchPaths: []
+ environmentPaths: inputEnvironmentPaths
}
property bool validate: {
@@ -56,21 +61,72 @@ CppApplication {
if (lhs.length !== rhs.length)
return false;
for (var i = 0; i < lhs.length; ++i) {
- if (lhs[i] !== rhs[i])
+ if ((lhs[i] instanceof Array) && (rhs[i] instanceof Array)) {
+ if (!compareArrays(lhs[i], rhs[i]))
+ return false;
+ } else if (FileInfo.resolvePath(path, lhs[i]) !== FileInfo.resolvePath(path, rhs[i])) {
return false;
+ }
}
return true;
};
- if (!probe.found)
+ if (outputCandidatePaths) {
+ var actual = probe.allResults.map(function(file) { return file.candidatePaths; });
+ if (!compareArrays(actual, outputCandidatePaths)) {
+ throw "Invalid canndidatePaths: actual = " + JSON.stringify(actual)
+ + ", expected = " + JSON.stringify(outputCandidatePaths);
+ }
+ }
+
+ if (!probe.found) {
+ if (probe.filePath) {
+ throw "Invalid filePath: actual = " + JSON.stringify(probe.filePath)
+ + ", expected = 'undefined'";
+ }
+ if (probe.fileName) {
+ throw "Invalid fileName: actual = " + JSON.stringify(probe.fileName)
+ + ", expected = 'undefined'";
+ }
+ if (probe.path) {
+ throw "Invalid path: actual = " + JSON.stringify(probe.path)
+ + ", expected = 'undefined'";
+ }
+
throw "Probe failed to find files";
+ }
if (outputFilePaths) {
var actual = probe.allResults.map(function(file) { return file.filePath; });
- if (!compareArrays(actual, outputFilePaths))
- throw "Invalid filePaths: actual = " + actual + ", expected = " + outputFilePaths;
+ if (!compareArrays(actual, outputFilePaths)) {
+ throw "Invalid filePaths: actual = " + JSON.stringify(actual)
+ + ", expected = " + JSON.stringify(outputFilePaths);
+ }
}
- }
- files: ["main.cpp"]
+ if (probe.allResults.length !== 1)
+ return;
+
+ // check that single-file interface matches the first value in allResults
+ var expectedFilePath = probe.allResults[0].filePath;
+ if (probe.filePath !== expectedFilePath) {
+ throw "Invalid filePath: actual = " + probe.filePath
+ + ", expected = " + expectedFilePath;
+ }
+ var expectedFileName = probe.allResults[0].fileName;
+ if (probe.fileName !== expectedFileName) {
+ throw "Invalid fileName: actual = " + probe.fileName
+ + ", expected = " + expectedFileName;
+ }
+ var expectedPath = probe.allResults[0].path;
+ if (FileInfo.resolvePath(path, probe.path) !== FileInfo.resolvePath(path, expectedPath)) {
+ throw "Invalid path: actual = " + probe.path
+ + ", expected = " + expectedPath;
+ }
+ var expectedCandidatePaths = probe.allResults[0].candidatePaths;
+ if (!compareArrays(probe.candidatePaths, expectedCandidatePaths)) {
+ throw "Invalid candidatePaths: actual = " + JSON.stringify(probe.candidatePaths)
+ + ", expected = " + JSON.stringify(expectedCandidatePaths);
+ }
+ }
}
diff --git a/tests/auto/blackbox/testdata/path-probe/candidate-filter.qbs b/tests/auto/blackbox/testdata/path-probe/candidate-filter.qbs
index a65256a68..5c259ae9b 100644
--- a/tests/auto/blackbox/testdata/path-probe/candidate-filter.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/candidate-filter.qbs
@@ -3,10 +3,12 @@ import qbs.FileInfo
BaseApp {
inputNames: ["tool.1", "tool.2"]
inputSearchPaths: "bin"
- outputFilePaths: ["bin/tool.2"]
inputCandidateFilter: {
+ var fi = FileInfo;
return function(f) {
- return FileInfo.fileName(f) == "tool.2";
+ return fi.fileName(f) == "tool.2";
}
}
+ outputFilePaths: ["bin/tool.2"]
+ outputCandidatePaths: [["bin/tool.1", "bin/tool.2"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/environment-paths.qbs b/tests/auto/blackbox/testdata/path-probe/environment-paths.qbs
new file mode 100644
index 000000000..fca824bfb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/environment-paths.qbs
@@ -0,0 +1,10 @@
+import qbs.FileInfo
+
+BaseApp {
+ inputNames: "tool"
+ inputSearchPaths: ["bin", "usr/bin"]
+ // env takes precedence
+ inputEnvironmentPaths: "SEARCH_PATH"
+ outputFilePaths: ["usr/bin/tool"]
+ outputCandidatePaths: [["usr/bin/tool"]]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/mult-files-common-suffixes.qbs b/tests/auto/blackbox/testdata/path-probe/mult-files-common-suffixes.qbs
new file mode 100644
index 000000000..c4d53a715
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/mult-files-common-suffixes.qbs
@@ -0,0 +1,10 @@
+BaseApp {
+ inputSelectors: [
+ {names : "tool"},
+ {names : "super-tool"},
+ ]
+ inputNameSuffixes: ".1"
+ inputSearchPaths: "bin"
+ outputFilePaths: ["bin/tool.1", "bin/super-tool.1"]
+ outputCandidatePaths: [["bin/tool.1"], ["bin/super-tool.1"]]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/mult-files-mult-suffixes.qbs b/tests/auto/blackbox/testdata/path-probe/mult-files-mult-suffixes.qbs
index b112db44d..33656d4e6 100644
--- a/tests/auto/blackbox/testdata/path-probe/mult-files-mult-suffixes.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/mult-files-mult-suffixes.qbs
@@ -1,8 +1,9 @@
BaseApp {
inputSelectors: [
- {names : "tool", nameSuffixes: [".1", ".2"]},
+ {names : "tool", nameSuffixes: [".0", ".1", ".2"]},
{names : "super-tool", nameSuffixes: [".1"]},
]
inputSearchPaths: "bin"
outputFilePaths: ["bin/tool.1", "bin/super-tool.1"]
+ outputCandidatePaths: [["bin/tool.0", "bin/tool.1"], ["bin/super-tool.1"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/mult-files-mult-variants.qbs b/tests/auto/blackbox/testdata/path-probe/mult-files-mult-variants.qbs
index 60c56e6b4..dd0b58aa2 100644
--- a/tests/auto/blackbox/testdata/path-probe/mult-files-mult-variants.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/mult-files-mult-variants.qbs
@@ -1,9 +1,10 @@
BaseApp {
inputSelectors: [
"tool",
- ["tool.1", "tool.2"],
+ ["tool.0", "tool.1", "tool.2"],
{names : ["tool.3", "tool.4"]},
]
inputSearchPaths: "bin"
outputFilePaths: ["bin/tool", "bin/tool.1", "bin/tool.3"]
+ outputCandidatePaths: [["bin/tool"], ["bin/tool.0", "bin/tool.1"], ["bin/tool.3"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/mult-files-suffixes.qbs b/tests/auto/blackbox/testdata/path-probe/mult-files-suffixes.qbs
index 5e4fc27ca..7ae78de24 100644
--- a/tests/auto/blackbox/testdata/path-probe/mult-files-suffixes.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/mult-files-suffixes.qbs
@@ -5,4 +5,5 @@ BaseApp {
]
inputSearchPaths: "bin"
outputFilePaths: ["bin/tool.2", "bin/super-tool.1"]
+ outputCandidatePaths: [["bin/tool.2"], ["bin/super-tool.1"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/mult-files.qbs b/tests/auto/blackbox/testdata/path-probe/mult-files.qbs
index 08727ac01..aa08befc8 100644
--- a/tests/auto/blackbox/testdata/path-probe/mult-files.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/mult-files.qbs
@@ -7,4 +7,5 @@ BaseApp {
]
inputSearchPaths: "bin"
outputFilePaths: ["bin/tool.1", "bin/tool.2", "bin/tool.3", "bin/tool.4"]
+ outputCandidatePaths: [["bin/tool.1"], ["bin/tool.2"], ["bin/tool.3"], ["bin/tool.4"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/name-filter.qbs b/tests/auto/blackbox/testdata/path-probe/name-filter.qbs
index 406988fed..b2840443b 100644
--- a/tests/auto/blackbox/testdata/path-probe/name-filter.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/name-filter.qbs
@@ -7,4 +7,5 @@ BaseApp {
};
}
outputFilePaths: ["bin/tool.2"]
+ outputCandidatePaths: [["bin/tool.2"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/non-existent-selector.qbs b/tests/auto/blackbox/testdata/path-probe/non-existent-selector.qbs
index aaa27042c..aabb0fe7b 100644
--- a/tests/auto/blackbox/testdata/path-probe/non-existent-selector.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/non-existent-selector.qbs
@@ -5,4 +5,5 @@ BaseApp {
"tool.2",
]
inputSearchPaths: "bin"
+ outputCandidatePaths: [["bin/tool.1"], ["bin/nonexistent"], ["bin/tool.2"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/non-existent.qbs b/tests/auto/blackbox/testdata/path-probe/non-existent.qbs
index f0c58fa6c..aad01c31b 100644
--- a/tests/auto/blackbox/testdata/path-probe/non-existent.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/non-existent.qbs
@@ -1,4 +1,5 @@
BaseApp {
inputNames: "nonexistent"
inputSearchPaths: "bin"
+ outputCandidatePaths: [["bin/nonexistent"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/single-file-mult-variants.qbs b/tests/auto/blackbox/testdata/path-probe/single-file-mult-variants.qbs
index 992a0bea4..98f5b141a 100644
--- a/tests/auto/blackbox/testdata/path-probe/single-file-mult-variants.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/single-file-mult-variants.qbs
@@ -2,4 +2,5 @@ BaseApp {
inputNames: ["tool.1", "tool.2"]
inputSearchPaths: "bin"
outputFilePaths: ["bin/tool.1"]
+ outputCandidatePaths: [["bin/tool.1"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/single-file-selector-array.qbs b/tests/auto/blackbox/testdata/path-probe/single-file-selector-array.qbs
index 697665242..292df4add 100644
--- a/tests/auto/blackbox/testdata/path-probe/single-file-selector-array.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/single-file-selector-array.qbs
@@ -2,4 +2,5 @@ BaseApp {
inputSelectors: ["tool"]
inputSearchPaths: "bin"
outputFilePaths: ["bin/tool"]
+ outputCandidatePaths: [["bin/tool"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/single-file-selector.qbs b/tests/auto/blackbox/testdata/path-probe/single-file-selector.qbs
index d57700baf..cf7cfe436 100644
--- a/tests/auto/blackbox/testdata/path-probe/single-file-selector.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/single-file-selector.qbs
@@ -2,4 +2,5 @@ BaseApp {
inputSelectors: "tool"
inputSearchPaths: "bin"
outputFilePaths: ["bin/tool"]
+ outputCandidatePaths: [["bin/tool"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/single-file-suffixes.qbs b/tests/auto/blackbox/testdata/path-probe/single-file-suffixes.qbs
index 4442e719a..3436a49c3 100644
--- a/tests/auto/blackbox/testdata/path-probe/single-file-suffixes.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/single-file-suffixes.qbs
@@ -1,6 +1,7 @@
BaseApp {
inputNames: "tool"
inputSearchPaths: "bin"
- inputNameSuffixes: [".1", ".2"]
+ inputNameSuffixes: [".0", ".1", ".2"]
outputFilePaths: ["bin/tool.1"]
+ outputCandidatePaths: [["bin/tool.0", "bin/tool.1"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/single-file.qbs b/tests/auto/blackbox/testdata/path-probe/single-file.qbs
index 3590e7664..e22d7ba0d 100644
--- a/tests/auto/blackbox/testdata/path-probe/single-file.qbs
+++ b/tests/auto/blackbox/testdata/path-probe/single-file.qbs
@@ -2,4 +2,5 @@ BaseApp {
inputNames: "tool"
inputSearchPaths: "bin"
outputFilePaths: ["bin/tool"]
+ outputCandidatePaths: [["bin/tool"]]
}
diff --git a/tests/auto/blackbox/testdata/path-probe/usr/bin/tool b/tests/auto/blackbox/testdata/path-probe/usr/bin/tool
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/usr/bin/tool
diff --git a/tests/auto/blackbox/testdata/plugin-dependency/helper1.cpp b/tests/auto/blackbox/testdata/plugin-dependency/helper1.cpp
index 72331da80..15a3e0d86 100644
--- a/tests/auto/blackbox/testdata/plugin-dependency/helper1.cpp
+++ b/tests/auto/blackbox/testdata/plugin-dependency/helper1.cpp
@@ -1,4 +1,4 @@
-#include <stdio.h>
+#include <cstdio>
#if defined(_WIN32) || defined(WIN32)
# define EXPORT __declspec(dllexport)
@@ -12,5 +12,5 @@
EXPORT void helper1_hello()
{
- puts("helper1 says hello!");
+ std::puts("helper1 says hello!");
}
diff --git a/tests/auto/blackbox/testdata/plugin-dependency/helper2.cpp b/tests/auto/blackbox/testdata/plugin-dependency/helper2.cpp
index cdcdfc942..dccd72a04 100644
--- a/tests/auto/blackbox/testdata/plugin-dependency/helper2.cpp
+++ b/tests/auto/blackbox/testdata/plugin-dependency/helper2.cpp
@@ -1,7 +1,7 @@
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT void helper2_hello()
{
- puts("Hello from helper2!");
+ std::puts("Hello from helper2!");
}
diff --git a/tests/auto/blackbox/testdata/plugin-dependency/plugin-dependency.qbs b/tests/auto/blackbox/testdata/plugin-dependency/plugin-dependency.qbs
index c619b33ef..752673b78 100644
--- a/tests/auto/blackbox/testdata/plugin-dependency/plugin-dependency.qbs
+++ b/tests/auto/blackbox/testdata/plugin-dependency/plugin-dependency.qbs
@@ -1,16 +1,18 @@
+import qbs.Host
+
Project {
CppApplication {
name: "myapp"
files: ["main.cpp"]
Depends {
name: "plugin1" // not to be linked
- cpp.link: qbs.hostOS === undefined
+ cpp.link: Host.os() === undefined
}
Depends { name: "plugin2" } // not to be linked
Depends {
name: "plugin3" // supposed to be linked
- //property bool theCondition: true
- cpp.link: /*theCondition && */product.name === "myapp" // TODO: Make this work
+ property bool theCondition: true
+ cpp.link: theCondition && product.name === "myapp"
}
Depends { name: "plugin4" } // supposed to be linked
Depends { name: "helper1" } // supposed to be linked
diff --git a/tests/auto/blackbox/testdata/plugin-dependency/plugin1.cpp b/tests/auto/blackbox/testdata/plugin-dependency/plugin1.cpp
index 2535bd85e..8cf7e3851 100644
--- a/tests/auto/blackbox/testdata/plugin-dependency/plugin1.cpp
+++ b/tests/auto/blackbox/testdata/plugin-dependency/plugin1.cpp
@@ -1,7 +1,7 @@
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT void plugin1_hello()
{
- puts("plugin1 says hello!");
+ std::puts("plugin1 says hello!");
}
diff --git a/tests/auto/blackbox/testdata/plugin-dependency/plugin2.cpp b/tests/auto/blackbox/testdata/plugin-dependency/plugin2.cpp
index fb2030d60..9efc83e2b 100644
--- a/tests/auto/blackbox/testdata/plugin-dependency/plugin2.cpp
+++ b/tests/auto/blackbox/testdata/plugin-dependency/plugin2.cpp
@@ -1,7 +1,7 @@
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT void plugin2_hello()
{
- puts("plugin2 says hello!");
+ std::puts("plugin2 says hello!");
}
diff --git a/tests/auto/blackbox/testdata/plugin-dependency/plugin3.cpp b/tests/auto/blackbox/testdata/plugin-dependency/plugin3.cpp
index 8a9f5ee76..0e08ac85a 100644
--- a/tests/auto/blackbox/testdata/plugin-dependency/plugin3.cpp
+++ b/tests/auto/blackbox/testdata/plugin-dependency/plugin3.cpp
@@ -1,7 +1,7 @@
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT void plugin3_hello()
{
- puts("plugin3 says hello!");
+ std::puts("plugin3 says hello!");
}
diff --git a/tests/auto/blackbox/testdata/plugin-dependency/plugin4.cpp b/tests/auto/blackbox/testdata/plugin-dependency/plugin4.cpp
index 4663247fa..cee2362ec 100644
--- a/tests/auto/blackbox/testdata/plugin-dependency/plugin4.cpp
+++ b/tests/auto/blackbox/testdata/plugin-dependency/plugin4.cpp
@@ -1,7 +1,7 @@
#include "../dllexport.h"
-#include <stdio.h>
+#include <cstdio>
DLL_EXPORT void plugin4_hello()
{
- puts("plugin4 says hello!");
+ std::puts("plugin4 says hello!");
}
diff --git a/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/precompiled-headers-and-redefine.qbs b/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/precompiled-headers-and-redefine.qbs
index 55b53a7af..3974b514e 100644
--- a/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/precompiled-headers-and-redefine.qbs
+++ b/tests/auto/blackbox/testdata/precompiled-headers-and-redefine/precompiled-headers-and-redefine.qbs
@@ -8,7 +8,7 @@ CppApplication {
Group {
files: ["file.cpp"]
cpp.defines: ["MYDEF=1"]
- cpp.cxxFlags: base.concat(qbs.toolchain.contains("clang-cl") ? ["-Wno-clang-cl-pch"] : [])
+ cpp.cxxFlags: base.concat(qbs.toolchain.includes("clang-cl") ? ["-Wno-clang-cl-pch"] : [])
}
cpp.treatWarningsAsErrors: true
diff --git a/tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs
index 41c6cfe50..45b8e157f 100644
--- a/tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs
+++ b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs
@@ -7,7 +7,7 @@ Module {
outputFileTags: "dep-out"
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating dep-out artifact";
+ cmd.description = "creating dep-out artifact";
cmd.sourceCode = function() {
console.info("prop: " + product.depmodule.prop);
console.info("listProp: " + product.depmodule.listProp);
diff --git a/tests/auto/blackbox/testdata/probe-in-exported-module/modules/mymodule/mymodule.qbs b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/mymodule/mymodule.qbs
index 89d544f7e..31275aa40 100644
--- a/tests/auto/blackbox/testdata/probe-in-exported-module/modules/mymodule/mymodule.qbs
+++ b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/mymodule/mymodule.qbs
@@ -13,7 +13,7 @@ Module {
outputFileTags: "out"
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating out artifact";
+ cmd.description = "creating out artifact";
cmd.sourceCode = function() {
console.info("found: " + product.mymodule.found);
};
diff --git a/tests/auto/blackbox/testdata/probeProperties/probeProperties.qbs b/tests/auto/blackbox/testdata/probeProperties/probeProperties.qbs
index 9846eacef..ce89d11f4 100644
--- a/tests/auto/blackbox/testdata/probeProperties/probeProperties.qbs
+++ b/tests/auto/blackbox/testdata/probeProperties/probeProperties.qbs
@@ -1,29 +1,40 @@
import qbs.Probes
-CppApplication {
- Probes.PathProbe {
- id: probe1
- names: ["bin/tool"]
- platformSearchPaths: [product.sourceDirectory]
- }
+Project {
- Probes.PathProbe {
- id: probe2
- names: ["tool"]
- platformSearchPaths: [product.sourceDirectory + "/bin"]
- }
+ CppApplication {
+ Probes.PathProbe {
+ id: probe1
+ names: ["bin/tool"]
+ platformSearchPaths: [product.sourceDirectory]
+ }
- targetName: {
- console.info("probe1.fileName=" + probe1.fileName);
- console.info("probe1.path=" + probe1.path);
- console.info("probe1.filePath=" + probe1.filePath);
+ Probes.PathProbe {
+ id: probe2
+ names: ["tool"]
+ platformSearchPaths: [product.sourceDirectory + "/bin"]
+ }
- console.info("probe2.fileName=" + probe2.fileName);
- console.info("probe2.path=" + probe2.path);
- console.info("probe2.filePath=" + probe2.filePath);
+ targetName: {
+ console.info("probe1.fileName=" + probe1.fileName);
+ console.info("probe1.path=" + probe1.path);
+ console.info("probe1.filePath=" + probe1.filePath);
- return name;
+ console.info("probe2.fileName=" + probe2.fileName);
+ console.info("probe2.path=" + probe2.path);
+ console.info("probe2.filePath=" + probe2.filePath);
+
+ console.info("probe3.fileName=" + probe3.fileName);
+ console.info("probe3.path=" + probe3.path);
+ console.info("probe3.filePath=" + probe3.filePath);
+ return name;
+ }
+ }
+
+ Probes.PathProbe {
+ id: probe3
+ names: ["tool"]
+ platformSearchPaths: [project.sourceDirectory + "/bin"]
}
- files: ["main.c"]
}
diff --git a/tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs b/tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs
index e5c368a88..92ece5be7 100644
--- a/tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs
+++ b/tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs
@@ -3,8 +3,7 @@ Module {
id: propProbe
property stringList prop: []
configure: {
- prop = [];
- prop.push("probe");
+ prop = ["probe"];
found = true;
}
}
diff --git a/tests/auto/blackbox/testdata/product-dependencies-by-type/product-dependencies-by-type.qbs b/tests/auto/blackbox/testdata/product-dependencies-by-type/product-dependencies-by-type.qbs
index 8fa761a2d..8e1f291f3 100644
--- a/tests/auto/blackbox/testdata/product-dependencies-by-type/product-dependencies-by-type.qbs
+++ b/tests/auto/blackbox/testdata/product-dependencies-by-type/product-dependencies-by-type.qbs
@@ -91,7 +91,7 @@ Project {
name: "lib-product"
files: "main.cpp"
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -116,7 +116,7 @@ Project {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Collecting apps";
+ cmd.description = "collecting apps";
cmd.sourceCode = function() {
var file = new TextFile(output.filePath, TextFile.WriteOnly);
for (var i = 0; i < inputs["application"].length; ++i)
diff --git a/tests/auto/blackbox/testdata/product-in-exported-module/modules/m/m.qbs b/tests/auto/blackbox/testdata/product-in-exported-module/modules/m/m.qbs
new file mode 100644
index 000000000..0e79d0abe
--- /dev/null
+++ b/tests/auto/blackbox/testdata/product-in-exported-module/modules/m/m.qbs
@@ -0,0 +1,3 @@
+Module {
+ Depends { name: "dummy"; condition: { console.info("product: " + product.name); return false; } }
+}
diff --git a/tests/auto/blackbox/testdata/product-in-exported-module/product-in-exported-module.qbs b/tests/auto/blackbox/testdata/product-in-exported-module/product-in-exported-module.qbs
new file mode 100644
index 000000000..3ead0ca6c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/product-in-exported-module/product-in-exported-module.qbs
@@ -0,0 +1,10 @@
+Project {
+ Product {
+ name: "importing"
+ Depends { name: "dep" }
+ }
+ Product {
+ name: "dep"
+ Export { Depends { name: "m" } }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/productproperties/header.qbs b/tests/auto/blackbox/testdata/productproperties/header.qbs
index 42f9c88d9..13a62035f 100644
--- a/tests/auto/blackbox/testdata/productproperties/header.qbs
+++ b/tests/auto/blackbox/testdata/productproperties/header.qbs
@@ -29,6 +29,6 @@ Product {
Export {
Depends { name: "cpp" }
- cpp.includePaths: product.buildDirectory
+ cpp.includePaths: exportingProduct.buildDirectory
}
}
diff --git a/tests/auto/blackbox/testdata/proper quoting/main.cpp b/tests/auto/blackbox/testdata/proper quoting/main.cpp
index 22cafeaa9..6e9be6df1 100644
--- a/tests/auto/blackbox/testdata/proper quoting/main.cpp
+++ b/tests/auto/blackbox/testdata/proper quoting/main.cpp
@@ -26,16 +26,16 @@
**
****************************************************************************/
-#include <stdio.h>
+#include <cstdio>
int bla();
int main()
{
- printf(DEFINE"\n");
- printf(DEFINEWITHSPACE"\n");
- printf(DEFINEWITHTAB"\n");
- printf(DEFINEWITHBACKSLASH"\n");
+ std::printf(DEFINE"\n");
+ std::printf(DEFINEWITHSPACE"\n");
+ std::printf(DEFINEWITHTAB"\n");
+ std::printf(DEFINEWITHBACKSLASH"\n");
return bla();
}
diff --git a/tests/auto/blackbox/testdata/proper quoting/my static lib.cpp b/tests/auto/blackbox/testdata/proper quoting/my static lib.cpp
index e7490e807..7c07fd4c9 100644
--- a/tests/auto/blackbox/testdata/proper quoting/my static lib.cpp
+++ b/tests/auto/blackbox/testdata/proper quoting/my static lib.cpp
@@ -26,12 +26,13 @@
**
****************************************************************************/
-#include <stdio.h>
#include <some helper.h>
+#include <cstdio>
+
int bla()
{
int n = getSomeNumber();
- printf("Hello World! The magic number is %d.", n);
+ std::printf("Hello World! The magic number is %d.", n);
return n;
}
diff --git a/tests/auto/blackbox/testdata/proper quoting/proper quoting.qbs b/tests/auto/blackbox/testdata/proper quoting/proper quoting.qbs
index 184ee13e3..1587940a2 100644
--- a/tests/auto/blackbox/testdata/proper quoting/proper quoting.qbs
+++ b/tests/auto/blackbox/testdata/proper quoting/proper quoting.qbs
@@ -1,7 +1,13 @@
-import qbs 1.0
+import qbs.Host
Project {
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
type: "application"
consoleApplication: true
name: "Hello World"
@@ -34,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/property-assignment-on-non-present-module/property-assignment-on-non-present-module.qbs b/tests/auto/blackbox/testdata/property-assignment-on-non-present-module/property-assignment-on-non-present-module.qbs
deleted file mode 100644
index a01d6c561..000000000
--- a/tests/auto/blackbox/testdata/property-assignment-on-non-present-module/property-assignment-on-non-present-module.qbs
+++ /dev/null
@@ -1,4 +0,0 @@
-Product {
- Depends { name: "nein"; required: false }
- nein.doch: "ohhh!"
-}
diff --git a/tests/auto/blackbox/testdata/property-evaluation-context/modules/base/base.qbs b/tests/auto/blackbox/testdata/property-evaluation-context/modules/base/base.qbs
new file mode 100644
index 000000000..a97538751
--- /dev/null
+++ b/tests/auto/blackbox/testdata/property-evaluation-context/modules/base/base.qbs
@@ -0,0 +1,4 @@
+Module {
+ property string productInBase: product.name
+ property string productInTop: ""
+}
diff --git a/tests/auto/blackbox/testdata/property-evaluation-context/modules/top/top.qbs b/tests/auto/blackbox/testdata/property-evaluation-context/modules/top/top.qbs
new file mode 100644
index 000000000..fa073ff78
--- /dev/null
+++ b/tests/auto/blackbox/testdata/property-evaluation-context/modules/top/top.qbs
@@ -0,0 +1,6 @@
+Module {
+ Depends { name: "base" }
+ base.productInTop: product.name
+ property string productInTop: product.name
+ property string productInExport: ""
+}
diff --git a/tests/auto/blackbox/testdata/property-evaluation-context/property-evaluation-context.qbs b/tests/auto/blackbox/testdata/property-evaluation-context/property-evaluation-context.qbs
new file mode 100644
index 000000000..ede32cf74
--- /dev/null
+++ b/tests/auto/blackbox/testdata/property-evaluation-context/property-evaluation-context.qbs
@@ -0,0 +1,34 @@
+Project {
+ qbsSearchPaths: [ path ]
+ Product {
+ name: "mylib"
+ Export {
+ Depends { name: "top" }
+ top.productInExport: exportingProduct.name
+ }
+ }
+
+ Product {
+ type: "rule-output"
+ name: "myapp"
+ Depends { name: "mylib" }
+
+ Rule {
+ alwaysRun: true
+ multiplex: true
+ requiresInputs: false
+ outputFileTags: "rule-output"
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.silent = true;
+ cmd.sourceCode = function() {
+ console.info("base.productInBase evaluated in: " + product.base.productInBase);
+ console.info("base.productInTop evaluated in: " + product.base.productInTop);
+ console.info("top.productInExport evaluated in: " + product.top.productInExport);
+ console.info("top.productInTop evaluated in: " + product.top.productInTop);
+ }
+ return [cmd];
+ }
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/propertyChanges/modules/TestModule/module.qbs b/tests/auto/blackbox/testdata/propertyChanges/modules/TestModule/module.qbs
index b1e4a1fdc..590736f6a 100644
--- a/tests/auto/blackbox/testdata/propertyChanges/modules/TestModule/module.qbs
+++ b/tests/auto/blackbox/testdata/propertyChanges/modules/TestModule/module.qbs
@@ -18,7 +18,7 @@ Module {
prepare: {
var cmd = new JavaScriptCommand();
cmd.highlight = "codegen";
- cmd.description = "Making output from input";
+ cmd.description = "making output from input";
cmd.sourceCode = function() {
// console.info('Change in source code');
console.info(input.TestModule.testProperty);
diff --git a/tests/auto/blackbox/testdata/propertyChanges/propertyChanges.qbs b/tests/auto/blackbox/testdata/propertyChanges/propertyChanges.qbs
index f13b1986e..29365a887 100644
--- a/tests/auto/blackbox/testdata/propertyChanges/propertyChanges.qbs
+++ b/tests/auto/blackbox/testdata/propertyChanges/propertyChanges.qbs
@@ -27,7 +27,7 @@ Project {
name: "library"
files: "lib.cpp"
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
}
@@ -80,7 +80,7 @@ Project {
prepare: {
var cmd = new JavaScriptCommand();
cmd.highlight = "codegen";
- cmd.description = "Making output from other output";
+ cmd.description = "making output from other output";
cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); }
return cmd;
}
diff --git a/tests/auto/blackbox/testdata/protobuf-library-install/hello.proto b/tests/auto/blackbox/testdata/protobuf-library-install/hello.proto
new file mode 100644
index 000000000..946108ddc
--- /dev/null
+++ b/tests/auto/blackbox/testdata/protobuf-library-install/hello.proto
@@ -0,0 +1,8 @@
+syntax = "proto3";
+package protobuf.library;
+
+import "hello/world.proto";
+
+message Hello {
+ hello.World world = 1;
+};
diff --git a/tests/auto/blackbox/testdata/protobuf-library-install/hello/world.proto b/tests/auto/blackbox/testdata/protobuf-library-install/hello/world.proto
new file mode 100644
index 000000000..f718621b6
--- /dev/null
+++ b/tests/auto/blackbox/testdata/protobuf-library-install/hello/world.proto
@@ -0,0 +1,6 @@
+syntax = "proto3";
+package protobuf.library.hello;
+
+message World {
+ int32 value = 1;
+};
diff --git a/tests/auto/blackbox/testdata/protobuf-library-install/protobuf-library.qbs b/tests/auto/blackbox/testdata/protobuf-library-install/protobuf-library.qbs
new file mode 100644
index 000000000..501675c15
--- /dev/null
+++ b/tests/auto/blackbox/testdata/protobuf-library-install/protobuf-library.qbs
@@ -0,0 +1,34 @@
+import qbs.Host
+
+StaticLibrary {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasProtobuf;
+ }
+
+ Depends { name: "cpp" }
+ cpp.cxxLanguageVersion: "c++11"
+ cpp.minimumMacosVersion: "10.8"
+
+ protobuf.cpp.importPaths: product.sourceDirectory
+
+ Depends { name: "protobuf.cpp"; required: false }
+ property bool hasProtobuf: {
+ console.info("has protobuf: " + protobuf.cpp.present);
+ return protobuf.cpp.present;
+ }
+
+ Group {
+ fileTagsFilter: "protobuf.hpp"
+ qbs.installDir: "include"
+ qbs.installSourceBase: protobuf.cpp.outputDir
+ qbs.install: true
+ }
+
+ files: [
+ "hello.proto",
+ "hello/world.proto",
+ ]
+}
diff --git a/tests/auto/blackbox/testdata/protobuf/addressbook_cpp.qbs b/tests/auto/blackbox/testdata/protobuf/addressbook_cpp.qbs
index a5a4caf75..959552ea5 100644
--- a/tests/auto/blackbox/testdata/protobuf/addressbook_cpp.qbs
+++ b/tests/auto/blackbox/testdata/protobuf/addressbook_cpp.qbs
@@ -1,16 +1,22 @@
-import qbs
+import qbs.Host
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasProtobuf;
+ }
name: "addressbook_cpp"
consoleApplication: true
- condition: hasProtobuf
Depends { name: "cpp" }
- cpp.cxxLanguageVersion: "c++11"
+ cpp.minimumMacosVersion: "10.15"
Depends { name: "protobuf.cpp"; required: false }
property bool hasProtobuf: {
console.info("has protobuf: " + protobuf.cpp.present);
+ console.info("has modules: " + protobuflib.present);
return protobuf.cpp.present;
}
diff --git a/tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.options b/tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.options
new file mode 100644
index 000000000..60726de93
--- /dev/null
+++ b/tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.options
@@ -0,0 +1,3 @@
+tutorial.Person.name max_size:128
+tutorial.Person.email max_size:256
+tutorial.Person.phones max_count:16
diff --git a/tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.proto b/tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.proto
new file mode 100644
index 000000000..5db0bedbf
--- /dev/null
+++ b/tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.proto
@@ -0,0 +1,38 @@
+// See README.txt for information and build instructions.
+//
+// Note: START and END tags are used in comments to define sections used in
+// tutorials. They are not part of the syntax for Protocol Buffers.
+//
+// To get an in-depth walkthrough of this file and the related examples, see:
+// https://developers.google.com/protocol-buffers/docs/tutorials
+
+// [START declaration]
+syntax = "proto3";
+package tutorial;
+// [END declaration]
+
+// [START messages]
+message Person {
+ string name = 1;
+ int32 id = 2; // Unique ID number for this person.
+ string email = 3;
+
+ enum PhoneType {
+ MOBILE = 0;
+ HOME = 1;
+ WORK = 2;
+ }
+
+ message PhoneNumber {
+ string number = 1;
+ PhoneType type = 2;
+ }
+
+ repeated PhoneNumber phones = 4;
+}
+
+// Our address book file is just one of these.
+message AddressBook {
+ repeated Person people = 1;
+}
+// [END messages]
diff --git a/tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.qbs b/tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.qbs
new file mode 100644
index 000000000..3dfc911e1
--- /dev/null
+++ b/tests/auto/blackbox/testdata/protobuf/addressbook_nanopb.qbs
@@ -0,0 +1,29 @@
+import qbs.Host
+
+CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasProtobuf;
+ }
+ name: "addressbook_nanopb"
+ consoleApplication: true
+
+ Depends { name: "cpp" }
+ cpp.minimumMacosVersion: "10.8"
+
+ Depends { name: "protobuf.nanopb"; required: false }
+ property bool hasProtobuf: {
+ console.info("has protobuf: " + protobuf.nanopb.present);
+ console.info("has modules: false");
+ return protobuf.nanopb.present;
+ }
+ protobuf.nanopb.importPaths: product.sourceDirectory
+
+ files: [
+ "addressbook_nanopb.proto",
+ "addressbook_nanopb.options",
+ "main_nanopb.cpp",
+ ]
+}
diff --git a/tests/auto/blackbox/testdata/protobuf/addressbook_objc.qbs b/tests/auto/blackbox/testdata/protobuf/addressbook_objc.qbs
index be68abfee..7f0b999aa 100644
--- a/tests/auto/blackbox/testdata/protobuf/addressbook_objc.qbs
+++ b/tests/auto/blackbox/testdata/protobuf/addressbook_objc.qbs
@@ -1,14 +1,20 @@
-import qbs
+import qbs.Host
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasProtobuf;
+ }
name: "addressbook_objc"
consoleApplication: true
- condition: hasProtobuf
Depends { name: "cpp" }
Depends { name: "protobuf.objc"; required: false }
property bool hasProtobuf: {
console.info("has protobuf: " + protobuf.objc.present);
+ console.info("has modules: false");
return protobuf.objc.present;
}
diff --git a/tests/auto/blackbox/testdata/protobuf/conanfile.txt b/tests/auto/blackbox/testdata/protobuf/conanfile.txt
new file mode 100644
index 000000000..e7d849b1a
--- /dev/null
+++ b/tests/auto/blackbox/testdata/protobuf/conanfile.txt
@@ -0,0 +1,6 @@
+[requires]
+protobuf/3.21.12
+[tool_requires]
+protobuf/3.21.12
+[generators]
+QbsDeps
diff --git a/tests/auto/blackbox/testdata/protobuf/create-proto-library.qbs b/tests/auto/blackbox/testdata/protobuf/create-proto-library.qbs
new file mode 100644
index 000000000..005752fd8
--- /dev/null
+++ b/tests/auto/blackbox/testdata/protobuf/create-proto-library.qbs
@@ -0,0 +1,53 @@
+import qbs.Host
+
+Project {
+ StaticLibrary {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasProtobuf;
+ }
+ name: "proto_lib"
+
+ Depends { name: "cpp" }
+ cpp.minimumMacosVersion: "10.8"
+
+ protobuf.cpp.importPaths: product.sourceDirectory
+
+ Depends { name: "protobuf.cpp"; required: false }
+ property bool hasProtobuf: {
+ console.info("has protobuf: " + protobuf.cpp.present);
+ console.info("has modules: " + protobuflib.present);
+ return protobuf.cpp.present;
+ }
+
+ files: [
+ "import.proto",
+ "subdir/myenum.proto",
+ ]
+
+ Export {
+ Depends { name: "cpp" }
+ Depends { name: "protobuf.cpp"; required: false }
+ cpp.cxxLanguageVersion: "c++11"
+ cpp.minimumMacosVersion: "10.8"
+ cpp.includePaths: exportingProduct.protobuf.cpp.outputDir
+ }
+ }
+
+ CppApplication {
+ condition: proto_lib.present
+ name: "consumes_proto_lib"
+ consoleApplication: true
+
+ files: [
+ "import-main.cpp",
+ ]
+
+ Depends {
+ name: "proto_lib"
+ required: false
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/protobuf/import-main.cpp b/tests/auto/blackbox/testdata/protobuf/import-main.cpp
index 6d90cdf16..65048dd83 100644
--- a/tests/auto/blackbox/testdata/protobuf/import-main.cpp
+++ b/tests/auto/blackbox/testdata/protobuf/import-main.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2018 Ivan Komissarov
-** Contact: abbapoh@gmail.com
+** Copyright (C) 2018 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
diff --git a/tests/auto/blackbox/testdata/protobuf/import.qbs b/tests/auto/blackbox/testdata/protobuf/import.qbs
index 4c4de063f..56d489de8 100644
--- a/tests/auto/blackbox/testdata/protobuf/import.qbs
+++ b/tests/auto/blackbox/testdata/protobuf/import.qbs
@@ -1,17 +1,23 @@
-import qbs
+import qbs.Host
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasProtobuf;
+ }
name: "app"
consoleApplication: true
- condition: hasProtobuf
protobuf.cpp.importPaths: [sourceDirectory]
- cpp.cxxLanguageVersion: "c++11"
+ cpp.minimumMacosVersion: "10.8"
Depends { name: "protobuf.cpp"; required: false }
property bool hasProtobuf: {
console.info("has protobuf: " + protobuf.cpp.present);
+ console.info("has modules: " + protobuflib.present);
return protobuf.cpp.present;
}
diff --git a/tests/auto/blackbox/testdata/protobuf/main.cpp b/tests/auto/blackbox/testdata/protobuf/main.cpp
index c93c46717..d4b1c431b 100644
--- a/tests/auto/blackbox/testdata/protobuf/main.cpp
+++ b/tests/auto/blackbox/testdata/protobuf/main.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2018 Ivan Komissarov
-** Contact: abbapoh@gmail.com
+** Copyright (C) 2018 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
diff --git a/tests/auto/blackbox/testdata/protobuf/main.m b/tests/auto/blackbox/testdata/protobuf/main.m
index e9d7ce66a..414d1aa2f 100644
--- a/tests/auto/blackbox/testdata/protobuf/main.m
+++ b/tests/auto/blackbox/testdata/protobuf/main.m
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2018 Ivan Komissarov
-** Contact: abbapoh@gmail.com
+** Copyright (C) 2018 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
diff --git a/tests/auto/blackbox/testdata/protobuf/main_nanopb.cpp b/tests/auto/blackbox/testdata/protobuf/main_nanopb.cpp
new file mode 100644
index 000000000..76fa03fca
--- /dev/null
+++ b/tests/auto/blackbox/testdata/protobuf/main_nanopb.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Kai Dohmen (psykai1993@gmail.com)
+** Contact: https://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.
+**
+****************************************************************************/
+
+#include <array>
+#include <cassert>
+#include <pb_encode.h>
+
+#include "addressbook_nanopb.pb.h"
+
+static_assert(std::is_array<decltype(std::declval<tutorial_Person>().name)>::value, "");
+static_assert(std::is_array<decltype(std::declval<tutorial_Person>().email)>::value, "");
+static_assert(std::is_array<decltype(std::declval<tutorial_Person>().phones)>::value, "");
+
+bool writeString(pb_ostream_t *stream, const pb_field_t *field, void *const *)
+{
+ constexpr auto str = "0123456789";
+ if (!pb_encode_tag_for_field(stream, field))
+ return false;
+ return pb_encode_string(stream, reinterpret_cast<const uint8_t*>(str), strlen(str));
+}
+
+int main()
+{
+ std::array<uint8_t, 32> buffer = {};
+
+ tutorial_Person_PhoneNumber phoneNumber;
+ phoneNumber.number.funcs.encode = writeString;
+ phoneNumber.type = tutorial_Person_PhoneType_WORK;
+
+ auto ostream = pb_ostream_from_buffer(buffer.data(), buffer.size());
+ assert(pb_encode(&ostream, tutorial_Person_PhoneNumber_fields, &phoneNumber));
+
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/protobuf/needs-import-dir-main.cpp b/tests/auto/blackbox/testdata/protobuf/needs-import-dir-main.cpp
index d6faf9e84..5d62a0d06 100644
--- a/tests/auto/blackbox/testdata/protobuf/needs-import-dir-main.cpp
+++ b/tests/auto/blackbox/testdata/protobuf/needs-import-dir-main.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2018 Ivan Komissarov
-** Contact: abbapoh@gmail.com
+** Copyright (C) 2018 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
diff --git a/tests/auto/blackbox/testdata/protobuf/needs-import-dir.qbs b/tests/auto/blackbox/testdata/protobuf/needs-import-dir.qbs
index 788bbc93c..07be566cb 100644
--- a/tests/auto/blackbox/testdata/protobuf/needs-import-dir.qbs
+++ b/tests/auto/blackbox/testdata/protobuf/needs-import-dir.qbs
@@ -1,18 +1,24 @@
-import qbs
+import qbs.Host
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result && hasProtobuf;
+ }
name: "app"
consoleApplication: true
- condition: hasProtobuf
property path theImportDir
protobuf.cpp.importPaths: (theImportDir ? [theImportDir] : []).concat([sourceDirectory])
- cpp.cxxLanguageVersion: "c++11"
+ cpp.minimumMacosVersion: "10.8"
Depends { name: "protobuf.cpp"; required: false }
property bool hasProtobuf: {
console.info("has protobuf: " + protobuf.cpp.present);
+ console.info("has modules: " + protobuflib.present);
return protobuf.cpp.present;
}
diff --git a/tests/auto/blackbox/testdata/qbs-config-import-export/config.json b/tests/auto/blackbox/testdata/qbs-config-import-export/config.json
new file mode 100644
index 000000000..edcaf238a
--- /dev/null
+++ b/tests/auto/blackbox/testdata/qbs-config-import-export/config.json
@@ -0,0 +1,11 @@
+{
+ "group": {
+ "key1": "value1",
+ "key2": "value2"
+ },
+ "key": "value",
+ "listKey": [
+ "valueOne",
+ "valueTwo"
+ ]
+}
diff --git a/tests/auto/blackbox/testdata/qbs-config-import-export/config.txt b/tests/auto/blackbox/testdata/qbs-config-import-export/config.txt
new file mode 100644
index 000000000..2bd19c422
--- /dev/null
+++ b/tests/auto/blackbox/testdata/qbs-config-import-export/config.txt
@@ -0,0 +1,4 @@
+group.key1: "value1"
+group.key2: "value2"
+key: "value"
+listKey: ["valueOne", "valueTwo"]
diff --git a/tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs b/tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs
index 4e9da01d3..4fc275877 100644
--- a/tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs
+++ b/tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs
@@ -23,7 +23,7 @@ Product {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.sourceCode = function() {
var inputList = explicitlyDependsOn["txt.in"];
var fileNameList = [];
diff --git a/tests/auto/blackbox/testdata/remove-duplicate-libs/remove-duplicate-libs.qbs b/tests/auto/blackbox/testdata/remove-duplicate-libs/remove-duplicate-libs.qbs
index 4ffb8d0e2..d89e47414 100644
--- a/tests/auto/blackbox/testdata/remove-duplicate-libs/remove-duplicate-libs.qbs
+++ b/tests/auto/blackbox/testdata/remove-duplicate-libs/remove-duplicate-libs.qbs
@@ -1,11 +1,13 @@
import "MyStaticLib.qbs" as MyStaticLib
+import qbs.Host
Project {
property bool removeDuplicates
property string libDir: buildDirectory + "/lib"
property bool dummy: {
+ // most BSD systems (including macOS) use LLVM linker now
console.info("is bfd linker: "
- + (qbs.toolchain.contains("gcc") && !qbs.hostOS.contains("macos")))
+ + (qbs.toolchain.includes("gcc") && !Host.os().includes("bsd")))
}
qbsSearchPaths: "."
diff --git a/tests/auto/blackbox/testdata/reproducible-build/reproducible-build.qbs b/tests/auto/blackbox/testdata/reproducible-build/reproducible-build.qbs
index f7ed8e61a..fabdf48db 100644
--- a/tests/auto/blackbox/testdata/reproducible-build/reproducible-build.qbs
+++ b/tests/auto/blackbox/testdata/reproducible-build/reproducible-build.qbs
@@ -2,4 +2,9 @@ CppApplication {
name: "the product"
files: ["file1.cpp", "file2.cpp", "main.cpp"]
cpp.cxxFlags: ["-flto"]
+ Probe {
+ id: checker
+ property bool isGcc: qbs.toolchain.contains("gcc") && !qbs.toolchain.contains("clang")
+ configure: { console.info("is gcc: " + isGcc); }
+ }
}
diff --git a/tests/auto/blackbox/testdata/require-deprecated/blubb.js b/tests/auto/blackbox/testdata/require-deprecated/blubb.js
deleted file mode 100644
index 9acc13968..000000000
--- a/tests/auto/blackbox/testdata/require-deprecated/blubb.js
+++ /dev/null
@@ -1,13 +0,0 @@
-var TextFile = loadExtension("qbs.TextFile")
-var zort = loadFile("zort.js")
-
-function createCommands(filePaths) {
- var cmd = new JavaScriptCommand();
- cmd.description = "Write an empty file";
- cmd.filePath = filePaths[0];
- cmd.sourceCode = function() {
- var f = new TextFile(filePath, TextFile.WriteOnly);
- f.close();
- }
- return [cmd, zort.createCommand(filePaths)];
-}
diff --git a/tests/auto/blackbox/testdata/require-deprecated/require.qbs b/tests/auto/blackbox/testdata/require-deprecated/require.qbs
deleted file mode 100644
index 87d8b054b..000000000
--- a/tests/auto/blackbox/testdata/require-deprecated/require.qbs
+++ /dev/null
@@ -1,21 +0,0 @@
-import 'blubb.js' as blubb
-
-Product {
- type: ["text"]
- Rule {
- multiplex: true
- Artifact {
- fileTags: ["text"]
- filePath: "one.txt"
- }
- Artifact {
- fileTags: ["text"]
- filePath: "two.txt"
- }
- prepare: {
- var filePaths = outputs.text.map(function (artifact) {return artifact.filePath; });
- return blubb.createCommands(filePaths);
- }
- }
-}
-
diff --git a/tests/auto/blackbox/testdata/require-deprecated/zort.js b/tests/auto/blackbox/testdata/require-deprecated/zort.js
deleted file mode 100644
index 0dcffb767..000000000
--- a/tests/auto/blackbox/testdata/require-deprecated/zort.js
+++ /dev/null
@@ -1,11 +0,0 @@
-var File = loadExtension("qbs.File")
-
-function createCommand(filePaths) {
- var cmd = new JavaScriptCommand();
- cmd.description = "Create another empty file";
- cmd.filePaths = filePaths;
- cmd.sourceCode = function() {
- File.copy(filePaths[0], filePaths[1]);
- };
- return cmd;
-}
diff --git a/tests/auto/blackbox/testdata/response-files/response-files.qbs b/tests/auto/blackbox/testdata/response-files/response-files.qbs
index fbb6f0518..c18fcac43 100644
--- a/tests/auto/blackbox/testdata/response-files/response-files.qbs
+++ b/tests/auto/blackbox/testdata/response-files/response-files.qbs
@@ -1,4 +1,5 @@
import qbs.FileInfo
+import qbs.Host
import qbs.TextFile
Project {
@@ -8,6 +9,12 @@ Project {
cpp.enableExceptions: true
}
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "response-file-text"
type: ["text"]
Depends { name: "cpp" }
@@ -38,6 +45,9 @@ Project {
Product {
name: "lotsofobjects"
type: ["dynamiclibrary"]
+ // clang-cl does not use response file internally, thus linker complains that command is
+ // too long. This can be worked around by calling the linker directly
+ cpp.linkerMode: qbs.toolchain.includes("clang-cl") ? "manual" : original
Depends { name: "cpp" }
Rule {
multiplex: true
diff --git a/tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication-lib.cpp b/tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication-lib.cpp
new file mode 100644
index 000000000..6418df94d
--- /dev/null
+++ b/tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication-lib.cpp
@@ -0,0 +1,3 @@
+int dynamicFunc() {
+ return 1;
+} \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication-main.cpp b/tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication-main.cpp
new file mode 100644
index 000000000..60f8494f6
--- /dev/null
+++ b/tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication-main.cpp
@@ -0,0 +1,5 @@
+extern int dynamicFunc();
+
+int main() {
+ return dynamicFunc();
+} \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication.qbs b/tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication.qbs
new file mode 100644
index 000000000..adb63872a
--- /dev/null
+++ b/tests/auto/blackbox/testdata/rpathlink-deduplication/rpathlink-deduplication.qbs
@@ -0,0 +1,47 @@
+Project {
+ DynamicLibrary {
+ Depends { name: "bundle" }
+ Depends { name: "cpp" }
+
+ bundle.isBundle: false
+ name: "DynamicLibraryA"
+ files: ["rpathlink-deduplication-lib.cpp"]
+ }
+
+ DynamicLibrary {
+ Depends { name: "bundle" }
+ Depends { name: "cpp" }
+ Depends { name: "DynamicLibraryA" }
+
+ bundle.isBundle: false
+ name: "DynamicLibraryB"
+ files: ["rpathlink-deduplication-lib.cpp"]
+ }
+
+ DynamicLibrary {
+ Depends { name: "bundle" }
+ Depends { name: "cpp" }
+ Depends { name: "DynamicLibraryA" }
+
+ bundle.isBundle: false
+ name: "DynamicLibraryC"
+ files: ["rpathlink-deduplication-lib.cpp"]
+ }
+
+ CppApplication {
+ Depends { name: "bundle" }
+ Depends { name: "DynamicLibraryB" }
+ Depends { name: "DynamicLibraryC" }
+ consoleApplication: true
+ bundle.isBundle: false
+ cpp.removeDuplicateLibraries: false
+ files: "rpathlink-deduplication-main.cpp"
+ property bool test: {
+ if (cpp.useRPathLink)
+ console.info("useRPathLink: true");
+ else
+ console.info("useRPathLink: false");
+ console.info("===" + cpp.rpathLinkFlag + "===");
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata/rule-with-non-required-inputs/rule-with-non-required-inputs.qbs b/tests/auto/blackbox/testdata/rule-with-non-required-inputs/rule-with-non-required-inputs.qbs
index 1bd9beebf..9d861b674 100644
--- a/tests/auto/blackbox/testdata/rule-with-non-required-inputs/rule-with-non-required-inputs.qbs
+++ b/tests/auto/blackbox/testdata/rule-with-non-required-inputs/rule-with-non-required-inputs.qbs
@@ -22,7 +22,7 @@ Product {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Generating " + output.fileName;
+ cmd.description = "generating " + output.fileName;
cmd.sourceCode = function() {
var f = new TextFile(output.filePath, TextFile.WriteOnly);
f.write('(');
diff --git a/tests/auto/blackbox/testdata/run-multiplexed/main.cpp b/tests/auto/blackbox/testdata/run-multiplexed/main.cpp
new file mode 100644
index 000000000..237c8ce18
--- /dev/null
+++ b/tests/auto/blackbox/testdata/run-multiplexed/main.cpp
@@ -0,0 +1 @@
+int main() {}
diff --git a/tests/auto/blackbox/testdata/run-multiplexed/run-multiplexed.qbs b/tests/auto/blackbox/testdata/run-multiplexed/run-multiplexed.qbs
new file mode 100644
index 000000000..11577b54a
--- /dev/null
+++ b/tests/auto/blackbox/testdata/run-multiplexed/run-multiplexed.qbs
@@ -0,0 +1,21 @@
+import qbs.Host
+
+CppApplication {
+ aggregate: false
+ consoleApplication: true
+ name: "app"
+ multiplexByQbsProperties: "buildVariants"
+
+ qbs.buildVariants: ["debug", "release"]
+
+ files: "main.cpp"
+
+ Probe {
+ id: checker
+ property string targetPlatform: qbs.targetPlatform
+ configure: {
+ if (targetPlatform !== Host.platform())
+ console.info("targetPlatform differs from hostPlatform");
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/sanitizer/sanitizer.cpp b/tests/auto/blackbox/testdata/sanitizer/sanitizer.cpp
new file mode 100644
index 000000000..4a7c3ee32
--- /dev/null
+++ b/tests/auto/blackbox/testdata/sanitizer/sanitizer.cpp
@@ -0,0 +1,4 @@
+int main(int argc, char *argv[])
+{
+ return 0;
+}
diff --git a/tests/auto/blackbox/testdata/sanitizer/sanitizer.qbs b/tests/auto/blackbox/testdata/sanitizer/sanitizer.qbs
new file mode 100644
index 000000000..438f3cc39
--- /dev/null
+++ b/tests/auto/blackbox/testdata/sanitizer/sanitizer.qbs
@@ -0,0 +1,44 @@
+CppApplication {
+ Depends { name: "Sanitizers.address" }
+ Sanitizers.address.enabled: sanitizer === "address"
+ property string sanitizer
+
+ property bool supportsSanitizer: {
+ if (qbs.toolchain.includes("mingw"))
+ return false;
+ if (sanitizer === "address")
+ return Sanitizers.address._supported;
+ if (qbs.toolchain.includes("clang-cl")) {
+ if (cpp.toolchainInstallPath.includes("Microsoft Visual Studio")
+ && qbs.architecture === "x86_64") {
+ // 32 bit sanitizer shipped with VS misses the x86_64 libraries
+ return false;
+ }
+ // only these are supported
+ return sanitizer === "address" || sanitizer === "undefined";
+ }
+ if (!qbs.toolchain.includes("gcc"))
+ return false;
+ if (qbs.targetOS.includes("ios")) {
+ // thread sanitizer is not supported
+ return sanitizer !== "thread";
+ }
+ return true;
+ }
+
+ condition: {
+ if (!sanitizer)
+ return true;
+ if (!supportsSanitizer)
+ console.info("Compiler does not support sanitizer");
+ return supportsSanitizer;
+ }
+ qbs.buildVariant: "release"
+ cpp.cxxLanguageVersion: "c++11"
+ cpp.minimumMacosVersion: "10.8"
+ consoleApplication: true
+ cpp.runtimeLibrary: "static"
+ cpp.driverFlags: sanitizer && sanitizer !== "address" ? ["-fsanitize=" + sanitizer] : []
+ cpp.debugInformation: true
+ files: "sanitizer.cpp"
+}
diff --git a/tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/app.h b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/app.h
new file mode 100644
index 000000000..a82b12fbd
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/app.h
@@ -0,0 +1 @@
+#include "lib.h"
diff --git a/tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/app.qbs b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/app.qbs
new file mode 100644
index 000000000..e931b853c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/app.qbs
@@ -0,0 +1,4 @@
+CppApplication {
+ cpp.includePaths: project.sourceDirectory + "/lib"
+ files: "main.cpp"
+}
diff --git a/tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/main.cpp b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/main.cpp
new file mode 100644
index 000000000..2e7bedac8
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/app/main.cpp
@@ -0,0 +1,3 @@
+#include "app.h"
+
+int main() { }
diff --git a/tests/auto/blackbox/testdata/scan-result-in-non-dependency/lib/lib.h b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/lib/lib.h
new file mode 100644
index 000000000..af6f627b7
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/lib/lib.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void lib1_foo(); \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata/scan-result-in-non-dependency/other/other.qbs b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/other/other.qbs
new file mode 100644
index 000000000..29682da1c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/other/other.qbs
@@ -0,0 +1,24 @@
+import qbs.TextFile
+
+Product {
+ type: "testproduct"
+ files: "../lib/lib.h"
+
+ Rule {
+ multiplex: true
+ Artifact {
+ fileTags: ["testproduct"]
+ filePath: "fubar"
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "generating text file";
+ cmd.sourceCode = function() {
+ var tf = new TextFile(output.filePath, TextFile.WriteOnly);
+ tf.writeLine("blubb");
+ tf.close();
+ }
+ return cmd;
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/scan-result-in-non-dependency/p.qbs b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/p.qbs
new file mode 100644
index 000000000..bcbd5ebce
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-non-dependency/p.qbs
@@ -0,0 +1,6 @@
+Project {
+ references: [
+ "app/app.qbs",
+ "other/other.qbs",
+ ]
+}
diff --git a/tests/auto/blackbox/testdata/scan-result-in-other-product/app/app.h b/tests/auto/blackbox/testdata/scan-result-in-other-product/app/app.h
new file mode 100644
index 000000000..a82b12fbd
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-other-product/app/app.h
@@ -0,0 +1 @@
+#include "lib.h"
diff --git a/tests/auto/blackbox/testdata/scan-result-in-other-product/app/app.qbs b/tests/auto/blackbox/testdata/scan-result-in-other-product/app/app.qbs
new file mode 100644
index 000000000..984e9aca9
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-other-product/app/app.qbs
@@ -0,0 +1,4 @@
+CppApplication {
+ Depends { name: "lib" }
+ files: "main.cpp"
+}
diff --git a/tests/auto/blackbox/testdata/scan-result-in-other-product/app/main.cpp b/tests/auto/blackbox/testdata/scan-result-in-other-product/app/main.cpp
new file mode 100644
index 000000000..2e7bedac8
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-other-product/app/main.cpp
@@ -0,0 +1,3 @@
+#include "app.h"
+
+int main() { }
diff --git a/tests/auto/blackbox/testdata/scan-result-in-other-product/lib/lib.h b/tests/auto/blackbox/testdata/scan-result-in-other-product/lib/lib.h
new file mode 100644
index 000000000..af6f627b7
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-other-product/lib/lib.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void lib1_foo(); \ No newline at end of file
diff --git a/tests/auto/blackbox/testdata/scan-result-in-other-product/lib/lib.qbs b/tests/auto/blackbox/testdata/scan-result-in-other-product/lib/lib.qbs
new file mode 100644
index 000000000..a6ed0c990
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-other-product/lib/lib.qbs
@@ -0,0 +1,7 @@
+Product {
+ files: "lib.h"
+ Export {
+ Depends { name: "cpp" }
+ cpp.includePaths: exportingProduct.sourceDirectory
+ }
+}
diff --git a/tests/auto/blackbox/testdata/scan-result-in-other-product/other/other.qbs b/tests/auto/blackbox/testdata/scan-result-in-other-product/other/other.qbs
new file mode 100644
index 000000000..29682da1c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-other-product/other/other.qbs
@@ -0,0 +1,24 @@
+import qbs.TextFile
+
+Product {
+ type: "testproduct"
+ files: "../lib/lib.h"
+
+ Rule {
+ multiplex: true
+ Artifact {
+ fileTags: ["testproduct"]
+ filePath: "fubar"
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "generating text file";
+ cmd.sourceCode = function() {
+ var tf = new TextFile(output.filePath, TextFile.WriteOnly);
+ tf.writeLine("blubb");
+ tf.close();
+ }
+ return cmd;
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/scan-result-in-other-product/p.qbs b/tests/auto/blackbox/testdata/scan-result-in-other-product/p.qbs
new file mode 100644
index 000000000..fedf84989
--- /dev/null
+++ b/tests/auto/blackbox/testdata/scan-result-in-other-product/p.qbs
@@ -0,0 +1,7 @@
+Project {
+ references: [
+ "app/app.qbs",
+ "lib/lib.qbs",
+ "other/other.qbs",
+ ]
+}
diff --git a/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs b/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs
index 0b16d1984..4198b863f 100644
--- a/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs
+++ b/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs
@@ -8,9 +8,13 @@ Project {
Probe {
id: osProbe
property stringList targetOS: qbs.targetOS
+ property stringList toolchain: qbs.toolchain
configure: {
- console.info("is windows: " + (targetOS.contains("windows") ? "yes" : "no"));
- console.info("is darwin: " + (targetOS.contains("darwin") ? "yes" : "no"));
+ console.info("is windows: " + (targetOS.includes("windows") ? "yes" : "no"));
+ console.info("is macos: " + (targetOS.includes("macos") ? "yes" : "no"));
+ console.info("is darwin: " + (targetOS.includes("darwin") ? "yes" : "no"));
+ console.info("is gcc: " + (toolchain.includes("gcc") ? "yes" : "no"));
+ console.info("is msvc: " + (toolchain.includes("msvc") ? "yes" : "no"));
}
}
}
@@ -54,7 +58,7 @@ Project {
files: ["main.cpp"]
cpp.separateDebugInformation: true
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
cpp.dsymutilFlags: ["--flat"]
}
}
@@ -65,7 +69,7 @@ Project {
files: ["foo.cpp"]
cpp.separateDebugInformation: true
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
cpp.dsymutilFlags: ["--flat"]
}
}
@@ -75,7 +79,7 @@ Project {
files: ["foo.cpp"]
cpp.separateDebugInformation: true
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
cpp.dsymutilFlags: ["--flat"]
}
}
@@ -93,7 +97,7 @@ Project {
type: ["dynamiclibrary"]
files: ["foo.cpp"]
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
cpp.separateDebugInformation: true
@@ -103,7 +107,7 @@ Project {
name: "bar4"
files: ["foo.cpp"]
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
cpp.separateDebugInformation: true
@@ -114,12 +118,12 @@ Project {
type: ["application"]
files: ["main.cpp"]
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
cpp.separateDebugInformation: true
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
cpp.dsymutilFlags: ["--flat"]
}
}
@@ -129,12 +133,12 @@ Project {
type: ["dynamiclibrary"]
files: ["foo.cpp"]
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
cpp.separateDebugInformation: true
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
cpp.dsymutilFlags: ["--flat"]
}
}
@@ -143,12 +147,12 @@ Project {
name: "bar5"
files: ["foo.cpp"]
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
cpp.separateDebugInformation: true
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
cpp.dsymutilFlags: ["--flat"]
}
}
diff --git a/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs b/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs
index d2d47b767..b1310c005 100644
--- a/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs
+++ b/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs
@@ -1,4 +1,5 @@
import qbs.FileInfo
+import qbs.Host
Project {
DynamicLibrary { // Product dependency, installed
@@ -7,13 +8,13 @@ Project {
files: ["lib1.cpp"]
- install: !qbs.targetOS.contains("darwin")
+ install: !qbs.targetOS.includes("darwin")
installImportLib: true
installDir: "lib1"
importLibInstallDir: installDir
Group {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
fileTagsFilter: ["bundle.content"]
qbs.install: true
qbs.installSourceBase: destinationDirectory
@@ -26,7 +27,7 @@ Project {
Depends { name: "lib5" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
@@ -40,7 +41,7 @@ Project {
files: ["lib3.cpp"]
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
@@ -57,14 +58,14 @@ Project {
files: ["lib4.cpp"]
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
// Testing shows that clang (8.0) does not find dynamic libraries via
// the -L<dir> and -l<libname> mechanism unless the name is "lib<libname>.a".
Properties {
- condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("clang")
+ condition: Host.os().includes("windows") && qbs.toolchain.includes("clang")
cpp.dynamicLibraryPrefix: "lib"
cpp.dynamicLibraryImportSuffix: ".a"
}
@@ -82,7 +83,7 @@ Project {
Depends { name: "cpp" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
@@ -90,6 +91,12 @@ Project {
}
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: "app"
consoleApplication: true
files: "main.cpp"
@@ -101,7 +108,7 @@ Project {
property string fullInstallPrefix: FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix)
property string lib3FilePath: FileInfo.joinPaths(fullInstallPrefix, "lib3",
- cpp.dynamicLibraryPrefix + "lib3" + (qbs.targetOS.contains("windows")
+ cpp.dynamicLibraryPrefix + "lib3" + (qbs.targetOS.includes("windows")
? cpp.dynamicLibraryImportSuffix
: cpp.dynamicLibrarySuffix))
cpp.dynamicLibraries: [lib3FilePath, "lib4"]
@@ -110,7 +117,7 @@ Project {
Probe {
id: osPrinter
- property bool isWindows: qbs.targetOS.contains("windows")
+ property bool isWindows: qbs.targetOS.includes("windows")
configure: {
console.info("is windows");
found = true;
diff --git a/tests/auto/blackbox/testdata/smart-relinking/smart-relinking.qbs b/tests/auto/blackbox/testdata/smart-relinking/smart-relinking.qbs
index aac0692a8..29e6c2e17 100644
--- a/tests/auto/blackbox/testdata/smart-relinking/smart-relinking.qbs
+++ b/tests/auto/blackbox/testdata/smart-relinking/smart-relinking.qbs
@@ -5,7 +5,7 @@ Project {
property stringList toolchain: qbs.toolchain
property stringList targetOS: qbs.targetOS
configure: {
- found = toolchain.contains("gcc") && targetOS.contains("unix");
+ found = toolchain.includes("gcc") && targetOS.includes("unix");
if (!found)
console.info("project disabled");
}
diff --git a/tests/auto/blackbox/testdata/source-artifact-changes/source-artifact-changes.qbs b/tests/auto/blackbox/testdata/source-artifact-changes/source-artifact-changes.qbs
index de56376df..a53819753 100644
--- a/tests/auto/blackbox/testdata/source-artifact-changes/source-artifact-changes.qbs
+++ b/tests/auto/blackbox/testdata/source-artifact-changes/source-artifact-changes.qbs
@@ -4,7 +4,7 @@ CppApplication {
consoleApplication: true
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.embedInfoPlist: false
}
@@ -12,7 +12,7 @@ CppApplication {
id: toolchainProbe
property stringList toolchain: qbs.toolchain
configure: {
- console.info("is gcc: " + toolchain.contains("gcc"));
+ console.info("is gcc: " + toolchain.includes("gcc"));
found = true;
}
}
diff --git a/tests/auto/blackbox/testdata/static-lib-without-sources/static-lib-without-sources.qbs b/tests/auto/blackbox/testdata/static-lib-without-sources/static-lib-without-sources.qbs
index 32a58c94b..54ec5e230 100644
--- a/tests/auto/blackbox/testdata/static-lib-without-sources/static-lib-without-sources.qbs
+++ b/tests/auto/blackbox/testdata/static-lib-without-sources/static-lib-without-sources.qbs
@@ -6,7 +6,7 @@ StaticLibrary {
}
Product {
- type: qbs.targetOS.contains("darwin") ? undefined : ["staticlibrary"]
+ type: qbs.targetOS.includes("darwin") ? undefined : ["staticlibrary"]
name: "b"
Depends { name: "cpp" }
Depends { name: "a" }
diff --git a/tests/auto/blackbox/testdata/successive-changes/successive-changes.qbs b/tests/auto/blackbox/testdata/successive-changes/successive-changes.qbs
index 77df81e39..c33e24d34 100644
--- a/tests/auto/blackbox/testdata/successive-changes/successive-changes.qbs
+++ b/tests/auto/blackbox/testdata/successive-changes/successive-changes.qbs
@@ -17,7 +17,7 @@ Project {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating output";
+ cmd.description = "creating output";
cmd.sourceCode = function() {
var f = new TextFile(output.filePath, TextFile.WriteOnly);
f.write(project.version);
diff --git a/tests/auto/blackbox/testdata/symbolLinkMode/lib.cpp b/tests/auto/blackbox/testdata/symbolLinkMode/lib.cpp
index 8d96f5094..9dcb48738 100644
--- a/tests/auto/blackbox/testdata/symbolLinkMode/lib.cpp
+++ b/tests/auto/blackbox/testdata/symbolLinkMode/lib.cpp
@@ -3,9 +3,9 @@ int somefunction()
return 42;
}
-#include <stdio.h>
+#include <cstdio>
static const auto func = []() {
- printf("Lib was loaded!\n");
+ std::printf("Lib was loaded!\n");
return 0;
}();
diff --git a/tests/auto/blackbox/testdata/symbolLinkMode/main.cpp b/tests/auto/blackbox/testdata/symbolLinkMode/main.cpp
index 801491634..4d847ba19 100644
--- a/tests/auto/blackbox/testdata/symbolLinkMode/main.cpp
+++ b/tests/auto/blackbox/testdata/symbolLinkMode/main.cpp
@@ -1,15 +1,15 @@
extern WEAK_IMPORT int somefunction();
extern void indirect();
-#include <stdio.h>
+#include <cstdio>
int main()
{
- printf("meow\n");
+ std::printf("meow\n");
if (&somefunction != nullptr)
- printf("somefunction existed and it returned %d\n", somefunction());
+ std::printf("somefunction existed and it returned %d\n", somefunction());
else
- printf("somefunction did not exist\n");
+ std::printf("somefunction did not exist\n");
#if SHOULD_INSTALL_LIB
indirect();
#endif
diff --git a/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs b/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs
index 2d3d64b00..49bcd9951 100644
--- a/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs
+++ b/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs
@@ -1,15 +1,22 @@
import qbs.FileInfo
+import qbs.Host
Project {
property bool shouldInstallLibrary: true
property bool lazy: false
Application {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
Depends { name: "cpp" }
Depends {
name: "functions";
cpp.symbolLinkMode: product.symbolLinkMode
- cpp.link: !(product.qbs.targetOS.contains("linux") && product.symbolLinkMode === "weak")
+ cpp.link: !(product.qbs.targetOS.includes("linux") && product.symbolLinkMode === "weak")
}
property string symbolLinkMode: project.lazy ? "lazy" : "weak"
@@ -20,7 +27,7 @@ Project {
property string installLib: "SHOULD_INSTALL_LIB=" + project.shouldInstallLibrary
cpp.defines: {
if (symbolLinkMode === "weak") {
- return qbs.targetOS.contains("darwin")
+ return qbs.targetOS.includes("darwin")
? ["WEAK_IMPORT=__attribute__((weak_import))", installLib]
: ["WEAK_IMPORT=__attribute__((weak))", installLib];
}
@@ -42,7 +49,7 @@ Project {
Depends { name: "indirect"; cpp.symbolLinkMode: "reexport" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
name: "functions"
@@ -52,7 +59,7 @@ Project {
cpp.rpaths: [cpp.rpathOrigin]
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
cpp.sonamePrefix: "@rpath"
}
@@ -65,7 +72,7 @@ Project {
Export {
// let the autotest pass on Linux where reexport is not supported
- Depends { name: "indirect"; condition: !qbs.targetOS.contains("darwin") }
+ Depends { name: "indirect"; condition: !qbs.targetOS.includes("darwin") }
// on Linux, there is no LC_WEAK_LOAD_DYLIB equivalent (the library is simply omitted
// from the list of load commands entirely), so use LD_PRELOAD to emulate
@@ -84,7 +91,7 @@ Project {
Depends { name: "cpp" }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
name: "indirect"
@@ -93,7 +100,7 @@ Project {
cpp.minimumMacosVersion: "10.7"
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
// reexport is incompatible with rpath,
// "ERROR: ld: file not found: @rpath/libindirect.dylib for architecture x86_64"
cpp.sonamePrefix: qbs.installRoot + "/lib"
diff --git a/tests/auto/blackbox/testdata/system-include-paths/main.cpp b/tests/auto/blackbox/testdata/system-include-paths/main.cpp
index e449173d3..10d376a31 100644
--- a/tests/auto/blackbox/testdata/system-include-paths/main.cpp
+++ b/tests/auto/blackbox/testdata/system-include-paths/main.cpp
@@ -1,4 +1,4 @@
-#include <stdio.h>
+#include <cstdio>
#include <gagagugu.h>
int main()
diff --git a/tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs b/tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs
index 6e2137173..35dd7a00f 100644
--- a/tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs
+++ b/tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs
@@ -20,4 +20,9 @@ Project {
cpp.rpaths: qbs.installRoot + "/lib"
cpp.systemRunPaths: project.setRunPaths ? [qbs.installRoot + "/lib"] : []
}
+ Probe {
+ id: checker
+ property bool isUnix: qbs.targetOS.contains("unix")
+ configure: { console.info("is unix: " + isUnix); }
+ }
}
diff --git a/tests/auto/blackbox/testdata/trackAddFile/after/main.cpp b/tests/auto/blackbox/testdata/trackAddFile/after/main.cpp
index 0e474b221..d108825d6 100644
--- a/tests/auto/blackbox/testdata/trackAddFile/after/main.cpp
+++ b/tests/auto/blackbox/testdata/trackAddFile/after/main.cpp
@@ -31,7 +31,7 @@
int main(int argc, char **argv)
{
- printf("Hello World!\n");
+ std::printf("Hello World!\n");
Narf narf;
narf.shout();
Zort zort;
diff --git a/tests/auto/blackbox/testdata/trackAddFile/after/trackAddFile.qbs b/tests/auto/blackbox/testdata/trackAddFile/after/trackAddFile.qbs
index f4b9ba21f..4d454d4ff 100644
--- a/tests/auto/blackbox/testdata/trackAddFile/after/trackAddFile.qbs
+++ b/tests/auto/blackbox/testdata/trackAddFile/after/trackAddFile.qbs
@@ -1,5 +1,13 @@
+import qbs.Host
+
Project {
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: 'someapp'
type: 'application'
consoleApplication: true
diff --git a/tests/auto/blackbox/testdata/trackAddFile/after/zort.cpp b/tests/auto/blackbox/testdata/trackAddFile/after/zort.cpp
index 1915ea869..55a9dfa6d 100644
--- a/tests/auto/blackbox/testdata/trackAddFile/after/zort.cpp
+++ b/tests/auto/blackbox/testdata/trackAddFile/after/zort.cpp
@@ -30,6 +30,6 @@
void Zort::shout()
{
- printf("ZORT!\n");
+ std::printf("ZORT!\n");
}
diff --git a/tests/auto/blackbox/testdata/trackAddFile/before/main.cpp b/tests/auto/blackbox/testdata/trackAddFile/before/main.cpp
index f989e1d9b..e8915030e 100644
--- a/tests/auto/blackbox/testdata/trackAddFile/before/main.cpp
+++ b/tests/auto/blackbox/testdata/trackAddFile/before/main.cpp
@@ -30,7 +30,7 @@
int main(int argc, char **argv)
{
- printf("Hello World!\n");
+ std::printf("Hello World!\n");
Narf narf;
narf.shout();
return 0;
diff --git a/tests/auto/blackbox/testdata/trackAddFile/before/narf.cpp b/tests/auto/blackbox/testdata/trackAddFile/before/narf.cpp
index 280d5f3bd..c301b57df 100644
--- a/tests/auto/blackbox/testdata/trackAddFile/before/narf.cpp
+++ b/tests/auto/blackbox/testdata/trackAddFile/before/narf.cpp
@@ -30,6 +30,6 @@
void Narf::shout()
{
- printf("NARF!\n");
+ std::printf("NARF!\n");
}
diff --git a/tests/auto/blackbox/testdata/trackAddFile/before/trackAddFile.qbs b/tests/auto/blackbox/testdata/trackAddFile/before/trackAddFile.qbs
index bb0ab7d44..fd858b247 100644
--- a/tests/auto/blackbox/testdata/trackAddFile/before/trackAddFile.qbs
+++ b/tests/auto/blackbox/testdata/trackAddFile/before/trackAddFile.qbs
@@ -1,5 +1,13 @@
+import qbs.Host
+
Project {
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: 'someapp'
type: 'application'
consoleApplication: true
diff --git a/tests/auto/blackbox/testdata/trackExternalProductChanges/trackExternalProductChanges.qbs b/tests/auto/blackbox/testdata/trackExternalProductChanges/trackExternalProductChanges.qbs
index 534f49ff2..0e28e5687 100644
--- a/tests/auto/blackbox/testdata/trackExternalProductChanges/trackExternalProductChanges.qbs
+++ b/tests/auto/blackbox/testdata/trackExternalProductChanges/trackExternalProductChanges.qbs
@@ -11,4 +11,9 @@ CppApplication {
name: "file that needs help from the environment to find a header"
files: "including.cpp"
}
+ Probe {
+ id: checker
+ property bool isGcc: qbs.toolchain.contains("gcc")
+ configure: { console.info("is gcc: " + isGcc); }
+ }
}
diff --git a/tests/auto/blackbox/testdata/trackFileTags/after/main.cpp b/tests/auto/blackbox/testdata/trackFileTags/after/main.cpp
index 1d2c8ebb7..7520b5ed7 100644
--- a/tests/auto/blackbox/testdata/trackFileTags/after/main.cpp
+++ b/tests/auto/blackbox/testdata/trackFileTags/after/main.cpp
@@ -31,7 +31,7 @@ int foo();
int main(int argc, char **argv)
{
- printf("there's %d foo here\n", foo());
+ std::printf("there's %d foo here\n", foo());
return 0;
}
diff --git a/tests/auto/blackbox/testdata/trackFileTags/after/trackFileTags.qbs b/tests/auto/blackbox/testdata/trackFileTags/after/trackFileTags.qbs
index 869ce238b..1c5b6b56f 100644
--- a/tests/auto/blackbox/testdata/trackFileTags/after/trackFileTags.qbs
+++ b/tests/auto/blackbox/testdata/trackFileTags/after/trackFileTags.qbs
@@ -1,7 +1,15 @@
import qbs.TextFile
+import qbs.Host
+
Project {
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: 'someapp'
type: 'application'
consoleApplication: true
diff --git a/tests/auto/blackbox/testdata/trackFileTags/before/main.cpp b/tests/auto/blackbox/testdata/trackFileTags/before/main.cpp
index 3016f8bb1..b4d71f995 100644
--- a/tests/auto/blackbox/testdata/trackFileTags/before/main.cpp
+++ b/tests/auto/blackbox/testdata/trackFileTags/before/main.cpp
@@ -29,7 +29,7 @@
int main(int argc, char **argv)
{
- printf("there's no foo here\n");
+ std::printf("there's no foo here\n");
return 0;
}
diff --git a/tests/auto/blackbox/testdata/trackFileTags/before/trackFileTags.qbs b/tests/auto/blackbox/testdata/trackFileTags/before/trackFileTags.qbs
index ebe31bf26..86771ab8f 100644
--- a/tests/auto/blackbox/testdata/trackFileTags/before/trackFileTags.qbs
+++ b/tests/auto/blackbox/testdata/trackFileTags/before/trackFileTags.qbs
@@ -1,7 +1,15 @@
import qbs.TextFile
+import qbs.Host
+
Project {
Product {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
name: 'someapp'
type: 'application'
consoleApplication: true
diff --git a/tests/auto/blackbox/testdata/trackProducts/after/zoo.cpp b/tests/auto/blackbox/testdata/trackProducts/after/zoo.cpp
index b65fb3f9d..fc0d13e4b 100644
--- a/tests/auto/blackbox/testdata/trackProducts/after/zoo.cpp
+++ b/tests/auto/blackbox/testdata/trackProducts/after/zoo.cpp
@@ -30,5 +30,5 @@
int main()
{
- printf("zoo\n");
+ std::printf("zoo\n");
}
diff --git a/tests/auto/blackbox/testdata/trackProducts/before/bar.cpp b/tests/auto/blackbox/testdata/trackProducts/before/bar.cpp
index 7880c8669..3664897de 100644
--- a/tests/auto/blackbox/testdata/trackProducts/before/bar.cpp
+++ b/tests/auto/blackbox/testdata/trackProducts/before/bar.cpp
@@ -30,5 +30,5 @@
int main()
{
- printf("bar\n");
+ std::printf("bar\n");
}
diff --git a/tests/auto/blackbox/testdata/trackProducts/before/foo.cpp b/tests/auto/blackbox/testdata/trackProducts/before/foo.cpp
index 865fb1299..fb5c32769 100644
--- a/tests/auto/blackbox/testdata/trackProducts/before/foo.cpp
+++ b/tests/auto/blackbox/testdata/trackProducts/before/foo.cpp
@@ -30,5 +30,5 @@
int main()
{
- printf("foo\n");
+ std::printf("foo\n");
}
diff --git a/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/a/a.qbs b/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/a/a.qbs
new file mode 100644
index 000000000..fd52488fb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/a/a.qbs
@@ -0,0 +1,5 @@
+Module {
+ validate: {
+ throw "Module cannot be loaded";
+ }
+}
diff --git a/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/b/b.qbs b/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/b/b.qbs
new file mode 100644
index 000000000..605a2aaee
--- /dev/null
+++ b/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/b/b.qbs
@@ -0,0 +1,3 @@
+Module {
+ Depends { name: "a" }
+}
diff --git a/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/c/c.qbs b/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/c/c.qbs
new file mode 100644
index 000000000..ac7dbbec6
--- /dev/null
+++ b/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/c/c.qbs
@@ -0,0 +1,3 @@
+Module {
+ Depends { name: "a"; required: false }
+}
diff --git a/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/d/d.qbs b/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/d/d.qbs
new file mode 100644
index 000000000..0bdd8c3b7
--- /dev/null
+++ b/tests/auto/blackbox/testdata/transitive-invalid-dependencies/modules/d/d.qbs
@@ -0,0 +1,4 @@
+Module {
+ Depends { name: "b"; }
+ Depends { name: "c"; }
+}
diff --git a/tests/auto/blackbox/testdata/transitive-invalid-dependencies/transitive-invalid-dependencies.qbs b/tests/auto/blackbox/testdata/transitive-invalid-dependencies/transitive-invalid-dependencies.qbs
new file mode 100644
index 000000000..209b1e47d
--- /dev/null
+++ b/tests/auto/blackbox/testdata/transitive-invalid-dependencies/transitive-invalid-dependencies.qbs
@@ -0,0 +1,11 @@
+Product {
+ property bool modulePresent: {
+ console.info("b.present = " + b.present);
+ console.info("c.present = " + c.present);
+ console.info("d.present = " + d.present);
+ }
+
+ Depends { name: "b"; required: false }
+ Depends { name: "c"; required: false }
+ Depends { name: "d"; required: false }
+}
diff --git a/tests/auto/blackbox/testdata/undefined-target-platform/undefined-target-platform.qbs b/tests/auto/blackbox/testdata/undefined-target-platform/undefined-target-platform.qbs
new file mode 100644
index 000000000..4a738afcc
--- /dev/null
+++ b/tests/auto/blackbox/testdata/undefined-target-platform/undefined-target-platform.qbs
@@ -0,0 +1,13 @@
+import qbs.File
+import qbs.FileInfo
+
+Product {
+ name: "undefined-target-platform"
+ qbs.targetPlatform: undefined
+
+ readonly property bool _validate: {
+ if ((qbs.targetOS instanceof Array) && qbs.targetOS.length === 0)
+ return true;
+ throw "Invalid qbs.targetOS value: " + qbs.targetOS;
+ }
+}
diff --git a/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs b/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs
index b6e025e4c..1131e6a2f 100644
--- a/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs
+++ b/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs
@@ -1,8 +1,8 @@
StaticLibrary {
name: "l"
- Depends { condition: qbs.targetOS.contains("darwin"); name: "bundle" }
- Properties { condition: qbs.targetOS.contains("darwin"); bundle.isBundle: false }
+ Depends { condition: qbs.targetOS.includes("darwin"); name: "bundle" }
+ Properties { condition: qbs.targetOS.includes("darwin"); bundle.isBundle: false }
aggregate: false
property string variantSuffix
@@ -31,8 +31,8 @@ StaticLibrary {
id: targetOSProbe
property stringList targetOS: qbs.targetOS
configure: {
- console.info("is Windows: " + targetOS.contains("windows"));
- console.info("is Apple: " + targetOS.contains("darwin"));
+ console.info("is Windows: " + targetOS.includes("windows"));
+ console.info("is Apple: " + targetOS.includes("darwin"));
}
}
}
diff --git a/tests/auto/blackbox/testdata/vcs/vcstest.qbs b/tests/auto/blackbox/testdata/vcs/vcstest.qbs
index 5d359e2c7..4f861654b 100644
--- a/tests/auto/blackbox/testdata/vcs/vcstest.qbs
+++ b/tests/auto/blackbox/testdata/vcs/vcstest.qbs
@@ -1,4 +1,12 @@
+import qbs.Host
+
CppApplication {
+ condition: {
+ var result = qbs.targetPlatform === Host.platform();
+ if (!result)
+ console.info("targetPlatform differs from hostPlatform");
+ return result;
+ }
Depends { name: "vcs" }
vcs.headerFileName: "my-repo-state.h"
files: ["main.cpp"]
diff --git a/tests/auto/blackbox/testdata/versionscript/versionscript.qbs b/tests/auto/blackbox/testdata/versionscript/versionscript.qbs
index cc5c7b1cc..fcb4314a2 100644
--- a/tests/auto/blackbox/testdata/versionscript/versionscript.qbs
+++ b/tests/auto/blackbox/testdata/versionscript/versionscript.qbs
@@ -20,6 +20,12 @@ DynamicLibrary {
return [cmd];
}
}
+ Probe {
+ id: checker
+ property bool isLinux: qbs.targetOS.includes("linux")
+ property bool isGcc: qbs.toolchain.contains("gcc")
+ configure: { console.info("is gcc for Linux: " + (isLinux && isGcc)); }
+ }
qbs.installPrefix: ""
install: true
diff --git a/tests/auto/blackbox/testdata/whole-archive/whole-archive.qbs b/tests/auto/blackbox/testdata/whole-archive/whole-archive.qbs
index f3bcff2cd..c138e46c0 100644
--- a/tests/auto/blackbox/testdata/whole-archive/whole-archive.qbs
+++ b/tests/auto/blackbox/testdata/whole-archive/whole-archive.qbs
@@ -32,7 +32,8 @@ Project {
property string compilerVersion: cpp.compilerVersion
property string dummy: product.linkWholeArchive // To force probe re-execution
configure: {
- if (!toolchain.contains("msvc")
+ if (!toolchain.includes("msvc")
+ || toolchain.includes("clang-cl")
|| Utilities.versionCompare(compilerVersion, "19.0.24215.1") >= 0) {
console.info("can link whole archives");
} else {
diff --git a/tests/auto/blackbox/testdata/wildcards-and-change-tracking/nonrecursive/subdir1/file.txt b/tests/auto/blackbox/testdata/wildcards-and-change-tracking/nonrecursive/subdir1/file.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/wildcards-and-change-tracking/nonrecursive/subdir1/file.txt
diff --git a/tests/auto/blackbox/testdata/wildcards-and-change-tracking/nonrecursive/subdir2/file.txt b/tests/auto/blackbox/testdata/wildcards-and-change-tracking/nonrecursive/subdir2/file.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/wildcards-and-change-tracking/nonrecursive/subdir2/file.txt
diff --git a/tests/auto/blackbox/testdata/wildcards-and-change-tracking/recursive1/recursive.txt b/tests/auto/blackbox/testdata/wildcards-and-change-tracking/recursive1/recursive.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/wildcards-and-change-tracking/recursive1/recursive.txt
diff --git a/tests/auto/blackbox/testdata/wildcards-and-change-tracking/recursive2/recursive.txt b/tests/auto/blackbox/testdata/wildcards-and-change-tracking/recursive2/recursive.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/wildcards-and-change-tracking/recursive2/recursive.txt
diff --git a/tests/auto/blackbox/testdata/wildcards-and-change-tracking/wildcards-and-change-tracking.qbs b/tests/auto/blackbox/testdata/wildcards-and-change-tracking/wildcards-and-change-tracking.qbs
new file mode 100644
index 000000000..0a889bab3
--- /dev/null
+++ b/tests/auto/blackbox/testdata/wildcards-and-change-tracking/wildcards-and-change-tracking.qbs
@@ -0,0 +1,16 @@
+Product {
+ Group {
+ name: "recursive"
+ files: "**/file.txt"
+ }
+ Group {
+ name: "directories"
+ prefix: "nonrecursive/"
+ files: "subdi?/file.txt"
+ }
+ Group {
+ prefix: "nonrecursive/empty/"
+ name: "no files"
+ files: "*.txt"
+ }
+}
diff --git a/tests/auto/blackbox/testdata/wildcards-and-rules/wildcards-and-rules.qbs b/tests/auto/blackbox/testdata/wildcards-and-rules/wildcards-and-rules.qbs
index f6662529d..fe6088943 100644
--- a/tests/auto/blackbox/testdata/wildcards-and-rules/wildcards-and-rules.qbs
+++ b/tests/auto/blackbox/testdata/wildcards-and-rules/wildcards-and-rules.qbs
@@ -22,7 +22,7 @@ Product {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating output artifact";
+ cmd.description = "creating output artifact";
cmd.highlight = "codegen";
cmd.sourceCode = function() {
var file = new TextFile(output.filePath, TextFile.WriteOnly);
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index faada314f..dbabfb311 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -49,10 +49,11 @@
#include <QtCore/qjsonobject.h>
#include <QtCore/qjsonvalue.h>
#include <QtCore/qlocale.h>
-#include <QtCore/qregexp.h>
+#include <QtCore/qregularexpression.h>
#include <QtCore/qsettings.h>
#include <QtCore/qtemporarydir.h>
#include <QtCore/qtemporaryfile.h>
+#include <QtCore/qversionnumber.h>
#include <algorithm>
#include <functional>
@@ -62,7 +63,6 @@
#define WAIT_FOR_NEW_TIMESTAMP() waitForNewTimestamp(testDataDir)
using qbs::Internal::HostOsInfo;
-using qbs::Profile;
class MacosTarHealer {
public:
@@ -138,12 +138,32 @@ QString TestBlackbox::findArchiver(const QString &fileName, int *status)
QString binary = findExecutable(QStringList(fileName));
if (binary.isEmpty()) {
const SettingsPtr s = settings();
- Profile p(profileName(), s.get());
+ qbs::Profile p(profileName(), s.get());
binary = findExecutable(p.value("archiver.command").toStringList());
}
return binary;
}
+bool TestBlackbox::prepareAndRunConan()
+{
+ QString executable = findExecutable({"conan"});
+ if (executable.isEmpty()) {
+ qInfo() << "conan is not installed or not available in PATH.";
+ return false;
+ }
+ const auto profilePath = QDir::homePath() + "/.conan2/profiles/qbs-test";
+ if (!QFileInfo(profilePath).exists()) {
+ qInfo() << "conan profile is not installed, run './scripts/setup-conan-profiles.sh'";
+ return false;
+ }
+ QProcess conan;
+ QDir::setCurrent(testDataDir + "/conan-provider/testlibdep");
+ rmDirR("build");
+ QStringList arguments{"install", ".", "--profile:all=qbs-test", "--output-folder=build"};
+ conan.start(executable, arguments);
+ return waitForProcessSuccess(conan, 60000);
+}
+
bool TestBlackbox::lexYaccExist()
{
return !findExecutable(QStringList("lex")).isEmpty()
@@ -253,6 +273,13 @@ void TestBlackbox::systemIncludePaths()
QCOMPARE(runQbs(), 0);
}
+void TestBlackbox::distributionIncludePaths()
+{
+ const QString projectDir = testDataDir + "/distribution-include-paths";
+ QDir::setCurrent(projectDir);
+ QCOMPARE(runQbs(), 0);
+}
+
void TestBlackbox::tar()
{
if (HostOsInfo::hostOs() == HostOsInfo::HostOsWindows)
@@ -291,7 +318,7 @@ void TestBlackbox::textTemplate()
static QStringList sortedFileList(const QByteArray &ba)
{
- auto list = QString::fromUtf8(ba).split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
+ auto list = QString::fromUtf8(ba).split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
std::sort(list.begin(), list.end());
return list;
}
@@ -356,6 +383,57 @@ TestBlackbox::TestBlackbox() : TestBlackboxBase (SRCDIR "/testdata", "blackbox")
{
}
+void TestBlackbox::allowedValues()
+{
+ QFETCH(QString, property);
+ QFETCH(QString, value);
+ QFETCH(QString, invalidValue);
+
+ QDir::setCurrent(testDataDir + "/allowed-values");
+ rmDirR(relativeBuildDir());
+
+ QbsRunParameters params;
+ if (!property.isEmpty() && !value.isEmpty()) {
+ params.arguments << QStringLiteral("%1:%2").arg(property, value);
+ }
+
+ params.expectFailure = !invalidValue.isEmpty();
+ QCOMPARE(runQbs(params) == 0, !params.expectFailure);
+ if (params.expectFailure) {
+ const auto errorString =
+ QStringLiteral("Value '%1' is not allowed for property").arg(invalidValue);
+ QVERIFY2(m_qbsStderr.contains(errorString.toUtf8()), m_qbsStderr.constData());
+ }
+}
+
+void TestBlackbox::allowedValues_data()
+{
+ QTest::addColumn<QString>("property");
+ QTest::addColumn<QString>("value");
+ QTest::addColumn<QString>("invalidValue");
+
+ QTest::newRow("default") << QString() << QString() << QString();
+
+ QTest::newRow("allowed (product, CLI)") << "products.p.prop" << "foo" << QString();
+ QTest::newRow("not allowed (product, CLI)") << "products.p.prop" << "bar" << "bar";
+ QTest::newRow("allowed (product, JS)") << "products.p.prop2" << "foo" << QString();
+ QTest::newRow("not allowed (product, JS)") << "products.p.prop2" << "bar" << "bar";
+
+ QTest::newRow("allowed single (module, CLI)") << "modules.a.prop" << "foo" << QString();
+ QTest::newRow("not allowed single (module, CLI)") << "modules.a.prop" << "baz" << "baz";
+ QTest::newRow("allowed mult (module, CLI)") << "modules.a.prop" << "foo,bar" << QString();
+ QTest::newRow("not allowed mult (module, CLI)") << "modules.a.prop" << "foo,baz" << "baz";
+
+ QTest::newRow("allowed single (module, JS)") << "modules.a.prop2" << "foo" << QString();
+ QTest::newRow("not allowed single (module, JS)") << "modules.a.prop2" << "baz" << "baz";
+ QTest::newRow("allowed mult (module, JS)") << "modules.a.prop2" << "foo,bar" << QString();
+ QTest::newRow("not allowed mult (module, JS)") << "modules.a.prop2" << "foo,baz" << "baz";
+
+ // undefined should always be allowed
+ QTest::newRow("undefined (product)") << "products.p.prop" << "undefined" << QString();
+ QTest::newRow("undefined (module)") << "modules.a.prop" << "undefined" << QString();
+}
+
void TestBlackbox::addFileTagToGeneratedArtifact()
{
QDir::setCurrent(testDataDir + "/add-filetag-to-generated-artifact");
@@ -640,7 +718,7 @@ void TestBlackbox::buildDirectories()
QDir::setCurrent(projectDir);
QCOMPARE(runQbs(), 0);
const QStringList outputLines
- = QString::fromLocal8Bit(m_qbsStdout.trimmed()).split('\n', QString::SkipEmptyParts);
+ = QString::fromLocal8Bit(m_qbsStdout.trimmed()).split('\n', Qt::SkipEmptyParts);
QVERIFY2(outputLines.contains(projectDir + '/' + relativeProductBuildDir("p1")),
m_qbsStdout.constData());
QVERIFY2(outputLines.contains(projectDir + '/' + relativeProductBuildDir("p2")),
@@ -649,6 +727,45 @@ void TestBlackbox::buildDirectories()
QVERIFY2(outputLines.contains(projectDir), m_qbsStdout.constData());
}
+void TestBlackbox::buildDirPlaceholders_data()
+{
+ QTest::addColumn<QString>("buildDir");
+ QTest::addColumn<bool>("setProjectFile");
+ QTest::addColumn<bool>("successExpected");
+
+ QTest::newRow("normal dir, with project file") << "somedir" << true << true;
+ QTest::newRow("normal dir, without project file") << "somedir" << false << true;
+ QTest::newRow("@project, with project file") << "somedir/@project" << true << true;
+ QTest::newRow("@project, without project file") << "somedir/@project" << false << false;
+ QTest::newRow("@path, with project file") << "somedir/@path" << true << true;
+ QTest::newRow("@path, without project file") << "somedir/@path" << false << false;
+}
+
+void TestBlackbox::buildDirPlaceholders()
+{
+ QFETCH(QString, buildDir);
+ QFETCH(bool, setProjectFile);
+ QFETCH(bool, successExpected);
+
+ const QString projectDir = testDataDir + "/build-dir-placeholders";
+ rmDirR(projectDir);
+ QVERIFY(QDir().mkpath(projectDir));
+ QDir::setCurrent(projectDir);
+ QFile projectFile("build-dir-placeholders.qbs");
+ QVERIFY(projectFile.open(QIODevice::WriteOnly));
+ projectFile.write("Product {\n}\n");
+ projectFile.flush();
+ rmDirR(relativeBuildDir());
+ QbsRunParameters params;
+ params.buildDirectory = buildDir;
+ if (setProjectFile) {
+ params.arguments << "-f"
+ << "build-dir-placeholders.qbs";
+ }
+ params.expectFailure = !successExpected;
+ QCOMPARE(runQbs(params) == 0, successExpected);
+}
+
void TestBlackbox::buildEnvChange()
{
QDir::setCurrent(testDataDir + "/buildenv-change");
@@ -713,6 +830,69 @@ void TestBlackbox::buildGraphVersions()
QVERIFY2(m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
}
+void TestBlackbox::buildVariantDefaults_data()
+{
+ QTest::addColumn<QString>("buildVariant");
+ QTest::newRow("default") << QString();
+ QTest::newRow("debug") << QStringLiteral("debug");
+ QTest::newRow("release") << QStringLiteral("release");
+ QTest::newRow("profiling") << QStringLiteral("profiling");
+}
+
+void TestBlackbox::buildVariantDefaults()
+{
+ QFETCH(QString, buildVariant);
+ QDir::setCurrent(testDataDir + "/build-variant-defaults");
+ QbsRunParameters params{QStringLiteral("resolve")};
+ if (!buildVariant.isEmpty())
+ params.arguments << ("modules.qbs.buildVariant:" + buildVariant);
+ QCOMPARE(runQbs(params), 0);
+}
+
+void TestBlackbox::capnproto()
+{
+ QFETCH(QString, projectFile);
+ QFETCH(QStringList, arguments);
+ QDir::setCurrent(testDataDir + "/capnproto");
+ rmDirR(relativeBuildDir());
+
+ if (QTest::currentDataTag() == QLatin1String("cpp-conan")
+ || QTest::currentDataTag() == QLatin1String("rpc-conan")) {
+ if (!prepareAndRunConan())
+ QSKIP("conan is not prepared, check messages above");
+ }
+
+ QbsRunParameters params{QStringLiteral("resolve"), {QStringLiteral("-f"), projectFile}};
+ params.arguments << arguments;
+ QCOMPARE(runQbs(params), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ if (m_qbsStdout.contains("capnproto is not present"))
+ QSKIP("capnproto is not present");
+
+ params.command = QStringLiteral("build");
+ QCOMPARE(runQbs(params), 0);
+}
+
+void TestBlackbox::capnproto_data()
+{
+ QTest::addColumn<QString>("projectFile");
+ QTest::addColumn<QStringList>("arguments");
+
+ QStringList pkgConfigArgs({"project.qbsModuleProviders:qbspkgconfig"});
+ QTest::newRow("cpp-pkgconfig") << QStringLiteral("capnproto_cpp.qbs") << pkgConfigArgs;
+ QTest::newRow("rpc-pkgconfig") << QStringLiteral("greeter_cpp.qbs") << pkgConfigArgs;
+ QTest::newRow("relative import")
+ << QStringLiteral("capnproto_relative_import.qbs") << pkgConfigArgs;
+ QTest::newRow("absolute import")
+ << QStringLiteral("capnproto_absolute_import.qbs") << pkgConfigArgs;
+
+ QStringList conanArgs(
+ {"project.qbsModuleProviders:conan", "moduleProviders.conan.installDirectory:build"});
+ QTest::newRow("cpp-conan") << QStringLiteral("capnproto_cpp.qbs") << conanArgs;
+ QTest::newRow("rpc-conan") << QStringLiteral("greeter_cpp.qbs") << conanArgs;
+}
+
void TestBlackbox::changedFiles_data()
{
QTest::addColumn<bool>("useChangedFilesForInitialBuild");
@@ -885,7 +1065,7 @@ void TestBlackbox::dependenciesProperty()
QJsonArray cpp_dependencies = product2_cpp.value("dependencies").toArray();
QVERIFY(!cpp_dependencies.isEmpty());
int qbsCount = 0;
- for (const auto &dep : cpp_dependencies) {
+ for (const auto dep : cpp_dependencies) {
if (dep.toObject().value("name").toString() == "qbs")
++qbsCount;
}
@@ -897,7 +1077,7 @@ void TestBlackbox::dependenciesProperty()
REPLACE_IN_FILE(projectFile, "// Depends { name: 'newDependency' }",
"Depends { name: 'newDependency' }");
QCOMPARE(runQbs(), 0);
- QVERIFY2(m_qbsStdout.contains("generate product1.deps"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("generating product1.deps"), m_qbsStdout.constData());
readDepsOutput(depsFile, jsondoc);
dependencies = jsondoc.array();
QCOMPARE(dependencies.size(), 3);
@@ -908,7 +1088,7 @@ void TestBlackbox::dependenciesProperty()
REPLACE_IN_FILE(projectFile, "// Depends { name: 'product2' }", "Depends { name: 'product2' }");
QCOMPARE(runQbs(), 0);
QVERIFY2(m_qbsStdout.contains("Resolving"), m_qbsStdout.constData());
- QVERIFY2(!m_qbsStdout.contains("generate product1.deps"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("generating product1.deps"), m_qbsStdout.constData());
readDepsOutput(depsFile, jsondoc);
dependencies = jsondoc.array();
QCOMPARE(dependencies.size(), 3);
@@ -918,7 +1098,7 @@ void TestBlackbox::dependenciesProperty()
0);
QCOMPARE(runQbs(), 0);
QVERIFY2(!m_qbsStdout.contains("compiling product2.cpp"), m_qbsStdout.constData());
- QVERIFY2(m_qbsStdout.contains("generate product1.deps"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("generating product1.deps"), m_qbsStdout.constData());
readDepsOutput(depsFile, jsondoc);
dependencies = jsondoc.array();
QCOMPARE(dependencies.size(), 3);
@@ -930,7 +1110,7 @@ void TestBlackbox::dependenciesProperty()
"products.product2.cpp.defines:DIGEDAG"})), 0);
QCOMPARE(runQbs(), 0);
QVERIFY2(m_qbsStdout.contains("compiling product2.cpp"), m_qbsStdout.constData());
- QVERIFY2(m_qbsStdout.contains("generate product1.deps"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("generating product1.deps"), m_qbsStdout.constData());
readDepsOutput(depsFile, jsondoc);
dependencies = jsondoc.array();
QCOMPARE(dependencies.size(), 3);
@@ -942,40 +1122,77 @@ void TestBlackbox::dependenciesProperty()
QCOMPARE(product2_cpp_defines.first().toString(), QLatin1String("DIGEDAG"));
}
-void TestBlackbox::dependencyProfileMismatch()
+void TestBlackbox::dependencyScanningLoop()
{
- QDir::setCurrent(testDataDir + "/dependency-profile-mismatch");
- const SettingsPtr s = settings();
- qbs::Internal::TemporaryProfile depProfile("qbs_autotests_profileMismatch", s.get());
- depProfile.p.setValue("qbs.architecture", "x86"); // Profiles must not be empty...
- s->sync();
- QbsRunParameters params(QStringList() << ("project.mainProfile:" + profileName())
- << ("project.depProfile:" + depProfile.p.name()));
- params.expectFailure = true;
- QVERIFY2(runQbs(params) != 0, m_qbsStderr.constData());
- QVERIFY2(m_qbsStderr.contains(profileName().toLocal8Bit())
- && m_qbsStderr.contains("', which does not exist"),
- m_qbsStderr.constData());
+ QDir::setCurrent(testDataDir + "/dependency-scanning-loop");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY2(m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
}
void TestBlackbox::deprecatedProperty()
{
+ QFETCH(QString, version);
+ QFETCH(QString, mode);
+ QFETCH(bool, expiringWarning);
+ QFETCH(bool, expiringError);
+
QDir::setCurrent(testDataDir + "/deprecated-property");
QbsRunParameters params(QStringList("-q"));
params.expectFailure = true;
+ params.environment.insert("REMOVAL_VERSION", version);
+ if (!mode.isEmpty())
+ params.arguments << "--deprecation-warnings" << mode;
QVERIFY(runQbs(params) != 0);
m_qbsStderr = QDir::fromNativeSeparators(QString::fromLocal8Bit(m_qbsStderr)).toLocal8Bit();
- QVERIFY2(m_qbsStderr.contains("deprecated-property.qbs:6:24 The property 'oldProp' is "
- "deprecated and will be removed in Qbs 99.9.0."), m_qbsStderr.constData());
- QVERIFY2(m_qbsStderr.contains("deprecated-property.qbs:7:28 The property 'veryOldProp' can no "
- "longer be used. It was removed in Qbs 1.3.0."), m_qbsStderr.constData());
+ const bool hasExpiringWarning = m_qbsStderr.contains(QByteArray(
+ "deprecated-property.qbs:4:29 The property 'expiringProp' is "
+ "deprecated and will be removed in Qbs ") + version.toLocal8Bit());
+ QVERIFY2(expiringWarning == hasExpiringWarning, m_qbsStderr.constData());
+ const bool hasRemovedOutput = m_qbsStderr.contains(
+ "deprecated-property.qbs:5:28 The property 'veryOldProp' can no "
+ "longer be used. It was removed in Qbs 1.3.0.");
+ QVERIFY2(hasRemovedOutput == !expiringError, m_qbsStderr.constData());
QVERIFY2(m_qbsStderr.contains("Property 'forgottenProp' was scheduled for removal in version "
"1.8.0, but is still present."), m_qbsStderr.constData());
QVERIFY2(m_qbsStderr.contains("themodule/m.qbs:22:5 Removal version for 'forgottenProp' "
"specified here."), m_qbsStderr.constData());
- QVERIFY2(m_qbsStderr.count("Use newProp instead.") == 2, m_qbsStderr.constData());
- QVERIFY2(m_qbsStderr.count("is deprecated") == 1, m_qbsStderr.constData());
- QVERIFY2(m_qbsStderr.count("was removed") == 1, m_qbsStderr.constData());
+ QVERIFY2(m_qbsStderr.count("Use newProp instead.") == 1
+ + int(expiringWarning && !expiringError), m_qbsStderr.constData());
+ QVERIFY2(m_qbsStderr.count("is deprecated") == int(expiringWarning), m_qbsStderr.constData());
+ QVERIFY2(m_qbsStderr.count("was removed") == int(!expiringError), m_qbsStderr.constData());
+}
+
+void TestBlackbox::deprecatedProperty_data()
+{
+ QTest::addColumn<QString>("version");
+ QTest::addColumn<QString>("mode");
+ QTest::addColumn<bool>("expiringWarning");
+ QTest::addColumn<bool>("expiringError");
+
+ const auto current = QVersionNumber::fromString(QBS_VERSION);
+ const QString next = QVersionNumber(current.majorVersion(), current.minorVersion() + 1)
+ .toString();
+ const QString nextNext = QVersionNumber(current.majorVersion(), current.minorVersion() + 2)
+ .toString();
+ const QString nextMajor = QVersionNumber(current.majorVersion() + 1).toString();
+
+ QTest::newRow("default/next") << next << QString() << true << false;
+ QTest::newRow("default/nextnext") << nextNext << QString() << false << false;
+ QTest::newRow("default/nextmajor") << nextMajor << QString() << true << false;
+ QTest::newRow("error/next") << next << QString("error") << true << true;
+ QTest::newRow("error/nextnext") << nextNext << QString("error") << true << true;
+ QTest::newRow("error/nextmajor") << nextMajor << QString("error") << true << true;
+ QTest::newRow("on/next") << next << QString("on") << true << false;
+ QTest::newRow("on/nextnext") << nextNext << QString("on") << true << false;
+ QTest::newRow("on/nextmajor") << nextMajor << QString("on") << true << false;
+ QTest::newRow("before-removal/next") << next << QString("before-removal") << true << false;
+ QTest::newRow("before-removal/nextnext") << nextNext << QString("before-removal")
+ << false << false;
+ QTest::newRow("before-removal/nextmajor") << nextMajor << QString("before-removal")
+ << true << false;
+ QTest::newRow("off/next") << next << QString("off") << false << false;
+ QTest::newRow("off/nextnext") << nextNext << QString("off") << false << false;
+ QTest::newRow("off/nextmajor") << nextMajor << QString("off") << false << false;
}
void TestBlackbox::disappearedProfile()
@@ -1008,16 +1225,16 @@ void TestBlackbox::disappearedProfile()
QbsRunParameters buildParams;
buildParams.profile.clear();
QCOMPARE(runQbs(buildParams), 0);
- QVERIFY2(m_qbsStdout.contains("Creating dummy1.txt with p1 from profile"),
+ QVERIFY2(m_qbsStdout.contains("creating dummy1.txt with p1 from profile"),
m_qbsStdout.constData());
- QVERIFY2(m_qbsStdout.contains("Creating dummy2.txt with p2 from profile"),
+ QVERIFY2(m_qbsStdout.contains("creating dummy2.txt with p2 from profile"),
m_qbsStdout.constData());
// Now we do use the "resolve" command, so the new property value is taken into account.
QCOMPARE(runQbs(resolveParams), 0);
QCOMPARE(runQbs(buildParams), 0);
- QVERIFY2(!m_qbsStdout.contains("Creating dummy1.txt"), m_qbsStdout.constData());
- QVERIFY2(m_qbsStdout.contains("Creating dummy2.txt with p2 new from profile"),
+ QVERIFY2(!m_qbsStdout.contains("creating dummy1.txt"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("creating dummy2.txt with p2 new from profile"),
m_qbsStdout.constData());
// Now we change the profile again without a "resolve" command. However, this time we
@@ -1030,8 +1247,8 @@ void TestBlackbox::disappearedProfile()
"property string p1: 'p1 from module'");
QCOMPARE(runQbs(buildParams), 0);
QVERIFY2(m_qbsStdout.contains("Resolving"), m_qbsStdout.constData());
- QVERIFY2(!m_qbsStdout.contains("Creating dummy1.txt"), m_qbsStdout.constData());
- QVERIFY2(!m_qbsStdout.contains("Creating dummy2.txt"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("creating dummy1.txt"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("creating dummy2.txt"), m_qbsStdout.constData());
// Now we run the "resolve" command without giving the necessary settings path to find
// the profile.
@@ -1055,10 +1272,12 @@ void TestBlackbox::discardUnusedData()
QVERIFY2(m_qbsStdout.contains("is Darwin"), m_qbsStdout.constData());
const bool isDarwin = m_qbsStdout.contains("is Darwin: true");
const QString output = QString::fromLocal8Bit(m_qbsStdout);
- QRegExp pattern(".*---(.*)---.*");
- QVERIFY2(pattern.exactMatch(output), qPrintable(output));
- QCOMPARE(pattern.captureCount(), 1);
- const QString nmPath = pattern.capturedTexts().at(1);
+ const QRegularExpression pattern(QRegularExpression::anchoredPattern(".*---(.*)---.*"),
+ QRegularExpression::DotMatchesEverythingOption);
+ const QRegularExpressionMatch match = pattern.match(output);
+ QVERIFY2(match.hasMatch(), qPrintable(output));
+ QCOMPARE(match.lastCapturedIndex(), 1);
+ const QString nmPath = match.captured(1);
if (!QFile::exists(nmPath))
QSKIP("Cannot check for symbol presence: No nm found.");
QProcess nm;
@@ -1082,6 +1301,13 @@ void TestBlackbox::discardUnusedData_data()
QTest::newRow("default") << QString() << true;
}
+void TestBlackbox::dotDotPcFile()
+{
+ QDir::setCurrent(testDataDir + "/dot-dot-pc-file");
+
+ QCOMPARE(runQbs(), 0);
+}
+
void TestBlackbox::driverLinkerFlags()
{
QDir::setCurrent(testDataDir + QLatin1String("/driver-linker-flags"));
@@ -1124,9 +1350,13 @@ void TestBlackbox::dynamicLibraryInModule()
QbsRunParameters libParams(QStringList({"-f", "thelibs.qbs", installRootSpec}));
libParams.buildDirectory = "libbuild";
QCOMPARE(runQbs(libParams), 0);
- QbsRunParameters appParams("run", QStringList({"-f", "theapp.qbs", installRootSpec}));
+ QbsRunParameters appParams("build", QStringList({"-f", "theapp.qbs", installRootSpec}));
appParams.buildDirectory = "appbuild";
QCOMPARE(runQbs(appParams), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ appParams.command = "run";
+ QCOMPARE(runQbs(appParams), 0);
QVERIFY2(m_qbsStdout.contains("Hello from thelib"), m_qbsStdout.constData());
QVERIFY2(m_qbsStdout.contains("Hello from theotherlib"), m_qbsStdout.constData());
QVERIFY2(!m_qbsStdout.contains("thirdlib"), m_qbsStdout.constData());
@@ -1232,19 +1462,6 @@ void TestBlackbox::variantSuffix_data()
std::make_pair(QString("unix"), QStringList())});
}
-static bool waitForProcessSuccess(QProcess &p)
-{
- if (!p.waitForStarted() || !p.waitForFinished()) {
- qDebug() << p.errorString();
- return false;
- }
- if (p.exitCode() != 0) {
- qDebug() << p.readAllStandardError();
- return false;
- }
- return true;
-}
-
void TestBlackbox::vcsGit()
{
const QString gitFilePath = findExecutable(QStringList("git"));
@@ -1275,6 +1492,9 @@ void TestBlackbox::vcsGit()
return m_qbsStdout.mid(startIndex + 2, endIndex - startIndex - 2);
};
+ QCOMPARE(runQbs({"resolve", {"-f", repoDir.path()}}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
// Run without git metadata.
QbsRunParameters params("run", QStringList{"-f", repoDir.path()});
params.workingDir = repoDir.path() + "/..";
@@ -1340,6 +1560,9 @@ void TestBlackbox::vcsSubversion()
if (svnFilePath.isEmpty())
QSKIP("svn not found");
+ if (HostOsInfo::isWindowsHost() && qEnvironmentVariableIsSet("GITHUB_ACTIONS"))
+ QSKIP("Skip this test when running on GitHub");
+
// Set up repo.
QTemporaryDir repoDir;
QVERIFY(repoDir.isValid());
@@ -1363,6 +1586,8 @@ void TestBlackbox::vcsSubversion()
failParams.command = "run";
failParams.expectFailure = true;
const int retval = runQbs(failParams);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
if (m_qbsStderr.contains("svn too old"))
QSKIP("svn too old");
QCOMPARE(retval, 0);
@@ -1431,19 +1656,21 @@ void TestBlackbox::versionCheck_data()
void TestBlackbox::versionScript()
{
- const SettingsPtr s = settings();
- Profile buildProfile(profileName(), s.get());
- QStringList toolchain = buildProfile.value("qbs.toolchain").toStringList();
- if (!toolchain.contains("gcc") || targetOs() != HostOsInfo::HostOsLinux)
- QSKIP("version script test only applies to Linux");
QDir::setCurrent(testDataDir + "/versionscript");
- QCOMPARE(runQbs(QbsRunParameters(QStringList("-q")
- << ("qbs.installRoot:" + QDir::currentPath()))), 0);
+ QCOMPARE(runQbs(QbsRunParameters("resolve", {"qbs.installRoot:" + QDir::currentPath()})), 0);
+ const bool isLinuxGcc = m_qbsStdout.contains("is gcc for Linux: true");
+ const bool isNotLinuxGcc = m_qbsStdout.contains("is gcc for Linux: false");
+ if (isNotLinuxGcc)
+ QSKIP("version script test only applies to Linux");
+ QVERIFY(isLinuxGcc);
+ QCOMPARE(runQbs(QbsRunParameters(QStringList("-q"))), 0);
const QString output = QString::fromLocal8Bit(m_qbsStderr);
- QRegExp pattern(".*---(.*)---.*");
- QVERIFY2(pattern.exactMatch(output), qPrintable(output));
+ const QRegularExpression pattern(QRegularExpression::anchoredPattern(".*---(.*)---.*"),
+ QRegularExpression::DotMatchesEverythingOption);
+ const QRegularExpressionMatch match = pattern.match(output);
+ QVERIFY2(match.hasMatch(), qPrintable(output));
QCOMPARE(pattern.captureCount(), 1);
- const QString nmPath = pattern.capturedTexts().at(1);
+ const QString nmPath = match.captured(1);
if (!QFile::exists(nmPath))
QSKIP("Cannot check for symbol presence: No nm found.");
QProcess nm;
@@ -1554,7 +1781,7 @@ void TestBlackbox::clean()
QVERIFY(!QFile(appExeFilePath).exists());
QVERIFY(!QFile(depObjectFilePath).exists());
QVERIFY(!QFile(depLibFilePath).exists());
- for (const QString &symLink : qAsConst(symlinks))
+ for (const QString &symLink : std::as_const(symlinks))
QVERIFY2(!symlinkExists(symLink), qPrintable(symLink));
// Remove all, with a forced re-resolve in between.
@@ -1573,7 +1800,7 @@ void TestBlackbox::clean()
QVERIFY(!QFile(appExeFilePath).exists());
QVERIFY(!QFile(depObjectFilePath).exists());
QVERIFY(!QFile(depLibFilePath).exists());
- for (const QString &symLink : qAsConst(symlinks))
+ for (const QString &symLink : std::as_const(symlinks))
QVERIFY2(!symlinkExists(symLink), qPrintable(symLink));
// Dry run.
@@ -1585,7 +1812,7 @@ void TestBlackbox::clean()
QVERIFY(regularFileExists(appExeFilePath));
QVERIFY(regularFileExists(depObjectFilePath));
QVERIFY(regularFileExists(depLibFilePath));
- for (const QString &symLink : qAsConst(symlinks))
+ for (const QString &symLink : std::as_const(symlinks))
QVERIFY2(symlinkExists(symLink), qPrintable(symLink));
// Product-wise, dependency only.
@@ -1599,7 +1826,7 @@ void TestBlackbox::clean()
QVERIFY(regularFileExists(appExeFilePath));
QVERIFY(!QFile(depObjectFilePath).exists());
QVERIFY(!QFile(depLibFilePath).exists());
- for (const QString &symLink : qAsConst(symlinks))
+ for (const QString &symLink : std::as_const(symlinks))
QVERIFY2(!symlinkExists(symLink), qPrintable(symLink));
// Product-wise, dependent product only.
@@ -1613,17 +1840,10 @@ void TestBlackbox::clean()
QVERIFY(!QFile(appExeFilePath).exists());
QVERIFY(regularFileExists(depObjectFilePath));
QVERIFY(regularFileExists(depLibFilePath));
- for (const QString &symLink : qAsConst(symlinks))
+ for (const QString &symLink : std::as_const(symlinks))
QVERIFY2(symlinkExists(symLink), qPrintable(symLink));
}
-void TestBlackbox::concurrentExecutor()
-{
- QDir::setCurrent(testDataDir + "/concurrent-executor");
- QCOMPARE(runQbs(QStringList() << "-j" << "2"), 0);
- QVERIFY2(!m_qbsStderr.contains("ASSERT"), m_qbsStderr.constData());
-}
-
void TestBlackbox::conditionalExport()
{
QDir::setCurrent(testDataDir + "/conditional-export");
@@ -1657,6 +1877,9 @@ void TestBlackbox::conditionalFileTagger()
void TestBlackbox::configure()
{
QDir::setCurrent(testDataDir + "/configure");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters params;
params.command = "run";
QCOMPARE(runQbs(params), 0);
@@ -1753,6 +1976,92 @@ void TestBlackbox::cxxLanguageVersion_data()
std::make_pair(QString("msvc-new"), QString("/std:"))});
}
+void TestBlackbox::conanfileProbe_data()
+{
+ QTest::addColumn<bool>("forceFailure");
+
+ QTest::newRow("success") << false;
+ QTest::newRow("failure") << true;
+}
+
+void TestBlackbox::conanfileProbe()
+{
+ QFETCH(bool, forceFailure);
+
+ if (qEnvironmentVariableIsSet("GITHUB_ACTIONS"))
+ QSKIP("Skip this test when running on GitHub");
+
+ QString executable = findExecutable({"conan"});
+ if (executable.isEmpty())
+ QSKIP("conan is not installed or not available in PATH.");
+
+ // We first build a dummy package testlib and use that as dependency
+ // in the testapp package.
+ QDir::setCurrent(testDataDir + "/conanfile-probe/testlib");
+ QStringList arguments { "create", "-o", "opt=True", "-s", "os=AIX", ".",
+ "testlib/1.2.3@qbs/testing" };
+ QProcess conan;
+ conan.start(executable, arguments);
+ QVERIFY(waitForProcessSuccess(conan));
+
+ QDir::setCurrent(testDataDir + "/conanfile-probe/testapp");
+ QCOMPARE(runQbs(QbsRunParameters("resolve",
+ {"--force-probe-execution",
+ QStringLiteral("projects.conanfile-probe-project.forceFailure:") +
+ (forceFailure ? "true" : "false")})), forceFailure ? 1 : 0);
+
+ QFile file(relativeBuildDir() + "/results.json");
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QVariantMap actualResults = QJsonDocument::fromJson(file.readAll()).toVariant().toMap();
+ const auto generatedFilesPath = actualResults.take("generatedFilesPath").toString();
+ // We want to make sure that generatedFilesPath is under the project directory,
+ // but we don't care about the actual name.
+ QVERIFY(directoryExists(relativeBuildDir() + "/genconan/"
+ + QFileInfo(generatedFilesPath).baseName()));
+
+ const QVariantMap expectedResults = {
+ { "json", "TESTLIB_ENV_VAL" },
+ { "dependencies", QVariantList{"testlib1", "testlib2"} },
+ };
+ QCOMPARE(actualResults, expectedResults);
+}
+
+void TestBlackbox::conflictingPropertyValues_data()
+{
+ QTest::addColumn<bool>("overrideInProduct");
+ QTest::newRow("don't override in product") << false;
+ QTest::newRow("override in product") << true;
+}
+
+void TestBlackbox::conflictingPropertyValues()
+{
+ QFETCH(bool, overrideInProduct);
+
+ QDir::setCurrent(testDataDir + "/conflicting-property-values");
+ if (overrideInProduct)
+ REPLACE_IN_FILE("conflicting-property-values.qbs", "// low.prop: name", "low.prop: name");
+ else
+ REPLACE_IN_FILE("conflicting-property-values.qbs", "low.prop: name", "// low.prop: name");
+ WAIT_FOR_NEW_TIMESTAMP();
+ QCOMPARE(runQbs(QString("resolve")), 0);
+ if (overrideInProduct) {
+ // Binding in product itself overrides everything else, module-level conflicts
+ // are irrelevant.
+ QVERIFY2(m_qbsStdout.contains("final prop value: toplevel"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
+ } else {
+ // Only the conflicts in the highest-level modules are reported, lower-level conflicts
+ // are irrelevant.
+ // prop2 does not cause a conflict, because the values are the same.
+ QVERIFY2(m_qbsStdout.contains("final prop value: highest"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStderr.contains("Conflicting scalar values for property 'prop'"),
+ m_qbsStderr.constData());
+ QVERIFY2(m_qbsStderr.count("values.qbs") == 2, m_qbsStderr.constData());
+ QVERIFY2(m_qbsStderr.contains("values.qbs:20:23"), m_qbsStderr.constData());
+ QVERIFY2(m_qbsStderr.contains("values.qbs:30:23"), m_qbsStderr.constData());
+ }
+}
+
void TestBlackbox::cpuFeatures()
{
QDir::setCurrent(testDataDir + "/cpu-features");
@@ -1784,6 +2093,13 @@ void TestBlackbox::cpuFeatures()
}
}
+void TestBlackbox::dateProperty()
+{
+ QDir::setCurrent(testDataDir + "/date-property");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY2(m_qbsStdout.contains("The stored date was 1999-12-31"), m_qbsStdout.constData());
+}
+
void TestBlackbox::renameDependency()
{
QDir::setCurrent(testDataDir + "/renameDependency");
@@ -1811,13 +2127,19 @@ void TestBlackbox::separateDebugInfo()
const bool isWindows = m_qbsStdout.contains("is windows: yes");
const bool isNotWindows = m_qbsStdout.contains("is windows: no");
QVERIFY(isWindows != isNotWindows);
+ const bool isMacos = m_qbsStdout.contains("is macos: yes");
+ const bool isNotMacos = m_qbsStdout.contains("is macos: no");
+ QVERIFY(isMacos != isNotMacos);
const bool isDarwin = m_qbsStdout.contains("is darwin: yes");
const bool isNotDarwin = m_qbsStdout.contains("is darwin: no");
QVERIFY(isDarwin != isNotDarwin);
+ const bool isGcc = m_qbsStdout.contains("is gcc: yes");
+ const bool isNotGcc = m_qbsStdout.contains("is gcc: no");
+ QVERIFY(isGcc != isNotGcc);
+ const bool isMsvc = m_qbsStdout.contains("is msvc: yes");
+ const bool isNotMsvc = m_qbsStdout.contains("is msvc: no");
+ QVERIFY(isMsvc != isNotMsvc);
- const SettingsPtr s = settings();
- Profile buildProfile(profileName(), s.get());
- QStringList toolchain = buildProfile.value("qbs.toolchain").toStringList();
if (isDarwin) {
QVERIFY(directoryExists(relativeProductBuildDir("app1") + "/app1.app.dSYM"));
QVERIFY(regularFileExists(relativeProductBuildDir("app1")
@@ -1829,8 +2151,13 @@ void TestBlackbox::separateDebugInfo()
.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).size(), 1);
QVERIFY(!QFile::exists(relativeProductBuildDir("app2") + "/app2.app.dSYM"));
QVERIFY(!QFile::exists(relativeProductBuildDir("app3") + "/app3.app.dSYM"));
- QVERIFY(regularFileExists(relativeProductBuildDir("app3")
- + "/app3.app/Contents/MacOS/app3.dwarf"));
+ if (isMacos) {
+ QVERIFY(regularFileExists(relativeProductBuildDir("app3")
+ + "/app3.app/Contents/MacOS/app3.dwarf"));
+ } else {
+ QVERIFY(regularFileExists(relativeProductBuildDir("app3")
+ + "/app3.app/app3.dwarf"));
+ }
QVERIFY(directoryExists(relativeProductBuildDir("app4") + "/app4.dSYM"));
QVERIFY(regularFileExists(relativeProductBuildDir("app4")
+ "/app4.dSYM/Contents/Info.plist"));
@@ -1850,8 +2177,13 @@ void TestBlackbox::separateDebugInfo()
.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).size(), 1);
QVERIFY(!QFile::exists(relativeProductBuildDir("foo2") + "/foo2.framework.dSYM"));
QVERIFY(!QFile::exists(relativeProductBuildDir("foo3") + "/foo3.framework.dSYM"));
- QVERIFY(regularFileExists(relativeProductBuildDir("foo3")
- + "/foo3.framework/Versions/A/foo3.dwarf"));
+ if (isMacos) {
+ QVERIFY(regularFileExists(relativeProductBuildDir("foo3")
+ + "/foo3.framework/Versions/A/foo3.dwarf"));
+ } else {
+ QVERIFY(regularFileExists(relativeProductBuildDir("foo3")
+ + "/foo3.framework/foo3.dwarf"));
+ }
QVERIFY(directoryExists(relativeProductBuildDir("foo4") + "/libfoo4.dylib.dSYM"));
QVERIFY(regularFileExists(relativeProductBuildDir("foo4")
+ "/libfoo4.dylib.dSYM/Contents/Info.plist"));
@@ -1871,8 +2203,13 @@ void TestBlackbox::separateDebugInfo()
.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).size(), 1);
QVERIFY(!QFile::exists(relativeProductBuildDir("bar2") + "/bar2.bundle.dSYM"));
QVERIFY(!QFile::exists(relativeProductBuildDir("bar3") + "/bar3.bundle.dSYM"));
- QVERIFY(regularFileExists(relativeProductBuildDir("bar3")
- + "/bar3.bundle/Contents/MacOS/bar3.dwarf"));
+ if (isMacos) {
+ QVERIFY(regularFileExists(relativeProductBuildDir("bar3")
+ + "/bar3.bundle/Contents/MacOS/bar3.dwarf"));
+ } else {
+ QVERIFY(regularFileExists(relativeProductBuildDir("bar3")
+ + "/bar3.bundle/bar3.dwarf"));
+ }
QVERIFY(directoryExists(relativeProductBuildDir("bar4") + "/bar4.bundle.dSYM"));
QVERIFY(regularFileExists(relativeProductBuildDir("bar4")
+ "/bar4.bundle.dSYM/Contents/Info.plist"));
@@ -1882,7 +2219,7 @@ void TestBlackbox::separateDebugInfo()
+ "/bar4.bundle.dSYM/Contents/Resources/DWARF")
.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).size(), 1);
QVERIFY(regularFileExists(relativeProductBuildDir("bar5") + "/bar5.bundle.dwarf"));
- } else if (toolchain.contains("gcc")) {
+ } else if (isGcc) {
const QString exeSuffix = isWindows ? ".exe" : "";
const QString dllPrefix = isWindows ? "" : "lib";
const QString dllSuffix = isWindows ? ".dll" : ".so";
@@ -1896,7 +2233,7 @@ void TestBlackbox::separateDebugInfo()
+ '/' + dllPrefix + "bar1" + dllSuffix + ".debug"));
QVERIFY(!QFile::exists(relativeProductBuildDir("bar2")
+ '/' + dllPrefix + "bar2" + dllSuffix + ".debug"));
- } else if (toolchain.contains("msvc")) {
+ } else if (isMsvc) {
QVERIFY(QFile::exists(relativeProductBuildDir("app1") + "/app1.pdb"));
QVERIFY(QFile::exists(relativeProductBuildDir("foo1") + "/foo1.pdb"));
QVERIFY(QFile::exists(relativeProductBuildDir("bar1") + "/bar1.pdb"));
@@ -1915,6 +2252,9 @@ void TestBlackbox::trackAddFile()
QDir().mkdir("work");
ccp("before", "work");
QDir::setCurrent(testDataDir + "/trackAddFile/work");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
const QbsRunParameters runParams("run", QStringList{"-qp", "someapp"});
QCOMPARE(runQbs(runParams), 0);
@@ -1950,6 +2290,9 @@ void TestBlackbox::trackExternalProductChanges()
QVERIFY(!m_qbsStdout.contains("compiling jsFileChange.cpp"));
QVERIFY(!m_qbsStdout.contains("compiling fileExists.cpp"));
+ const bool isGcc = m_qbsStdout.contains("is gcc: true");
+ const bool isNotGcc = m_qbsStdout.contains("is gcc: false");
+
QbsRunParameters params;
params.environment.insert("QBS_TEST_PULL_IN_FILE_VIA_ENV", "1");
QCOMPARE(runQbs(params), 0);
@@ -1999,13 +2342,12 @@ void TestBlackbox::trackExternalProductChanges()
QVERIFY(!m_qbsStdout.contains("compiling jsFileChange.cpp"));
QVERIFY(m_qbsStdout.contains("compiling fileExists.cpp"));
+ if (isNotGcc)
+ QSKIP("The remainder of this test requires a GCC-like toolchain");
+ QVERIFY(isGcc);
+
rmDirR(relativeBuildDir());
- const SettingsPtr s = settings();
- const Profile profile(profileName(), s.get());
- const QStringList toolchainTypes = profile.value("qbs.toolchain").toStringList();
- if (!toolchainTypes.contains("gcc"))
- QSKIP("Need GCC-like compiler to run this test");
- params.environment = QProcessEnvironment::systemEnvironment();
+ params.environment = QbsRunParameters::defaultEnvironment();
params.environment.insert("INCLUDE_PATH_TEST", "1");
params.expectFailure = true;
QVERIFY(runQbs(params) != 0);
@@ -2044,6 +2386,9 @@ void TestBlackbox::trackRemoveFile()
ccp("before", "work");
ccp("after", "work");
QDir::setCurrent(testDataDir + "/trackAddFile/work");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
const QbsRunParameters runParams("run", QStringList{"-qp", "someapp"});
QCOMPARE(runQbs(runParams), 0);
output = m_qbsStdout.split('\n');
@@ -2088,6 +2433,9 @@ void TestBlackbox::trackAddFileTag()
QDir().mkdir("work");
ccp("before", "work");
QDir::setCurrent(testDataDir + "/trackFileTags/work");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
const QbsRunParameters runParams("run", QStringList{"-qp", "someapp"});
QCOMPARE(runQbs(runParams), 0);
output = m_qbsStdout.split('\n');
@@ -2112,6 +2460,9 @@ void TestBlackbox::trackRemoveFileTag()
QDir().mkdir("work");
ccp("after", "work");
QDir::setCurrent(testDataDir + "/trackFileTags/work");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
const QbsRunParameters runParams("run", QStringList{"-qp", "someapp"});
QCOMPARE(runQbs(runParams), 0);
@@ -2260,8 +2611,8 @@ void TestBlackbox::referenceErrorInExport()
QbsRunParameters params;
params.expectFailure = true;
QVERIFY(runQbs(params) != 0);
- QVERIFY(m_qbsStderr.contains(
- "referenceErrorInExport.qbs:15:12 ReferenceError: Can't find variable: includePaths"));
+ QVERIFY2(m_qbsStderr.contains("referenceErrorInExport.qbs:5:27 'includePaths' is not defined"),
+ m_qbsStderr.constData());
}
void TestBlackbox::removeDuplicateLibraries_data()
@@ -2288,20 +2639,21 @@ void TestBlackbox::removeDuplicateLibraries()
void TestBlackbox::reproducibleBuild()
{
- const SettingsPtr s = settings();
- const Profile profile(profileName(), s.get());
- const QStringList toolchains = profile.value("qbs.toolchain").toStringList();
- if (!toolchains.contains("gcc") || toolchains.contains("clang"))
- QSKIP("reproducible builds only supported for gcc");
-
QFETCH(bool, reproducible);
QDir::setCurrent(testDataDir + "/reproducible-build");
- QbsRunParameters params;
+ QbsRunParameters params("resolve");
params.arguments << QString("modules.cpp.enableReproducibleBuilds:")
+ (reproducible ? "true" : "false");
rmDirR(relativeBuildDir());
QCOMPARE(runQbs(params), 0);
+ const bool isGcc = m_qbsStdout.contains("is gcc: true");
+ const bool isNotGcc = m_qbsStdout.contains("is gcc: false");
+ if (isNotGcc)
+ QSKIP("reproducible builds only supported for gcc");
+ QVERIFY(isGcc);
+
+ QCOMPARE(runQbs(), 0);
QFile object(relativeProductBuildDir("the product") + '/' + inputDirHash(".") + '/'
+ objectFileName("file1.cpp", profileName()));
QVERIFY2(object.open(QIODevice::ReadOnly), qPrintable(object.fileName()));
@@ -2309,6 +2661,7 @@ void TestBlackbox::reproducibleBuild()
object.close();
QCOMPARE(runQbs(QbsRunParameters("clean")), 0);
QVERIFY(!object.exists());
+ params.command = "build";
QCOMPARE(runQbs(params), 0);
if (reproducible) {
QVERIFY(object.open(QIODevice::ReadOnly));
@@ -2329,6 +2682,9 @@ void TestBlackbox::reproducibleBuild_data()
void TestBlackbox::responseFiles()
{
QDir::setCurrent(testDataDir + "/response-files");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters params;
params.command = "install";
params.arguments << "--install-root" << "installed";
@@ -2367,6 +2723,32 @@ void TestBlackbox::retaggedOutputArtifact()
QVERIFY2(!QFile::exists(a3), qPrintable(a3));
}
+void TestBlackbox::rpathlinkDeduplication()
+{
+ QDir::setCurrent(testDataDir + "/rpathlink-deduplication");
+ QbsRunParameters resolveParams{"resolve"};
+ QCOMPARE(runQbs(resolveParams), 0);
+ const bool useRPathLink = m_qbsStdout.contains("useRPathLink: true");
+ const bool dontUseRPathLink = m_qbsStdout.contains("useRPathLink: false");
+ QVERIFY2(useRPathLink || dontUseRPathLink, m_qbsStdout);
+ if (dontUseRPathLink)
+ QSKIP("Only applies to toolchains that support rPathLink");
+ const QString output = QString::fromLocal8Bit(m_qbsStdout);
+ const QRegularExpression pattern(QRegularExpression::anchoredPattern(".*===(.*)===.*"),
+ QRegularExpression::DotMatchesEverythingOption);
+ const QRegularExpressionMatch match = pattern.match(output);
+ QVERIFY2(match.hasMatch(), qPrintable(output));
+ QCOMPARE(pattern.captureCount(), 1);
+ const QString linkFlag = match.captured(1);
+
+ QbsRunParameters buildParams;
+ buildParams.arguments = QStringList({"--command-echo-mode", "command-line"});
+ QCOMPARE(runQbs(buildParams), 0);
+ // private DynamicLibraryA is a dependency for 2 other libs but should only appear once
+ const auto libDir = QFileInfo(relativeProductBuildDir("DynamicLibraryA")).absoluteFilePath();
+ QCOMPARE(m_qbsStdout.count((linkFlag + libDir).toUtf8()), 1);
+}
+
void TestBlackbox::ruleConditions()
{
QDir::setCurrent(testDataDir + "/ruleConditions");
@@ -2444,11 +2826,60 @@ void TestBlackbox::ruleWithNonRequiredInputs()
output = outFile.readAll();
QCOMPARE(output, QByteArray("(a.inp,b.inp,c.inp,)"));
QCOMPARE(runQbs(), 0);
- QVERIFY2(!m_qbsStdout.contains("Generating"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("generating"), m_qbsStdout.constData());
WAIT_FOR_NEW_TIMESTAMP();
touch("a.inp");
QCOMPARE(runQbs(), 0);
- QVERIFY2(m_qbsStdout.contains("Generating"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("generating"), m_qbsStdout.constData());
+}
+
+void TestBlackbox::runMultiplexed()
+{
+ QDir::setCurrent(testDataDir + "/run-multiplexed");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+
+ QbsRunParameters params("run");
+ params.expectFailure = true;
+ QVERIFY(runQbs(params) != 0);
+ params.arguments = QStringList{"-p", "app"};
+ QVERIFY(runQbs(params) != 0);
+ params.expectFailure = false;
+ params.arguments.last() = "app {\"buildVariant\":\"debug\"}";
+ QCOMPARE(runQbs(params), 0);
+ params.arguments.last() = "app {\"buildVariant\":\"release\"}";
+ QCOMPARE(runQbs(params), 0);
+}
+
+void TestBlackbox::sanitizer_data()
+{
+ QTest::addColumn<QString>("sanitizer");
+ QTest::newRow("none") << QString();
+ QTest::newRow("address") << QStringLiteral("address");
+ QTest::newRow("undefined") << QStringLiteral("undefined");
+ QTest::newRow("thread") << QStringLiteral("thread");
+}
+
+void TestBlackbox::sanitizer()
+{
+ QFETCH(QString, sanitizer);
+ QDir::setCurrent(testDataDir + "/sanitizer");
+ rmDirR(relativeBuildDir());
+ QbsRunParameters params("build", {"--command-echo-mode", "command-line"});
+ if (!sanitizer.isEmpty()) {
+ params.arguments.append(
+ {QStringLiteral("products.sanitizer.sanitizer:\"") + sanitizer + "\""});
+ }
+ QCOMPARE(runQbs(params), 0);
+ if (m_qbsStdout.contains(QByteArrayLiteral("Compiler does not support sanitizer")))
+ QSKIP("Compiler does not support the specified sanitizer");
+ if (!sanitizer.isEmpty()) {
+ QVERIFY2(m_qbsStdout.contains(QByteArrayLiteral("fsanitize=") + sanitizer.toLatin1()),
+ qPrintable(m_qbsStdout));
+ } else {
+ QVERIFY2(!m_qbsStdout.contains(QByteArrayLiteral("fsanitize=")), qPrintable(m_qbsStdout));
+ }
}
void TestBlackbox::scannerItem()
@@ -2469,6 +2900,47 @@ void TestBlackbox::scannerItem()
QVERIFY2(m_qbsStdout.contains("handling file2.in"), m_qbsStdout.constData());
}
+void TestBlackbox::scanResultInOtherProduct()
+{
+ QDir::setCurrent(testDataDir + "/scan-result-in-other-product");
+ QCOMPARE(runQbs(QStringList("-vv")), 0);
+ QVERIFY2(m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("generating text file"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStderr.contains("The file dependency might get lost during change tracking"),
+ m_qbsStderr.constData());
+ WAIT_FOR_NEW_TIMESTAMP();
+ REPLACE_IN_FILE("other/other.qbs", "blubb", "blubb2");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY2(!m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("generating text file"), m_qbsStdout.constData());
+ WAIT_FOR_NEW_TIMESTAMP();
+ touch("lib/lib.h");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY2(m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("generating text file"), m_qbsStdout.constData());
+}
+
+void TestBlackbox::scanResultInNonDependency()
+{
+ QDir::setCurrent(testDataDir + "/scan-result-in-non-dependency");
+ QCOMPARE(runQbs(QStringList("-vv")), 0);
+ QVERIFY2(m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("generating text file"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStderr.contains("The file dependency might get lost during change tracking"),
+ m_qbsStderr.constData());
+ WAIT_FOR_NEW_TIMESTAMP();
+ REPLACE_IN_FILE("other/other.qbs", "blubb", "blubb2");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY2(!m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("generating text file"), m_qbsStdout.constData());
+ WAIT_FOR_NEW_TIMESTAMP();
+ touch("lib/lib.h");
+ QCOMPARE(runQbs(), 0);
+ QEXPECT_FAIL("", "QBS-1532", Continue);
+ QVERIFY2(m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("generating text file"), m_qbsStdout.constData());
+}
+
void TestBlackbox::setupBuildEnvironment()
{
QDir::setCurrent(testDataDir + "/setup-build-environment");
@@ -2486,6 +2958,8 @@ void TestBlackbox::setupRunEnvironment()
{
QDir::setCurrent(testDataDir + "/setup-run-environment");
QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters failParams("run", QStringList({"--setup-run-env-config",
"ignore-lib-dependencies"}));
failParams.expectFailure = true;
@@ -2760,9 +3234,11 @@ void TestBlackbox::pathProbe_data()
QTest::newRow("mult-files-mult-variants") << QString("mult-files-mult-variants.qbs") << true;
QTest::newRow("single-file-suffixes") << QString("single-file-suffixes.qbs") << true;
QTest::newRow("mult-files-suffixes") << QString("mult-files-suffixes.qbs") << true;
+ QTest::newRow("mult-files-common-suffixes") << QString("mult-files-common-suffixes.qbs") << true;
QTest::newRow("mult-files-mult-suffixes") << QString("mult-files-mult-suffixes.qbs") << true;
QTest::newRow("name-filter") << QString("name-filter.qbs") << true;
QTest::newRow("candidate-filter") << QString("candidate-filter.qbs") << true;
+ QTest::newRow("environment-paths") << QString("environment-paths.qbs") << true;
}
void TestBlackbox::pathProbe()
@@ -2774,23 +3250,41 @@ void TestBlackbox::pathProbe()
QbsRunParameters buildParams("build", QStringList{"-f", projectFile});
buildParams.expectFailure = !successExpected;
+ buildParams.environment.insert("SEARCH_PATH", "usr/bin");
QCOMPARE(runQbs(buildParams) == 0, successExpected);
+ if (!successExpected)
+ QVERIFY2(m_qbsStderr.contains("Probe failed to find files"), m_qbsStderr);
+}
+
+void TestBlackbox::pathListInProbe()
+{
+ QDir::setCurrent(testDataDir + "/path-list-in-probe");
+ QCOMPARE(runQbs(), 0);
}
void TestBlackbox::pchChangeTracking()
{
QDir::setCurrent(testDataDir + "/pch-change-tracking");
- QCOMPARE(runQbs(), 0);
+ bool success = runQbs() == 0;
+ if (!success && m_qbsStderr.contains("mingw32_gt_pch_use_address"))
+ QSKIP("https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91440");
+ QVERIFY(success);
QVERIFY(m_qbsStdout.contains("precompiling pch.h (cpp)"));
WAIT_FOR_NEW_TIMESTAMP();
touch("header1.h");
- QCOMPARE(runQbs(), 0);
+ success = runQbs() == 0;
+ if (!success && m_qbsStderr.contains("mingw32_gt_pch_use_address"))
+ QSKIP("https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91440");
+ QVERIFY(success);
QVERIFY(m_qbsStdout.contains("precompiling pch.h (cpp)"));
QVERIFY(m_qbsStdout.contains("compiling header2.cpp"));
QVERIFY(m_qbsStdout.contains("compiling main.cpp"));
WAIT_FOR_NEW_TIMESTAMP();
touch("header2.h");
- QCOMPARE(runQbs(), 0);
+ success = runQbs() == 0;
+ if (!success && m_qbsStderr.contains("mingw32_gt_pch_use_address"))
+ QSKIP("https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91440");
+ QVERIFY(success);
QVERIFY2(!m_qbsStdout.contains("precompiling pch.h (cpp)"), m_qbsStdout.constData());
}
@@ -2920,13 +3414,19 @@ void TestBlackbox::pluginDependency()
void TestBlackbox::precompiledAndPrefixHeaders()
{
QDir::setCurrent(testDataDir + "/precompiled-and-prefix-headers");
- QCOMPARE(runQbs(), 0);
+ const bool success = runQbs() == 0;
+ if (!success && m_qbsStderr.contains("mingw32_gt_pch_use_address"))
+ QSKIP("https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91440");
+ QVERIFY(success);
}
void TestBlackbox::precompiledHeaderAndRedefine()
{
QDir::setCurrent(testDataDir + "/precompiled-headers-and-redefine");
- QCOMPARE(runQbs(), 0);
+ const bool success = runQbs() == 0;
+ if (!success && m_qbsStderr.contains("mingw32_gt_pch_use_address"))
+ QSKIP("https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91440");
+ QVERIFY(success);
}
void TestBlackbox::preventFloatingPointValues()
@@ -3031,6 +3531,9 @@ void TestBlackbox::probeProperties()
QVERIFY2(m_qbsStdout.contains("probe2.fileName=tool"), m_qbsStdout.constData());
QVERIFY2(m_qbsStdout.contains("probe2.path=" + dir + "/bin"), m_qbsStdout.constData());
QVERIFY2(m_qbsStdout.contains("probe2.filePath=" + dir + "/bin/tool"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("probe3.fileName=tool"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("probe3.path=" + dir + "/bin"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("probe3.filePath=" + dir + "/bin/tool"), m_qbsStdout.constData());
}
void TestBlackbox::probesAndShadowProducts()
@@ -3053,7 +3556,7 @@ void TestBlackbox::probeInExportedModule()
<< QStringLiteral("probe-in-exported-module.qbs"))), 0);
QVERIFY2(m_qbsStdout.contains("found: true"), m_qbsStdout.constData());
QVERIFY2(m_qbsStdout.contains("prop: yes"), m_qbsStdout.constData());
- QVERIFY2(m_qbsStdout.contains("listProp: my,myother"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("listProp: myother,my"), m_qbsStdout.constData());
}
void TestBlackbox::probesAndArrayProperties()
@@ -3075,13 +3578,6 @@ void TestBlackbox::productProperties()
QVERIFY(regularFileExists(relativeExecutableFilePath("blubb_user")));
}
-void TestBlackbox::propertyAssignmentOnNonPresentModule()
-{
- QDir::setCurrent(testDataDir + "/property-assignment-on-non-present-module");
- QCOMPARE(runQbs(), 0);
- QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
-}
-
void TestBlackbox::propertyAssignmentInFailedModule()
{
QDir::setCurrent(testDataDir + "/property-assignment-in-failed-module");
@@ -3091,7 +3587,7 @@ void TestBlackbox::propertyAssignmentInFailedModule()
QVERIFY(runQbs(failParams) != 0);
QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("modules.m.doFail:true"))), 0);
QVERIFY2(m_qbsStdout.contains("Resolving"), m_qbsStdout.constData());
- QEXPECT_FAIL(0, "circular dependency between module merging and validation", Continue);
+ failParams.expectFailure = false;
QCOMPARE(runQbs(failParams), 0);
}
@@ -3109,9 +3605,9 @@ void TestBlackbox::propertyChanges()
QVERIFY(m_qbsStdout.contains("compiling lib.cpp"));
QVERIFY(m_qbsStdout.contains("linking product 1.debug"));
QVERIFY(m_qbsStdout.contains("generated.txt"));
- QVERIFY(m_qbsStdout.contains("Making output from input"));
+ QVERIFY(m_qbsStdout.contains("making output from input"));
QVERIFY(m_qbsStdout.contains("default value"));
- QVERIFY(m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(m_qbsStdout.contains("making output from other output"));
QFile generatedFile(relativeProductBuildDir("generated text file") + "/generated.txt");
QVERIFY(generatedFile.open(QIODevice::ReadOnly));
QCOMPARE(generatedFile.readAll(), QByteArray("prefix 1contents 1suffix 1"));
@@ -3125,8 +3621,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("compiling lib.cpp.cpp"));
QVERIFY(!m_qbsStdout.contains("linking"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
// Incremental build with no changes, but updated project file timestamp.
WAIT_FOR_NEW_TIMESTAMP();
@@ -3138,8 +3634,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("compiling lib.cpp"));
QVERIFY(!m_qbsStdout.contains("linking"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
// Incremental build, input property changed for first product
WAIT_FOR_NEW_TIMESTAMP();
@@ -3151,8 +3647,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("linking product 3"));
QVERIFY(!m_qbsStdout.contains("linking library"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
// Incremental build, input property changed via project for second product.
WAIT_FOR_NEW_TIMESTAMP();
@@ -3162,8 +3658,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(m_qbsStdout.contains("compiling source2.cpp"));
QVERIFY(!m_qbsStdout.contains("linking product 3"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
// Incremental build, input property changed via command line for second product.
params.command = "resolve";
@@ -3181,8 +3677,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(m_qbsStdout.contains("compiling source2.cpp"));
QVERIFY(!m_qbsStdout.contains("linking product 3"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
// Incremental build, input property changed via environment for third product.
params.environment.insert("QBS_BLACKBOX_DEFINE", "newvalue");
@@ -3197,8 +3693,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("linking product 2"));
QVERIFY(!m_qbsStdout.contains("compiling source3.cpp"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
params.environment.insert("QBS_BLACKBOX_DEFINE", "newvalue");
QCOMPARE(runQbs(params), 0);
QCOMPARE(runQbs(), 0);
@@ -3213,8 +3709,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("linking product 2"));
QVERIFY(m_qbsStdout.contains("compiling source3.cpp"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
// Incremental build, module property changed via command line.
params.arguments << "qbs.enableDebugCode:false";
@@ -3234,8 +3730,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(m_qbsStdout.contains("compiling source2.cpp"));
QVERIFY(m_qbsStdout.contains("compiling source3.cpp"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
// Incremental build, non-essential dependency removed.
WAIT_FOR_NEW_TIMESTAMP();
@@ -3247,8 +3743,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("linking product 3"));
QVERIFY(!m_qbsStdout.contains("linking library"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
// Incremental build, prepare script of a transformer changed.
WAIT_FOR_NEW_TIMESTAMP();
@@ -3259,8 +3755,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("compiling source3.cpp"));
QVERIFY(!m_qbsStdout.contains("compiling lib.cpp"));
QVERIFY(m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
QVERIFY(generatedFile.open(QIODevice::ReadOnly));
QCOMPARE(generatedFile.readAll(), QByteArray("prefix 1contents 2suffix 1"));
generatedFile.close();
@@ -3274,8 +3770,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("compiling source3.cpp"));
QVERIFY(!m_qbsStdout.contains("compiling lib.cpp"));
QVERIFY(m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
QVERIFY(generatedFile.open(QIODevice::ReadOnly));
QCOMPARE(generatedFile.readAll(), QByteArray("prefix 2contents 2suffix 1"));
generatedFile.close();
@@ -3289,8 +3785,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("compiling source3.cpp"));
QVERIFY(!m_qbsStdout.contains("compiling lib.cpp"));
QVERIFY(m_qbsStdout.contains("generated.txt"));
- QVERIFY(!m_qbsStdout.contains("Making output from input"));
- QVERIFY(!m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(!m_qbsStdout.contains("making output from input"));
+ QVERIFY(!m_qbsStdout.contains("making output from other output"));
QVERIFY(generatedFile.open(QIODevice::ReadOnly));
QCOMPARE(generatedFile.readAll(), QByteArray("prefix 2contents 2suffix 2"));
generatedFile.close();
@@ -3304,8 +3800,8 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("compiling source3.cpp"));
QVERIFY(!m_qbsStdout.contains("compiling lib.cpp"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(m_qbsStdout.contains("Making output from input"));
- QVERIFY(m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(m_qbsStdout.contains("making output from input"));
+ QVERIFY(m_qbsStdout.contains("making output from other output"));
QVERIFY(m_qbsStdout.contains("new value"));
// Incremental build, prepare script of a rule in a module changed.
@@ -3318,22 +3814,31 @@ void TestBlackbox::propertyChanges()
QVERIFY(!m_qbsStdout.contains("compiling source3.cpp"));
QVERIFY(!m_qbsStdout.contains("compiling lib.cpp"));
QVERIFY(!m_qbsStdout.contains("generated.txt"));
- QVERIFY(m_qbsStdout.contains("Making output from input"));
- QVERIFY(m_qbsStdout.contains("Making output from other output"));
+ QVERIFY(m_qbsStdout.contains("making output from input"));
+ QVERIFY(m_qbsStdout.contains("making output from other output"));
+}
+
+void TestBlackbox::propertyEvaluationContext()
+{
+ const QString testDir = testDataDir + "/property-evaluation-context";
+ QDir::setCurrent(testDir);
+ QCOMPARE(runQbs(), 0);
+ QCOMPARE(m_qbsStdout.count("base.productInBase evaluated in: myapp"), 1);
+ QCOMPARE(m_qbsStdout.count("base.productInTop evaluated in: myapp"), 1);
+ QCOMPARE(m_qbsStdout.count("top.productInExport evaluated in: mylib"), 1);
+ QCOMPARE(m_qbsStdout.count("top.productInTop evaluated in: myapp"), 1);
}
void TestBlackbox::qtBug51237()
{
- const QString profileName = "profile-qtBug51237";
- const QString propertyName = "mymodule.theProperty";
- {
- const SettingsPtr s = settings();
- Profile profile(profileName, s.get());
- profile.setValue(propertyName, QStringList());
- }
+ const SettingsPtr s = settings();
+ qbs::Internal::TemporaryProfile profile("qbs_autotests_qtBug51237", s.get());
+ profile.p.setValue("mymodule.theProperty", QStringList());
+ s->sync();
+
QDir::setCurrent(testDataDir + "/QTBUG-51237");
QbsRunParameters params;
- params.profile = profileName;
+ params.profile = profile.p.name();
QCOMPARE(runQbs(params), 0);
}
@@ -3406,6 +3911,42 @@ void TestBlackbox::dynamicRuleOutputs()
QVERIFY(!QFile::exists(sourceFile2));
}
+void TestBlackbox::emptyProfile()
+{
+ QDir::setCurrent(testDataDir + "/empty-profile");
+
+ const SettingsPtr s = settings();
+ const qbs::Profile buildProfile(profileName(), s.get());
+ bool isMsvc = false;
+ auto toolchainType = buildProfile.value(QStringLiteral("qbs.toolchainType")).toString();
+ QbsRunParameters params;
+ params.profile = "none";
+
+ if (toolchainType.isEmpty()) {
+ const auto toolchain = buildProfile.value(QStringLiteral("qbs.toolchain")).toStringList();
+ if (!toolchain.isEmpty())
+ toolchainType = toolchain.first();
+ }
+ if (!toolchainType.isEmpty()) {
+ params.arguments = QStringList{QStringLiteral("qbs.toolchainType:") + toolchainType};
+ isMsvc = toolchainType == "msvc" || toolchainType == "clang-cl";
+ }
+
+ if (!isMsvc) {
+ const auto tcPath =
+ QDir::toNativeSeparators(
+ buildProfile.value(QStringLiteral("cpp.toolchainInstallPath")).toString());
+ auto paths = params.environment.value(QStringLiteral("PATH"))
+ .split(HostOsInfo::pathListSeparator(), Qt::SkipEmptyParts);
+ if (!tcPath.isEmpty() && !paths.contains(tcPath)) {
+ paths.prepend(tcPath);
+ params.environment.insert(
+ QStringLiteral("PATH"), paths.join(HostOsInfo::pathListSeparator()));
+ }
+ }
+ QCOMPARE(runQbs(params), 0);
+}
+
void TestBlackbox::erroneousFiles_data()
{
QTest::addColumn<QString>("errorMessage");
@@ -3433,7 +3974,7 @@ void TestBlackbox::erroneousFiles()
params.expectFailure = true;
QVERIFY(runQbs(params) != 0);
QString err = QString::fromLocal8Bit(m_qbsStderr);
- if (!err.contains(QRegExp(errorMessage))) {
+ if (!err.contains(QRegularExpression(errorMessage))) {
qDebug().noquote() << "Output: " << err;
qDebug().noquote() << "Expected: " << errorMessage;
QFAIL("Unexpected error message.");
@@ -3496,13 +4037,16 @@ void TestBlackbox::errorInfo()
void TestBlackbox::escapedLinkerFlags()
{
- const SettingsPtr s = settings();
- const Profile buildProfile(profileName(), s.get());
- const QStringList toolchain = buildProfile.value("qbs.toolchain").toStringList();
- if (!toolchain.contains("gcc") || targetOs() == HostOsInfo::HostOsMacos)
- QSKIP("escaped linker flags test only applies with gcc and GNU ld");
QDir::setCurrent(testDataDir + "/escaped-linker-flags");
- QbsRunParameters params(QStringList("products.app.escapeLinkerFlags:false"));
+ QbsRunParameters params("resolve", QStringList("products.app.escapeLinkerFlags:false"));
+ QCOMPARE(runQbs(params), 0);
+ const bool isGcc = m_qbsStdout.contains("is gcc: true");
+ const bool isNotGcc = m_qbsStdout.contains("is gcc: false");
+ if (isNotGcc)
+ QSKIP("escaped linker flags test only applies on plain unix with gcc and GNU ld");
+ QVERIFY(isGcc);
+
+ params.command = "build";
QCOMPARE(runQbs(params), 0);
params.command = "resolve";
params.arguments = QStringList() << "products.app.escapeLinkerFlags:true";
@@ -3559,26 +4103,24 @@ void TestBlackbox::exportedPropertyInDisabledProduct_data()
void TestBlackbox::systemRunPaths()
{
- const SettingsPtr s = settings();
- const Profile buildProfile(profileName(), s.get());
- switch (targetOs()) {
- case HostOsInfo::HostOsLinux:
- case HostOsInfo::HostOsMacos:
- case HostOsInfo::HostOsOtherUnix:
- break;
- default:
- QSKIP("only applies on Unix");
- }
-
const QString lddFilePath = findExecutable(QStringList() << "ldd");
if (lddFilePath.isEmpty())
QSKIP("ldd not found");
+
QDir::setCurrent(testDataDir + "/system-run-paths");
QFETCH(bool, setRunPaths);
rmDirR(relativeBuildDir());
- QbsRunParameters params;
+ QbsRunParameters params("resolve");
params.arguments << QString("project.setRunPaths:") + (setRunPaths ? "true" : "false");
QCOMPARE(runQbs(params), 0);
+ const bool isUnix = m_qbsStdout.contains("is unix: true");
+ const bool isNotUnix = m_qbsStdout.contains("is unix: false");
+ if (isNotUnix)
+ QSKIP("only applies on Unix");
+ QVERIFY(isUnix);
+
+ params.command = "build";
+ QCOMPARE(runQbs(params), 0);
QProcess ldd;
ldd.start(lddFilePath, QStringList() << relativeExecutableFilePath("app"));
QVERIFY2(ldd.waitForStarted(), qPrintable(ldd.errorString()));
@@ -3615,7 +4157,7 @@ void TestBlackbox::exportRule()
params.expectFailure = false;
QCOMPARE(runQbs(params), 0);
QCOMPARE(runQbs(), 0);
- QVERIFY2(m_qbsStdout.contains("Creating C++ source file"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("creating C++ source file"), m_qbsStdout.constData());
QVERIFY2(m_qbsStdout.contains("compiling myapp.cpp"), m_qbsStdout.constData());
}
@@ -3629,12 +4171,88 @@ void TestBlackbox::exportToOutsideSearchPath()
m_qbsStderr.constData());
}
+void TestBlackbox::exportsCMake()
+{
+ QFETCH(QStringList, arguments);
+
+ QDir::setCurrent(testDataDir + "/exports-cmake");
+ rmDirR(relativeBuildDir());
+ QbsRunParameters findCMakeParams("resolve", {"-f", "find-cmake.qbs"});
+ QCOMPARE(runQbs(findCMakeParams), 0);
+ const QString output = QString::fromLocal8Bit(m_qbsStdout);
+ const QRegularExpression pattern(
+ QRegularExpression::anchoredPattern(".*---(.*)---.*"),
+ QRegularExpression::DotMatchesEverythingOption);
+ const QRegularExpressionMatch match = pattern.match(output);
+ QVERIFY2(match.hasMatch(), qPrintable(output));
+ QCOMPARE(pattern.captureCount(), 1);
+ const QString jsonString = match.captured(1);
+ const QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
+ const QJsonObject jsonData = jsonDoc.object();
+
+ rmDirR(relativeBuildDir());
+ const QStringList exporterArgs{"-f", "exports-cmake.qbs"};
+ QbsRunParameters exporterRunParams("build", exporterArgs);
+ exporterRunParams.arguments << arguments;
+ QCOMPARE(runQbs(exporterRunParams), 0);
+
+ if (!jsonData.value(u"cmakeFound").toBool()) {
+ QSKIP("cmake is not installed");
+ return;
+ }
+
+ if (jsonData.value(u"crossCompiling").toBool()) {
+ QSKIP("test is not applicable with cross-compile toolchains");
+ return;
+ }
+
+ const auto cmakeFilePath = jsonData.value(u"cmakeFilePath").toString();
+ QVERIFY(!cmakeFilePath.isEmpty());
+
+ const auto generator = jsonData.value(u"generator").toString();
+ if (generator.isEmpty()) {
+ QSKIP("cannot detect cmake generator");
+ return;
+ }
+
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ const auto buildEnv = jsonData.value(u"buildEnv").toObject();
+ for (auto it = buildEnv.begin(), end = buildEnv.end(); it != end; ++it) {
+ env.insert(it.key(), it.value().toString());
+ }
+
+ const auto installPrefix = jsonData.value(u"installPrefix").toString();
+ const auto cmakePrefixPath = QFileInfo(relativeBuildDir()).absoluteFilePath() + "/install-root/"
+ + installPrefix + "/lib/cmake";
+ const auto sourceDirectory = testDataDir + "/exports-cmake/cmake";
+ QProcess configure;
+ configure.setProcessEnvironment(env);
+ configure.setWorkingDirectory(sourceDirectory);
+ configure.start(
+ cmakeFilePath, {".", "-DCMAKE_PREFIX_PATH=" + cmakePrefixPath, "-G" + generator});
+ QVERIFY(waitForProcessSuccess(configure, 120000));
+
+ QProcess build;
+ build.setProcessEnvironment(env);
+ build.setWorkingDirectory(sourceDirectory);
+ build.start(cmakeFilePath, QStringList{"--build", "."});
+ QVERIFY(waitForProcessSuccess(build));
+}
+
+void TestBlackbox::exportsCMake_data()
+{
+ QTest::addColumn<QStringList>("arguments");
+ QTest::newRow("dynamic lib") << QStringList("project.isStatic: false");
+ QTest::newRow("static lib") << QStringList("project.isStatic: true");
+ QTest::newRow("framework") << QStringList("project.isBundle: true");
+}
+
void TestBlackbox::exportsPkgconfig()
{
QDir::setCurrent(testDataDir + "/exports-pkgconfig");
QCOMPARE(runQbs(), 0);
- QVERIFY2(m_qbsStdout.contains("Creating TheFirstLib.pc"), m_qbsStdout.constData());
- QVERIFY2(m_qbsStdout.contains("Creating TheSecondLib.pc"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("creating TheFirstLib.pc"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("creating TheSecondLib.pc"), m_qbsStdout.constData());
QFile sourcePcFile(HostOsInfo::isWindowsHost() ? "TheFirstLib_windows.pc" : "TheFirstLib.pc");
QString generatedPcFilePath = relativeProductBuildDir("TheFirstLib") + "/TheFirstLib.pc";
QFile generatedPcFile(generatedPcFilePath);
@@ -3649,14 +4267,17 @@ void TestBlackbox::exportsPkgconfig()
touch("firstlib.cpp");
QCOMPARE(runQbs(), 0);
QVERIFY2(m_qbsStdout.contains("linking"), m_qbsStdout.constData());
- QVERIFY2(!m_qbsStdout.contains("Creating TheFirstLib.pc"), m_qbsStdout.constData());
- QVERIFY2(!m_qbsStdout.contains("Creating TheSecondLib.pc"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("creating TheFirstLib.pc"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("creating TheSecondLib.pc"), m_qbsStdout.constData());
}
void TestBlackbox::exportsQbs()
{
QDir::setCurrent(testDataDir + "/exports-qbs");
+ QCOMPARE(runQbs({"resolve", {"-f", "exports-qbs.qbs"}}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
// First we build exportable products and use them (as products) inside
// the original project.
QCOMPARE(runQbs(QStringList{"-f", "exports-qbs.qbs", "--command-echo-mode", "command-line"}),
@@ -3679,11 +4300,12 @@ void TestBlackbox::exportsQbs()
// Trying to build with an unsupported build variant must fail.
paramsExternalBuild.arguments = QStringList{"-f", "consumer.qbs",
- "modules.qbs.buildVariant:unknown"};
+ "modules.qbs.buildVariant:profiling"};
paramsExternalBuild.buildDirectory = QDir::currentPath() + "/external-consumer-profile";
paramsExternalBuild.expectFailure = true;
QVERIFY(runQbs(paramsExternalBuild) != 0);
- QVERIFY2(m_qbsStderr.contains("MyLib could not be loaded"), m_qbsStderr.constData());
+ QVERIFY2(m_qbsStderr.contains("Dependency 'MyLib' not found for product 'consumer'"),
+ m_qbsStderr.constData());
// Removing the condition from the generated module leaves us with two conflicting
// candidates.
@@ -3697,19 +4319,19 @@ void TestBlackbox::exportsQbs()
// Change tracking for accesses to product.exports (negative).
QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList{"-f", "exports-qbs.qbs"})), 0);
QCOMPARE(runQbs(), 0);
- QVERIFY2(m_qbsStdout.contains("Creating MyTool.qbs"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("creating MyTool.qbs"), m_qbsStdout.constData());
WAIT_FOR_NEW_TIMESTAMP();
touch("exports-qbs.qbs");
QCOMPARE(runQbs(QStringList({"-p", "MyTool"})), 0);
- QVERIFY2(!m_qbsStdout.contains("Creating MyTool.qbs"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("creating MyTool.qbs"), m_qbsStdout.constData());
// Rebuilding the target binary should not cause recreating the module file.
WAIT_FOR_NEW_TIMESTAMP();
touch("mylib.cpp");
QCOMPARE(runQbs(), 0);
QVERIFY2(m_qbsStdout.count("linking") >= 2, m_qbsStdout.constData());
- QVERIFY2(!m_qbsStdout.contains("Creating MyLib"), m_qbsStdout.constData());
- QVERIFY2(!m_qbsStdout.contains("Creating MyTool.qbs"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("creating MyLib"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("creating MyTool.qbs"), m_qbsStdout.constData());
// Changing a setting that influences the name of a target artifact should cause
// recreating the module file.
@@ -3718,14 +4340,14 @@ void TestBlackbox::exportsQbs()
QCOMPARE(runQbs(resolveParams), 0);
QCOMPARE(runQbs(), 0);
QVERIFY2(m_qbsStdout.count("linking") >= 2, m_qbsStdout.constData());
- QVERIFY2(m_qbsStdout.count("Creating MyLib") == 2, m_qbsStdout.constData());
- QVERIFY2(!m_qbsStdout.contains("Creating MyTool.qbs"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.count("creating MyLib") == 2, m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("creating MyTool.qbs"), m_qbsStdout.constData());
// Change tracking for accesses to product.exports (positive).
WAIT_FOR_NEW_TIMESTAMP();
- REPLACE_IN_FILE("tool.qbs", "product.toolTags", "[]");
+ REPLACE_IN_FILE("tool.qbs", "exportingProduct.toolTags", "[]");
QCOMPARE(runQbs(QStringList({"-p", "MyTool"})), 0);
- QVERIFY2(m_qbsStdout.contains("Creating MyTool.qbs"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("creating MyTool.qbs"), m_qbsStdout.constData());
}
void TestBlackbox::externalLibs()
@@ -3787,6 +4409,77 @@ void TestBlackbox::fileTagsFilterMerging()
QVERIFY2(QFile::exists(otherOutput), qPrintable(otherOutput));
}
+void TestBlackbox::flatbuf()
+{
+ QFETCH(QString, projectFile);
+
+ QDir::setCurrent(testDataDir + "/flatbuf");
+
+ rmDirR(relativeBuildDir());
+ if (!prepareAndRunConan())
+ QSKIP("conan is not prepared, check messages above");
+
+ QbsRunParameters resolveParams(
+ "resolve", QStringList{"-f", projectFile, "moduleProviders.conan.installDirectory:build"});
+ QCOMPARE(runQbs(resolveParams), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ const bool withFlatbuffers = m_qbsStdout.contains("has flatbuffers: true");
+ const bool withoutFlatbuffers = m_qbsStdout.contains("has flatbuffers: false");
+ QVERIFY2(withFlatbuffers || withoutFlatbuffers, m_qbsStdout.constData());
+ if (withoutFlatbuffers)
+ QSKIP("flatbuf module not present");
+ QbsRunParameters runParams("run");
+ QCOMPARE(runQbs(runParams), 0);
+}
+
+void TestBlackbox::flatbuf_data()
+{
+ QTest::addColumn<QString>("projectFile");
+
+ // QTest::newRow("c") << QString("flat_c.qbs");
+ QTest::newRow("cpp") << QString("flat_cpp.qbs");
+ QTest::newRow("relative import") << QString("flat_relative_import.qbs");
+ QTest::newRow("absolute import") << QString("flat_absolute_import.qbs");
+ QTest::newRow("filename suffix") << QString("flat_filename_suffix.qbs");
+ QTest::newRow("filename extension") << QString("flat_filename_extension.qbs");
+ QTest::newRow("keep prefix") << QString("flat_keep_prefix.qbs");
+}
+
+void TestBlackbox::freedesktop()
+{
+ if (!HostOsInfo::isAnyUnixHost())
+ QSKIP("only applies on Unix");
+ if (HostOsInfo::isMacosHost())
+ QSKIP("Does not apply on macOS");
+ QDir::setCurrent(testDataDir + "/freedesktop");
+ QCOMPARE(runQbs(), 0);
+
+ // Check desktop file
+ QString desktopFilePath =
+ defaultInstallRoot + "/usr/local/share/applications/myapp.desktop";
+ QVERIFY(QFile::exists(desktopFilePath));
+ QFile desktopFile(desktopFilePath);
+ QVERIFY2(desktopFile.open(QIODevice::ReadOnly), qPrintable(desktopFile.errorString()));
+ QByteArrayList lines = desktopFile.readAll().split('\n');
+ // Automatically filled line:
+ QVERIFY(lines.contains("Exec=main"));
+ // Name specified in `freedesktop.name` property
+ QVERIFY(lines.contains("Name=My App"));
+ // Overridden line:
+ QVERIFY(lines.contains("Icon=myapp.png"));
+ // Untouched line:
+ QVERIFY(lines.contains("Terminal=false"));
+
+ // Check AppStream file
+ QVERIFY(QFile::exists(defaultInstallRoot +
+ "/usr/local/share/metainfo/myapp.appdata.xml"));
+
+ // Check icon file
+ QVERIFY(QFile::exists(defaultInstallRoot +
+ "/usr/local/share/icons/hicolor/scalable/apps/myapp.png"));
+}
+
void TestBlackbox::installedTransformerOutput()
{
QDir::setCurrent(testDataDir + "/installed-transformer-output");
@@ -3800,8 +4493,16 @@ void TestBlackbox::installLocations_data()
QTest::addColumn<QString>("binDir");
QTest::addColumn<QString>("dllDir");
QTest::addColumn<QString>("libDir");
- QTest::newRow("explicit values") << QString("bindir") << QString("dlldir") << QString("libdir");
- QTest::newRow("default values") << QString() << QString() << QString();
+ QTest::addColumn<QString>("pluginDir");
+ QTest::addColumn<QString>("dsymDir");
+ QTest::newRow("explicit values")
+ << QString("bindir")
+ << QString("dlldir")
+ << QString("libdir")
+ << QString("pluginDir")
+ << QString("dsymDir");
+ QTest::newRow("default values")
+ << QString() << QString() << QString() << QString() << QString();
}
void TestBlackbox::installLocations()
@@ -3810,6 +4511,8 @@ void TestBlackbox::installLocations()
QFETCH(QString, binDir);
QFETCH(QString, dllDir);
QFETCH(QString, libDir);
+ QFETCH(QString, pluginDir);
+ QFETCH(QString, dsymDir);
QbsRunParameters params("resolve");
if (!binDir.isEmpty())
params.arguments.push_back("products.theapp.installDir:" + binDir);
@@ -3817,35 +4520,98 @@ void TestBlackbox::installLocations()
params.arguments.push_back("products.thelib.installDir:" + dllDir);
if (!libDir.isEmpty())
params.arguments.push_back("products.thelib.importLibInstallDir:" + libDir);
+ if (!pluginDir.isEmpty())
+ params.arguments.push_back("products.theplugin.installDir:" + pluginDir);
+ if (!dsymDir.isEmpty()) {
+ params.arguments.push_back("products.theapp.debugInformationInstallDir:" + dsymDir);
+ params.arguments.push_back("products.thelib.debugInformationInstallDir:" + dsymDir);
+ params.arguments.push_back("products.theplugin.debugInformationInstallDir:" + dsymDir);
+ }
QCOMPARE(runQbs(params), 0);
const bool isWindows = m_qbsStdout.contains("is windows");
+ const bool isDarwin = m_qbsStdout.contains("is darwin");
const bool isMac = m_qbsStdout.contains("is mac");
const bool isUnix = m_qbsStdout.contains("is unix");
- QVERIFY(isWindows || isMac || isUnix);
+ const bool isMingw = m_qbsStdout.contains("is mingw");
+ QVERIFY(isWindows || isDarwin || isUnix);
QCOMPARE(runQbs(QbsRunParameters(QStringList("--clean-install-root"))), 0);
- const QString dllFileName = isWindows ? "thelib.dll" : isMac ? "thelib" : "libthelib.so";
- const QString appFileName = isWindows ? "theapp.exe" : "theapp";
- if (binDir.isEmpty())
- binDir = isMac ? "/Applications" : "/bin";
- if (dllDir.isEmpty())
- dllDir = isMac ? "/Library/Frameworks" : isWindows ? "/bin" : "/lib";
- if (libDir.isEmpty())
- libDir = "/lib";
- if (isMac) {
- binDir += "/theapp.app/Contents/MacOS";
- dllDir += "/thelib.framework";
- }
+
+ struct BinaryInfo
+ {
+ QString fileName;
+ QString installDir;
+ QString subDir;
+
+ QString absolutePath(const QString &prefix) const
+ {
+ return QDir::cleanPath(prefix + '/' + installDir + '/' + subDir + '/' + fileName);
+ }
+ };
+
+ const BinaryInfo dll = {
+ isWindows ? "thelib.dll" : isDarwin ? "thelib" : "libthelib.so",
+ dllDir.isEmpty()
+ ? (isDarwin ? "/Library/Frameworks" : (isWindows ? "/bin" : "/lib"))
+ : dllDir,
+ isDarwin ? "thelib.framework" : ""
+ };
+ const BinaryInfo dllDsym = {
+ isWindows
+ ? (!isMingw ? "thelib.pdb" : "thelib.dll.debug")
+ : isDarwin ? "thelib.framework.dSYM" : "libthelib.so.debug",
+ dsymDir.isEmpty() ? dll.installDir : dsymDir,
+ {}
+ };
+ const BinaryInfo plugin = {
+ isWindows ? "theplugin.dll" : isDarwin ? "theplugin" : "libtheplugin.so",
+ pluginDir.isEmpty() ? dll.installDir : pluginDir,
+ isDarwin ? (isMac ? "theplugin.bundle/Contents/MacOS" : "theplugin.bundle") : ""
+ };
+ const BinaryInfo pluginDsym = {
+ isWindows
+ ? (!isMingw ? "theplugin.pdb" : "theplugin.dll.debug")
+ : isDarwin ? "theplugin.bundle.dSYM" : "libtheplugin.so.debug",
+ dsymDir.isEmpty() ? plugin.installDir : dsymDir,
+ {}
+ };
+ const BinaryInfo app = {
+ isWindows ? "theapp.exe" : "theapp",
+ binDir.isEmpty() ? (isDarwin ? "/Applications" : "/bin") : binDir,
+ isDarwin ? (isMac ? "theapp.app/Contents/MacOS" : "theapp.app") : ""
+ };
+ const BinaryInfo appDsym = {
+ isWindows
+ ? (!isMingw ? "theapp.pdb" : "theapp.exe.debug")
+ : isDarwin ? "theapp.app.dSYM" : "theapp.debug",
+ dsymDir.isEmpty() ? app.installDir : dsymDir,
+ {}
+ };
+
const QString installRoot = QDir::currentPath() + "/default/install-root";
const QString installPrefix = isWindows ? QString() : "/usr/local";
const QString fullInstallPrefix = installRoot + '/' + installPrefix + '/';
- const QString appFilePath = fullInstallPrefix + binDir + '/' + appFileName;
+ const QString appFilePath = app.absolutePath(fullInstallPrefix);
QVERIFY2(QFile::exists(appFilePath), qPrintable(appFilePath));
- const QString dllFilePath = fullInstallPrefix + dllDir + '/' + dllFileName;
+ const QString dllFilePath = dll.absolutePath(fullInstallPrefix);
QVERIFY2(QFile::exists(dllFilePath), qPrintable(dllFilePath));
if (isWindows) {
- const QString libFilePath = fullInstallPrefix + libDir + "/thelib.lib";
+ const BinaryInfo lib = {
+ "thelib.lib",
+ libDir.isEmpty() ? "/lib" : libDir,
+ ""
+ };
+ const QString libFilePath = lib.absolutePath(fullInstallPrefix);
QVERIFY2(QFile::exists(libFilePath), qPrintable(libFilePath));
}
+ const QString pluginFilePath = plugin.absolutePath(fullInstallPrefix);
+ QVERIFY2(QFile::exists(pluginFilePath), qPrintable(pluginFilePath));
+
+ const QString appDsymFilePath = appDsym.absolutePath(fullInstallPrefix);
+ QVERIFY2(QFileInfo(appDsymFilePath).exists(), qPrintable(appDsymFilePath));
+ const QString dllDsymFilePath = dllDsym.absolutePath(fullInstallPrefix);
+ QVERIFY2(QFileInfo(dllDsymFilePath).exists(), qPrintable(dllDsymFilePath));
+ const QString pluginDsymFilePath = pluginDsym.absolutePath(fullInstallPrefix);
+ QVERIFY2(QFile::exists(pluginDsymFilePath), qPrintable(pluginDsymFilePath));
}
void TestBlackbox::inputsFromDependencies()
@@ -3887,7 +4653,7 @@ void TestBlackbox::installPackage()
cleanOutputLines.push_back(trimmedLine);
}
QCOMPARE(cleanOutputLines.size(), 3);
- for (const QByteArray &line : qAsConst(cleanOutputLines)) {
+ for (const QByteArray &line : std::as_const(cleanOutputLines)) {
QVERIFY2(line.contains("public_tool") || line.contains("mylib") || line.contains("lib.h"),
line.constData());
}
@@ -3915,6 +4681,9 @@ void TestBlackbox::installable()
void TestBlackbox::installableAsAuxiliaryInput()
{
QDir::setCurrent(testDataDir + "/installable-as-auxiliary-input");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QCOMPARE(runQbs(QbsRunParameters("run")), 0);
QVERIFY2(m_qbsStdout.contains("f-impl"), m_qbsStdout.constData());
}
@@ -3931,6 +4700,33 @@ void TestBlackbox::installTree()
QVERIFY(QFile::exists(installRoot + "content/subdir2/baz.txt"));
}
+void TestBlackbox::invalidArtifactPath_data()
+{
+ QTest::addColumn<QString>("baseDir");
+ QTest::addColumn<bool>("isValid");
+
+ QTest::newRow("inside, normal case") << "subdir" << true;
+ QTest::newRow("inside, build dir 1") << "project.buildDirectory" << true;
+ QTest::newRow("inside, build dir 2") << "subdir/.." << true;
+ QTest::newRow("outside, absolute") << "/tmp" << false;
+ QTest::newRow("outside, relative 1") << "../../" << false;
+ QTest::newRow("outside, relative 2") << "subdir/../../.." << false;
+}
+
+void TestBlackbox::invalidArtifactPath()
+{
+ QFETCH(QString, baseDir);
+ QFETCH(bool, isValid);
+
+ rmDirR(relativeBuildDir());
+ QDir::setCurrent(testDataDir + "/invalid-artifact-path");
+ QbsRunParameters params(QStringList("project.artifactDir:" + baseDir));
+ params.expectFailure = !isValid;
+ QCOMPARE(runQbs(params) == 0, isValid);
+ if (!isValid)
+ QVERIFY2(m_qbsStderr.contains("outside of build directory"), m_qbsStderr.constData());
+}
+
void TestBlackbox::invalidCommandProperty_data()
{
QTest::addColumn<QString>("errorType");
@@ -3961,7 +4757,7 @@ void TestBlackbox::invalidLibraryNames()
QbsRunParameters params(QStringList("project.valueIndex:" + index));
params.expectFailure = !success;
QCOMPARE(runQbs(params) == 0, success);
- for (const QString &diag : qAsConst(diagnostics))
+ for (const QString &diag : std::as_const(diagnostics))
QVERIFY2(m_qbsStderr.contains(diag.toLocal8Bit()), m_qbsStderr.constData());
}
@@ -4022,8 +4818,8 @@ void TestBlackbox::cli()
QCOMPARE(status, 0);
const SettingsPtr s = settings();
- Profile p("qbs_autotests-cli", s.get());
- const QStringList toolchain = p.value("qbs.toolchain").toStringList();
+ qbs::Profile p("qbs_autotests-cli", s.get());
+ const QStringList toolchain = profileToolchain(p);
if (!p.exists() || !(toolchain.contains("dotnet") || toolchain.contains("mono")))
QSKIP("No suitable Common Language Infrastructure test profile");
@@ -4114,7 +4910,7 @@ void TestBlackbox::jsExtensionsFileInfo()
QVERIFY(output.exists());
QVERIFY(output.open(QIODevice::ReadOnly));
const QList<QByteArray> lines = output.readAll().trimmed().split('\n');
- QCOMPARE(lines.size(), 26);
+ QCOMPARE(lines.size(), 28);
int i = 0;
QCOMPARE(lines.at(i++).trimmed().constData(), "blubb");
QCOMPARE(lines.at(i++).trimmed().constData(), qUtf8Printable(
@@ -4143,11 +4939,52 @@ void TestBlackbox::jsExtensionsFileInfo()
QCOMPARE(lines.at(i++).trimmed().constData(), "../blubb.tar.gz");
QCOMPARE(lines.at(i++).trimmed().constData(), "\\tmp\\blubb.tar.gz");
QCOMPARE(lines.at(i++).trimmed().constData(), "c:\\tmp\\blubb.tar.gz");
+ QCOMPARE(lines.at(i++).trimmed().constData(), qUtf8Printable(HostOsInfo::pathListSeparator()));
+ QCOMPARE(lines.at(i++).trimmed().constData(), qUtf8Printable(HostOsInfo::pathSeparator()));
+}
+
+void TestBlackbox::jsExtensionsHost()
+{
+ QDir::setCurrent(testDataDir + "//jsextensions-host");
+ QbsRunParameters params(QStringList { "-f", "host.qbs" });
+ QCOMPARE(runQbs(params), 0);
+ QFile output("output.txt");
+ QVERIFY(output.exists());
+ QVERIFY(output.open(QIODevice::ReadOnly));
+ const QList<QByteArray> lines = output.readAll().trimmed().split('\n');
+ QCOMPARE(lines.size(), 10);
+ int i = 0;
+ QCOMPARE(lines.at(i++).trimmed().constData(), "architecture: " +
+ HostOsInfo::hostOSArchitecture());
+ QStringList list;
+ for (const auto &s : HostOsInfo::canonicalOSIdentifiers(HostOsInfo::hostOSIdentifier()))
+ list.push_back(s);
+ QCOMPARE(lines.at(i++).trimmed().constData(), "os: " + list.join(','));
+ QCOMPARE(lines.at(i++).trimmed().constData(), "platform: " + HostOsInfo::hostOSIdentifier());
+ QCOMPARE(lines.at(i++).trimmed().constData(), "osVersion: " +
+ HostOsInfo::hostOsVersion().toString());
+ QCOMPARE(lines.at(i++).trimmed().constData(), "osBuildVersion: " +
+ (HostOsInfo::hostOsBuildVersion().isNull() ? "undefined" :
+ HostOsInfo::hostOsBuildVersion()));
+ QCOMPARE(lines.at(i++).trimmed().constData(), "osVersionParts: " +
+ HostOsInfo::hostOsVersion().toString(','));
+ QCOMPARE(lines.at(i++).trimmed().constData(), "osVersionMajor: " + QString::number(
+ HostOsInfo::hostOsVersion().majorVersion()));
+ QCOMPARE(lines.at(i++).trimmed().constData(), "osVersionMinor: " + QString::number(
+ HostOsInfo::hostOsVersion().minorVersion()));
+ QCOMPARE(lines.at(i++).trimmed().constData(), "osVersionPatch: " + QString::number(
+ HostOsInfo::hostOsVersion().patchLevel()));
+ QString nullDevice = HostOsInfo::isWindowsHost() ? QStringLiteral("NUL") :
+ QStringLiteral("/dev/null");
+ QCOMPARE(lines.at(i++).trimmed().constData(), "nullDevice: " + nullDevice);
}
void TestBlackbox::jsExtensionsProcess()
{
QDir::setCurrent(testDataDir + "/jsextensions-process");
+ QCOMPARE(runQbs({"resolve", {"-f", "process.qbs"}}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters params(QStringList() << "-f" << "process.qbs");
QCOMPARE(runQbs(params), 0);
QFile output("output.txt");
@@ -4249,6 +5086,20 @@ void TestBlackbox::jsExtensionsBinaryFile()
QCOMPARE(data.at(5), char(0x05));
QCOMPARE(data.at(6), char(0x06));
QCOMPARE(data.at(7), char(0xFF));
+ QFile destination2("destination2.dat");
+ QVERIFY(destination2.exists());
+ QVERIFY(destination2.open(QIODevice::ReadOnly));
+ QCOMPARE(destination2.readAll(), data);
+}
+
+void TestBlackbox::lastModuleCandidateBroken()
+{
+ QDir::setCurrent(testDataDir + "/last-module-candidate-broken");
+ QbsRunParameters params;
+ params.expectFailure = true;
+ QVERIFY(runQbs(params) != 0);
+ QVERIFY2(m_qbsStderr.contains("Dependency 'Foo' not found for product "
+ "'last-module-candidate-broken'"), m_qbsStderr);
}
void TestBlackbox::ld()
@@ -4264,6 +5115,9 @@ void TestBlackbox::symbolLinkMode()
QDir::setCurrent(testDataDir + "/symbolLinkMode");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters params;
params.command = "run";
const QStringList commonArgs{"-p", "driver", "--setup-run-env-config",
@@ -4351,6 +5205,7 @@ void TestBlackbox::linkerVariant_data()
QTest::newRow("default") << QString();
QTest::newRow("bfd") << QString("bfd");
QTest::newRow("gold") << QString("gold");
+ QTest::newRow("mold") << QString("mold");
}
void TestBlackbox::linkerVariant()
@@ -4378,6 +5233,9 @@ void TestBlackbox::lexyacc()
if (!lexYaccExist())
QSKIP("lex or yacc not present");
QDir::setCurrent(testDataDir + "/lexyacc/one-grammar");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QCOMPARE(runQbs(), 0);
const QString parserBinary = relativeExecutableFilePath("one-grammar");
QProcess p;
@@ -4393,7 +5251,7 @@ void TestBlackbox::lexyacc()
env.insert("PATH", dir);
p.setProcessEnvironment(env);
}
- p.start(parserBinary);
+ p.start(parserBinary, QStringList());
QVERIFY2(p.waitForStarted(), qPrintable(p.errorString()));
p.write("a && b || c && !d");
p.closeWriteChannel();
@@ -4481,22 +5339,20 @@ void TestBlackbox::lexyaccOutputs_data()
void TestBlackbox::linkerLibraryDuplicates()
{
- const SettingsPtr s = settings();
- Profile buildProfile(profileName(), s.get());
- QStringList toolchain = buildProfile.value("qbs.toolchain").toStringList();
- if (!toolchain.contains("gcc"))
- QSKIP("linkerLibraryDuplicates test only applies to GCC toolchain");
-
QDir::setCurrent(testDataDir + "/linker-library-duplicates");
rmDirR(relativeBuildDir());
-
QFETCH(QString, removeDuplicateLibraries);
QStringList runParams;
- if (!removeDuplicateLibraries.isEmpty()) {
+ if (!removeDuplicateLibraries.isEmpty())
runParams.append(removeDuplicateLibraries);
- }
QCOMPARE(runQbs(QbsRunParameters("resolve", runParams)), 0);
+ const bool isGcc = m_qbsStdout.contains("is gcc: true");
+ const bool isNotGcc = m_qbsStdout.contains("is gcc: false");
+ if (isNotGcc)
+ QSKIP("linkerLibraryDuplicates test only applies to GCC toolchain");
+ QVERIFY(isGcc);
+
QCOMPARE(runQbs(QStringList { "--command-echo-mode", "command-line" }), 0);
const QByteArrayList output = m_qbsStdout.split('\n');
QByteArray linkLine;
@@ -4561,25 +5417,27 @@ void TestBlackbox::linkerLibraryDuplicates_data()
void TestBlackbox::linkerScripts()
{
- const SettingsPtr s = settings();
- Profile buildProfile(profileName(), s.get());
- QStringList toolchain = buildProfile.value("qbs.toolchain").toStringList();
- if (!toolchain.contains("gcc") || targetOs() != HostOsInfo::HostOsLinux)
- QSKIP("linker script test only applies to Linux ");
-
- QbsRunParameters runParams(QStringList()
-// << "--log-level" << "debug"
- << ("qbs.installRoot:" + QDir::currentPath()));
const QString sourceDir = QDir::cleanPath(testDataDir + "/linkerscripts");
+ QbsRunParameters runParams("resolve", {"qbs.installRoot:" + QDir::currentPath()});
runParams.buildDirectory = sourceDir + "/build";
runParams.workingDir = sourceDir;
QCOMPARE(runQbs(runParams), 0);
+ const bool isGcc = m_qbsStdout.contains("is Linux gcc: true");
+ const bool isNotGcc = m_qbsStdout.contains("is Linux gcc: false");
+ if (isNotGcc)
+ QSKIP("linker script test only applies to Linux");
+ QVERIFY(isGcc);
+
+ runParams.command = "build";
+ QCOMPARE(runQbs(runParams), 0);
const QString output = QString::fromLocal8Bit(m_qbsStderr);
- QRegExp pattern(".*---(.*)---.*");
- QVERIFY2(pattern.exactMatch(output), qPrintable(output));
+ const QRegularExpression pattern(QRegularExpression::anchoredPattern(".*---(.*)---.*"),
+ QRegularExpression::DotMatchesEverythingOption);
+ const QRegularExpressionMatch match = pattern.match(output);
+ QVERIFY2(match.hasMatch(), qPrintable(output));
QCOMPARE(pattern.captureCount(), 1);
- const QString nmPath = pattern.capturedTexts().at(1);
+ const QString nmPath = match.captured(1);
if (!QFile::exists(nmPath))
QSKIP("Cannot check for symbol presence: No nm found.");
@@ -4652,6 +5510,26 @@ void TestBlackbox::linkerScripts()
"TEST_SYMBOL_FROM_RECURSIVE_MODIFIED"}));
}
+void TestBlackbox::linkerModuleDefinition()
+{
+ QDir::setCurrent(testDataDir + "/linker-module-definition");
+ QCOMPARE(runQbs({"build"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ QCOMPARE(runQbs({"run"}), 0);
+ const auto verifyOutput = [this](const QByteArrayList &symbols) {
+ for (const QByteArray &symbol : symbols) {
+ if (!m_qbsStdout.contains(symbol)) {
+ qDebug() << "Expected symbol" << symbol
+ << "not found in" << m_qbsStdout;
+ return false;
+ }
+ }
+ return true;
+ };
+ QVERIFY(verifyOutput({"foo", "bar"}));
+}
+
void TestBlackbox::listProducts()
{
QDir::setCurrent(testDataDir + "/list-products");
@@ -4680,7 +5558,7 @@ void TestBlackbox::listPropertyOrder()
const QbsRunParameters params(QStringList() << "-q");
QCOMPARE(runQbs(params), 0);
const QByteArray firstOutput = m_qbsStderr;
- QVERIFY(firstOutput.contains("listProp = [\"higher1\",\"higher2\",\"higher3\"]"));
+ QVERIFY(firstOutput.contains("listProp = [\"product\",\"higher3\",\"higher2\",\"higher1\",\"lower\"]"));
for (int i = 0; i < 25; ++i) {
rmDirR(relativeBuildDir());
QCOMPARE(runQbs(params), 0);
@@ -4696,16 +5574,6 @@ void TestBlackbox::require()
QCOMPARE(runQbs(), 0);
}
-void TestBlackbox::requireDeprecated()
-{
- QDir::setCurrent(testDataDir + "/require-deprecated");
- QCOMPARE(runQbs(), 0);
- QVERIFY2(m_qbsStderr.contains("loadExtension() function is deprecated"),
- m_qbsStderr.constData());
- QVERIFY2(m_qbsStderr.contains("loadFile() function is deprecated"),
- m_qbsStderr.constData());
-}
-
void TestBlackbox::rescueTransformerData()
{
QDir::setCurrent(testDataDir + "/rescue-transformer-data");
@@ -4767,6 +5635,9 @@ void TestBlackbox::multipleConfigurations()
void TestBlackbox::multiplexedTool()
{
QDir::setCurrent(testDataDir + "/multiplexed-tool");
+ QCOMPARE(runQbs(QStringLiteral("resolve")), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QCOMPARE(runQbs(), 0);
QCOMPARE(m_qbsStdout.count("creating tool.out"), 4);
}
@@ -4922,6 +5793,8 @@ void TestBlackbox::propertyPrecedence()
// Case 1: [cmdline=0,prod=0,export=0,nonleaf=0,profile=0]
QCOMPARE(runQbs(params), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
+
QVERIFY2(m_qbsStdout.contains("scalar prop: leaf\n")
&& m_qbsStdout.contains("list prop: [\"leaf\"]\n"),
m_qbsStdout.constData());
@@ -4930,6 +5803,8 @@ void TestBlackbox::propertyPrecedence()
// Case 2: [cmdline=0,prod=0,export=0,nonleaf=0,profile=1]
switchProfileContents(profile.p, s.get(), true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
+
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: profile\n")
&& m_qbsStdout.contains("list prop: [\"profile\"]\n"),
@@ -4941,6 +5816,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), false);
switchFileContents(nonleafFile, true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: nonleaf\n")
&& m_qbsStdout.contains("list prop: [\"nonleaf\",\"leaf\"]\n"),
@@ -4949,6 +5825,7 @@ void TestBlackbox::propertyPrecedence()
// Case 4: [cmdline=0,prod=0,export=0,nonleaf=1,profile=1]
switchProfileContents(profile.p, s.get(), true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: nonleaf\n")
&& m_qbsStdout.contains("list prop: [\"nonleaf\",\"profile\"]\n"),
@@ -4961,6 +5838,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(nonleafFile, false);
switchFileContents(depFile, true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: export\n")
&& m_qbsStdout.contains("list prop: [\"export\",\"leaf\"]\n"),
@@ -4969,16 +5847,18 @@ void TestBlackbox::propertyPrecedence()
// Case 6: [cmdline=0,prod=0,export=1,nonleaf=0,profile=1]
switchProfileContents(profile.p, s.get(), true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: export\n")
&& m_qbsStdout.contains("list prop: [\"export\",\"profile\"]\n"),
m_qbsStdout.constData());
+
// Case 7: [cmdline=0,prod=0,export=1,nonleaf=1,profile=0]
switchProfileContents(profile.p, s.get(), false);
switchFileContents(nonleafFile, true);
QCOMPARE(runQbs(resolveParams), 0);
- QCOMPARE(runQbs(params), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData()); QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: export\n")
&& m_qbsStdout.contains("list prop: [\"export\",\"nonleaf\",\"leaf\"]\n"),
m_qbsStdout.constData());
@@ -4986,6 +5866,7 @@ void TestBlackbox::propertyPrecedence()
// Case 8: [cmdline=0,prod=0,export=1,nonleaf=1,profile=1]
switchProfileContents(profile.p, s.get(), true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: export\n")
&& m_qbsStdout.contains("list prop: [\"export\",\"nonleaf\",\"profile\"]\n"),
@@ -4999,6 +5880,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(depFile, false);
switchFileContents(productFile, true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: product\n")
&& m_qbsStdout.contains("list prop: [\"product\",\"leaf\"]\n"),
@@ -5007,6 +5889,7 @@ void TestBlackbox::propertyPrecedence()
// Case 10: [cmdline=0,prod=1,export=0,nonleaf=0,profile=1]
switchProfileContents(profile.p, s.get(), true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: product\n")
&& m_qbsStdout.contains("list prop: [\"product\",\"profile\"]\n"),
@@ -5016,6 +5899,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), false);
switchFileContents(nonleafFile, true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: product\n")
&& m_qbsStdout.contains("list prop: [\"product\",\"nonleaf\",\"leaf\"]\n"),
@@ -5024,6 +5908,7 @@ void TestBlackbox::propertyPrecedence()
// Case 12: [cmdline=0,prod=1,export=0,nonleaf=1,profile=1]
switchProfileContents(profile.p, s.get(), true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: product\n")
&& m_qbsStdout.contains("list prop: [\"product\",\"nonleaf\",\"profile\"]\n"),
@@ -5034,6 +5919,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(nonleafFile, false);
switchFileContents(depFile, true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: product\n")
&& m_qbsStdout.contains("list prop: [\"product\",\"export\",\"leaf\"]\n"),
@@ -5042,6 +5928,7 @@ void TestBlackbox::propertyPrecedence()
// Case 14: [cmdline=0,prod=1,export=1,nonleaf=0,profile=1]
switchProfileContents(profile.p, s.get(), true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: product\n")
&& m_qbsStdout.contains("list prop: [\"product\",\"export\",\"profile\"]\n"),
@@ -5051,6 +5938,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), false);
switchFileContents(nonleafFile, true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: product\n")
&& m_qbsStdout.contains("list prop: [\"product\",\"export\",\"nonleaf\",\"leaf\"]\n"),
@@ -5059,6 +5947,7 @@ void TestBlackbox::propertyPrecedence()
// Case 16: [cmdline=0,prod=1,export=1,nonleaf=1,profile=1]
switchProfileContents(profile.p, s.get(), true);
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: product\n")
&& m_qbsStdout.contains("list prop: [\"product\",\"export\",\"nonleaf\",\"profile\"]\n"),
@@ -5072,6 +5961,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(productFile, false);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5081,6 +5971,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5091,6 +5982,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(nonleafFile, true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5100,6 +5992,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5111,6 +6004,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(depFile, true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5120,6 +6014,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5130,6 +6025,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(nonleafFile, true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5139,6 +6035,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5151,6 +6048,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(productFile, true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5160,6 +6058,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5170,6 +6069,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(nonleafFile, true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5179,6 +6079,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5190,6 +6091,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(depFile, true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5199,6 +6101,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5209,6 +6112,7 @@ void TestBlackbox::propertyPrecedence()
switchFileContents(nonleafFile, true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5218,6 +6122,7 @@ void TestBlackbox::propertyPrecedence()
switchProfileContents(profile.p, s.get(), true);
resolveParams.arguments << "modules.leaf.scalarProp:cmdline" << "modules.leaf.listProp:cmdline";
QCOMPARE(runQbs(resolveParams), 0);
+ QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData());
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("scalar prop: cmdline\n")
&& m_qbsStdout.contains("list prop: [\"cmdline\"]\n"),
@@ -5247,10 +6152,19 @@ void TestBlackbox::productDependenciesByType()
QVERIFY(apps.empty());
}
+void TestBlackbox::productInExportedModule()
+{
+ QDir::setCurrent(testDataDir + "/product-in-exported-module");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY2(m_qbsStdout.contains("product: importing"), m_qbsStdout.constData());
+}
+
void TestBlackbox::properQuoting()
{
QDir::setCurrent(testDataDir + "/proper quoting");
QCOMPARE(runQbs(), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters params(QStringLiteral("run"), QStringList() << "-q" << "-p" << "Hello World");
params.expectFailure = true; // Because the exit code is non-zero.
QCOMPARE(runQbs(params), 156);
@@ -5272,15 +6186,27 @@ void TestBlackbox::protobuf_data()
{
QTest::addColumn<QString>("projectFile");
QTest::addColumn<QStringList>("properties");
+ QTest::addColumn<bool>("hasModules");
QTest::addColumn<bool>("successExpected");
- QTest::newRow("cpp") << QString("addressbook_cpp.qbs") << QStringList() << true;
- QTest::newRow("objc") << QString("addressbook_objc.qbs") << QStringList() << true;
- QTest::newRow("import") << QString("import.qbs") << QStringList() << true;
+ QTest::newRow("cpp-pkgconfig")
+ << QString("addressbook_cpp.qbs")
+ << QStringList({"project.qbsModuleProviders:qbspkgconfig"}) << true << true;
+ QTest::newRow("cpp-conan") << QString("addressbook_cpp.qbs")
+ << QStringList(
+ {"project.qbsModuleProviders:conan",
+ "qbs.buildVariant:release",
+ "moduleProviders.conan.installDirectory:build"})
+ << true << true;
+ QTest::newRow("objc") << QString("addressbook_objc.qbs") << QStringList() << false << true;
+ QTest::newRow("nanopb") << QString("addressbook_nanopb.qbs") << QStringList() << false << true;
+ QTest::newRow("import") << QString("import.qbs") << QStringList() << true << true;
QTest::newRow("missing import dir") << QString("needs-import-dir.qbs")
- << QStringList() << false;
+ << QStringList() << true << false;
QTest::newRow("provided import dir")
<< QString("needs-import-dir.qbs")
- << QStringList("products.app.theImportDir:subdir") << true;
+ << QStringList("products.app.theImportDir:subdir") << true << true;
+ QTest::newRow("create proto library")
+ << QString("create-proto-library.qbs") << QStringList() << true << true;
}
void TestBlackbox::protobuf()
@@ -5288,20 +6214,55 @@ void TestBlackbox::protobuf()
QDir::setCurrent(testDataDir + "/protobuf");
QFETCH(QString, projectFile);
QFETCH(QStringList, properties);
+ QFETCH(bool, hasModules);
QFETCH(bool, successExpected);
rmDirR(relativeBuildDir());
+
+ if (QTest::currentDataTag() == QLatin1String("cpp-conan")) {
+ if (!prepareAndRunConan())
+ QSKIP("conan is not prepared, check messages above");
+ }
+
QbsRunParameters resolveParams("resolve", QStringList{"-f", projectFile} << properties);
QCOMPARE(runQbs(resolveParams), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
const bool withProtobuf = m_qbsStdout.contains("has protobuf: true");
const bool withoutProtobuf = m_qbsStdout.contains("has protobuf: false");
QVERIFY2(withProtobuf || withoutProtobuf, m_qbsStdout.constData());
if (withoutProtobuf)
QSKIP("protobuf module not present");
+ const bool hasMods = m_qbsStdout.contains("has modules: true");
+ const bool dontHaveMods = m_qbsStdout.contains("has modules: false");
+ QVERIFY2(hasMods == !dontHaveMods, m_qbsStdout.constData());
+ QCOMPARE(hasMods, hasModules);
QbsRunParameters runParams("run");
runParams.expectFailure = !successExpected;
QCOMPARE(runQbs(runParams) == 0, successExpected);
}
+void TestBlackbox::protobufLibraryInstall()
+{
+ QDir::setCurrent(testDataDir + "/protobuf-library-install");
+ rmDirR(relativeBuildDir());
+ QbsRunParameters resolveParams("resolve", QStringList{"qbs.installPrefix:/usr/local"});
+ QCOMPARE(runQbs(resolveParams), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ const bool withProtobuf = m_qbsStdout.contains("has protobuf: true");
+ const bool withoutProtobuf = m_qbsStdout.contains("has protobuf: false");
+ QVERIFY2(withProtobuf || withoutProtobuf, m_qbsStdout.constData());
+ if (withoutProtobuf)
+ QSKIP("protobuf module not present");
+ QbsRunParameters buildParams("build");
+ buildParams.expectFailure = false;
+ QCOMPARE(runQbs(buildParams), 0);
+
+ const QString installRootInclude = relativeBuildDir() + "/install-root/usr/local/include";
+ QVERIFY(QFileInfo::exists(installRootInclude + "/hello.pb.h") &&
+ QFileInfo::exists(installRootInclude + "/hello/world.pb.h"));
+}
+
void TestBlackbox::pseudoMultiplexing()
{
// This is "pseudo-multiplexing" on all platforms that initialize qbs.architectures
@@ -5411,7 +6372,158 @@ void TestBlackbox::qbsConfig()
if (!canWriteToSystemSettings) {
QVERIFY2(m_qbsStderr.contains("You do not have permission to write to that location."),
m_qbsStderr.constData());
+ } else {
+ // cleanup system settings
+ params.arguments = QStringList{"--system", "--unset", "key.subkey.scalar"};
+ QCOMPARE(runQbs(params) == 0, canWriteToSystemSettings);
+ }
+}
+
+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");
+}
+
+void TestBlackbox::qbsConfigImport()
+{
+ QFETCH(QString, format);
+
+ QDir::setCurrent(testDataDir + "/qbs-config-import-export");
+
+ QbsRunParameters params("config");
+ QTemporaryDir settingsDir;
+ QVERIFY(settingsDir.isValid());
+ const QStringList settingsDirArgs = QStringList{"--settings-dir", settingsDir.path()};
+ params.arguments = settingsDirArgs;
+ params.arguments << "--import" << "config." + format;
+
+ QCOMPARE(runQbs(params), 0);
+
+ params.arguments = settingsDirArgs;
+ params.arguments << "--list";
+ QCOMPARE(runQbs(params), 0);
+ const QByteArray output = m_qbsStdout;
+ const auto lines = output.split('\n');
+ QCOMPARE(lines.count(), 5);
+ QCOMPARE(lines[0], "group.key1: \"value1\"");
+ QCOMPARE(lines[1], "group.key2: \"value2\"");
+ QCOMPARE(lines[2], "key: \"value\"");
+ QCOMPARE(lines[3], "listKey: [\"valueOne\", \"valueTwo\"]");
+ QCOMPARE(lines[4], "");
+}
+
+void TestBlackbox::qbsConfigImport_data()
+{
+ QTest::addColumn<QString>("format");
+
+ QTest::newRow("text") << QStringLiteral("txt");
+ QTest::newRow("json") << QStringLiteral("json");
+}
+
+void TestBlackbox::qbsConfigExport()
+{
+ QFETCH(QString, format);
+
+ QDir::setCurrent(testDataDir + "/qbs-config-import-export");
+
+ QbsRunParameters params("config");
+ QTemporaryDir settingsDir;
+ const QString fileName = "config." + format;
+ const QString filePath = settingsDir.path() + "/" + fileName;
+ QVERIFY(settingsDir.isValid());
+ const QStringList commonArgs = QStringList{"--settings-dir", settingsDir.path(), "--user"};
+
+ std::pair<QString, QString> values[] = {
+ {"key", "value"},
+ {"listKey", "[\"valueOne\",\"valueTwo\"]"},
+ {"group.key1", "value1"},
+ {"group.key2", "value2"}
+ };
+
+ for (const auto &value: values) {
+ params.arguments = commonArgs;
+ params.arguments << value.first << value.second;
+ QCOMPARE(runQbs(params), 0);
+ }
+
+ params.arguments = commonArgs;
+ params.arguments << "--export" << filePath;
+
+ QCOMPARE(runQbs(params), 0);
+
+ QVERIFY(QFileInfo(filePath).canonicalPath() != QFileInfo(fileName).canonicalPath());
+
+ QFile exported(filePath);
+ QFile expected(fileName);
+
+ QVERIFY(exported.open(QIODevice::ReadOnly | QIODevice::Text));
+ QVERIFY(expected.open(QIODevice::ReadOnly | QIODevice::Text));
+
+ QCOMPARE(exported.readAll(), expected.readAll());
+}
+
+void TestBlackbox::qbsConfigExport_data()
+{
+ QTest::addColumn<QString>("format");
+
+ QTest::newRow("text") << QStringLiteral("txt");
+ QTest::newRow("json") << QStringLiteral("json");
}
static QJsonObject getNextSessionPacket(QProcess &session, QByteArray &data)
@@ -5450,6 +6562,137 @@ static QJsonObject getNextSessionPacket(QProcess &session, QByteArray &data)
return QJsonDocument::fromJson(QByteArray::fromBase64(msg)).object();
}
+static void sendSessionPacket(QProcess &sessionProc, const QJsonObject &message)
+{
+ const QByteArray data = QJsonDocument(message).toJson().toBase64();
+ sessionProc.write("qbsmsg:");
+ sessionProc.write(QByteArray::number(data.length()));
+ sessionProc.write("\n");
+ sessionProc.write(data);
+}
+
+void TestBlackbox::qbsLanguageServer_data()
+{
+ QTest::addColumn<QString>("request");
+ QTest::addColumn<QString>("location");
+ QTest::addColumn<QString>("insertLocation");
+ QTest::addColumn<QString>("insertString");
+ QTest::addColumn<QString>("expectedReply");
+
+ QTest::addRow("follow to module") << "--goto-def"
+ << (testDataDir + "/lsp/lsp.qbs:4:9")
+ << QString() << QString()
+ << (testDataDir + "/lsp/modules/m/m.qbs:1:1");
+ QTest::addRow("follow to submodules")
+ << "--goto-def"
+ << (testDataDir + "/lsp/lsp.qbs:5:35")
+ << QString() << QString()
+ << ((testDataDir + "/lsp/modules/Prefix/m1/m1.qbs:1:1\n")
+ + (testDataDir + "/lsp/modules/Prefix/m2/m2.qbs:1:1\n")
+ + (testDataDir + "/lsp/modules/Prefix/m3/m3.qbs:1:1"));
+ QTest::addRow("follow to product")
+ << "--goto-def" << (testDataDir + "/lsp/lsp.qbs:9:19") << QString() << QString()
+ << (testDataDir + "/lsp/lsp.qbs:2:5");
+ QTest::addRow("follow to module, non-invalidating insert")
+ << "--goto-def" << (testDataDir + "/lsp/lsp.qbs:4:9") << "5:9"
+ << QString("property bool dummy\n") << (testDataDir + "/lsp/modules/m/m.qbs:1:1");
+ QTest::addRow("follow to module, invalidating insert")
+ << "--goto-def" << (testDataDir + "/lsp/lsp.qbs:4:9") << QString()
+ << QString("property bool dummy\n") << QString();
+ QTest::addRow("completion: LHS, module prefix")
+ << "--completion" << (testDataDir + "/lsp/lsp.qbs:7:1") << QString() << QString("P")
+ << QString("Prefix.m1\nPrefix.m2\nPrefix.m3");
+ QTest::addRow("completion: LHS, module name")
+ << "--completion" << (testDataDir + "/lsp/lsp.qbs:7:1") << QString() << QString("Prefix.m")
+ << QString("m1\nm2\nm3");
+ QTest::addRow("completion: LHS, module property right after dot")
+ << "--completion" << (testDataDir + "/lsp/lsp.qbs:7:1") << QString()
+ << QString("Prefix.m1.") << QString("p1 bool\np2 string\nx bool");
+ QTest::addRow("completion: LHS, module property with identifier prefix")
+ << "--completion" << (testDataDir + "/lsp/lsp.qbs:7:1") << QString()
+ << QString("Prefix.m1.p") << QString("p1 bool\np2 string");
+ QTest::addRow("completion: simple RHS, module property")
+ << "--completion" << (testDataDir + "/lsp/lsp.qbs:7:1") << QString()
+ << QString("property bool dummy: Prefix.m1.p") << QString("p1 bool\np2 string");
+ QTest::addRow("completion: complex RHS, module property")
+ << "--completion" << (testDataDir + "/lsp/lsp.qbs:7:1") << QString()
+ << QString("property bool dummy: { return Prefix.m1.p") << QString("p1 bool\np2 string");
+}
+
+void TestBlackbox::qbsLanguageServer()
+{
+ QFETCH(QString, request);
+ QFETCH(QString, location);
+ QFETCH(QString, insertLocation);
+ QFETCH(QString, insertString);
+ QFETCH(QString, expectedReply);
+
+ QDir::setCurrent(testDataDir + "/lsp");
+ QProcess sessionProc;
+ sessionProc.start(qbsExecutableFilePath, QStringList("session"));
+
+ QVERIFY(sessionProc.waitForStarted());
+
+ QByteArray incomingData;
+
+ // Wait for and verify hello packet.
+ QJsonObject receivedMessage = getNextSessionPacket(sessionProc, incomingData);
+ const QString socketPath = receivedMessage.value("lsp-socket").toString();
+ QVERIFY(!socketPath.isEmpty());
+
+ // Resolve project.
+ QJsonObject resolveMessage;
+ resolveMessage.insert("type", "resolve-project");
+ resolveMessage.insert("top-level-profile", profileName());
+ resolveMessage.insert("project-file-path", QDir::currentPath() + "/lsp.qbs");
+ resolveMessage.insert("build-root", QDir::currentPath());
+ resolveMessage.insert("settings-directory", settings()->baseDirectory());
+ sendSessionPacket(sessionProc, resolveMessage);
+ bool receivedReply = false;
+ while (!receivedReply) {
+ receivedMessage = getNextSessionPacket(sessionProc, incomingData);
+ QVERIFY(!receivedMessage.isEmpty());
+ const QString msgType = receivedMessage.value("type").toString();
+ if (msgType == "project-resolved") {
+ receivedReply = true;
+ const QJsonObject error = receivedMessage.value("error").toObject();
+ if (!error.isEmpty())
+ qDebug() << error;
+ QVERIFY(error.isEmpty());
+ }
+ }
+ QVERIFY(receivedReply);
+
+ // Employ client app to send request.
+ QProcess lspClient;
+ const QFileInfo qbsFileInfo(qbsExecutableFilePath);
+ const QString clientFilePath = HostOsInfo::appendExecutableSuffix(
+ qbsFileInfo.absolutePath() + "/qbs_lspclient");
+ QStringList args{"--socket", socketPath, request, location};
+ if (!insertString.isEmpty())
+ args << "--insert-code" << insertString;
+ if (!insertLocation.isEmpty())
+ args << "--insert-location" << insertLocation;
+ lspClient.start(clientFilePath, args);
+ QVERIFY2(lspClient.waitForStarted(), qPrintable(lspClient.errorString()));
+ QVERIFY2(lspClient.waitForFinished(), qPrintable(lspClient.errorString()));
+ QString errMsg;
+ if (lspClient.exitStatus() != QProcess::NormalExit)
+ errMsg = lspClient.errorString();
+ if (errMsg.isEmpty())
+ errMsg = QString::fromLocal8Bit(lspClient.readAllStandardError());
+ QVERIFY2(lspClient.exitCode() == 0, qPrintable(errMsg));
+ QVERIFY2(errMsg.isEmpty(), qPrintable(errMsg));
+ QString output = QString::fromUtf8(lspClient.readAllStandardOutput().trimmed());
+ output.replace("\r\n", "\n");
+ QCOMPARE(output, expectedReply);
+
+ QJsonObject quitRequest;
+ quitRequest.insert("type", "quit");
+ sendSessionPacket(sessionProc, quitRequest);
+ QVERIFY(sessionProc.waitForFinished(3000));
+}
+
void TestBlackbox::qbsSession()
{
QDir::setCurrent(testDataDir + "/qbs-session");
@@ -5466,11 +6709,7 @@ void TestBlackbox::qbsSession()
QVERIFY(sessionProc.waitForStarted());
const auto sendPacket = [&sessionProc](const QJsonObject &message) {
- const QByteArray data = QJsonDocument(message).toJson().toBase64();
- sessionProc.write("qbsmsg:");
- sessionProc.write(QByteArray::number(data.length()));
- sessionProc.write("\n");
- sessionProc.write(data);
+ sendSessionPacket(sessionProc, message);
};
static const auto envToJson = [](const QProcessEnvironment &env) {
@@ -5494,8 +6733,8 @@ void TestBlackbox::qbsSession()
// Wait for and verify hello packet.
QJsonObject receivedMessage = getNextSessionPacket(sessionProc, incomingData);
QCOMPARE(receivedMessage.value("type"), "hello");
- QCOMPARE(receivedMessage.value("api-level").toInt(), 1);
- QCOMPARE(receivedMessage.value("api-compat-level").toInt(), 1);
+ QCOMPARE(receivedMessage.value("api-level").toInt(), 5);
+ QCOMPARE(receivedMessage.value("api-compat-level").toInt(), 2);
// Resolve & verify structure
QJsonObject resolveMessage;
@@ -5508,8 +6747,9 @@ void TestBlackbox::qbsSession()
QJsonObject overriddenValues;
overriddenValues.insert("products.theLib.cpp.cxxLanguageVersion", "c++17");
resolveMessage.insert("overridden-properties", overriddenValues);
- resolveMessage.insert("environment", envToJson(QProcessEnvironment::systemEnvironment()));
+ resolveMessage.insert("environment", envToJson(QbsRunParameters::defaultEnvironment()));
resolveMessage.insert("data-mode", "only-if-changed");
+ resolveMessage.insert("max-job-count", 2);
resolveMessage.insert("log-time", true);
resolveMessage.insert("module-properties",
QJsonArray::fromStringList({"cpp.cxxLanguageVersion"}));
@@ -5553,7 +6793,7 @@ void TestBlackbox::qbsSession()
const QJsonObject group = v.toObject();
const QJsonArray sourceArtifacts
= group.value("source-artifacts").toArray();
- const auto findArtifact = [&sourceArtifacts](const QString fileName) {
+ const auto findArtifact = [&sourceArtifacts](const QString &fileName) {
for (const QJsonValue &v : sourceArtifacts) {
const QJsonObject artifact = v.toObject();
if (QFileInfo(artifact.value("file-path").toString()).fileName()
@@ -5815,7 +7055,7 @@ void TestBlackbox::qbsSession()
QCOMPARE(receivedMessage.value("type").toString(), QString("files-added"));
error = receivedMessage.value("error").toObject();
if (!error.isEmpty()) {
- for (const auto &item: error[QStringLiteral("items")].toArray()) {
+ for (const auto item: error[QStringLiteral("items")].toArray()) {
const auto description = QStringLiteral("Project file updates are not enabled");
if (item.toObject()[QStringLiteral("description")].toString().contains(description))
QSKIP("File updates are disabled");
@@ -5823,34 +7063,51 @@ void TestBlackbox::qbsSession()
qDebug() << error;
}
QVERIFY(error.isEmpty());
- QJsonObject projectData = receivedMessage.value("project-data").toObject();
- QJsonArray products = projectData.value("products").toArray();
- bool file1 = false;
- bool file2 = false;
- for (const QJsonValue &v : products) {
- const QJsonObject product = v.toObject();
- const QString productName = product.value("full-display-name").toString();
- const QJsonArray groups = product.value("groups").toArray();
- for (const QJsonValue &v : groups) {
- const QJsonObject group = v.toObject();
- const QString groupName = group.value("name").toString();
- const QJsonArray sourceArtifacts = group.value("source-artifacts").toArray();
- for (const QJsonValue &v : sourceArtifacts) {
- const QString filePath = v.toObject().value("file-path").toString();
- if (filePath.endsWith("file1.cpp")) {
- QCOMPARE(productName, QString("theLib"));
- QCOMPARE(groupName, QString("sources"));
- file1 = true;
- } else if (filePath.endsWith("file2.cpp")) {
- QCOMPARE(productName, QString("theLib"));
- QCOMPARE(groupName, QString("sources"));
- file2 = true;
+
+ receivedReply = false;
+ sendPacket(resolveMessage);
+ while (!receivedReply) {
+ receivedMessage = getNextSessionPacket(sessionProc, incomingData);
+ QVERIFY(!receivedMessage.isEmpty());
+ const QString msgType = receivedMessage.value("type").toString();
+ if (msgType == "project-resolved") {
+ receivedReply = true;
+ const QJsonObject error = receivedMessage.value("error").toObject();
+ if (!error.isEmpty())
+ qDebug() << error;
+ QVERIFY(error.isEmpty());
+ const QJsonObject projectData = receivedMessage.value("project-data").toObject();
+ QJsonArray products = projectData.value("products").toArray();
+ bool file1 = false;
+ bool file2 = false;
+ for (const QJsonValue v : products) {
+ const QJsonObject product = v.toObject();
+ const QString productName = product.value("full-display-name").toString();
+ const QJsonArray groups = product.value("groups").toArray();
+ for (const QJsonValue &v : groups) {
+ const QJsonObject group = v.toObject();
+ const QString groupName = group.value("name").toString();
+ const QJsonArray sourceArtifacts = group.value("source-artifacts").toArray();
+ for (const QJsonValue &v : sourceArtifacts) {
+ const QString filePath = v.toObject().value("file-path").toString();
+ if (filePath.endsWith("file1.cpp")) {
+ QCOMPARE(productName, QString("theLib"));
+ QCOMPARE(groupName, QString("sources"));
+ file1 = true;
+ } else if (filePath.endsWith("file2.cpp")) {
+ QCOMPARE(productName, QString("theLib"));
+ QCOMPARE(groupName, QString("sources"));
+ file2 = true;
+ }
+ }
}
}
+ QVERIFY(file1);
+ QVERIFY(file2);
}
}
- QVERIFY(file1);
- QVERIFY(file2);
+ QVERIFY(receivedReply);
+
receivedReply = false;
receivedProcessResult = false;
bool compiledFile1 = false;
@@ -5909,32 +7166,48 @@ void TestBlackbox::qbsSession()
if (!error.isEmpty())
qDebug() << error;
QVERIFY(error.isEmpty());
- projectData = receivedMessage.value("project-data").toObject();
- products = projectData.value("products").toArray();
- file1 = false;
- file2 = false;
- for (const QJsonValue &v : products) {
- const QJsonObject product = v.toObject();
- const QString productName = product.value("full-display-name").toString();
- const QJsonArray groups = product.value("groups").toArray();
- for (const QJsonValue &v : groups) {
- const QJsonObject group = v.toObject();
- const QString groupName = group.value("name").toString();
- const QJsonArray sourceArtifacts = group.value("source-artifacts").toArray();
- for (const QJsonValue &v : sourceArtifacts) {
- const QString filePath = v.toObject().value("file-path").toString();
- if (filePath.endsWith("file1.cpp")) {
- file1 = true;
- } else if (filePath.endsWith("file2.cpp")) {
- QCOMPARE(productName, QString("theLib"));
- QCOMPARE(groupName, QString("sources"));
- file2 = true;
+ receivedReply = false;
+ sendPacket(resolveMessage);
+ while (!receivedReply) {
+ receivedMessage = getNextSessionPacket(sessionProc, incomingData);
+ QVERIFY(!receivedMessage.isEmpty());
+ const QString msgType = receivedMessage.value("type").toString();
+ if (msgType == "project-resolved") {
+ receivedReply = true;
+ const QJsonObject error = receivedMessage.value("error").toObject();
+ if (!error.isEmpty())
+ qDebug() << error;
+ QVERIFY(error.isEmpty());
+ const QJsonObject projectData = receivedMessage.value("project-data").toObject();
+ QJsonArray products = projectData.value("products").toArray();
+ bool file1 = false;
+ bool file2 = false;
+ for (const QJsonValue v : products) {
+ const QJsonObject product = v.toObject();
+ const QString productName = product.value("full-display-name").toString();
+ const QJsonArray groups = product.value("groups").toArray();
+ for (const QJsonValue &v : groups) {
+ const QJsonObject group = v.toObject();
+ const QString groupName = group.value("name").toString();
+ const QJsonArray sourceArtifacts = group.value("source-artifacts").toArray();
+ for (const QJsonValue &v : sourceArtifacts) {
+ const QString filePath = v.toObject().value("file-path").toString();
+ if (filePath.endsWith("file1.cpp")) {
+ file1 = true;
+ } else if (filePath.endsWith("file2.cpp")) {
+ QCOMPARE(productName, QString("theLib"));
+ QCOMPARE(groupName, QString("sources"));
+ file2 = true;
+ }
+ }
}
}
+ QVERIFY(!file1);
+ QVERIFY(file2);
}
}
- QVERIFY(!file1);
- QVERIFY(file2);
+ QVERIFY(receivedReply);
+
receivedReply = false;
receivedProcessResult = false;
compiledFile1 = false;
@@ -6388,6 +7661,9 @@ void TestBlackbox::assembly()
void TestBlackbox::autotestWithDependencies()
{
QDir::setCurrent(testDataDir + "/autotest-with-dependencies");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QCOMPARE(runQbs(QStringList({"-p", "autotest-runner"})), 0);
QVERIFY2(m_qbsStdout.contains("i am the test app")
&& m_qbsStdout.contains("i am the helper"), m_qbsStdout.constData());
@@ -6397,14 +7673,19 @@ void TestBlackbox::autotestTimeout()
{
QFETCH(QStringList, resolveParams);
QFETCH(bool, expectFailure);
+ QFETCH(QString, errorDetails);
QDir::setCurrent(testDataDir + "/autotest-timeout");
QbsRunParameters resolveParameters("resolve", resolveParams);
QCOMPARE(runQbs(resolveParameters), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters buildParameters(QStringList({"-p", "autotest-runner"}));
buildParameters.expectFailure = expectFailure;
if (expectFailure) {
QVERIFY(runQbs(buildParameters) != 0);
- QVERIFY(m_qbsStderr.contains("cancelled") && m_qbsStderr.contains("timeout"));
+ QVERIFY(
+ m_qbsStderr.contains("cancelled") && m_qbsStderr.contains("timeout")
+ && m_qbsStderr.contains(errorDetails.toLocal8Bit()));
}
else
QVERIFY(runQbs(buildParameters) == 0);
@@ -6414,11 +7695,12 @@ void TestBlackbox::autotestTimeout_data()
{
QTest::addColumn<QStringList>("resolveParams");
QTest::addColumn<bool>("expectFailure");
- QTest::newRow("no timeout") << QStringList() << false;
- QTest::newRow("timeout on test") << QStringList({"products.testApp.autotest.timeout:2"})
- << true;
- QTest::newRow("timeout on runner") << QStringList({"products.autotest-runner.timeout:2"})
- << true;
+ QTest::addColumn<QString>("errorDetails");
+ QTest::newRow("no timeout") << QStringList() << false << QString();
+ QTest::newRow("timeout on test")
+ << QStringList({"products.testApp.autotest.timeout:2"}) << true << QString("testApp");
+ QTest::newRow("timeout on runner")
+ << QStringList({"products.autotest-runner.timeout:2"}) << true << QString("testApp");
}
void TestBlackbox::autotests_data()
@@ -6444,6 +7726,8 @@ void TestBlackbox::autotests()
if (!evilPropertySpec.isEmpty())
resolveParams.arguments << evilPropertySpec;
QCOMPARE(runQbs(resolveParams), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters testParams(QStringList{"-p", "autotest-runner"});
if (!evilPropertySpec.isEmpty())
testParams.expectFailure = true;
@@ -6452,9 +7736,9 @@ void TestBlackbox::autotests()
QVERIFY2(m_qbsStderr.contains(expectedErrorMessage), m_qbsStderr.constData());
return;
}
- QVERIFY2(m_qbsStdout.contains("Running test test1")
- && m_qbsStdout.contains("Running test test2")
- && m_qbsStdout.contains("Running test test3"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("running test test1")
+ && m_qbsStdout.contains("running test test2")
+ && m_qbsStdout.contains("running test test3"), m_qbsStdout.constData());
QCOMPARE(m_qbsStdout.count("PASS"), 2);
QCOMPARE(m_qbsStderr.count("FAIL"), 1);
}
@@ -6543,9 +7827,9 @@ static bool haveMakeNsis()
<< QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS");
QStringList paths = QProcessEnvironment::systemEnvironment().value("PATH")
- .split(HostOsInfo::pathListSeparator(), QString::SkipEmptyParts);
+ .split(HostOsInfo::pathListSeparator(), Qt::SkipEmptyParts);
- for (const QString &key : qAsConst(regKeys)) {
+ for (const QString &key : std::as_const(regKeys)) {
QSettings settings(key, QSettings::NativeFormat);
QString str = settings.value(QStringLiteral(".")).toString();
if (!str.isEmpty())
@@ -6553,7 +7837,7 @@ static bool haveMakeNsis()
}
bool haveMakeNsis = false;
- for (const QString &path : qAsConst(paths)) {
+ for (const QString &path : std::as_const(paths)) {
if (regularFileExists(QDir::fromNativeSeparators(path) +
HostOsInfo::appendExecutableSuffix(QStringLiteral("/makensis")))) {
haveMakeNsis = true;
@@ -6678,12 +7962,16 @@ void TestBlackbox::enableRtti()
void TestBlackbox::envMerging()
{
QDir::setCurrent(testDataDir + "/env-merging");
- QbsRunParameters params;
+ QbsRunParameters params("resolve");
QString pathVal = params.environment.value("PATH");
pathVal.prepend(HostOsInfo::pathListSeparator()).prepend("/opt/blackbox/bin");
const QString keyName = HostOsInfo::isWindowsHost() ? "pATh" : "PATH";
params.environment.insert(keyName, pathVal);
QCOMPARE(runQbs(params), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ params.command = "build";
+ QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains(QByteArray("PATH=/opt/tool/bin")
+ HostOsInfo::pathListSeparator().toLatin1())
&& m_qbsStdout.contains(HostOsInfo::pathListSeparator().toLatin1()
@@ -6774,98 +8062,10 @@ 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(), QString::SkipEmptyParts);
-
- 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();
- Profile p(profileName(), s.get());
+ qbs::Profile p(profileName(), s.get());
int status;
findNodejs(&status);
@@ -6884,6 +8084,13 @@ void TestBlackbox::nodejs()
QSKIP("nodejs.packageManagerFilePath not set and automatic detection failed");
}
+ if (p.value("nodejs.interpreterFilePath").toString().isEmpty()
+ && status != 0 && m_qbsStderr.contains("interpreterPath")) {
+ QSKIP("nodejs.interpreterFilePath not set and automatic detection failed");
+ }
+
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QCOMPARE(status, 0);
QbsRunParameters params;
@@ -6895,8 +8102,11 @@ void TestBlackbox::nodejs()
void TestBlackbox::typescript()
{
+ if (qEnvironmentVariableIsSet("GITHUB_ACTIONS"))
+ QSKIP("Skip this test when running on GitHub");
+
const SettingsPtr s = settings();
- Profile p(profileName(), s.get());
+ qbs::Profile p(profileName(), s.get());
int status;
findTypeScript(&status);
@@ -6930,6 +8140,12 @@ void TestBlackbox::typescript()
QVERIFY(regularFileExists(relativeProductBuildDir("animals") + "/main.js"));
}
+void TestBlackbox::undefinedTargetPlatform()
+{
+ QDir::setCurrent(testDataDir + "/undefined-target-platform");
+ QCOMPARE(runQbs(), 0);
+}
+
void TestBlackbox::importInPropertiesCondition()
{
QDir::setCurrent(testDataDir + "/import-in-properties-condition");
@@ -6959,77 +8175,15 @@ void TestBlackbox::importsConflict()
void TestBlackbox::includeLookup()
{
QDir::setCurrent(testDataDir + "/includeLookup");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters params;
params.command = "run";
QCOMPARE(runQbs(params), 0);
QVERIFY2(m_qbsStdout.contains("definition.."), m_qbsStdout.constData());
}
-static bool haveInnoSetup(const Profile &profile)
-{
- if (profile.value("innosetup.toolchainInstallPath").isValid())
- return true;
-
- QStringList regKeys;
- regKeys << QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Inno Setup 5_is1")
- << QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Inno Setup 5_is1");
-
- QStringList paths = QProcessEnvironment::systemEnvironment().value("PATH")
- .split(HostOsInfo::pathListSeparator(), QString::SkipEmptyParts);
-
- for (const QString &key : qAsConst(regKeys)) {
- QSettings settings(key, QSettings::NativeFormat);
- QString str = settings.value(QStringLiteral("InstallLocation")).toString();
- if (!str.isEmpty())
- paths.prepend(str);
- }
-
- for (const QString &path : qAsConst(paths)) {
- if (regularFileExists(QDir::fromNativeSeparators(path) +
- HostOsInfo::appendExecutableSuffix(QStringLiteral("/ISCC"))))
- return true;
- }
-
- return false;
-}
-
-void TestBlackbox::innoSetup()
-{
- const SettingsPtr s = settings();
- Profile profile(profileName(), s.get());
-
- if (!haveInnoSetup(profile)) {
- QSKIP("Inno Setup is not installed");
- return;
- }
-
- QDir::setCurrent(testDataDir + "/innosetup");
- 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());
-
- if (!haveInnoSetup(profile)) {
- QSKIP("Inno Setup is not installed");
- return;
- }
-
- QDir::setCurrent(testDataDir + "/innosetupDependencies");
- QbsRunParameters params;
- if (!HostOsInfo::isWindowsHost())
- params.arguments << "qbs.targetOS:windows";
- 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");
@@ -7091,7 +8245,7 @@ void TestBlackbox::wildCardsAndRules()
{
QDir::setCurrent(testDataDir + "/wildcards-and-rules");
QCOMPARE(runQbs(), 0);
- QVERIFY(m_qbsStdout.contains("Creating output artifact"));
+ QVERIFY(m_qbsStdout.contains("creating output artifact"));
QFile output(relativeProductBuildDir("wildcards-and-rules") + "/test.mytype");
QVERIFY2(output.open(QIODevice::ReadOnly), qPrintable(output.errorString()));
QCOMPARE(output.readAll().count('\n'), 1);
@@ -7103,7 +8257,7 @@ void TestBlackbox::wildCardsAndRules()
QbsRunParameters params;
params.expectFailure = true;
QCOMPARE(runQbs(params), 0);
- QVERIFY(m_qbsStdout.contains("Creating output artifact"));
+ QVERIFY(m_qbsStdout.contains("creating output artifact"));
QVERIFY2(output.open(QIODevice::ReadOnly), qPrintable(output.errorString()));
QCOMPARE(output.readAll().count('\n'), 2);
output.close();
@@ -7112,17 +8266,49 @@ void TestBlackbox::wildCardsAndRules()
WAIT_FOR_NEW_TIMESTAMP();
touch("dep.dep");
QCOMPARE(runQbs(), 0);
- QVERIFY(m_qbsStdout.contains("Creating output artifact"));
+ QVERIFY(m_qbsStdout.contains("creating output artifact"));
// Add nothing.
QCOMPARE(runQbs(), 0);
- QVERIFY(!m_qbsStdout.contains("Creating output artifact"));
+ QVERIFY(!m_qbsStdout.contains("creating output artifact"));
+}
+
+void TestBlackbox::wildCardsAndChangeTracking_data()
+{
+ QTest::addColumn<QString>("dirToModify");
+ QTest::addColumn<bool>("expectReResolve");
+
+ QTest::newRow("root path") << QString(".") << false;
+ QTest::newRow("dir with recursive match") << QString("recursive1") << false;
+ QTest::newRow("non-recursive base dir") << QString("nonrecursive") << true;
+ QTest::newRow("empty base dir with file patterns") << QString("nonrecursive/empty") << true;
+}
+
+void TestBlackbox::wildCardsAndChangeTracking()
+{
+ QFETCH(QString, dirToModify);
+ QFETCH(bool, expectReResolve);
+
+ const QString srcDir = testDataDir + "/wildcards-and-change-tracking";
+ QDir::setCurrent(srcDir);
+ rmDirR("default");
+ QDir::current().mkdir("nonrecursive/empty");
+
+ QCOMPARE(runQbs({"resolve"}), 0);
+ QVERIFY2(m_qbsStdout.contains("Resolving"), m_qbsStdout.constData());
+ WAIT_FOR_NEW_TIMESTAMP();
+ touch(dirToModify + "/blubb.txt");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ QCOMPARE(m_qbsStdout.contains("Resolving"), expectReResolve);
}
void TestBlackbox::loadableModule()
{
QDir::setCurrent(testDataDir + QLatin1String("/loadablemodule"));
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters params;
params.command = "run";
QCOMPARE(runQbs(params), 0);
@@ -7136,6 +8322,10 @@ void TestBlackbox::localDeployment()
QVERIFY(main.open(QIODevice::ReadOnly));
QByteArray content = main.readAll();
content.replace('\r', "");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+
QbsRunParameters params;
params.command = "run";
QCOMPARE(runQbs(params), 0);
@@ -7149,6 +8339,8 @@ void TestBlackbox::makefileGenerator()
QCOMPARE(runQbs(params), 0);
if (HostOsInfo::isWindowsHost())
return;
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QProcess make;
make.setWorkingDirectory(QDir::currentPath() + '/' + relativeBuildDir());
const QString customInstallRoot = QDir::currentPath() + "/my-install-root";
@@ -7157,7 +8349,7 @@ void TestBlackbox::makefileGenerator()
QVERIFY(QFile::exists(relativeExecutableFilePath("the app")));
QVERIFY(!QFile::exists(relativeBuildGraphFilePath()));
QProcess app;
- app.start('"' + customInstallRoot + "/usr/local/bin/the app\"");
+ app.start(customInstallRoot + "/usr/local/bin/the app", QStringList());
QVERIFY(waitForProcessSuccess(app));
const QByteArray appStdout = app.readAllStandardOutput();
QVERIFY2(appStdout.contains("Hello, World!"), appStdout.constData());
@@ -7171,14 +8363,18 @@ void TestBlackbox::maximumCLanguageVersion()
QDir::setCurrent(testDataDir + "/maximum-c-language-version");
QCOMPARE(runQbs(QbsRunParameters("resolve",
QStringList("products.app.enableNewestModule:true"))), 0);
- if (m_qbsStdout.contains("is msvc"))
- QSKIP("MSVC has no support for setting the C language version.");
+ const bool isMsvc = m_qbsStdout.contains("is msvc: true");
+ if (isMsvc && m_qbsStdout.contains("is old msvc: true"))
+ QSKIP("MSVC supports setting the C language version only from version 16.8, and Clang from version 13.");
QCOMPARE(runQbs(QStringList({"--command-echo-mode", "command-line", "-n"})), 0);
QVERIFY2(m_qbsStdout.contains("c11") || m_qbsStdout.contains("c1x"), m_qbsStdout.constData());
QCOMPARE(runQbs(QbsRunParameters("resolve",
QStringList("products.app.enableNewestModule:false"))), 0);
QCOMPARE(runQbs(QStringList({"--command-echo-mode", "command-line", "-n"})), 0);
- QVERIFY2(m_qbsStdout.contains("c99"), m_qbsStdout.constData());
+ if (isMsvc)
+ QVERIFY2(!m_qbsStdout.contains("c11"), m_qbsStdout.constData());
+ else
+ QVERIFY2(m_qbsStdout.contains("c99"), m_qbsStdout.constData());
}
void TestBlackbox::maximumCxxLanguageVersion()
@@ -7187,7 +8383,7 @@ void TestBlackbox::maximumCxxLanguageVersion()
QCOMPARE(runQbs(QbsRunParameters("resolve",
QStringList("products.app.enableNewestModule:true"))), 0);
QCOMPARE(runQbs(QStringList({"--command-echo-mode", "command-line", "-n"})), 0);
- QVERIFY2(m_qbsStdout.contains("c++17") || m_qbsStdout.contains("c++1z")
+ QVERIFY2(m_qbsStdout.contains("c++23") || m_qbsStdout.contains("c++2b")
|| m_qbsStdout.contains("c++latest"), m_qbsStdout.constData());
QCOMPARE(runQbs(QbsRunParameters("resolve",
QStringList("products.app.enableNewestModule:false"))), 0);
@@ -7196,107 +8392,6 @@ void TestBlackbox::maximumCxxLanguageVersion()
m_qbsStdout.constData());
}
-void TestBlackbox::moduleProviders()
-{
- QDir::setCurrent(testDataDir + "/module-providers");
-
- // Resolving in dry-run mode must not leave any data behind.
- QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
- QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 2);
- QVERIFY(!QFile::exists(relativeBuildDir()));
-
- // Initial build.
- QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
- QVERIFY(QFile::exists(relativeBuildDir()));
- QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 2);
- QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
- QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
- QVERIFY2(m_qbsStdout.contains("The letters are Z and Y"), m_qbsStdout.constData());
-
- // Rebuild with overridden module provider config. The output for product 2 must change,
- // but no setup script must be re-run, because both config values have already been
- // handled in the first run.
- const QStringList resolveArgs("moduleProviders.mygenerator.chooseLettersFrom:beginning");
- QCOMPARE(runQbs(QbsRunParameters("resolve", resolveArgs)), 0);
- QVERIFY2(!m_qbsStdout.contains("Running setup script"), m_qbsStdout.constData());
- QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
- QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
- QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
- QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
-
- // Forcing Probe execution triggers a re-run of the setup script. But only once,
- // because the module provider config is the same now.
- QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList(resolveArgs)
- << "--force-probe-execution")), 0);
- QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 1);
- QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
- QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
- QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
- QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
-
- // Now re-run without the module provider config override. Again, the setup script must
- // run once, for the config value that was not present in the last run.
- QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
- QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 1);
- QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
- QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
- QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
- QVERIFY2(m_qbsStdout.contains("The letters are Z and Y"), m_qbsStdout.constData());
-}
-
-void TestBlackbox::fallbackModuleProvider_data()
-{
- QTest::addColumn<bool>("fallbacksEnabledGlobally");
- QTest::addColumn<bool>("fallbacksEnabledInProduct");
- QTest::addColumn<QStringList>("pkgConfigLibDirs");
- QTest::addColumn<bool>("successExpected");
- QTest::newRow("without custom lib dir, fallbacks disabled globally and in product")
- << false << false << QStringList() << false;
- QTest::newRow("without custom lib dir, fallbacks disabled globally, enabled in product")
- << false << true << QStringList() << false;
- QTest::newRow("without custom lib dir, fallbacks enabled globally, disabled in product")
- << true << false << QStringList() << false;
- QTest::newRow("without custom lib dir, fallbacks enabled globally and in product")
- << true << true << QStringList() << false;
- QTest::newRow("with custom lib dir, fallbacks disabled globally and in product")
- << false << false << QStringList(testDataDir + "/fallback-module-provider/libdir")
- << false;
- QTest::newRow("with custom lib dir, fallbacks disabled globally, enabled in product")
- << false << true << QStringList(testDataDir + "/fallback-module-provider/libdir")
- << false;
- QTest::newRow("with custom lib dir, fallbacks enabled globally, disabled in product")
- << true << false << QStringList(testDataDir + "/fallback-module-provider/libdir")
- << false;
- QTest::newRow("with custom lib dir, fallbacks enabled globally and in product")
- << true << true << QStringList(testDataDir + "/fallback-module-provider/libdir")
- << true;
-}
-
-void TestBlackbox::fallbackModuleProvider()
-{
- QFETCH(bool, fallbacksEnabledInProduct);
- QFETCH(bool, fallbacksEnabledGlobally);
- QFETCH(QStringList, pkgConfigLibDirs);
- QFETCH(bool, successExpected);
- QDir::setCurrent(testDataDir + "/fallback-module-provider");
- static const auto b2s = [](bool b) { return QString(b ? "true" : "false"); };
- QbsRunParameters resolveParams("resolve",
- QStringList{"modules.pkgconfig.libDirs:" + pkgConfigLibDirs.join(','),
- "products.p.fallbacksEnabled:" + b2s(fallbacksEnabledInProduct),
- "--force-probe-execution"});
- if (!fallbacksEnabledGlobally)
- resolveParams.arguments << "--no-fallback-module-provider";
- QCOMPARE(runQbs(resolveParams), 0);
- const bool pkgConfigPresent = m_qbsStdout.contains("pkg-config present: true");
- const bool pkgConfigNotPresent = m_qbsStdout.contains("pkg-config present: false");
- QVERIFY(pkgConfigPresent != pkgConfigNotPresent);
- if (pkgConfigNotPresent)
- successExpected = false;
- QbsRunParameters buildParams;
- buildParams.expectFailure = !successExpected;
- QCOMPARE(runQbs(buildParams) == 0, successExpected);
-}
-
void TestBlackbox::minimumSystemVersion()
{
rmDirR(relativeBuildDir());
@@ -7304,6 +8399,10 @@ void TestBlackbox::minimumSystemVersion()
QFETCH(QString, file);
QFETCH(QString, output);
QbsRunParameters params({ "-f", file + ".qbs" });
+ params.command = "resolve";
+ QCOMPARE(runQbs(params), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
params.command = "run";
QCOMPARE(runQbs(params), 0);
if (m_qbsStdout.contains("Unsupported compiler"))
@@ -7385,7 +8484,7 @@ void TestBlackbox::minimumSystemVersion_data()
return "__MAC_OS_X_VERSION_MIN_REQUIRED=1070\nversion 10.7\n";
if (HostOsInfo::isWindowsHost())
- return "WINVER=1536\n6.00 operating system version\n6.00 subsystem version\n";
+ return "WINVER=1538\n6.02 operating system version\n6.02 subsystem version\n";
return "";
}();
@@ -7413,7 +8512,7 @@ void TestBlackbox::missingBuildGraph()
QbsRunParameters params;
params.expectFailure = true;
params.arguments << QLatin1String("config:") + actualConfigName;
- for (const QString &command : qAsConst(commands)) {
+ for (const QString &command : std::as_const(commands)) {
params.command = command;
QVERIFY2(runQbs(params) != 0, qPrintable(command));
const QString expectedErrorMessage = QString("Build graph not found for "
@@ -7523,6 +8622,12 @@ void TestBlackbox::movedFileDependency()
QVERIFY2(!m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
}
+void TestBlackbox::msvcAsmLinkerFlags()
+{
+ QDir::setCurrent(testDataDir + "/msvc-asm-flags");
+ QCOMPARE(runQbs(), 0);
+}
+
void TestBlackbox::badInterpreter()
{
if (!HostOsInfo::isAnyUnixHost())
@@ -7531,16 +8636,19 @@ void TestBlackbox::badInterpreter()
QDir::setCurrent(testDataDir + QLatin1String("/badInterpreter"));
QCOMPARE(runQbs(), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+
QbsRunParameters params("run");
params.expectFailure = true;
- const QRegExp reNoSuchFileOrDir("bad interpreter:.* No such file or directory");
- const QRegExp rePermissionDenied("bad interpreter:.* Permission denied");
+ const QRegularExpression reNoSuchFileOrDir("bad interpreter:.* No such file or directory");
+ const QRegularExpression rePermissionDenied("bad interpreter:.* Permission denied");
params.arguments = QStringList() << "-p" << "script-interp-missing";
QCOMPARE(runQbs(params), 1);
QString strerr = QString::fromLocal8Bit(m_qbsStderr);
- QVERIFY(strerr.contains(reNoSuchFileOrDir));
+ QVERIFY2(strerr.contains(reNoSuchFileOrDir), m_qbsStderr);
params.arguments = QStringList() << "-p" << "script-interp-noexec";
QCOMPARE(runQbs(params), 1);
@@ -7609,6 +8717,16 @@ void TestBlackbox::qbsVersion()
QVERIFY(runQbs(params) != 0);
}
+void TestBlackbox::transitiveInvalidDependencies()
+{
+ QDir::setCurrent(testDataDir + "/transitive-invalid-dependencies");
+ QbsRunParameters params;
+ QCOMPARE(runQbs(params), 0);
+ QVERIFY2(m_qbsStdout.contains("b.present = false"), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains("c.present = true"), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains("d.present = false"), m_qbsStdout);
+}
+
void TestBlackbox::transitiveOptionalDependencies()
{
QDir::setCurrent(testDataDir + "/transitive-optional-dependencies");
@@ -7619,19 +8737,23 @@ void TestBlackbox::transitiveOptionalDependencies()
void TestBlackbox::groupsInModules()
{
QDir::setCurrent(testDataDir + "/groups-in-modules");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters params;
QCOMPARE(runQbs(params), 0);
- QVERIFY(m_qbsStdout.contains("compile rock.coal => rock.diamond"));
- QVERIFY(m_qbsStdout.contains("compile chunk.coal => chunk.diamond"));
+ QVERIFY(m_qbsStdout.contains("compiling rock.coal to rock.diamond"));
+ QVERIFY(m_qbsStdout.contains("compiling chunk.coal to chunk.diamond"));
QVERIFY(m_qbsStdout.contains("compiling helper2.c"));
QVERIFY(!m_qbsStdout.contains("compiling helper3.c"));
QVERIFY(m_qbsStdout.contains("compiling helper4.c"));
QVERIFY(m_qbsStdout.contains("compiling helper5.c"));
QVERIFY(!m_qbsStdout.contains("compiling helper6.c"));
+ QVERIFY(m_qbsStdout.contains("compiling helper7.c"));
QCOMPARE(runQbs(params), 0);
- QVERIFY(!m_qbsStdout.contains("compile rock.coal => rock.diamond"));
- QVERIFY(!m_qbsStdout.contains("compile chunk.coal => chunk.diamond"));
+ QVERIFY(!m_qbsStdout.contains("compiling rock.coal to rock.diamond"));
+ QVERIFY(!m_qbsStdout.contains("compiling chunk.coal to chunk.diamond"));
WAIT_FOR_NEW_TIMESTAMP();
touch("modules/helper/diamondc.c");
@@ -7639,8 +8761,8 @@ void TestBlackbox::groupsInModules()
waitForFileUnlock();
QCOMPARE(runQbs(params), 0);
QVERIFY(m_qbsStdout.contains("compiling diamondc.c"));
- QVERIFY(m_qbsStdout.contains("compile rock.coal => rock.diamond"));
- QVERIFY(m_qbsStdout.contains("compile chunk.coal => chunk.diamond"));
+ QVERIFY(m_qbsStdout.contains("compiling rock.coal to rock.diamond"));
+ QVERIFY(m_qbsStdout.contains("compiling chunk.coal to chunk.diamond"));
QVERIFY(regularFileExists(relativeProductBuildDir("groups-in-modules") + "/rock.diamond"));
QFile output(relativeProductBuildDir("groups-in-modules") + "/rock.diamond");
QVERIFY(output.open(QIODevice::ReadOnly));
@@ -7650,15 +8772,36 @@ void TestBlackbox::groupsInModules()
void TestBlackbox::grpc_data()
{
QTest::addColumn<QString>("projectFile");
- QTest::newRow("cpp") << QString("grpc_cpp.qbs");
+ QTest::addColumn<QStringList>("arguments");
+ QTest::addColumn<bool>("hasModules");
+
+ QStringList pkgConfigArgs({"project.qbsModuleProviders:qbspkgconfig"});
+ // on macOS, openSSL is hidden from pkg-config by default
+ if (qbs::Internal::HostOsInfo::isMacosHost()) {
+ pkgConfigArgs
+ << "moduleProviders.qbspkgconfig.extraPaths:/usr/local/opt/openssl@1.1/lib/pkgconfig";
+ }
+ QTest::newRow("cpp-pkgconfig") << QString("grpc_cpp.qbs") << pkgConfigArgs << true;
+ QStringList conanArgs(
+ {"project.qbsModuleProviders:conan", "moduleProviders.conan.installDirectory:build"});
+ QTest::newRow("cpp-conan") << QString("grpc_cpp.qbs") << conanArgs << true;
}
void TestBlackbox::grpc()
{
QDir::setCurrent(testDataDir + "/grpc");
QFETCH(QString, projectFile);
+ QFETCH(QStringList, arguments);
+ QFETCH(bool, hasModules);
+
rmDirR(relativeBuildDir());
+ if (QTest::currentDataTag() == QLatin1String("cpp-conan")) {
+ if (!prepareAndRunConan())
+ QSKIP("conan is not prepared, check messages above");
+ }
+
QbsRunParameters resolveParams("resolve", QStringList{"-f", projectFile});
+ resolveParams.arguments << arguments;
QCOMPARE(runQbs(resolveParams), 0);
const bool withGrpc = m_qbsStdout.contains("has grpc: true");
const bool withoutGrpc = m_qbsStdout.contains("has grpc: false");
@@ -7666,10 +8809,33 @@ void TestBlackbox::grpc()
if (withoutGrpc)
QSKIP("grpc module not present");
+ const bool hasMods = m_qbsStdout.contains("has modules: true");
+ const bool dontHaveMods = m_qbsStdout.contains("has modules: false");
+ QVERIFY2(hasMods == !dontHaveMods, m_qbsStdout.constData());
+ QCOMPARE(hasMods, hasModules);
+
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+
QbsRunParameters runParams;
QCOMPARE(runQbs(runParams), 0);
}
+void TestBlackbox::hostOsProperties()
+{
+ QDir::setCurrent(testDataDir + "/host-os-properties");
+ QCOMPARE(runQbs(QStringLiteral("resolve")), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ QCOMPARE(runQbs(QStringLiteral("run")), 0);
+ QVERIFY2(m_qbsStdout.contains(
+ ("HOST_ARCHITECTURE = " + HostOsInfo::hostOSArchitecture().toUtf8()).data()),
+ m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains(
+ ("HOST_PLATFORM = " + HostOsInfo::hostOSIdentifier().toUtf8()).data()),
+ m_qbsStdout.constData());
+}
+
void TestBlackbox::ico()
{
QDir::setCurrent(testDataDir + "/ico");
@@ -7747,8 +8913,8 @@ void TestBlackbox::ico()
QCOMPARE(b.at(12), '\0');
QCOMPARE(b.at(26), '\0');
QCOMPARE(b.at(28), '\0');
- QWARN("this version of icoutil does not support setting the hotspot "
- "for cursor files with multiple images");
+ qWarning() << "this version of icoutil does not support setting the hotspot "
+ "for cursor files with multiple images";
} else {
QCOMPARE(b.at(10), '\x8');
QCOMPARE(b.at(12), '\x9');
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index 4e2755724..3f817b481 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -40,6 +40,8 @@ public:
TestBlackbox();
private slots:
+ void allowedValues();
+ void allowedValues_data();
void addFileTagToGeneratedArtifact();
void alwaysRun();
void alwaysRun_data();
@@ -58,8 +60,14 @@ private slots:
void bomSources();
void buildDataOfDisabledProduct();
void buildDirectories();
+ void buildDirPlaceholders_data();
+ void buildDirPlaceholders();
void buildEnvChange();
void buildGraphVersions();
+ void buildVariantDefaults_data();
+ void buildVariantDefaults();
+ void capnproto();
+ void capnproto_data();
void changedFiles_data();
void changedFiles();
void changedInputsFromDependencies();
@@ -76,26 +84,33 @@ private slots:
void combinedSources();
void commandFile();
void compilerDefinesByLanguage();
- void concurrentExecutor();
void conditionalExport();
void conditionalFileTagger();
void configure();
void conflictingArtifacts();
void cxxLanguageVersion();
void cxxLanguageVersion_data();
+ void conanfileProbe_data();
+ void conanfileProbe();
+ void conflictingPropertyValues_data();
+ void conflictingPropertyValues();
void cpuFeatures();
+ void dateProperty();
void dependenciesProperty();
- void dependencyProfileMismatch();
+ void dependencyScanningLoop();
void deprecatedProperty();
+ void deprecatedProperty_data();
void disappearedProfile();
void discardUnusedData();
void discardUnusedData_data();
+ void dotDotPcFile();
void driverLinkerFlags();
void driverLinkerFlags_data();
void dynamicLibraryInModule();
void dynamicMultiplexRule();
void dynamicProject();
void dynamicRuleOutputs();
+ void emptyProfile();
void enableExceptions();
void enableExceptions_data();
void enableRtti();
@@ -113,11 +128,16 @@ private slots:
void exportedPropertyInDisabledProduct_data();
void exportRule();
void exportToOutsideSearchPath();
+ void exportsCMake();
+ void exportsCMake_data();
void exportsPkgconfig();
void exportsQbs();
void externalLibs();
void fileDependencies();
void fileTagsFilterMerging();
+ void flatbuf();
+ void flatbuf_data();
+ void freedesktop();
void generatedArtifactAsInputToDynamicRule();
void generateLinkerMapFile();
void generator();
@@ -125,6 +145,7 @@ private slots:
void groupsInModules();
void grpc_data();
void grpc();
+ void hostOsProperties();
void ico();
void importAssignment();
void importChangeTracking();
@@ -133,8 +154,6 @@ private slots:
void importingProduct();
void importsConflict();
void includeLookup();
- void innoSetup();
- void innoSetupDependencies();
void inputTagsChangeTracking_data();
void inputTagsChangeTracking();
void inputsFromDependencies();
@@ -150,6 +169,8 @@ private slots:
void installPackage();
void installRootFromProjectFile();
void installTree();
+ void invalidArtifactPath_data();
+ void invalidArtifactPath();
void invalidCommandProperty_data();
void invalidCommandProperty();
void invalidExtensionInstantiation();
@@ -159,11 +180,13 @@ private slots:
void invalidLibraryNames_data();
void jsExtensionsFile();
void jsExtensionsFileInfo();
+ void jsExtensionsHost();
void jsExtensionsProcess();
void jsExtensionsPropertyList();
void jsExtensionsTemporaryDir();
void jsExtensionsTextFile();
void jsExtensionsBinaryFile();
+ void lastModuleCandidateBroken();
void ld();
void linkerMode();
void linkerVariant_data();
@@ -174,6 +197,7 @@ private slots:
void linkerLibraryDuplicates();
void linkerLibraryDuplicates_data();
void linkerScripts();
+ void linkerModuleDefinition();
void listProducts();
void listPropertiesWithOuter();
void listPropertyOrder();
@@ -182,9 +206,6 @@ private slots:
void makefileGenerator();
void maximumCLanguageVersion();
void maximumCxxLanguageVersion();
- void moduleProviders();
- void fallbackModuleProvider_data();
- void fallbackModuleProvider();
void minimumSystemVersion();
void minimumSystemVersion_data();
void missingBuildGraph();
@@ -194,6 +215,7 @@ private slots:
void missingOverridePrefix();
void moduleConditions();
void movedFileDependency();
+ void msvcAsmLinkerFlags();
void multipleChanges();
void multipleConfigurations();
void multiplexedTool();
@@ -216,6 +238,7 @@ private slots:
void overrideProjectProperties();
void pathProbe_data();
void pathProbe();
+ void pathListInProbe();
void pchChangeTracking();
void perGroupDefineInExportItem();
void pkgConfigProbe();
@@ -232,17 +255,27 @@ private slots:
void probesAndArrayProperties();
void probesInNestedModules();
void productDependenciesByType();
+ void productInExportedModule();
void productProperties();
- void propertyAssignmentOnNonPresentModule();
void propertyAssignmentInFailedModule();
void propertyChanges();
+ void propertyEvaluationContext();
void propertyPrecedence();
void properQuoting();
void propertiesInExportItems();
void protobuf_data();
void protobuf();
+ void protobufLibraryInstall();
void pseudoMultiplexing();
void qbsConfig();
+ void qbsConfigAddProfile();
+ void qbsConfigAddProfile_data();
+ void qbsConfigImport();
+ void qbsConfigImport_data();
+ void qbsConfigExport();
+ void qbsConfigExport_data();
+ void qbsLanguageServer_data();
+ void qbsLanguageServer();
void qbsSession();
void qbsVersion();
void qtBug51237();
@@ -256,16 +289,21 @@ private slots:
void reproducibleBuild();
void reproducibleBuild_data();
void require();
- void requireDeprecated();
void rescueTransformerData();
void responseFiles();
void retaggedOutputArtifact();
+ void rpathlinkDeduplication();
void ruleConditions();
void ruleConnectionWithExcludedInputs();
void ruleCycle();
void ruleWithNoInputs();
void ruleWithNonRequiredInputs();
+ void runMultiplexed();
+ void sanitizer_data();
+ void sanitizer();
void scannerItem();
+ void scanResultInOtherProduct();
+ void scanResultInNonDependency();
void setupBuildEnvironment();
void setupRunEnvironment();
void smartRelinking();
@@ -285,6 +323,7 @@ private slots:
void suspiciousCalls();
void suspiciousCalls_data();
void systemIncludePaths();
+ void distributionIncludePaths();
void systemRunPaths();
void systemRunPaths_data();
void tar();
@@ -299,8 +338,10 @@ private slots:
void trackRemoveFile();
void trackRemoveFileTag();
void trackRemoveProduct();
+ void transitiveInvalidDependencies();
void transitiveOptionalDependencies();
void typescript();
+ void undefinedTargetPlatform();
void usingsAsSoleInputsNonMultiplexed();
void variantSuffix();
void variantSuffix_data();
@@ -312,9 +353,9 @@ private slots:
void wholeArchive();
void wholeArchive_data();
void wildCardsAndRules();
+ void wildCardsAndChangeTracking_data();
+ void wildCardsAndChangeTracking();
void wildcardRenaming();
- void wix();
- void wixDependencies();
void zip();
void zip_data();
void zipInvalid();
@@ -324,6 +365,7 @@ private:
QMap<QString, QString> findNodejs(int *status);
QMap<QString, QString> findTypeScript(int *status);
QString findArchiver(const QString &fileName, int *status = nullptr);
+ bool prepareAndRunConan();
static bool lexYaccExist();
static qbs::Version bisonVersion();
};
diff --git a/tests/auto/blackbox/tst_blackboxandroid.cpp b/tests/auto/blackbox/tst_blackboxandroid.cpp
index e312c4493..a74d9415d 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())},
@@ -80,11 +81,19 @@ void TestBlackboxAndroid::android()
QFETCH(QStringList, productNames);
QFETCH(QList<QByteArrayList>, expectedFilesLists);
QFETCH(QStringList, customProperties);
+ 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"))
+ QSKIP("Skip Android tests when running on GitHub");
const SettingsPtr s = settings();
- Profile p(theProfileName(projectDir == "qml-app"), s.get());
+ Profile p(theProfileName(projectDir == "qml-app" || projectDir == "qt-app"), s.get());
if (!p.exists())
- p = Profile("none", s.get());
+ QSKIP("Qt is not installed");
int status;
const auto androidPaths = findAndroid(&status, p.name());
QCOMPARE(status, 0);
@@ -103,33 +112,39 @@ void TestBlackboxAndroid::android()
&& ndkSamplesDirs.contains(projectDir))
QSKIP("NDK samples directory not present");
+ const QString buildSubDir = enableAapt2 ? (generateAab ? "aab" : "aapt2") : "aapt";
QDir::setCurrent(testDataDir + "/" + projectDir);
+ if (!isIncrementalBuild)
+ rmDirR(relativeBuildDir(buildSubDir));
static const QStringList configNames { "debug", "release" };
for (const QString &configName : configNames) {
auto currentExpectedFilesLists = expectedFilesLists;
const QString configArgument = "config:" + configName;
QbsRunParameters resolveParams("resolve");
+ resolveParams.buildDirectory = buildSubDir;
resolveParams.arguments << configArgument << customProperties;
resolveParams.profile = p.name();
QCOMPARE(runQbs(resolveParams), 0);
QbsRunParameters buildParams(QStringList{"--command-echo-mode", "command-line",
configArgument});
+ buildParams.buildDirectory = buildSubDir;
buildParams.profile = p.name();
QCOMPARE(runQbs(buildParams), 0);
- for (const QString &productName : qAsConst(productNames)) {
+ for (const QString &productName : std::as_const(productNames)) {
const QByteArray tag(QTest::currentDataTag());
- const bool isIncrementalBuild = tag.startsWith("qml app") && tag != "qml app";
- QCOMPARE(m_qbsStdout.count("Generating BuildConfig.java"),
+ QCOMPARE(m_qbsStdout.count("generating BuildConfig.java"),
isIncrementalBuild ? 0 : productNames.size());
- QVERIFY(m_qbsStdout.contains(productName.toLocal8Bit() + ".apk"));
- const QString apkFilePath = relativeProductBuildDir(productName, configName)
- + '/' + productName + ".apk";
- QVERIFY2(regularFileExists(apkFilePath), qPrintable(apkFilePath));
+ const QString packageName = productName + (generateAab ? ".aab" : ".apk");
+ QVERIFY(m_qbsStdout.contains(packageName.toLocal8Bit()));
+ const QString packageFilePath = buildSubDir + "/" + relativeProductBuildDir(productName,
+ configName)
+ + '/' + packageName;
+ QVERIFY2(regularFileExists(packageFilePath), qPrintable(packageFilePath));
const QString jarFilePath = androidPaths["jar"];
QVERIFY(!jarFilePath.isEmpty());
QProcess jar;
- jar.start(jarFilePath, QStringList() << "-tf" << apkFilePath);
+ jar.start(jarFilePath, QStringList() << "-tf" << packageFilePath);
QVERIFY2(jar.waitForStarted(), qPrintable(jar.errorString()));
QVERIFY2(jar.waitForFinished(), qPrintable(jar.errorString()));
QVERIFY2(jar.exitCode() == 0, qPrintable(jar.readAllStandardError().constData()));
@@ -159,8 +174,8 @@ void TestBlackboxAndroid::android()
return f.contains("qmltooling");
};
if (none_of(actualFiles, isFileSharedObject)
- || std::all_of(actualFiles.cbegin(), actualFiles.cend(), isQmlToolingLib)) {
- QWARN(msg);
+ || qbs::Internal::all_of(actualFiles, isQmlToolingLib)) {
+ qWarning() << msg;
} else {
QFAIL(msg);
}
@@ -168,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;
@@ -204,71 +220,102 @@ void TestBlackboxAndroid::android_data()
const auto cxxLibPath = [&p, &pQt](const QByteArray &oldcxxLib, bool forQt) {
const bool usesClang = (forQt ? pQt : p).value(QStringLiteral("qbs.toolchainType"))
.toString() == "clang";
- return QByteArray("lib/${ARCH}/") + (usesClang ? "libc++_shared.so" : oldcxxLib);
+ const QByteArray path = "lib/${ARCH}/";
+ return path + (usesClang ? QByteArrayLiteral("libc++_shared.so") : oldcxxLib);
};
- const QByteArrayList archsForQt = { pQt.value("qbs.architecture").toString().toUtf8() };
- QByteArrayList ndkArchsForQt = archsForQt;
- if (ndkArchsForQt.first() == "armv7a")
- ndkArchsForQt.first() = "armeabi-v7a";
- else if (ndkArchsForQt.first() == "armv5te")
- ndkArchsForQt.first() = "armeabi";
- else if (ndkArchsForQt.first() == "arm64")
- ndkArchsForQt.first() = "arm64-v8a";
+ qbs::Version version(5, 13);
+ QStringList qmakeFilePaths = pQt.value(QStringLiteral("moduleProviders.Qt.qmakeFilePaths")).
+ toStringList();
+ if (qmakeFilePaths.size() >= 1)
+ version = TestBlackboxBase::qmakeVersion(qmakeFilePaths[0]);
+ bool singleArchQt = (version < qbs::Version(5, 14));
+ QByteArray qtVersionMajor((version >= qbs::Version(6, 0)) ? "6" : "5");
+ QByteArrayList archsForQt;
+ if (singleArchQt) {
+ archsForQt = { pQt.value("qbs.architecture").toString().toUtf8() };
+ if (archsStringList.empty())
+ archsStringList << QStringLiteral("armv7a"); // must match default in common.qbs
+ } else {
+ QStringList archsForQtStringList = pQt.value(QStringLiteral("qbs.architectures"))
+ .toStringList();
+ if (archsForQtStringList.empty())
+ archsForQtStringList << pQt.value("qbs.architecture").toString();
+ std::transform(archsForQtStringList.begin(),
+ archsForQtStringList.end(),
+ std::back_inserter(archsForQt),
+ [] (const QString &s) {
+ return s.toUtf8();
+ });
+ }
+
+ QByteArrayList ndkArchsForQt;
+ std::transform(archsForQt.begin(), archsForQt.end(), std::back_inserter(ndkArchsForQt),
+ [] (const QString &s) {
+ return s.toUtf8().replace("armv7a", "armeabi-v7a")
+ .replace("armv5te", "armeabi")
+ .replace("arm64", "arm64-v8a");
+ });
- auto expandArchs = [] (const QByteArrayList &archs, const QByteArrayList &lst) {
+ auto expandArchs = [] (const QByteArrayList &archs, const QByteArrayList &lst, bool aabPackage) {
const QByteArray &archPlaceHolder = "${ARCH}";
QByteArrayList result;
+ QByteArray base( aabPackage ? "base/" : "");
for (const QByteArray &entry : lst) {
if (entry.contains(archPlaceHolder)) {
- for (const QByteArray &arch : qAsConst(archs))
- result << QByteArray(entry).replace(archPlaceHolder, arch);
+ for (const QByteArray &arch : std::as_const(archs))
+ result << (base + QByteArray(entry).replace(archPlaceHolder, arch));
} else {
- result << entry;
+ result << (base + entry);
}
}
return result;
};
- const QByteArrayList commonFiles = expandArchs(archs, {
- "AndroidManifest.xml", "META-INF/ANDROIDD.RSA", "META-INF/ANDROIDD.SF",
- "META-INF/MANIFEST.MF", "classes.dex"
- });
+ auto commonFiles = [](bool generateAab, bool codeSign = true,
+ QString keyAlias="androiddebugkey") {
+ QByteArrayList files;
+ if (generateAab)
+ files << "base/manifest/AndroidManifest.xml" << "base/dex/classes.dex"
+ << "BundleConfig.pb";
+ else
+ files << "AndroidManifest.xml" << "classes.dex";
+ if (codeSign)
+ files << QByteArray("META-INF/" + keyAlias.toUpper().left(8).toUtf8() + ".RSA")
+ << QByteArray("META-INF/" + keyAlias.toUpper().left(8).toUtf8() + ".SF")
+ << "META-INF/MANIFEST.MF";
+ return files;
+ };
QTest::addColumn<QString>("projectDir");
QTest::addColumn<QStringList>("productNames");
QTest::addColumn<QList<QByteArrayList>>("expectedFilesLists");
QTest::addColumn<QStringList>("customProperties");
- QTest::newRow("teapot")
- << "teapot" << QStringList("TeapotNativeActivity")
- << (QList<QByteArrayList>() << commonFiles + expandArchs(archs, {
- "resources.arsc",
- "assets/Shaders/ShaderPlain.fsh",
- "assets/Shaders/VS_ShaderPlain.vsh",
- "lib/${ARCH}/libgdbserver.so",
- cxxLibPath("libgnustl_shared.so", false),
- "lib/${ARCH}/libTeapotNativeActivity.so",
- "res/layout/widgets.xml"}))
- << QStringList();
- QTest::newRow("minimal-native")
- << "minimal-native" << QStringList("minimalnative")
- << (QList<QByteArrayList>() << commonFiles + expandArchs({archs.first()}, {
- "lib/${ARCH}/libminimalnative.so",
- cxxLibPath("libstlport_shared.so", false),
- "lib/${ARCH}/libdependency.so"}))
- << QStringList{"products.minimalnative.multiplexByQbsProperties:[]",
- "modules.qbs.architecture:" + archsStringList.first()};
- QTest::newRow("qml app")
- << "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << commonFiles + expandArchs(ndkArchsForQt, {
- "resources.arsc",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/plugins.qmltypes",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/qmldir",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/plugins.qmltypes",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/qmldir",
- "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list",
- "lib/${ARCH}/libgdbserver.so",
+ 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");
+ };
+ bool enableAapt2 = false;
+ const auto packageType = [](bool generateAab) {
+ return QString("modules.Android.sdk.packageType:") + (generateAab ? "aab" : "apk");
+ };
+ 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;
+ if (singleArchQt) {
+ expectedFile << commonFiles(generateAab, codeSign, keyAlias) + expandArchs(ndkArchsForQt, {
cxxLibPath("libgnustl_shared.so", true),
- "lib/${ARCH}/libplugins_bearer_libqandroidbearer.so",
+ "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list",
"lib/${ARCH}/libplugins_imageformats_libqgif.so",
"lib/${ARCH}/libplugins_imageformats_libqicns.so",
"lib/${ARCH}/libplugins_imageformats_libqico.so",
@@ -278,139 +325,791 @@ void TestBlackboxAndroid::android_data()
"lib/${ARCH}/libplugins_imageformats_libqwbmp.so",
"lib/${ARCH}/libplugins_imageformats_libqwebp.so",
"lib/${ARCH}/libplugins_platforms_android_libqtforandroid.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_debugger.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_inspector.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_local.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_messages.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_native.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_nativedebugger.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_profiler.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_preview.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_quickprofiler.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_server.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_tcp.so",
- "lib/${ARCH}/libqml_QtQuick.2_libqtquick2plugin.so",
- "lib/${ARCH}/libqml_QtQuick_Window.2_libwindowplugin.so",
+ "lib/${ARCH}/libplugins_styles_libqandroidstyle.so",
"lib/${ARCH}/libQt5Core.so",
"lib/${ARCH}/libQt5Gui.so",
- "lib/${ARCH}/libQt5Network.so",
- "lib/${ARCH}/libQt5Qml.so",
- "lib/${ARCH}/libQt5QuickParticles.so",
- "lib/${ARCH}/libQt5Quick.so",
- "lib/${ARCH}/libqmlapp.so",
- "res/layout/splash.xml"}))
- << QStringList{"modules.Android.sdk.automaticSources:false",
- "modules.qbs.architecture:" + archsForQt.first()};
- QTest::newRow("qml app using Ministro")
- << "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << commonFiles + expandArchs(ndkArchsForQt, {
- "resources.arsc",
- "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list",
- "lib/${ARCH}/libgdbserver.so",
+ "lib/${ARCH}/libQt5Widgets.so",
+ "lib/${ARCH}/libqt-app.so"}, generateAab);
+ } else {
+ expectedFile << commonFiles(generateAab, codeSign, keyAlias) + expandArchs(ndkArchsForQt, {
cxxLibPath("libgnustl_shared.so", true),
- "lib/${ARCH}/libqmlapp.so",
- "res/layout/splash.xml"}))
- << QStringList{"modules.Qt.android_support.useMinistro:true",
- "modules.Android.sdk.automaticSources:false"};
+ "lib/${ARCH}/libplugins_imageformats_qgif_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qico_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qjpeg_${ARCH}.so",
+ "lib/${ARCH}/libplugins_platforms_qtforandroid_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Core_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Gui_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Widgets_${ARCH}.so",
+ "lib/${ARCH}/libqt-app_${ARCH}.so"}, generateAab);
+ }
+ if (generateAab)
+ expectedFile << "base/resources.pb" << "base/native.pb";
+ else
+ expectedFile << "resources.arsc";
+ if (version >= qbs::Version(5, 14))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libplugins_styles_qandroidstyle_${ARCH}.so"}, generateAab);
+ if (version < qbs::Version(6, 0) && version >= qbs::Version(5, 14))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libplugins_imageformats_qicns_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qtga_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qtiff_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qwbmp_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qwebp_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(6, 5))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libQt6Svg_${ARCH}.so",
+ "lib/${ARCH}/libplugins_iconengines_qsvgicon_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qsvg_${ARCH}.so"}, generateAab);
+ if (!enableAapt2 && version < qbs::Version(6, 0))
+ expectedFile << "res/layout/splash.xml";
+ return expectedFile;
+ };
+ auto codeSignProperties = [&](bool codeSign, QString keyStorePath, QString keystorePassword,
+ QString keyPassword, QString keyAlias) {
+ if (!codeSign)
+ return QStringList{"modules.codesign.enableCodeSigning:false"};
+ return QStringList{
+ "modules.codesign.enableCodeSigning:true",
+ "modules.codesign.keystorePath:" + keyStorePath,
+ "modules.codesign.keystorePassword:" + keystorePassword,
+ "modules.codesign.keyPassword:" + keyPassword,
+ "modules.codesign.keyAlias:" + keyAlias,
+ };
+ };
+ bool codeSign = true;
+ QString keyStorePath(testDataDir + "/qt-app/test.keystore");
+ QString keystorePassword("qbsKeystoreTest");
+ QString keyPassword("qbsKeyTest");
+ QString keyAlias("qbsTest");
+ QTest::newRow("qt app")
+ << "qt-app" << QStringList("qt-app")
+ << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab,
+ enableAapt2,
+ codeSign,
+ keyAlias)))
+ << (QStringList() << codeSignProperties(codeSign, keyStorePath, keystorePassword,
+ keyPassword, keyAlias)
+ << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;;
+ codeSign = false;
+ QTest::newRow("qt app no signing")
+ << "qt-app" << QStringList("qt-app")
+ << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab,
+ enableAapt2,
+ codeSign,
+ keyAlias)))
+ << (QStringList() << codeSignProperties(codeSign, keyStorePath, keystorePassword,
+ keyPassword, keyAlias)
+ << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ enableAapt2 = true;
+ codeSign = true;
+ QTest::newRow("qt app aapt2")
+ << "qt-app" << QStringList("qt-app")
+ << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab,
+ enableAapt2,
+ codeSign,
+ keyAlias)))
+ << (QStringList() << codeSignProperties(codeSign, keyStorePath, keystorePassword,
+ keyPassword, keyAlias)
+ << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ generateAab = true;
+ QTest::newRow("qt app aab")
+ << "qt-app" << QStringList("qt-app")
+ << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab,
+ enableAapt2,
+ codeSign,
+ keyAlias)))
+ << (QStringList() << codeSignProperties(codeSign, keyStorePath, keystorePassword,
+ keyPassword, keyAlias)
+ << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ codeSign = false;
+ QTest::newRow("qt app aab no signing")
+ << "qt-app" << QStringList("qt-app")
+ << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab,
+ enableAapt2,
+ codeSign,
+ keyAlias)))
+ << (QStringList() << codeSignProperties(codeSign, keyStorePath, keystorePassword,
+ keyPassword, keyAlias)
+ << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+
+ const QByteArrayList ndkArchsForQtSave = ndkArchsForQt;
+ ndkArchsForQt = {ndkArchsForQt.first()};
+ QTest::newRow("qt app (single arch)")
+ << "qt-app" << QStringList("qt-app")
+ << (QList<QByteArrayList>() << (QByteArrayList() << qtAppExpectedFiles(generateAab,
+ enableAapt2)))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab),
+ "modules.qbs.architectures:" + archsForQt.first()}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ ndkArchsForQt = ndkArchsForQtSave;
+
+ auto teaPotAppExpectedFiles = [&](const QByteArrayList &archs, bool generateAab) {
+ QByteArrayList expectedFile;
+ expectedFile << commonFiles(generateAab) + expandArchs(archs, {
+ "assets/Shaders/ShaderPlain.fsh",
+ "assets/Shaders/VS_ShaderPlain.vsh",
+ cxxLibPath("libgnustl_shared.so", false),
+ "lib/${ARCH}/libTeapotNativeActivity.so",
+ "res/layout/widgets.xml",
+ "res/mipmap-hdpi-v4/ic_launcher.png",
+ "res/mipmap-mdpi-v4/ic_launcher.png",
+ "res/mipmap-xhdpi-v4/ic_launcher.png",
+ "res/mipmap-xxhdpi-v4/ic_launcher.png"}, generateAab);
+ if (generateAab)
+ expectedFile << "base/resources.pb" << "base/assets.pb" << "base/native.pb";
+ else
+ 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 << enableD8;
+ enableAapt2 = true;
+ QTest::newRow("teapot aapt2")
+ << "teapot" << QStringList("TeapotNativeActivity")
+ << (QList<QByteArrayList>() << teaPotAppExpectedFiles(archs, generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << 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 << enableD8;
+ enableAapt2 = false;
+ generateAab = false;
+ QTest::newRow("minimal-native")
+ << "minimal-native" << QStringList("minimalnative")
+ << (QList<QByteArrayList>() << commonFiles(generateAab) + expandArchs({archs.first()}, {
+ "lib/${ARCH}/libminimalnative.so",
+ cxxLibPath("libstlport_shared.so", false),
+ "lib/${ARCH}/libdependency.so"}, generateAab))
+ << QStringList{"products.minimalnative.multiplexByQbsProperties:[]",
+ "modules.qbs.architecture:" + archsStringList.first(),
+ aaptVersion(enableAapt2)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ enableAapt2 = true;
+ QTest::newRow("minimal-native aapt2")
+ << "minimal-native" << QStringList("minimalnative")
+ << (QList<QByteArrayList>() << commonFiles(generateAab) +
+ (QByteArrayList() << "resources.arsc") + expandArchs({archs.first()}, {
+ "lib/${ARCH}/libminimalnative.so",
+ cxxLibPath("libstlport_shared.so", false),
+ "lib/${ARCH}/libdependency.so"}, generateAab))
+ << QStringList{"products.minimalnative.multiplexByQbsProperties:[]",
+ "modules.qbs.architecture:" + archsStringList.first(),
+ aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ generateAab = true;
+ QTest::newRow("minimal-native aapt2 aab")
+ << "minimal-native" << QStringList("minimalnative")
+ << (QList<QByteArrayList>() << commonFiles(generateAab) +
+ (QByteArrayList() << "base/resources.pb" << "base/native.pb") +
+ expandArchs({archs.first()}, {
+ "lib/${ARCH}/libminimalnative.so",
+ cxxLibPath("libstlport_shared.so", false),
+ "lib/${ARCH}/libdependency.so"}, generateAab))
+ << QStringList{"products.minimalnative.multiplexByQbsProperties:[]",
+ "modules.qbs.architecture:" + archsStringList.first(),
+ aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ auto qmlAppExpectedFiles = [&](bool generateAab, bool enableAapt2) {
+ QByteArrayList expectedFile;
+ if (singleArchQt) {
+ expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/plugins.qmltypes",
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/qmldir",
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/plugins.qmltypes",
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/qmldir",
+ "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list",
+ cxxLibPath("libgnustl_shared.so", true),
+ "lib/${ARCH}/libplugins_bearer_libqandroidbearer.so",
+ "lib/${ARCH}/libplugins_imageformats_libqgif.so",
+ "lib/${ARCH}/libplugins_imageformats_libqicns.so",
+ "lib/${ARCH}/libplugins_imageformats_libqico.so",
+ "lib/${ARCH}/libplugins_imageformats_libqjpeg.so",
+ "lib/${ARCH}/libplugins_imageformats_libqtga.so",
+ "lib/${ARCH}/libplugins_imageformats_libqtiff.so",
+ "lib/${ARCH}/libplugins_imageformats_libqwbmp.so",
+ "lib/${ARCH}/libplugins_imageformats_libqwebp.so",
+ "lib/${ARCH}/libplugins_platforms_android_libqtforandroid.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_debugger.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_inspector.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_local.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_messages.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_native.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_nativedebugger.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_profiler.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_preview.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_quickprofiler.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_server.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_tcp.so",
+ "lib/${ARCH}/libqml_QtQuick.2_libqtquick2plugin.so",
+ "lib/${ARCH}/libqml_QtQuick_Window.2_libwindowplugin.so",
+ "lib/${ARCH}/libQt5Core.so",
+ "lib/${ARCH}/libQt5Gui.so",
+ "lib/${ARCH}/libQt5Network.so",
+ "lib/${ARCH}/libQt5Qml.so",
+ "lib/${ARCH}/libQt5QuickParticles.so",
+ "lib/${ARCH}/libQt5Quick.so",
+ "lib/${ARCH}/libqmlapp.so"}, generateAab);
+ } else {
+ expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
+ "assets/android_rcc_bundle.rcc",
+ cxxLibPath("libgnustl_shared.so", true),
+ "lib/${ARCH}/libplugins_imageformats_qgif_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qico_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qjpeg_${ARCH}.so",
+ "lib/${ARCH}/libplugins_platforms_qtforandroid_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_debugger_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_inspector_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_local_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_messages_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_native_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_nativedebugger_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_profiler_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_preview_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_quickprofiler_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_server_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_tcp_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Core_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Gui_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Network_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Qml_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Quick_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "QmlModels_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "QmlWorkerScript_${ARCH}.so",
+ "lib/${ARCH}/libqmlapp_${ARCH}.so"}, generateAab);
+ if (version < qbs::Version(5, 15))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libQt5QuickParticles_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(5, 15) && version < qbs::Version(6, 0))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQml_StateMachine_qtqmlstatemachine_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_WorkerScript.2_workerscriptplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_Models.2_modelsplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_qmlplugin_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(5, 14) && version < qbs::Version(6, 0))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQuick.2_qtquick2plugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Window.2_windowplugin_${ARCH}.so"},
+ generateAab);
+ if (version < qbs::Version(6, 0))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libplugins_bearer_qandroidbearer_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qicns_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qtga_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qtiff_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qwbmp_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qwebp_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(6, 5))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libQt6Svg_${ARCH}.so",
+ "lib/${ARCH}/libplugins_iconengines_qsvgicon_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qsvg_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(6, 0)) {
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libQt6OpenGL_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_Models_modelsplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_WorkerScript_workerscriptplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_qtquick2plugin_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(6, 5))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQml_Base_qmlplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_qmlmetaplugin_${ARCH}.so"}, generateAab);
+ else
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQml_qmlplugin_${ARCH}.so"}, generateAab);
+ }
+ if (version >= qbs::Version(6, 2))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libplugins_networkinformation_qandroidnetworkinformation_${ARCH}.so",
+ "lib/${ARCH}/libplugins_tls_qcertonlybackend_${ARCH}.so",
+ "lib/${ARCH}/libplugins_tls_qopensslbackend_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Window_quickwindowplugin_${ARCH}.so",
+ }, generateAab);
+
+ if (version >= qbs::Version(6, 0) && version < qbs::Version(6, 3)) {
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libQt6QuickControls2Impl_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickControls2_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickParticles_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickShapes_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickTemplates2_${ARCH}.so",
+ "lib/${ARCH}/libQt6Sql_${ARCH}.so",
+ "lib/${ARCH}/libplugins_sqldrivers_qsqlite_${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",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Fusion_qtquickcontrols2fusionstyleplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Imagine_impl_qtquickcontrols2imaginestyleimplplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Imagine_qtquickcontrols2imaginestyleplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Material_impl_qtquickcontrols2materialstyleimplplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Material_qtquickcontrols2materialstyleplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Universal_impl_qtquickcontrols2universalstyleimplplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Universal_qtquickcontrols2universalstyleplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_impl_qtquickcontrols2implplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_qtquickcontrols2plugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_LocalStorage_qmllocalstorageplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_NativeStyle_qtquickcontrols2nativestyleplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Particles_particlesplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Shapes_qmlshapesplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Templates_qtquicktemplates2plugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Timeline_qtquicktimelineplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Layouts_qquicklayoutsplugin_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(6, 2))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQuick_tooling_quicktoolingplugin_${ARCH}.so",
+ "lib/${ARCH}/libQt6QmlLocalStorage_${ARCH}.so",
+ "lib/${ARCH}/libQt6QmlXmlListModel_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickDialogs2QuickImpl_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickDialogs2Utils_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickDialogs2_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickLayouts_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickTimeline_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_XmlListModel_qmlxmllistmodelplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Dialogs_qtquickdialogsplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Dialogs_quickimpl_qtquickdialogs2quickimplplugin_${ARCH}.so"},
+ generateAab);
+ else
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQuick_Window_quickwindow_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_tooling_quicktooling_${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) {
+ expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/plugins.qmltypes",
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/qmldir",
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/plugins.qmltypes",
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/qmldir",
+ "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list",
+ "assets/dummyasset.txt",
+ cxxLibPath("libgnustl_shared.so", true),
+ "lib/${ARCH}/libplugins_bearer_libqandroidbearer.so",
+ "lib/${ARCH}/libplugins_imageformats_libqgif.so",
+ "lib/${ARCH}/libplugins_imageformats_libqicns.so",
+ "lib/${ARCH}/libplugins_imageformats_libqico.so",
+ "lib/${ARCH}/libplugins_imageformats_libqjpeg.so",
+ "lib/${ARCH}/libplugins_imageformats_libqtga.so",
+ "lib/${ARCH}/libplugins_imageformats_libqtiff.so",
+ "lib/${ARCH}/libplugins_imageformats_libqwbmp.so",
+ "lib/${ARCH}/libplugins_imageformats_libqwebp.so",
+ "lib/${ARCH}/libplugins_platforms_android_libqtforandroid.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_debugger.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_inspector.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_local.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_messages.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_native.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_nativedebugger.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_profiler.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_preview.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_quickprofiler.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_server.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_tcp.so",
+ "lib/${ARCH}/libqml_QtQuick.2_libqtquick2plugin.so",
+ "lib/${ARCH}/libqml_QtQuick_Window.2_libwindowplugin.so",
+ "lib/${ARCH}/libQt5Core.so",
+ "lib/${ARCH}/libQt5Gui.so",
+ "lib/${ARCH}/libQt5Network.so",
+ "lib/${ARCH}/libQt5Qml.so",
+ "lib/${ARCH}/libQt5QuickParticles.so",
+ "lib/${ARCH}/libQt5Quick.so",
+ "lib/${ARCH}/libqmlapp.so"}, generateAab);
+ } else {
+ expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
+ "assets/android_rcc_bundle.rcc",
+ "assets/dummyasset.txt",
+ cxxLibPath("libgnustl_shared.so", true),
+ "lib/${ARCH}/libplugins_imageformats_qgif_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qico_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qjpeg_${ARCH}.so",
+ "lib/${ARCH}/libplugins_platforms_qtforandroid_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_debugger_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_inspector_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_local_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_messages_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_native_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_nativedebugger_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_profiler_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_preview_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_quickprofiler_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_server_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_tcp_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Core_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Gui_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Network_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Qml_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "Quick_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "QmlModels_${ARCH}.so",
+ "lib/${ARCH}/libQt" + qtVersionMajor + "QmlWorkerScript_${ARCH}.so",
+ "lib/${ARCH}/libqmlapp_${ARCH}.so"}, generateAab);
+ if (version < qbs::Version(5, 15))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libQt5QuickParticles_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(5, 15) && version < qbs::Version(6, 0))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQml_StateMachine_qtqmlstatemachine_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_WorkerScript.2_workerscriptplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_Models.2_modelsplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_qmlplugin_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(5, 14) && version < qbs::Version(6, 0))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQuick.2_qtquick2plugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Window.2_windowplugin_${ARCH}.so"},
+ generateAab);
+ if (version < qbs::Version(6, 0))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libplugins_bearer_qandroidbearer_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qicns_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qtga_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qtiff_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qwbmp_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qwebp_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(6, 5))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libQt6Svg_${ARCH}.so",
+ "lib/${ARCH}/libplugins_iconengines_qsvgicon_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qsvg_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(6, 0)) {
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libQt6OpenGL_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_Models_modelsplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_WorkerScript_workerscriptplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_qtquick2plugin_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(6, 5))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQml_Base_qmlplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_qmlmetaplugin_${ARCH}.so"}, generateAab);
+ else
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQml_qmlplugin_${ARCH}.so"}, generateAab);
+ }
+ if (version >= qbs::Version(6, 2))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libplugins_networkinformation_qandroidnetworkinformation_${ARCH}.so",
+ "lib/${ARCH}/libplugins_tls_qcertonlybackend_${ARCH}.so",
+ "lib/${ARCH}/libplugins_tls_qopensslbackend_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Window_quickwindowplugin_${ARCH}.so",
+ }, generateAab);
+ if (version >= qbs::Version(6, 0) && version < qbs::Version(6, 3)) {
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libQt6QuickControls2Impl_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickControls2_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickParticles_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickShapes_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickTemplates2_${ARCH}.so",
+ "lib/${ARCH}/libQt6Sql_${ARCH}.so",
+ "lib/${ARCH}/libplugins_sqldrivers_qsqlite_${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",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Fusion_qtquickcontrols2fusionstyleplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Imagine_impl_qtquickcontrols2imaginestyleimplplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Imagine_qtquickcontrols2imaginestyleplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Material_impl_qtquickcontrols2materialstyleimplplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Material_qtquickcontrols2materialstyleplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Universal_impl_qtquickcontrols2universalstyleimplplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_Universal_qtquickcontrols2universalstyleplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_impl_qtquickcontrols2implplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Controls_qtquickcontrols2plugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_LocalStorage_qmllocalstorageplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_NativeStyle_qtquickcontrols2nativestyleplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Particles_particlesplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Shapes_qmlshapesplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Templates_qtquicktemplates2plugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Timeline_qtquicktimelineplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Layouts_qquicklayoutsplugin_${ARCH}.so"}, generateAab);
+ if (version >= qbs::Version(6, 2))
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQuick_tooling_quicktoolingplugin_${ARCH}.so",
+ "lib/${ARCH}/libQt6QmlLocalStorage_${ARCH}.so",
+ "lib/${ARCH}/libQt6QmlXmlListModel_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickDialogs2QuickImpl_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickDialogs2Utils_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickDialogs2_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickLayouts_${ARCH}.so",
+ "lib/${ARCH}/libQt6QuickTimeline_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQml_XmlListModel_qmlxmllistmodelplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Dialogs_qtquickdialogsplugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Dialogs_quickimpl_qtquickdialogs2quickimplplugin_${ARCH}.so"},
+ generateAab);
+ else
+ expectedFile << expandArchs(ndkArchsForQt, {
+ "lib/${ARCH}/libqml_QtQuick_Window_quickwindow_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_tooling_quicktooling_${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;
+ };
+ QStringList qmlAppCustomProperties;
+ if (singleArchQt) {
+ qmlAppCustomProperties = QStringList{"modules.Android.sdk.automaticSources:false",
+ "modules.qbs.architecture:" + archsForQt.first()};
+ } else {
+ qmlAppCustomProperties = QStringList{"modules.Android.sdk.automaticSources:false"};
+ }
+ // aapt tool for the resources works with a directory option pointing to the parent directory
+ // of the resources (res).
+ // The Qt.android_support module adds res/values/libs.xml (from Qt install dir). So the res from
+ // Qt install res directory is added to aapt. This results in adding res/layout/splash.xml to
+ // the package eventhough the file is not needed.
+ // On the other hand aapt2 requires giving all the resources files.
+ // Also when enabling aapt2 the resources.arsc is always created, eventhough no resources are
+ // declared.
+ enableAapt2 = false;
+ generateAab = false;
+ QTest::newRow("qml app")
+ << "qml-app" << QStringList("qmlapp")
+ << (QList<QByteArrayList>() << qmlAppExpectedFiles(generateAab, enableAapt2))
+ << (QStringList() << qmlAppCustomProperties << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ enableAapt2 = true;
+ QTest::newRow("qml app aapt2")
+ << "qml-app" << QStringList("qmlapp")
+ << (QList<QByteArrayList>() << qmlAppExpectedFiles(generateAab, enableAapt2))
+ << (QStringList() << qmlAppCustomProperties << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << 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 << enableD8;
+ enableAapt2 = false;
+ generateAab = false;
QTest::newRow("qml app with custom metadata")
<< "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << commonFiles + expandArchs(ndkArchsForQt, {
- "resources.arsc",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/plugins.qmltypes",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/qmldir",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/plugins.qmltypes",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/qmldir",
- "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list",
- "assets/dummyasset.txt",
- "lib/${ARCH}/libgdbserver.so",
- cxxLibPath("libgnustl_shared.so", true),
- "lib/${ARCH}/libplugins_bearer_libqandroidbearer.so",
- "lib/${ARCH}/libplugins_imageformats_libqgif.so",
- "lib/${ARCH}/libplugins_imageformats_libqicns.so",
- "lib/${ARCH}/libplugins_imageformats_libqico.so",
- "lib/${ARCH}/libplugins_imageformats_libqjpeg.so",
- "lib/${ARCH}/libplugins_imageformats_libqtga.so",
- "lib/${ARCH}/libplugins_imageformats_libqtiff.so",
- "lib/${ARCH}/libplugins_imageformats_libqwbmp.so",
- "lib/${ARCH}/libplugins_imageformats_libqwebp.so",
- "lib/${ARCH}/libplugins_platforms_android_libqtforandroid.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_debugger.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_inspector.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_local.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_messages.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_native.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_nativedebugger.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_profiler.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_preview.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_quickprofiler.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_server.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_tcp.so",
- "lib/${ARCH}/libqml_QtQuick.2_libqtquick2plugin.so",
- "lib/${ARCH}/libqml_QtQuick_Window.2_libwindowplugin.so",
- "lib/${ARCH}/libQt5Core.so",
- "lib/${ARCH}/libQt5Gui.so",
- "lib/${ARCH}/libQt5Network.so",
- "lib/${ARCH}/libQt5Qml.so",
- "lib/${ARCH}/libQt5QuickParticles.so",
- "lib/${ARCH}/libQt5Quick.so",
- "lib/${ARCH}/libqmlapp.so",
- "res/layout/splash.xml"}))
- << QStringList("modules.Android.sdk.automaticSources:true");
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << qmlAppCustomMetaDataExpectedFiles(generateAab,
+ enableAapt2)))
+ << QStringList{"modules.Android.sdk.automaticSources:true",
+ aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ enableAapt2 = true;
+ QTest::newRow("qml app with custom metadata aapt2")
+ << "qml-app" << QStringList("qmlapp")
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << qmlAppCustomMetaDataExpectedFiles(generateAab,
+ enableAapt2)))
+ << QStringList{"modules.Android.sdk.automaticSources:true", aaptVersion(enableAapt2),
+ packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ generateAab = true;
+ if (!singleArchQt) {
+ QTest::newRow("qml app with custom metadata aab")
+ << "qml-app" << QStringList("qmlapp")
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << qmlAppCustomMetaDataExpectedFiles(generateAab,
+ enableAapt2)))
+ << QStringList{"modules.Android.sdk.automaticSources:true", aaptVersion(enableAapt2),
+ packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ }
+ isIncrementalBuild = false;
+ enableAapt2 = false;
+ generateAab = false;
+ auto noNativeExpectedFiles = [&](bool generateAab) {
+ QByteArrayList expectedFile;
+ expectedFile << commonFiles(generateAab) + expandArchs(archs, {
+ "res/drawable-hdpi-v4/ic_action_play_disabled.png",
+ "res/drawable-hdpi-v4/ic_action_play.png",
+ "res/drawable-hdpi-v4/ic_launcher.png",
+ "res/drawable-hdpi-v4/tile.9.png",
+ "res/drawable-mdpi-v4/ic_action_play_disabled.png",
+ "res/drawable-mdpi-v4/ic_action_play.png",
+ "res/drawable-mdpi-v4/ic_launcher.png",
+ "res/drawable/selector_play.xml",
+ "res/drawable-xhdpi-v4/ic_action_play_disabled.png",
+ "res/drawable-xhdpi-v4/ic_action_play.png",
+ "res/drawable-xhdpi-v4/ic_launcher.png",
+ "res/drawable-xxhdpi-v4/ic_launcher.png",
+ "res/layout/sample_main.xml",
+ "res/menu/action_menu.xml",
+ "res/raw/vid_bigbuckbunny.mp4"}, generateAab);
+ if (generateAab)
+ expectedFile << "base/resources.pb";
+ else
+ expectedFile << "resources.arsc";
+ return expectedFile;
+ };
+
QTest::newRow("no native")
<< "no-native"
<< QStringList("com.example.android.basicmediadecoder")
- << (QList<QByteArrayList>() << commonFiles + expandArchs(archs, {
- "resources.arsc",
- "res/drawable-hdpi-v4/ic_action_play_disabled.png",
- "res/drawable-hdpi-v4/ic_action_play.png",
- "res/drawable-hdpi-v4/ic_launcher.png",
- "res/drawable-hdpi-v4/tile.9.png",
- "res/drawable-mdpi-v4/ic_action_play_disabled.png",
- "res/drawable-mdpi-v4/ic_action_play.png",
- "res/drawable-mdpi-v4/ic_launcher.png",
- "res/drawable/selector_play.xml",
- "res/drawable-xhdpi-v4/ic_action_play_disabled.png",
- "res/drawable-xhdpi-v4/ic_action_play.png",
- "res/drawable-xhdpi-v4/ic_launcher.png",
- "res/drawable-xxhdpi-v4/ic_launcher.png",
- "res/layout/sample_main.xml",
- "res/menu/action_menu.xml",
- "res/menu-v11/action_menu.xml",
- "res/raw/vid_bigbuckbunny.mp4"}))
- << QStringList();
+ << (QList<QByteArrayList>() << noNativeExpectedFiles(generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << 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 << 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 << enableD8;
+ enableAapt2 = false;
+ generateAab = false;
QTest::newRow("aidl") << "aidl" << QStringList("io.qbs.aidltest")
- << QList<QByteArrayList>{commonFiles} << QStringList();
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << commonFiles(generateAab)))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ enableAapt2 = true;
+ QTest::newRow("aidl aapt2") << "aidl" << QStringList("io.qbs.aidltest")
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << commonFiles(generateAab)
+ << "resources.arsc"))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ generateAab = true;
+ QTest::newRow("aidl aab") << "aidl" << QStringList("io.qbs.aidltest")
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << commonFiles(generateAab)
+ << "base/resources.pb"))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ enableAapt2 = false;
+ generateAab = false;
+ enableD8 = false;
QTest::newRow("multiple libs")
<< "multiple-libs-per-apk"
<< QStringList("twolibs")
- << (QList<QByteArrayList>() << commonFiles + expandArchs(archs, {
+ << (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 = 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"
+ << QStringList("twolibs")
+ << (QList<QByteArrayList>() << commonFiles(generateAab) + expandArchs(archs, {
"resources.arsc",
- "lib/${ARCH}/libgdbserver.so",
"lib/${ARCH}/liblib1.so",
"lib/${ARCH}/liblib2.so",
- cxxLibPath("libstlport_shared.so", false)}))
- << QStringList();
- QByteArrayList expectedFiles1 = (commonFiles
- + expandArchs(QByteArrayList{"armeabi-v7a", "x86"}, {
- "resources.arsc",
- "lib/${ARCH}/libgdbserver.so",
- "lib/${ARCH}/libp1lib1.so",
- cxxLibPath("libstlport_shared.so", false)})
- + expandArchs(QByteArrayList{archs}, {
- "resources.arsc",
- "lib/${ARCH}/libgdbserver.so",
- "lib/${ARCH}/libp1lib2.so",
- cxxLibPath("libstlport_shared.so", false)})).toSet().toList();
- QByteArrayList expectedFiles2 = commonFiles + expandArchs(archs, {
- "lib/${ARCH}/libgdbserver.so",
- "lib/${ARCH}/libp2lib1.so",
- "lib/${ARCH}/libp2lib2.so",
- cxxLibPath("libstlport_shared.so", false)});
+ cxxLibPath("libstlport_shared.so", false)}, generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab),
+ dexCompilerVersion(enableD8)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ generateAab = true;
+ QTest::newRow("multiple libs aab")
+ << "multiple-libs-per-apk"
+ << QStringList("twolibs")
+ << (QList<QByteArrayList>() << commonFiles(generateAab) + expandArchs(archs, {
+ "resources.pb", "native.pb",
+ "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;
+
+ enableAapt2 = false;
+ generateAab = false;
+ auto expectedFiles1 = [&](bool generateAab) {
+ QByteArrayList expectedFile = qbs::toList(qbs::toSet(commonFiles(generateAab)
+ + expandArchs(QByteArrayList{"armeabi-v7a", "x86"}, {
+ "lib/${ARCH}/libp1lib1.so",
+ cxxLibPath("libstlport_shared.so", false)}, generateAab)
+ + expandArchs(QByteArrayList{archs}, {
+ "lib/${ARCH}/libp1lib2.so",
+ cxxLibPath("libstlport_shared.so", false)}, generateAab)));
+ if (generateAab)
+ expectedFile << "base/resources.pb" << "base/native.pb";
+ else
+ expectedFile << "resources.arsc";
+ return expectedFile;
+ };
+ auto expectedFiles2 = [&](bool generateAab) {
+ QByteArrayList expectedFile = commonFiles(generateAab) + expandArchs(archs, {
+ "lib/${ARCH}/libp2lib1.so",
+ "lib/${ARCH}/libp2lib2.so",
+ cxxLibPath("libstlport_shared.so", false)}, generateAab);
+ return expectedFile;
+ };
QTest::newRow("multiple apks")
<< "multiple-apks-per-project"
<< (QStringList() << "twolibs1" << "twolibs2")
- << QList<QByteArrayList>{expectedFiles1, expectedFiles2}
- << QStringList();
+ << QList<QByteArrayList>{expectedFiles1(generateAab), expectedFiles2(generateAab)}
+ << 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),
+ dexCompilerVersion(enableD8)}
+ << enableAapt2 << generateAab << isIncrementalBuild << enableD8;
+ generateAab = true;
+ QTest::newRow("multiple apks aab")
+ << "multiple-apks-per-project"
+ << (QStringList() << "twolibs1" << "twolibs2")
+ << (QList<QByteArrayList>() << expectedFiles1(generateAab)
+ << (QByteArrayList() << expectedFiles2(generateAab) << "base/resources.pb"
+ << "base/native.pb"))
+ << 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 96cd70b58..30e20a1c9 100644
--- a/tests/auto/blackbox/tst_blackboxapple.cpp
+++ b/tests/auto/blackbox/tst_blackboxapple.cpp
@@ -31,7 +31,9 @@
#include "../shared.h"
#include <tools/hostosinfo.h>
#include <tools/profile.h>
+#include <tools/qttools.h>
+#include <QtCore/qdiriterator.h>
#include <QtCore/qjsondocument.h>
#include <QtCore/qjsonobject.h>
#include <QtXml/qdom.h>
@@ -60,6 +62,117 @@ static QString getEmbeddedBinaryPlist(const QString &file)
return QString::fromUtf8(p.readAllStandardOutput()).trimmed();
}
+static QVariantMap readInfoPlistFile(const QString &infoPlistPath)
+{
+ if (!QFile::exists(infoPlistPath)) {
+ qWarning() << infoPlistPath << "doesn't exist";
+ return {};
+ }
+
+ QProcess plutil;
+ plutil.start("plutil", {
+ QStringLiteral("-convert"),
+ QStringLiteral("json"),
+ infoPlistPath
+ });
+ if (!plutil.waitForStarted()) {
+ qWarning() << plutil.errorString();
+ return {};
+ }
+ if (!plutil.waitForFinished()) {
+ qWarning() << plutil.errorString();
+ return {};
+ }
+ if (plutil.exitCode() != 0) {
+ qWarning() << plutil.readAllStandardError().constData();
+ return {};
+ }
+
+ QFile infoPlist(infoPlistPath);
+ if (!infoPlist.open(QIODevice::ReadOnly)) {
+ qWarning() << infoPlist.errorString();
+ return {};
+ }
+ QJsonParseError error;
+ const auto json = QJsonDocument::fromJson(infoPlist.readAll(), &error);
+ if (error.error != QJsonParseError::NoError) {
+ qWarning() << error.errorString();
+ return {};
+ }
+ return json.object().toVariantMap();
+}
+
+static QString getInfoPlistPath(const QString &bundlePath)
+{
+ QFileInfo contents(bundlePath + "/Contents");
+ if (contents.exists() && contents.isDir())
+ return contents.filePath() + "/Info.plist"; // macOS bundle
+ return bundlePath + "/Info.plist";
+}
+
+static bool testVariantListType(const QVariant &variant, QMetaType::Type type)
+{
+ if (variant.userType() != QMetaType::QVariantList)
+ return false;
+ for (const auto &value : variant.toList()) {
+ if (value.userType() != type)
+ return false;
+ }
+ return true;
+}
+
+static QString findFatLibrary(const QString &dir, const QString &libraryName)
+{
+ QDirIterator it(dir, {}, QDir::AllEntries, QDirIterator::Subdirectories);
+ while (it.hasNext()) {
+ it.next();
+ if (it.fileInfo().fileName() == libraryName) {
+ QProcess lipo;
+ lipo.start("lipo", { QStringLiteral("-info"), it.filePath() });
+ if (!lipo.waitForStarted() || !lipo.waitForFinished() || lipo.exitCode() != 0)
+ return {};
+ auto output = lipo.readAllStandardOutput();
+ if (output.contains(QByteArrayLiteral("Architectures in the fat file")))
+ return QDir::cleanPath(it.filePath());
+ }
+ }
+
+ return {};
+}
+
+enum class CodeSignResult { Failed = 0, Signed, Unsigned };
+using CodeSignData = QMap<QByteArray, QByteArray>;
+static std::pair<CodeSignResult, CodeSignData> parseCodeSignOutput(const QByteArray &output)
+{
+ CodeSignData data;
+ if (output.contains("code object is not signed at all"))
+ return {CodeSignResult::Unsigned, data};
+ const auto lines = output.split('\n');
+ for (const auto &line: lines) {
+ if (line.isEmpty()
+ || line.startsWith("CodeDirectory")
+ || line.startsWith("Sealed Resources")
+ || line.startsWith("Internal requirements")) {
+ continue;
+ }
+ const int index = line.indexOf('=');
+ if (index == -1)
+ return {CodeSignResult::Failed, {}};
+ data[line.mid(0, index)] = line.mid(index + 1);
+ }
+ return {CodeSignResult::Signed, data};
+}
+
+static std::pair<CodeSignResult, CodeSignData> getCodeSignInfo(const QString &path)
+{
+ QProcess codesign;
+ codesign.start("codesign", { QStringLiteral("-dv"), path });
+ if (!codesign.waitForStarted() || !codesign.waitForFinished())
+ return {CodeSignResult::Failed, {}};
+ const auto output = codesign.readAllStandardError();
+ return parseCodeSignOutput(output);
+}
+
TestBlackboxApple::TestBlackboxApple()
: TestBlackboxBase (SRCDIR "/testdata-apple", "blackbox-apple")
{
@@ -78,106 +191,190 @@ void TestBlackboxApple::initTestCase()
void TestBlackboxApple::appleMultiConfig()
{
const auto xcodeVersion = findXcodeVersion();
- const bool supportsX86 = xcodeVersion < qbs::Version(10);
-
+ if (!xcodeVersion)
+ QSKIP("requires Xcode profile");
QDir::setCurrent(testDataDir + "/apple-multiconfig");
QCOMPARE(runQbs(QbsRunParameters(QStringList{
"qbs.installPrefix:''",
- QString("project.enableX86:") + (supportsX86 ? "true" : "false")})), 0);
-
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/MacOS/singleapp").isExecutable());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/Info.plist").isRegularFile());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/PkgInfo").isRegularFile());
-
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp_agg.app/Contents/MacOS/singleapp_agg").isExecutable());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp_agg.app/Contents/Info.plist").isRegularFile());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp_agg.app/Contents/PkgInfo").isRegularFile());
-
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/singlelib").isFileSymLink());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Resources").isDirSymLink());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions").isRegularDir());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions/A").isRegularDir());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions/A/singlelib").isRegularFile());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions/A/Resources").isRegularDir());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions/A/Resources/Info.plist").isRegularFile());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions/Current").isDirSymLink());
-
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multiapp.app/Contents/MacOS/multiapp").isExecutable());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multiapp.app/Contents/Info.plist").isRegularFile());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multiapp.app/Contents/PkgInfo").isRegularFile());
-
- QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiapp.app/Contents/MacOS/fatmultiapp").isExecutable());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiapp.app/Contents/Info.plist").isRegularFile());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiapp.app/Contents/PkgInfo").isRegularFile());
-
- QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Contents/MacOS/"
- "fatmultiappmultivariant").isFileSymLink());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Contents/MacOS/"
- "fatmultiappmultivariant_debug").isExecutable());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Contents/MacOS/"
- "fatmultiappmultivariant_profile").isExecutable());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Contents/Info.plist")
- .isRegularFile());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Contents/PkgInfo")
- .isRegularFile());
-
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/multilib").isFileSymLink());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Resources").isDirSymLink());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions").isRegularDir());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A").isRegularDir());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A/multilib").isRegularFile());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A/multilib_debug").isRegularFile());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A/multilib_profile").isRegularFile());
- QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A/Resources").isRegularDir());
- 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", "profile" }) {
- for (const QString &arch : { "x86_64" }) {
- QProcess process;
- process.setProgram("/usr/bin/arch");
- process.setArguments({
- "-arch", arch,
- "-e", "DYLD_IMAGE_SUFFIX=_" + variant,
- defaultInstallRoot + "/multiapp.app/Contents/MacOS/multiapp"
- });
- process.start();
- process.waitForFinished();
- QCOMPARE(process.exitCode(), 0);
- const auto processStdout = process.readAllStandardOutput();
- QVERIFY2(processStdout.contains("Hello from " + variant.toUtf8() + " " + arch.toUtf8()),
- processStdout.constData());
+ QStringLiteral("project.xcodeVersion:") + xcodeVersion->toString()})), 0);
+
+ if (m_qbsStdout.contains("isShallow: false")) {
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/MacOS/singleapp").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/Info.plist").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/PkgInfo").isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp_agg.app/Contents/MacOS/singleapp_agg").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp_agg.app/Contents/Info.plist").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp_agg.app/Contents/PkgInfo").isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/singlelib").isFileSymLink());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Resources").isDirSymLink());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions").isRegularDir());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions/A").isRegularDir());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions/A/singlelib").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions/A/Resources").isRegularDir());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions/A/Resources/Info.plist").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Versions/Current").isDirSymLink());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multiapp.app/Contents/MacOS/multiapp").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multiapp.app/Contents/Info.plist").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multiapp.app/Contents/PkgInfo").isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiapp.app/Contents/MacOS/fatmultiapp").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiapp.app/Contents/Info.plist").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiapp.app/Contents/PkgInfo").isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Contents/MacOS/"
+ "fatmultiappmultivariant").isFileSymLink());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Contents/MacOS/"
+ "fatmultiappmultivariant_debug").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Contents/MacOS/"
+ "fatmultiappmultivariant_profiling").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Contents/Info.plist")
+ .isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Contents/PkgInfo")
+ .isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/multilib").isFileSymLink());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Resources").isDirSymLink());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions").isRegularDir());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A").isRegularDir());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A/multilib").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A/multilib_debug").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A/multilib_profiling").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Versions/A/Resources").isRegularDir());
+ 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" }) {
+ QProcess process;
+ process.setProgram("/usr/bin/arch");
+ process.setArguments({
+ "-arch", arch,
+ "-e", "DYLD_IMAGE_SUFFIX=_" + variant,
+ defaultInstallRoot + "/multiapp.app/Contents/MacOS/multiapp"
+ });
+ process.start();
+ process.waitForFinished();
+ QCOMPARE(process.exitCode(), 0);
+ const auto processStdout = process.readAllStandardOutput();
+ QVERIFY2(processStdout.contains("Hello from " + variant.toUtf8() + " " + arch.toUtf8()),
+ processStdout.constData());
+ }
}
+ } else if (m_qbsStdout.contains("isShallow: true")) {
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/singleapp").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Info.plist").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/PkgInfo").isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp_agg.app/singleapp_agg").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp_agg.app/Info.plist").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp_agg.app/PkgInfo").isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/singlelib").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/singlelib.framework/Info.plist").isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multiapp.app/multiapp").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multiapp.app/Info.plist").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multiapp.app/PkgInfo").isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiapp.app/fatmultiapp").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiapp.app/Info.plist").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiapp.app/PkgInfo").isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/"
+ "fatmultiappmultivariant").isFileSymLink());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/"
+ "fatmultiappmultivariant_debug").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/"
+ "fatmultiappmultivariant_profiling").isExecutable());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/Info.plist")
+ .isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/fatmultiappmultivariant.app/PkgInfo")
+ .isRegularFile());
+
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/multilib").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/multilib_debug").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/multilib_profiling").isRegularFile());
+ QVERIFY(QFileInfo2(defaultInstallRoot + "/multilib.framework/Info.plist").isRegularFile());
+ } else {
+ QVERIFY2(false, qPrintable(m_qbsStdout));
}
}
void TestBlackboxApple::aggregateDependencyLinking()
{
- if (HostOsInfo::hostOsVersion() > qbs::Version(10, 13, 4))
- QSKIP("32-bit arch build is no longer supported on macOS versions higher than 10.13.4.");
+ const auto xcodeVersion = findXcodeVersion();
+
+ if (!xcodeVersion)
+ QSKIP("requires Xcode profile");
+
+ // XCode 11 produces warning about deprecation of 32-bit apps, but still works
+ const bool hasX86Mac = xcodeVersion < qbs::Version(12);
+ const bool hasArmMac = xcodeVersion >= qbs::Version(12, 2);
QDir::setCurrent(testDataDir + "/aggregateDependencyLinking");
- QCOMPARE(runQbs(QStringList{"-p", "multi_arch_lib"}), 0);
+ QbsRunParameters params{QStringList{"-p", "multi_arch_lib"}};
+ params.arguments << QStringLiteral("products.multi_arch_lib.hasX86Mac:%1").arg(hasX86Mac);
+ params.arguments << QStringLiteral("products.multi_arch_lib.hasArmMac:%1").arg(hasArmMac);
+ QCOMPARE(runQbs(params), 0);
+ if (m_qbsStdout.contains("Cannot build fat binaries"))
+ QSKIP("Building fat binaries is not supported for this profile");
QCOMPARE(runQbs(QStringList{"-p", "just_app", "--command-echo-mode", "command-line"}), 0);
int linkedInLibrariesCount =
- QString::fromUtf8(m_qbsStdout).count(QStringLiteral("multi_arch_lib.a"));
+ QString::fromUtf8(m_qbsStdout).count(QStringLiteral("libmulti_arch_lib.a"));
QCOMPARE(linkedInLibrariesCount, 1);
+ const auto fatLibPath = findFatLibrary(testDataDir, QStringLiteral("libmulti_arch_lib.a"));
+ QVERIFY(!fatLibPath.isEmpty());
+ QVERIFY2(QString::fromUtf8(m_qbsStdout).contains(fatLibPath), m_qbsStdout);
+}
+
+void TestBlackboxApple::appiconset()
+{
+ QDir::setCurrent(testDataDir + QLatin1String("/ib/appiconset"));
+
+ QbsRunParameters params;
+ params.arguments = QStringList() << "-f" << "appiconset.qbs";
+ QCOMPARE(runQbs(params), 0);
+
+ const auto infoPlistPath = getInfoPlistPath(
+ relativeProductBuildDir("appiconset") + "/appiconset.app");
+ QVERIFY(QFile::exists(infoPlistPath));
+ const auto content = readInfoPlistFile(infoPlistPath);
+ QVERIFY(!content.isEmpty());
+
+ if (m_qbsStdout.contains("bundle.isShallow: false")) {
+ QCOMPARE(content.value(QStringLiteral("CFBundleIconFile")), QStringLiteral("AppIcon"));
+ QCOMPARE(content.value(QStringLiteral("CFBundleIconName")), QStringLiteral("AppIcon"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("appiconset")
+ + "/appiconset.app/Contents/Resources/AppIcon.icns"));
+ } else if (m_qbsStdout.contains("bundle.isShallow: true")) {
+ const auto icons = content.value(QStringLiteral("CFBundleIcons")).toMap();
+ QVERIFY2(!icons.isEmpty(), "Info.plist doesn't contain CFBundleIcons key");
+ const auto primaryIcon = icons.value(QStringLiteral("CFBundlePrimaryIcon")).toMap();
+ QVERIFY2(!primaryIcon.isEmpty(), "Info.plist doesn't contain CFBundlePrimaryIcon key");
+ QCOMPARE(primaryIcon.value(QStringLiteral("CFBundleIconName")), QStringLiteral("AppIcon"));
+ } else {
+ QVERIFY2(false, "Cannot determine bundle type");
+ }
}
void TestBlackboxApple::assetCatalog()
{
QFETCH(bool, flatten);
- const auto xcodeVersion = findXcodeVersion();
QDir::setCurrent(testDataDir + QLatin1String("/ib/assetcatalog"));
rmDirR(relativeBuildDir());
+ if (!findXcode())
+ QSKIP("requires Xcode profile");
+
QbsRunParameters params;
- const auto v = HostOsInfo::hostOsVersion();
const QString flattens = "modules.ib.flatten:" + QString(flatten ? "true" : "false");
- const QString macosTarget = "modules.cpp.minimumMacosVersion:'" + v.toString() + "'";
+ const QString macosTarget = "modules.cpp.minimumMacosVersion:'10.15'";
// Make sure a dry run does not write anything
params.arguments = QStringList() << "-f" << "assetcatalogempty.qbs" << "--dry-run"
@@ -185,44 +382,20 @@ void TestBlackboxApple::assetCatalog()
QCOMPARE(runQbs(params), 0);
QVERIFY(!directoryExists(relativeBuildDir()));
+ if (m_qbsStdout.contains("Skip this test"))
+ QSKIP("Skip this test");
+
params.arguments = QStringList() << "-f" << "assetcatalogempty.qbs"
<< flattens << macosTarget;
QCOMPARE(runQbs(params), 0);
// empty asset catalogs must still produce output
- if (xcodeVersion >= qbs::Version(5))
- QVERIFY((bool)m_qbsStdout.contains("compiling empty.xcassets"));
-
- // should additionally produce raw assets since deployment target will be < 10.9
- // older versions of ibtool generated either raw assets OR .car files;
- // newer versions always generate the .car file regardless of the deployment target
- if (v < qbs::Version(10, 9)) {
- QVERIFY(regularFileExists(relativeProductBuildDir("assetcatalogempty")
- + "/assetcatalogempty.app/Contents/Resources/other.png"));
- QVERIFY(regularFileExists(relativeProductBuildDir("assetcatalogempty")
- + "/assetcatalogempty.app/Contents/Resources/other@2x.png"));
- }
-
- rmDirR(relativeBuildDir());
- params.arguments.push_back("modules.cpp.minimumMacosVersion:'10.10'"); // force CAR generation
- QCOMPARE(runQbs(params), 0);
+ QVERIFY((bool)m_qbsStdout.contains("compiling empty.xcassets"));
// empty asset catalogs must still produce output
- if (xcodeVersion >= qbs::Version(5)) {
- QVERIFY((bool)m_qbsStdout.contains("compiling empty.xcassets"));
- // No matter what, we need a 10.9 host to build CAR files
- if (HostOsInfo::hostOsVersion() >= qbs::Version(10, 9)) {
- QVERIFY(regularFileExists(relativeProductBuildDir("assetcatalogempty")
- + "/assetcatalogempty.app/Contents/Resources/Assets.car"));
- } else {
- QVERIFY(regularFileExists(relativeProductBuildDir("assetcatalogempty")
- + "/assetcatalogempty.app/Contents/Resources/empty.icns"));
- QVERIFY(regularFileExists(relativeProductBuildDir("assetcatalogempty")
- + "/assetcatalogempty.app/Contents/Resources/other.png"));
- QVERIFY(regularFileExists(relativeProductBuildDir("assetcatalogempty")
- + "/assetcatalogempty.app/Contents/Resources/other@2x.png"));
- }
- }
+ QVERIFY((bool)m_qbsStdout.contains("compiling empty.xcassets"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("assetcatalogempty")
+ + "/assetcatalogempty.app/Contents/Resources/Assets.car"));
// this asset catalog happens to have an embedded icon set,
// but this should NOT be built since it is not in the files list
@@ -301,19 +474,10 @@ void TestBlackboxApple::bundleStructure()
{
QFETCH(QString, productName);
QFETCH(QString, productTypeIdentifier);
- QFETCH(bool, isShallow);
QDir::setCurrent(testDataDir + "/bundle-structure");
QbsRunParameters params(QStringList{"qbs.installPrefix:''"});
params.arguments << "project.buildableProducts:" + productName;
- if (isShallow) {
- // Coerce shallow bundles - don't set bundle.isShallow directly because we want to test the
- // automatic detection
- const auto xcode5 = findXcodeVersion() >= qbs::Version(5);
- params.arguments
- << "modules.qbs.targetPlatform:ios"
- << (xcode5 ? "qbs.architectures:arm64" : "qbs.architectures:armv7a");
- }
if (productName == "ABadApple" || productName == "ABadThirdParty")
params.expectFailure = true;
@@ -330,7 +494,10 @@ void TestBlackboxApple::bundleStructure()
QCOMPARE(status, 0);
- if (!isShallow) {
+ if (m_qbsStdout.contains("bundle.isShallow: false")) {
+ // Test shallow bundles detection - bundles are not shallow only on macOS, so also check
+ // the qbs.targetOS property
+ QVERIFY2(m_qbsStdout.contains("qbs.targetOS: macos"), m_qbsStdout);
if (productName == "A") {
QVERIFY(QFileInfo2(defaultInstallRoot + "/A.app").isRegularDir());
QVERIFY(QFileInfo2(defaultInstallRoot + "/A.app/Contents").isRegularDir());
@@ -424,7 +591,9 @@ void TestBlackboxApple::bundleStructure()
QVERIFY(QFileInfo2(defaultInstallRoot + "/G/ContentInfo.plist").isRegularFile());
QVERIFY(QFileInfo2(defaultInstallRoot + "/G/Contents/resource.txt").isRegularFile());
}
- } else {
+ } else if (m_qbsStdout.contains("bundle.isShallow: true")) {
+ QVERIFY2(m_qbsStdout.contains("qbs.targetOS:"), m_qbsStdout);
+ QVERIFY2(!m_qbsStdout.contains("qbs.targetOS: macos"), m_qbsStdout);
if (productName == "A") {
QVERIFY(QFileInfo2(defaultInstallRoot + "/A.app").isRegularDir());
QVERIFY(QFileInfo2(defaultInstallRoot + "/A.app/A").isRegularFile());
@@ -502,6 +671,8 @@ void TestBlackboxApple::bundleStructure()
QVERIFY(QFileInfo2(defaultInstallRoot + "/G/ContentInfo.plist").isRegularFile());
QVERIFY(QFileInfo2(defaultInstallRoot + "/G/Contents/resource.txt").isRegularFile());
}
+ } else {
+ QVERIFY2(false, qPrintable(m_qbsStdout));
}
}
@@ -511,21 +682,127 @@ void TestBlackboxApple::bundleStructure_data()
QTest::addColumn<QString>("productTypeIdentifier");
QTest::addColumn<bool>("isShallow");
- const auto addRows = [](bool isShallow) {
- const QString s = (isShallow ? " shallow" : "");
- QTest::newRow(("A" + s).toLatin1()) << "A" << "com.apple.product-type.application" << isShallow;
- QTest::newRow(("ABadApple" + s).toLatin1()) << "ABadApple" << "com.apple.product-type.will.never.exist.ever.guaranteed" << isShallow;
- QTest::newRow(("ABadThirdParty" + s).toLatin1()) << "ABadThirdParty" << "org.special.third.party.non.existent.product.type" << isShallow;
- QTest::newRow(("B" + s).toLatin1()) << "B" << "com.apple.product-type.framework" << isShallow;
- QTest::newRow(("C" + s).toLatin1()) << "C" << "com.apple.product-type.framework.static" << isShallow;
- QTest::newRow(("D" + s).toLatin1()) << "D" << "com.apple.product-type.bundle" << isShallow;
- QTest::newRow(("E" + s).toLatin1()) << "E" << "com.apple.product-type.app-extension" << isShallow;
- QTest::newRow(("F" + s).toLatin1()) << "F" << "com.apple.product-type.xpc-service" << isShallow;
- QTest::newRow(("G" + s).toLatin1()) << "G" << "com.apple.product-type.in-app-purchase-content" << isShallow;
- };
+ QTest::newRow("A") << "A" << "com.apple.product-type.application";
+ QTest::newRow("ABadApple") << "ABadApple" << "com.apple.product-type.will.never.exist.ever.guaranteed";
+ QTest::newRow("ABadThirdParty") << "ABadThirdParty" << "org.special.third.party.non.existent.product.type";
+ QTest::newRow("B") << "B" << "com.apple.product-type.framework";
+ QTest::newRow("C") << "C" << "com.apple.product-type.framework.static";
+ QTest::newRow("D") << "D" << "com.apple.product-type.bundle";
+ QTest::newRow("E") << "E" << "com.apple.product-type.app-extension";
+ QTest::newRow("F") << "F" << "com.apple.product-type.xpc-service";
+ QTest::newRow("G") << "G" << "com.apple.product-type.in-app-purchase-content";
+}
+
+void TestBlackboxApple::byteArrayInfoPlist()
+{
+ QDir::setCurrent(testDataDir + "/byteArrayInfoPlist");
+
+ QCOMPARE(runQbs(), 0);
+
+ const auto infoPlistPath = getInfoPlistPath(
+ relativeProductBuildDir("byteArrayInfoPlist") + "/byteArrayInfoPlist.app");
+ QVERIFY(QFile::exists(infoPlistPath));
+ const auto outFilePath =
+ relativeProductBuildDir("byteArrayInfoPlist") + "/bytearrayInfoPlist-Info.plist.out";
+ QFile file(outFilePath);
+ QVERIFY(file.exists());
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QCOMPARE(file.readAll(), "The data value");
+}
+
+void TestBlackboxApple::codesign()
+{
+ QFETCH(int, expectedCount);
+ QFETCH(bool, isBundle);
+ QFETCH(bool, enableSigning);
+ QFETCH(bool, multiArch);
+ QFETCH(bool, multiVariant);
+
+ const auto xcodeVersion = findXcodeVersion();
+
+ if (!xcodeVersion)
+ QSKIP("requires Xcode profile");
+
+ QDir::setCurrent(testDataDir + "/codesign");
+ QbsRunParameters params(QStringList{"qbs.installPrefix:''"});
+ // the test can't use xcode module to determine version itself
+ params.arguments << QStringLiteral("project.xcodeVersion:") + xcodeVersion->toString();
+ params.arguments << QStringLiteral("project.isBundle:%1").arg(isBundle ? "true" : "false");
+ params.arguments << QStringLiteral("project.enableSigning:%1")
+ .arg(enableSigning ? "true" : "false");
+ params.arguments << QStringLiteral("project.multiArch:%1").arg(multiArch ? "true" : "false");
+ params.arguments << QStringLiteral("project.multiVariant:%1")
+ .arg(multiVariant ? "true" : "false");
+
+ rmDirR(relativeBuildDir());
+ QCOMPARE(runQbs(params), 0);
+
+ const int codeSignCount =
+ QString::fromUtf8(m_qbsStdout).count(QStringLiteral("codesign"));
+ QCOMPARE(codeSignCount, expectedCount);
+
+ const auto appName = isBundle ? QStringLiteral("A.app") : QStringLiteral("A");
+ const auto appPath = defaultInstallRoot + "/" + appName;
+ QVERIFY(QFileInfo(appPath).exists());
+ auto codeSignInfo = getCodeSignInfo(appPath);
+ QVERIFY(codeSignInfo.first != CodeSignResult::Failed);
+ QCOMPARE(codeSignInfo.first == CodeSignResult::Signed, enableSigning);
+ QCOMPARE(codeSignInfo.second.isEmpty(), !enableSigning);
+ if (!codeSignInfo.second.isEmpty()) {
+ QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Executable")));
+ QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Identifier")));
+ QCOMPARE(codeSignInfo.second.value(QByteArrayLiteral("Signature")), "adhoc");
+ }
+
+ const auto libName =
+ isBundle ? QStringLiteral("B.framework") : QStringLiteral("libB.1.0.0.dylib");
+ const auto libPath = defaultInstallRoot + "/" + libName;
+ QVERIFY(QFileInfo(libPath).exists());
+ codeSignInfo = getCodeSignInfo(libPath);
+ QVERIFY(codeSignInfo.first != CodeSignResult::Failed);
+ QCOMPARE(codeSignInfo.first == CodeSignResult::Signed, enableSigning);
+ QCOMPARE(codeSignInfo.second.isEmpty(), !enableSigning);
+ if (!codeSignInfo.second.isEmpty()) {
+ QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Executable")));
+ QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Identifier")));
+ QCOMPARE(codeSignInfo.second.value(QByteArrayLiteral("Signature")), "adhoc");
+ }
+
+ const auto pluginPath = defaultInstallRoot + "/" + QStringLiteral("C.bundle");
+ QVERIFY(QFileInfo(pluginPath).exists());
+ QVERIFY(QFileInfo(pluginPath).isDir() == isBundle);
+ codeSignInfo = getCodeSignInfo(pluginPath);
+ QVERIFY(codeSignInfo.first != CodeSignResult::Failed);
+ QCOMPARE(codeSignInfo.first == CodeSignResult::Signed, enableSigning);
+ QCOMPARE(codeSignInfo.second.isEmpty(), !enableSigning);
+ if (!codeSignInfo.second.isEmpty()) {
+ QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Executable")));
+ QVERIFY(codeSignInfo.second.contains(QByteArrayLiteral("Identifier")));
+ QCOMPARE(codeSignInfo.second.value(QByteArrayLiteral("Signature")), "adhoc");
+ }
+}
- addRows(true);
- addRows(false);
+void TestBlackboxApple::codesign_data()
+{
+ QTest::addColumn<int>("expectedCount");
+ QTest::addColumn<bool>("isBundle");
+ QTest::addColumn<bool>("enableSigning");
+ QTest::addColumn<bool>("multiArch");
+ QTest::addColumn<bool>("multiVariant");
+
+ QTest::newRow("standalone, unsigned") << 0 << false << false << false << false;
+ QTest::newRow("bundle, unsigned") << 0 << true << false << false << false;
+ QTest::newRow("standalone, signed") << 3 << false << true << false << false;
+ QTest::newRow("bundle, signed") << 3 << true << true << false << false;
+ // here we only sign the resulting lipo artifact
+ QTest::newRow("standalone, signed, multiarch") << 3 << false << true << true << false;
+ QTest::newRow("bundle, signed, multiarch") << 3 << true << true << true << false;
+ // here we sign all artifacts
+ QTest::newRow("standalone, signed, multivariant") << 15 << false << true << false << true;
+ QTest::newRow("bundle, signed, multivariant") << 15 << true << true << false << true;
+ QTest::newRow("standalone, signed, multiarch, multivariant")
+ << 15 << false << true << true << true;
+ QTest::newRow("bundle, signed, multiarch, multivariant") << 15 << true << true << true << true;
}
void TestBlackboxApple::deploymentTarget()
@@ -538,6 +815,9 @@ void TestBlackboxApple::deploymentTarget()
QDir::setCurrent(testDataDir + "/deploymentTarget");
+ if (!findXcode())
+ QSKIP("requires Xcode profile");
+
QbsRunParameters params;
params.arguments = QStringList()
<< "--command-echo-mode"
@@ -591,52 +871,54 @@ void TestBlackboxApple::deploymentTarget_data()
}
QTest::newRow("macos x86_64") << "macosx" << macos << "x86_64"
<< "-triple x86_64-apple-macosx10.6"
- << "-macosx_version_min 10.6";
+ << "10.6";
if (xcodeVersion >= qbs::Version(6))
QTest::newRow("macos x86_64h") << "macosx" << macos << "x86_64h"
<< "-triple x86_64h-apple-macosx10.12"
- << "-macosx_version_min 10.12";
+ << "10.12";
QTest::newRow("ios armv7a") << "iphoneos" << ios << "armv7a"
<< "-triple thumbv7-apple-ios6.0"
- << "-iphoneos_version_min 6.0";
+ << "6.0";
QTest::newRow("ios armv7s") << "iphoneos" <<ios << "armv7s"
<< "-triple thumbv7s-apple-ios7.0"
- << "-iphoneos_version_min 7.0";
+ << "7.0";
if (xcodeVersion >= qbs::Version(5))
QTest::newRow("ios arm64") << "iphoneos" <<ios << "arm64"
<< "-triple arm64-apple-ios7.0"
- << "-iphoneos_version_min 7.0";
+ << "7.0";
QTest::newRow("ios-simulator x86") << "iphonesimulator" << ios_sim << "x86"
<< "-triple i386-apple-ios6.0"
- << "-ios_simulator_version_min 6.0";
+ << "6.0";
if (xcodeVersion >= qbs::Version(5))
QTest::newRow("ios-simulator x86_64") << "iphonesimulator" << ios_sim << "x86_64"
<< "-triple x86_64-apple-ios7.0"
- << "-ios_simulator_version_min 7.0";
+ << "7.0";
if (xcodeVersion >= qbs::Version(7)) {
if (xcodeVersion >= qbs::Version(7, 1)) {
QTest::newRow("tvos arm64") << "appletvos" << tvos << "arm64"
<< "-triple arm64-apple-tvos9.0"
- << "-tvos_version_min 9.0";
+ << "9.0";
QTest::newRow("tvos-simulator x86_64") << "appletvsimulator" << tvos_sim << "x86_64"
<< "-triple x86_64-apple-tvos9.0"
- << "-tvos_simulator_version_min 9.0";
+ << "9.0";
}
QTest::newRow("watchos armv7k") << "watchos" << watchos << "armv7k"
<< "-triple thumbv7k-apple-watchos2.0"
- << "-watchos_version_min 2.0";
+ << "2.0";
QTest::newRow("watchos-simulator x86") << "watchsimulator" << watchos_sim << "x86"
<< "-triple i386-apple-watchos2.0"
- << "-watchos_simulator_version_min 2.0";
+ << "2.0";
}
}
void TestBlackboxApple::dmg()
{
+ if (qEnvironmentVariableIsSet("GITHUB_ACTIONS"))
+ QSKIP("Skip this test when running on GitHub");
QDir::setCurrent(testDataDir + "/apple-dmg");
QCOMPARE(runQbs(), 0);
}
@@ -669,16 +951,29 @@ void TestBlackboxApple::frameworkStructure()
QbsRunParameters params;
QCOMPARE(runQbs(params), 0);
- QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/A/Widget"));
- QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/A/Headers/Widget.h"));
- QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/A/PrivateHeaders/WidgetPrivate.h"));
- QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/A/Resources/BaseResource"));
- QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/A/Resources/en.lproj/EnglishResource"));
- QVERIFY(directoryExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/Current"));
- QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Widget"));
- QVERIFY(directoryExists(relativeProductBuildDir("Widget") + "/Widget.framework/Headers"));
- QVERIFY(directoryExists(relativeProductBuildDir("Widget") + "/Widget.framework/PrivateHeaders"));
- QVERIFY(directoryExists(relativeProductBuildDir("Widget") + "/Widget.framework/Resources"));
+ if (m_qbsStdout.contains("isShallow: false")) {
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/A/Widget"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/A/Headers/Widget.h"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/A/PrivateHeaders/WidgetPrivate.h"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/A/Resources/BaseResource"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/A/Resources/en.lproj/EnglishResource"));
+ QVERIFY(directoryExists(relativeProductBuildDir("Widget") + "/Widget.framework/Versions/Current"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Widget"));
+ QVERIFY(directoryExists(relativeProductBuildDir("Widget") + "/Widget.framework/Headers"));
+ QVERIFY(directoryExists(relativeProductBuildDir("Widget") + "/Widget.framework/PrivateHeaders"));
+ QVERIFY(directoryExists(relativeProductBuildDir("Widget") + "/Widget.framework/Resources"));
+ } else if (m_qbsStdout.contains("isShallow: true")) {
+ QVERIFY(directoryExists(relativeProductBuildDir("Widget") + "/Widget.framework/Headers"));
+ QVERIFY(directoryExists(relativeProductBuildDir("Widget") + "/Widget.framework/PrivateHeaders"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Widget"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Headers/Widget.h"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/PrivateHeaders/WidgetPrivate.h"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/BaseResource"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/en.lproj/EnglishResource"));
+ QVERIFY(regularFileExists(relativeProductBuildDir("Widget") + "/Widget.framework/Widget"));
+ } else {
+ QVERIFY2(false, qPrintable(m_qbsStdout));
+ }
params.command = "resolve";
params.arguments = QStringList() << "project.includeHeaders:false";
@@ -708,7 +1003,15 @@ void TestBlackboxApple::iconsetApp()
params.arguments = QStringList() << "-f" << "iconsetapp.qbs";
QCOMPARE(runQbs(params), 0);
- QVERIFY(regularFileExists(relativeProductBuildDir("iconsetapp") + "/iconsetapp.app/Contents/Resources/white.icns"));
+ if (m_qbsStdout.contains("isShallow: false")) {
+ QVERIFY(regularFileExists(relativeProductBuildDir("iconsetapp")
+ + "/iconsetapp.app/Contents/Resources/white.icns"));
+ } else if (m_qbsStdout.contains("isShallow: true")) {
+ QVERIFY(regularFileExists(relativeProductBuildDir("iconsetapp")
+ + "/iconsetapp.app/white.icns"));
+ } else {
+ QVERIFY2(false, qPrintable(m_qbsStdout));
+ }
}
void TestBlackboxApple::infoPlist()
@@ -719,40 +1022,74 @@ void TestBlackboxApple::infoPlist()
params.arguments = QStringList() << "-f" << "infoplist.qbs";
QCOMPARE(runQbs(params), 0);
- auto infoplistPath = relativeProductBuildDir("infoplist")
- + "/infoplist.app/Contents/Info.plist";
- if (!QFile::exists(infoplistPath))
- infoplistPath = relativeProductBuildDir("infoplist") + "/infoplist.app/Info.plist";
- QVERIFY(QFile::exists(infoplistPath));
- QProcess plutil;
- plutil.start("plutil", {
- QStringLiteral("-convert"),
- QStringLiteral("json"),
- infoplistPath
- });
- QVERIFY2(plutil.waitForStarted(), qPrintable(plutil.errorString()));
- QVERIFY2(plutil.waitForFinished(), qPrintable(plutil.errorString()));
- QVERIFY2(plutil.exitCode() == 0, qPrintable(plutil.readAllStandardError().constData()));
+ const auto infoPlistPath = getInfoPlistPath(
+ relativeProductBuildDir("infoplist") + "/infoplist.app");
+ QVERIFY(QFile::exists(infoPlistPath));
+ const auto content = readInfoPlistFile(infoPlistPath);
+ QVERIFY(!content.isEmpty());
- QFile infoplist(infoplistPath);
- QVERIFY(infoplist.open(QIODevice::ReadOnly));
- QJsonParseError error;
- const auto json = QJsonDocument::fromJson(infoplist.readAll(), &error);
- QCOMPARE(error.error, QJsonParseError::NoError);
- QVERIFY(json.isObject());
// common values
- QCOMPARE(json.object().value(QStringLiteral("CFBundleIdentifier")),
+ QCOMPARE(content.value(QStringLiteral("CFBundleIdentifier")),
QStringLiteral("org.example.infoplist"));
- QCOMPARE(json.object().value(QStringLiteral("CFBundleName")), QStringLiteral("infoplist"));
- QCOMPARE(json.object().value(QStringLiteral("CFBundleExecutable")),
+ QCOMPARE(content.value(QStringLiteral("CFBundleName")), QStringLiteral("infoplist"));
+ QCOMPARE(content.value(QStringLiteral("CFBundleExecutable")),
QStringLiteral("infoplist"));
- if (!json.object().contains(QStringLiteral("SDKROOT"))) { // macOS-specific values
- QCOMPARE(json.object().value("LSMinimumSystemVersion"), QStringLiteral("10.7"));
- QVERIFY(json.object().contains("NSPrincipalClass"));
+ if (!content.contains(QStringLiteral("SDKROOT"))) { // macOS-specific values
+ QCOMPARE(content.value("LSMinimumSystemVersion"), QStringLiteral("10.7"));
+ QCOMPARE(content.value("NSPrincipalClass"), QStringLiteral("NSApplication"));
+ QCOMPARE(content.value(QStringLiteral("NSSupportsAutomaticGraphicsSwitching")), true);
+ } else {
+ // QBS-1447: UIDeviceFamily was set to a string instead of an array
+ const auto family = content.value(QStringLiteral("UIDeviceFamily"));
+ if (family.isValid()) {
+ // Prior to Qt 5.15, int gets converted to a double when exporting plist as JSON
+ QVERIFY(testVariantListType(family, QMetaType::LongLong)
+ || testVariantListType(family, QMetaType::Double));
+ }
+ const auto caps = content.value(QStringLiteral("UIRequiredDeviceCapabilities"));
+ if (caps.isValid())
+ QVERIFY(testVariantListType(caps, QMetaType::QString));
+ const auto orientations = content.value(QStringLiteral("UIRequiredDeviceCapabilities"));
+ if (orientations.isValid())
+ QVERIFY(testVariantListType(orientations, QMetaType::QString));
}
}
+void TestBlackboxApple::infoPlistVariables()
+{
+ QDir::setCurrent(testDataDir + "/infoPlistVariables");
+
+ QbsRunParameters params;
+ params.arguments = QStringList() << "-f" << "infoPlistVariables.qbs";
+ QCOMPARE(runQbs(params), 0);
+
+ const auto infoPlistPath = getInfoPlistPath(
+ relativeProductBuildDir("infoPlistVariables") + "/infoPlistVariables.app");
+ QVERIFY(QFile::exists(infoPlistPath));
+ const auto content = readInfoPlistFile(infoPlistPath);
+ QVERIFY(!content.isEmpty());
+
+ QCOMPARE(content.value(QStringLiteral("Curly")),
+ QStringLiteral("infoPlistVariables"));
+ QCOMPARE(content.value(QStringLiteral("Braces")),
+ QStringLiteral("infoPlistVariables"));
+ QCOMPARE(content.value(QStringLiteral("At")),
+ QStringLiteral("infoPlistVariables"));
+ QCOMPARE(content.value(QStringLiteral("CurlyMult")),
+ QStringLiteral("infoPlistVariables_infoPlistVariables"));
+ QCOMPARE(content.value(QStringLiteral("BracesMult")),
+ QStringLiteral("infoPlistVariables_infoPlistVariables"));
+ QCOMPARE(content.value(QStringLiteral("AtMult")),
+ QStringLiteral("infoPlistVariables_infoPlistVariables"));
+ QCOMPARE(content.value(QStringLiteral("CurlyNested")),
+ QStringLiteral("infoPlistVariables"));
+ QCOMPARE(content.value(QStringLiteral("BracesNested")),
+ QStringLiteral("infoPlistVariables"));
+ QCOMPARE(content.value(QStringLiteral("WithDefault")),
+ QStringLiteral("DEFAULT"));
+}
+
void TestBlackboxApple::objcArc()
{
QDir::setCurrent(testDataDir + QLatin1String("/objc-arc"));
@@ -760,8 +1097,36 @@ void TestBlackboxApple::objcArc()
QCOMPARE(runQbs(), 0);
}
+void TestBlackboxApple::overrideInfoPlist()
+{
+ QDir::setCurrent(testDataDir + "/overrideInfoPlist");
+
+ QCOMPARE(runQbs(), 0);
+
+ const auto infoPlistPath = getInfoPlistPath(
+ relativeProductBuildDir("overrideInfoPlist") + "/overrideInfoPlist.app");
+ QVERIFY(QFile::exists(infoPlistPath));
+ const auto content = readInfoPlistFile(infoPlistPath);
+ QVERIFY(!content.isEmpty());
+
+ // test we do not override custom values by default
+ QCOMPARE(content.value(QStringLiteral("DefaultValue")),
+ QStringLiteral("The default value"));
+ // test we can override custom values
+ QCOMPARE(content.value(QStringLiteral("OverriddenValue")),
+ QStringLiteral("The overridden value"));
+ // test we do not override special values set by Qbs by default
+ QCOMPARE(content.value(QStringLiteral("CFBundleExecutable")),
+ QStringLiteral("overrideInfoPlist"));
+ // test we can override special values set by Qbs
+ QCOMPARE(content.value(QStringLiteral("CFBundleName")), QStringLiteral("My Bundle"));
+}
+
void TestBlackboxApple::xcode()
{
+ if (!findXcode())
+ QSKIP("requires Xcode profile");
+
QProcess xcodeSelect;
xcodeSelect.start("xcode-select", QStringList() << "--print-path");
QVERIFY2(xcodeSelect.waitForStarted(), qPrintable(xcodeSelect.errorString()));
@@ -775,8 +1140,10 @@ void TestBlackboxApple::xcode()
xcodebuildShowSdks.start("xcrun", QStringList() << "xcodebuild" << "-showsdks");
QVERIFY2(xcodebuildShowSdks.waitForStarted(), qPrintable(xcodebuildShowSdks.errorString()));
QVERIFY2(xcodebuildShowSdks.waitForFinished(), qPrintable(xcodebuildShowSdks.errorString()));
- QVERIFY2(xcodebuildShowSdks.exitCode() == 0, qPrintable(xcodebuildShowSdks.readAllStandardError().constData()));
- const auto lines = QString::fromLocal8Bit(xcodebuildShowSdks.readAllStandardOutput().trimmed()).split('\n', QString::SkipEmptyParts);
+ QVERIFY2(xcodebuildShowSdks.exitCode() == 0,
+ qPrintable(xcodebuildShowSdks.readAllStandardError().constData()));
+ const auto lines = QString::fromLocal8Bit(xcodebuildShowSdks.readAllStandardOutput().trimmed())
+ .split('\n', Qt::SkipEmptyParts);
for (const QString &line : lines) {
static const std::regex regexp("^.+\\s+\\-sdk\\s+([a-z]+)([0-9]+\\.[0-9]+)$");
const auto ln = line.toStdString();
@@ -812,11 +1179,10 @@ void TestBlackboxApple::xcode()
QTEST_MAIN(TestBlackboxApple)
-QVariantMap TestBlackboxApple::findXcode(int *status)
+std::optional<QVariantMap> TestBlackboxApple::findXcode(int *status)
{
QTemporaryDir temp;
QbsRunParameters params = QStringList({"-f", testDataDir + "/find/find-xcode.qbs"});
- params.profile = "none";
params.buildDirectory = temp.path();
const int res = runQbs(params);
if (status)
@@ -825,10 +1191,16 @@ QVariantMap TestBlackboxApple::findXcode(int *status)
+ "/xcode.json");
if (!file.open(QIODevice::ReadOnly))
return {};
- return QJsonDocument::fromJson(file.readAll()).toVariant().toMap();
+ auto result = QJsonDocument::fromJson(file.readAll()).toVariant().toMap();
+ if (!result["present"].toBool())
+ return {};
+ return result;
}
-qbs::Version TestBlackboxApple::findXcodeVersion()
+std::optional<qbs::Version> TestBlackboxApple::findXcodeVersion()
{
- return qbs::Version::fromString(findXcode().value("version").toString());
+ const auto xcode = findXcode();
+ if (!xcode)
+ return {};
+ return qbs::Version::fromString(xcode->value("version").toString());
}
diff --git a/tests/auto/blackbox/tst_blackboxapple.h b/tests/auto/blackbox/tst_blackboxapple.h
index 76711ddf5..a51414917 100644
--- a/tests/auto/blackbox/tst_blackboxapple.h
+++ b/tests/auto/blackbox/tst_blackboxapple.h
@@ -31,6 +31,8 @@
#include "tst_blackboxbase.h"
+#include <optional>
+
namespace qbs {
class Version;
} // namespace qbs
@@ -48,12 +50,16 @@ public slots:
private slots:
void appleMultiConfig();
void aggregateDependencyLinking();
+ void appiconset();
void assetCatalog();
void assetCatalog_data();
void assetCatalogsEmpty();
void assetCatalogsMultiple();
void bundleStructure();
void bundleStructure_data();
+ void byteArrayInfoPlist();
+ void codesign();
+ void codesign_data();
void deploymentTarget();
void deploymentTarget_data();
void dmg();
@@ -62,12 +68,14 @@ private slots:
void iconset();
void iconsetApp();
void infoPlist();
+ void infoPlistVariables();
void objcArc();
+ void overrideInfoPlist();
void xcode();
private:
- QVariantMap findXcode(int *status = nullptr);
- qbs::Version findXcodeVersion();
+ std::optional<QVariantMap> findXcode(int *status = nullptr);
+ std::optional<qbs::Version> findXcodeVersion();
};
#endif // TST_BLACKBOXAPPLE_H
diff --git a/tests/auto/blackbox/tst_blackboxbaremetal.cpp b/tests/auto/blackbox/tst_blackboxbaremetal.cpp
new file mode 100644
index 000000000..ec6ffcdc6
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxbaremetal.cpp
@@ -0,0 +1,311 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://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.
+**
+****************************************************************************/
+
+#include "tst_blackboxbaremetal.h"
+
+#include "../shared.h"
+
+#include <QtCore/qdir.h>
+#include <QtCore/qregularexpression.h>
+
+static bool extractToolset(const QByteArray &output,
+ QByteArray &toolchain, QByteArray &architecture)
+{
+ const QRegularExpression re("%%([\\w\\-]+)%%, %%(\\w+)%%");
+ QRegularExpressionMatchIterator it = re.globalMatch(output);
+ if (!it.hasNext())
+ return false;
+ const QRegularExpressionMatch match = it.next();
+ toolchain = match.captured(1).toLocal8Bit();
+ architecture = match.captured(2).toLocal8Bit();
+ return true;
+}
+
+static bool extractCompilerIncludePaths(const QByteArray &output, QStringList &compilerIncludePaths)
+{
+ const QRegularExpression re("%%([^%%]+)%%");
+ QRegularExpressionMatchIterator it = re.globalMatch(output);
+ if (!it.hasNext())
+ return false;
+ const QRegularExpressionMatch match = it.next();
+ compilerIncludePaths = match.captured(1).split(",");
+ return true;
+}
+
+static bool extractQuitedValue(const QByteArray &output, QString &pattern)
+{
+ const QRegularExpression re("%%(.+)%%");
+ const QRegularExpressionMatch match = re.match(output);
+ if (!match.hasMatch())
+ return false;
+ pattern = match.captured(1);
+ return true;
+}
+
+static QByteArray unsupportedToolsetMessage(const QByteArray &output)
+{
+ QByteArray toolchain;
+ QByteArray architecture;
+ extractToolset(output, toolchain, architecture);
+ return "Unsupported toolchain '" + toolchain
+ + "' for architecture '" + architecture + "'";
+}
+
+static QByteArray brokenProbeMessage(const QByteArray &output)
+{
+ QByteArray toolchain;
+ QByteArray architecture;
+ extractToolset(output, toolchain, architecture);
+ return "Broken probe for toolchain '" + toolchain
+ + "' for architecture '" + architecture + "'";
+}
+
+TestBlackboxBareMetal::TestBlackboxBareMetal()
+ : TestBlackboxBase (SRCDIR "/testdata-baremetal", "blackbox-baremetal")
+{
+}
+
+void TestBlackboxBareMetal::targetPlatform()
+{
+ QDir::setCurrent(testDataDir + "/target-platform");
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ if (m_qbsStdout.contains("unsupported toolset:"))
+ QSKIP(unsupportedToolsetMessage(m_qbsStdout));
+ const bool hasNoPlatform = m_qbsStdout.contains("has no platform: true");
+ QCOMPARE(hasNoPlatform, true);
+ const bool hasNoOS = m_qbsStdout.contains("has no os: true");
+ QCOMPARE(hasNoOS, true);
+}
+
+void TestBlackboxBareMetal::application_data()
+{
+ QTest::addColumn<QString>("testPath");
+ QTest::newRow("one-object-application") << "/one-object-application";
+ QTest::newRow("two-object-application") << "/two-object-application";
+ QTest::newRow("one-object-asm-application") << "/one-object-asm-application";
+}
+
+void TestBlackboxBareMetal::application()
+{
+ QFETCH(QString, testPath);
+ QDir::setCurrent(testDataDir + testPath);
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ if (m_qbsStdout.contains("unsupported toolset:"))
+ QSKIP(unsupportedToolsetMessage(m_qbsStdout));
+ QCOMPARE(runQbs(QbsRunParameters("build")), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ QCOMPARE(runQbs(QbsRunParameters("run")), 0);
+}
+
+void TestBlackboxBareMetal::staticLibraryDependencies()
+{
+ QDir::setCurrent(testDataDir + "/static-library-dependencies");
+ QCOMPARE(runQbs(QStringList{"-p", "lib-a,lib-b,lib-c,lib-d,lib-e"}), 0);
+ QCOMPARE(runQbs(QStringList{"--command-echo-mode", "command-line"}), 0);
+ const QByteArray output = m_qbsStdout + '\n' + m_qbsStderr;
+ QVERIFY(output.contains("lib-a"));
+ QVERIFY(output.contains("lib-b"));
+ QVERIFY(output.contains("lib-c"));
+ QVERIFY(output.contains("lib-d"));
+ QVERIFY(output.contains("lib-e"));
+}
+
+void TestBlackboxBareMetal::externalStaticLibraries()
+{
+ QDir::setCurrent(testDataDir + "/external-static-libraries");
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ if (m_qbsStdout.contains("unsupported toolset:"))
+ QSKIP(unsupportedToolsetMessage(m_qbsStdout));
+ QCOMPARE(runQbs(), 0);
+}
+
+void TestBlackboxBareMetal::sharedLibraries()
+{
+ QDir::setCurrent(testDataDir + "/shared-libraries");
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ if (m_qbsStdout.contains("unsupported toolset:"))
+ QSKIP(unsupportedToolsetMessage(m_qbsStdout));
+ QCOMPARE(runQbs(QbsRunParameters("build")), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ QCOMPARE(runQbs(QbsRunParameters("run")), 0);
+ QVERIFY2(m_qbsStdout.contains("Hello from app"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("Hello from lib"), m_qbsStdout.constData());
+}
+
+void TestBlackboxBareMetal::userIncludePaths()
+{
+ QDir::setCurrent(testDataDir + "/user-include-paths");
+ QCOMPARE(runQbs(), 0);
+}
+
+void TestBlackboxBareMetal::systemIncludePaths()
+{
+ QDir::setCurrent(testDataDir + "/system-include-paths");
+ QCOMPARE(runQbs(), 0);
+}
+
+void TestBlackboxBareMetal::distributionIncludePaths()
+{
+ QDir::setCurrent(testDataDir + "/distribution-include-paths");
+ QCOMPARE(runQbs(), 0);
+}
+
+void TestBlackboxBareMetal::compilerIncludePaths()
+{
+ QDir::setCurrent(testDataDir + "/compiler-include-paths");
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ if (!m_qbsStdout.contains("compilerIncludePaths:"))
+ QFAIL("No compiler include paths exists");
+
+ QStringList includePaths;
+ QVERIFY(extractCompilerIncludePaths(m_qbsStdout, includePaths));
+ QVERIFY(includePaths.count() > 0);
+ for (const auto &includePath : includePaths) {
+ const QDir dir(includePath);
+ QVERIFY(dir.exists());
+ }
+}
+
+void TestBlackboxBareMetal::preincludeHeaders()
+{
+ QDir::setCurrent(testDataDir + "/preinclude-headers");
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ if (m_qbsStdout.contains("unsupported toolset:"))
+ QSKIP(unsupportedToolsetMessage(m_qbsStdout));
+ QCOMPARE(runQbs(), 0);
+}
+
+void TestBlackboxBareMetal::defines()
+{
+ QDir::setCurrent(testDataDir + "/defines");
+ QCOMPARE(runQbs(), 0);
+}
+
+void TestBlackboxBareMetal::compilerListingFiles_data()
+{
+ QTest::addColumn<bool>("generateListing");
+ QTest::addColumn<QString>("customListingSuffix");
+ QTest::newRow("do-not-generate-compiler-listing") << false << "";
+ QTest::newRow("generate-default-compiler-listing") << true << "";
+ QTest::newRow("generate-custom-compiler-listing") << true << ".lll";
+}
+
+void TestBlackboxBareMetal::compilerListingFiles()
+{
+ QFETCH(bool, generateListing);
+ QFETCH(QString, customListingSuffix);
+ QDir::setCurrent(testDataDir + "/compiler-listing");
+
+ rmDirR(relativeBuildDir());
+ QStringList args = {QStringLiteral("modules.cpp.generateCompilerListingFiles:%1")
+ .arg(generateListing ? "true" : "false")};
+ if (!customListingSuffix.isEmpty())
+ args << QStringLiteral("modules.cpp.compilerListingSuffix:%1").arg(customListingSuffix);
+
+ QCOMPARE(runQbs(QbsRunParameters("resolve", args)), 0);
+ if (m_qbsStdout.contains("unsupported toolset:"))
+ QSKIP(unsupportedToolsetMessage(m_qbsStdout));
+ if (!m_qbsStdout.contains("compiler listing suffix:"))
+ QFAIL("No current compiler listing suffix pattern exists");
+
+ QString compilerListingSuffix;
+ if (!extractQuitedValue(m_qbsStdout, compilerListingSuffix))
+ QFAIL("Unable to extract current compiler listing suffix");
+
+ if (!customListingSuffix.isEmpty())
+ QCOMPARE(compilerListingSuffix, customListingSuffix);
+
+ QCOMPARE(runQbs(QbsRunParameters(args)), 0);
+ const QString productBuildDir = relativeProductBuildDir("compiler-listing");
+ const QString hash = inputDirHash(".");
+ const QString mainListing = productBuildDir + "/" + hash
+ + "/main.c" + compilerListingSuffix;
+ QCOMPARE(regularFileExists(mainListing), generateListing);
+ const QString funListing = productBuildDir + "/" + hash
+ + "/fun.c" + compilerListingSuffix;
+ QCOMPARE(regularFileExists(funListing), generateListing);
+}
+
+void TestBlackboxBareMetal::linkerMapFile_data()
+{
+ QTest::addColumn<bool>("generateMap");
+ QTest::addColumn<QString>("customMapSuffix");
+ QTest::newRow("do-not-generate-linker-map") << false << "";
+ QTest::newRow("generate-default-linker-map") << true << "";
+ QTest::newRow("generate-custom-linker-map") << true << ".mmm";
+}
+
+void TestBlackboxBareMetal::linkerMapFile()
+{
+ QFETCH(bool, generateMap);
+ QFETCH(QString, customMapSuffix);
+ QDir::setCurrent(testDataDir + "/linker-map");
+
+ rmDirR(relativeBuildDir());
+ QStringList args = {QStringLiteral("modules.cpp.generateLinkerMapFile:%1")
+ .arg(generateMap ? "true" : "false")};
+ if (!customMapSuffix.isEmpty())
+ args << QStringLiteral("modules.cpp.linkerMapSuffix:%1").arg(customMapSuffix);
+
+ QCOMPARE(runQbs(QbsRunParameters("resolve", args)), 0);
+ if (!m_qbsStdout.contains("linker map suffix:"))
+ QFAIL("No current linker map suffix pattern exists");
+
+ QString linkerMapSuffix;
+ if (!extractQuitedValue(m_qbsStdout, linkerMapSuffix))
+ QFAIL("Unable to extract current linker map suffix");
+
+ if (!customMapSuffix.isEmpty())
+ QCOMPARE(linkerMapSuffix, customMapSuffix);
+
+ QCOMPARE(runQbs(QbsRunParameters(args)), 0);
+ const QString productBuildDir = relativeProductBuildDir("linker-map");
+ const QString linkerMap = productBuildDir + "/linker-map" + linkerMapSuffix;
+ QCOMPARE(regularFileExists(linkerMap), generateMap);
+}
+
+void TestBlackboxBareMetal::compilerDefinesByLanguage()
+{
+ QDir::setCurrent(testDataDir + "/compiler-defines-by-language");
+ QbsRunParameters params(QStringList{ "-f", "compiler-defines-by-language.qbs" });
+ QCOMPARE(runQbs(params), 0);
+}
+
+void TestBlackboxBareMetal::toolchainProbe()
+{
+ QDir::setCurrent(testDataDir + "/toolchain-probe");
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ if (m_qbsStdout.contains("broken probe:"))
+ QFAIL(brokenProbeMessage(m_qbsStdout));
+}
+
+QTEST_MAIN(TestBlackboxBareMetal)
diff --git a/tests/auto/blackbox/tst_blackboxbaremetal.h b/tests/auto/blackbox/tst_blackboxbaremetal.h
new file mode 100644
index 000000000..9c45fa63c
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxbaremetal.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://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.
+**
+****************************************************************************/
+
+#ifndef TST_BLACKBOXBAREMETAL_H
+#define TST_BLACKBOXBAREMETAL_H
+
+#include "tst_blackboxbase.h"
+
+class TestBlackboxBareMetal : public TestBlackboxBase
+{
+ Q_OBJECT
+
+public:
+ TestBlackboxBareMetal();
+
+private slots:
+ void targetPlatform();
+
+ void application_data();
+ void application();
+
+ void staticLibraryDependencies();
+ void externalStaticLibraries();
+
+ void sharedLibraries();
+
+ void userIncludePaths();
+ void systemIncludePaths();
+ void distributionIncludePaths();
+ void compilerIncludePaths();
+
+ void preincludeHeaders();
+
+ void defines();
+
+ void compilerListingFiles_data();
+ void compilerListingFiles();
+
+ void linkerMapFile_data();
+ void linkerMapFile();
+
+ void compilerDefinesByLanguage();
+
+ void toolchainProbe();
+
+private:
+
+};
+
+#endif // TST_BLACKBOXBAREMETAL_H
diff --git a/tests/auto/blackbox/tst_blackboxbase.cpp b/tests/auto/blackbox/tst_blackboxbase.cpp
index 61b0271f6..317a6b663 100644
--- a/tests/auto/blackbox/tst_blackboxbase.cpp
+++ b/tests/auto/blackbox/tst_blackboxbase.cpp
@@ -64,7 +64,7 @@ static bool supportsSettingsDirOption(const QString &command) {
TestBlackboxBase::TestBlackboxBase(const QString &testDataSrcDir, const QString &testName)
: testDataDir(testWorkDir(testName)),
- testSourceDir(QDir::cleanPath(testDataSrcDir)),
+ testSourceDir(testDataSourceDir(testDataSrcDir)),
qbsExecutableFilePath(initQbsExecutableFilePath()),
defaultInstallRoot(relativeBuildDir() + QLatin1Char('/') + InstallOptions::defaultInstallRoot())
{
@@ -96,14 +96,18 @@ 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 if (m_qbsStdout.contains("Memory leak:")) {
+ exitCode = 27;
+ } else {
+ exitCode = process.exitCode();
}
m_qbsStderr = process.readAllStandardError();
@@ -111,14 +115,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;
}
/*!
@@ -194,10 +198,30 @@ void TestBlackboxBase::initTestCase()
QVERIFY(copyDllExportHeader(testSourceDir, testDataDir));
}
+void TestBlackboxBase::validateTestProfile()
+{
+ const SettingsPtr s = settings();
+ if (profileName() != "none" && !s->profiles().contains(profileName()))
+ QFAIL(QByteArray("The build profile '" + profileName().toLocal8Bit() +
+ "' could not be found. Please set it up on your machine."));
+ if (!m_needsQt)
+ return;
+ const QStringList qmakeFilePaths = Profile(profileName(), s.get())
+ .value("moduleProviders.Qt.qmakeFilePaths").toStringList();
+ if (!qmakeFilePaths.empty())
+ return;
+ if (!findExecutable(QStringList{"qmake"}).isEmpty())
+ return;
+ QSKIP(QByteArray("The build profile '" + profileName().toLocal8Bit() +
+ "' is not a valid Qt profile and Qt was not found "
+ "in the global search paths."));
+
+}
+
QString TestBlackboxBase::findExecutable(const QStringList &fileNames)
{
const QStringList path = QString::fromLocal8Bit(qgetenv("PATH"))
- .split(HostOsInfo::pathListSeparator(), QString::SkipEmptyParts);
+ .split(HostOsInfo::pathListSeparator(), Qt::SkipEmptyParts);
for (const QString &fileName : fileNames) {
QFileInfo fi(fileName);
@@ -232,3 +256,34 @@ QMap<QString, QString> TestBlackboxBase::findJdkTools(int *status)
{"jar", QDir::fromNativeSeparators(tools["jar"].toString())}
};
}
+
+qbs::Version TestBlackboxBase::qmakeVersion(const QString &qmakeFilePath)
+{
+ QStringList arguments;
+ arguments << "-query" << "QT_VERSION";
+ QProcess qmakeProcess;
+ qmakeProcess.start(qmakeFilePath, arguments);
+ if (!qmakeProcess.waitForStarted() || !qmakeProcess.waitForFinished()
+ || qmakeProcess.exitStatus() != QProcess::NormalExit) {
+ qDebug() << "qmake '" << qmakeFilePath << "' could not be run.";
+ return qbs::Version();
+ }
+ QByteArray result = qmakeProcess.readAll().simplified();
+ qbs::Version version = qbs::Version::fromString(result);
+ if (!version.isValid())
+ qDebug() << "qmake '" << qmakeFilePath << "' version is not valid.";
+ return version;
+}
+
+bool waitForProcessSuccess(QProcess &p, int msecs)
+{
+ if (!p.waitForStarted(msecs) || !p.waitForFinished(msecs)) {
+ qDebug() << p.errorString();
+ return false;
+ }
+ if (p.exitCode() != 0) {
+ qDebug() << p.readAllStandardError();
+ return false;
+ }
+ return true;
+}
diff --git a/tests/auto/blackbox/tst_blackboxbase.h b/tests/auto/blackbox/tst_blackboxbase.h
index 251f3752d..5733cacd7 100644
--- a/tests/auto/blackbox/tst_blackboxbase.h
+++ b/tests/auto/blackbox/tst_blackboxbase.h
@@ -42,14 +42,14 @@ public:
init();
}
- QbsRunParameters(const QString &cmd, const QStringList &args = QStringList())
- : command(cmd), arguments(args)
+ QbsRunParameters(QString cmd, QStringList args = QStringList())
+ : command(std::move(cmd)), arguments(std::move(args))
{
init();
}
- QbsRunParameters(const QStringList &args)
- : arguments(args)
+ QbsRunParameters(QStringList args)
+ : arguments(std::move(args))
{
init();
}
@@ -60,7 +60,14 @@ public:
expectCrash = false;
profile = profileName();
settingsDir = settings()->baseDirectory();
- environment = QProcessEnvironment::systemEnvironment();
+ environment = defaultEnvironment();
+ }
+
+ static QProcessEnvironment defaultEnvironment()
+ {
+ auto result = QProcessEnvironment::systemEnvironment();
+ result.insert(QStringLiteral("QBS_AUTOTEST_CODE_SIGNING_REQUIRED"), QStringLiteral("0"));
+ return result;
}
QString command;
@@ -83,15 +90,19 @@ public:
public slots:
virtual void initTestCase();
+ static QString findExecutable(const QStringList &fileNames);
+
protected:
- virtual void validateTestProfile() { }
+ virtual void validateTestProfile();
+
+ void setNeedsQt() { m_needsQt = true; }
int runQbs(const QbsRunParameters &params = QbsRunParameters());
void rmDirR(const QString &dir);
static QByteArray unifiedLineEndings(const QByteArray &ba);
static void sanitizeOutput(QByteArray *ba);
static void ccp(const QString &sourceDirPath, const QString &targetDirPath);
- static QString findExecutable(const QStringList &fileNames);
QMap<QString, QString> findJdkTools(int *status);
+ static qbs::Version qmakeVersion(const QString &qmakeFilePath);
const QString testDataDir;
const QString testSourceDir;
@@ -100,6 +111,9 @@ protected:
QByteArray m_qbsStderr;
QByteArray m_qbsStdout;
+ int m_needsQt = false;
};
+bool waitForProcessSuccess(QProcess &p, int msecs = 30000);
+
#endif // TST_BLACKBOXBASE_H
diff --git a/tests/auto/blackbox/tst_blackboxexamples.cpp b/tests/auto/blackbox/tst_blackboxexamples.cpp
new file mode 100644
index 000000000..13ccb7796
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxexamples.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://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.
+**
+****************************************************************************/
+
+#include "tst_blackboxexamples.h"
+
+#include <QtCore/qdir.h>
+#include <QtCore/qdiriterator.h>
+
+QStringList TestBlackboxExamples::collectExamples(const QString &dirPath)
+{
+ QStringList result;
+ QDir dir(dirPath);
+ const auto subDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
+ for (const auto &subDir : subDirs) {
+ const auto path = dir.filePath(subDir);
+ if (!QFileInfo::exists(path + "/" + subDir + ".qbs"))
+ continue;
+ result.append(QDir(testDataDir).relativeFilePath(path));
+ }
+ return result;
+}
+
+TestBlackboxExamples::TestBlackboxExamples()
+ : TestBlackboxBase(SRCDIR "/../../../examples/", "blackbox-examples")
+{
+ setNeedsQt();
+}
+
+void TestBlackboxExamples::baremetal_data()
+{
+ QTest::addColumn<QString>("example");
+
+ QDir baremetal(testDataDir + "/baremetal/");
+ const auto subDirs = baremetal.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
+ for (const auto &subDir : subDirs) {
+ const auto examples = collectExamples(baremetal.filePath(subDir));
+ for (const auto &example: examples) {
+ const auto relativePath = baremetal.relativeFilePath(example);
+ QTest::newRow(relativePath.toUtf8().data()) << relativePath;
+ }
+ }
+}
+
+void TestBlackboxExamples::baremetal()
+{
+ QFETCH(QString, example);
+
+ QVERIFY(QDir::setCurrent(testDataDir + "/" + example));
+ QCOMPARE(runQbs(), 0);
+}
+
+void TestBlackboxExamples::examples_data()
+{
+ QTest::addColumn<QString>("example");
+
+ auto examples = collectExamples(testDataDir);
+ examples.append(collectExamples(testDataDir + "/protobuf"));
+ examples.append(collectExamples(testDataDir + "/flatbuffers"));
+ std::sort(examples.begin(), examples.end());
+
+ for (const auto &example: examples) {
+ if (example == u"baremetal")
+ continue;
+ QTest::newRow(example.toUtf8().data()) << example;
+ }
+}
+
+void TestBlackboxExamples::examples()
+{
+ QFETCH(QString, example);
+
+ QVERIFY(QDir::setCurrent(testDataDir + "/" + example));
+ QbsRunParameters params(
+ {QStringLiteral("-f"), QFileInfo(example).fileName() + QStringLiteral(".qbs")});
+ QCOMPARE(runQbs(params), 0);
+}
+
+QTEST_MAIN(TestBlackboxExamples)
diff --git a/tests/auto/blackbox/tst_blackboxexamples.h b/tests/auto/blackbox/tst_blackboxexamples.h
new file mode 100644
index 000000000..bea8be768
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxexamples.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://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.
+**
+****************************************************************************/
+
+#ifndef TST_BLACKBOXEXAMPLES_H
+#define TST_BLACKBOXEXAMPLES_H
+
+#include "tst_blackboxbase.h"
+
+class TestBlackboxExamples : public TestBlackboxBase
+{
+ Q_OBJECT
+
+private:
+ QStringList collectExamples(const QString &dirPath);
+
+public:
+ TestBlackboxExamples();
+
+private slots:
+ void baremetal_data();
+ void baremetal();
+ void examples_data();
+ void examples();
+};
+
+#endif // TST_BLACKBOXEXAMPLES_H
diff --git a/tests/auto/blackbox/tst_blackboxjava.cpp b/tests/auto/blackbox/tst_blackboxjava.cpp
index f7feb0612..4ddd6cdda 100644
--- a/tests/auto/blackbox/tst_blackboxjava.cpp
+++ b/tests/auto/blackbox/tst_blackboxjava.cpp
@@ -39,7 +39,9 @@
using qbs::Internal::HostOsInfo;
using qbs::Profile;
-TestBlackboxJava::TestBlackboxJava() : TestBlackboxBase (SRCDIR "/testdata-java", "blackbox-java")
+TestBlackboxJava::TestBlackboxJava()
+ : TestBlackboxBase (SRCDIR "/testdata-java", "blackbox-java"),
+ m_blacklistedJdks(qgetenv("QBS_AUTOTEST_JDK_BLACKLIST"))
{
}
@@ -73,6 +75,9 @@ void TestBlackboxJava::java()
QSKIP("java.jdkPath not set and automatic detection failed");
}
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Skip test in cross-compiled build");
+
QCOMPARE(status, 0);
const QStringList classFiles =
@@ -93,7 +98,7 @@ void TestBlackboxJava::java()
// Now check whether we correctly predicted the class file output paths.
QCOMPARE(runQbs(QbsRunParameters("clean")), 0);
- for (const QString &classFile : qAsConst(classFiles1)) {
+ for (const QString &classFile : std::as_const(classFiles1)) {
QVERIFY2(!regularFileExists(classFile), qPrintable(classFile));
}
@@ -119,7 +124,7 @@ void TestBlackboxJava::java()
if (process.waitForStarted()) {
QVERIFY2(process.waitForFinished(), qPrintable(process.errorString()));
const QByteArray stdOut = process.readAllStandardOutput();
- QVERIFY2(stdOut.contains("Class-Path: car_jar.jar random_stuff.jar"), stdOut.constData());
+ QVERIFY2(stdOut.contains("Class-Path: random_stuff.jar car_jar.jar"), stdOut.constData());
QVERIFY2(stdOut.contains("Main-Class: Vehicles"), stdOut.constData());
QVERIFY2(stdOut.contains("Some-Property: Some-Value"), stdOut.constData());
QVERIFY2(stdOut.contains("Additional-Property: Additional-Value"), stdOut.constData());
@@ -145,8 +150,11 @@ void TestBlackboxJava::javaDependencyTracking()
QDir::setCurrent(testDataDir + "/java");
QbsRunParameters rp;
rp.arguments.push_back("--check-outputs");
- if (!jdkPath.isEmpty())
+ if (!jdkPath.isEmpty()) {
+ if (m_blacklistedJdks.contains(jdkPath))
+ QSKIP("skipping blacklisted JDK");
rp.arguments << ("modules.java.jdkPath:" + jdkPath);
+ }
if (!javaVersion.isEmpty())
rp.arguments << ("modules.java.languageVersion:'" + javaVersion + "'");
rmDirR(relativeBuildDir());
@@ -167,7 +175,7 @@ void TestBlackboxJava::javaDependencyTracking_data()
auto getSpecificJdkVersion = [](const QString &jdkVersion) -> QString {
if (HostOsInfo::isMacosHost()) {
QProcess java_home;
- java_home.start("/usr/libexec/java_home", QStringList() << "--version" << jdkVersion);
+ java_home.start("/usr/libexec/java_home", {"--version", jdkVersion, "--failfast"});
java_home.waitForFinished();
if (java_home.exitStatus() == QProcess::NormalExit && java_home.exitCode() == 0)
return QString::fromLocal8Bit(java_home.readAllStandardOutput().trimmed());
@@ -184,6 +192,7 @@ void TestBlackboxJava::javaDependencyTracking_data()
"/usr/lib/jvm/java-" + minorVersion + "-openjdk" + dpkgArch("-"), // Debian
"/usr/lib/jvm/java-" + minorVersion + "-openjdk", // Arch
"/usr/lib/jvm/jre-1." + minorVersion + ".0-openjdk", // Fedora
+ "/usr/lib64/jvm/java-1." + minorVersion + ".0-openjdk", // OpenSuSE
};
for (const QString &searchPath : searchPaths) {
if (QFile::exists(searchPath + "/bin/javac"))
@@ -194,7 +203,7 @@ void TestBlackboxJava::javaDependencyTracking_data()
return {};
};
- static const auto knownJdkVersions = QStringList() << "1.6" << "1.7" << "1.8" << "1.9"
+ static const auto knownJdkVersions = QStringList() << "1.7" << "1.8" << "1.9"
<< QString(); // default JDK;
QStringList seenJdkVersions;
for (const auto &jdkVersion : knownJdkVersions) {
diff --git a/tests/auto/blackbox/tst_blackboxjava.h b/tests/auto/blackbox/tst_blackboxjava.h
index 68d8a7f80..e770306df 100644
--- a/tests/auto/blackbox/tst_blackboxjava.h
+++ b/tests/auto/blackbox/tst_blackboxjava.h
@@ -43,6 +43,9 @@ private slots:
void javaDependencyTracking();
void javaDependencyTracking_data();
void javaDependencyTrackingInnerClass();
+
+private:
+ const QStringList m_blacklistedJdks;
};
#endif // TST_BLACKBOX_H
diff --git a/tests/auto/blackbox/tst_blackboxjoblimits.cpp b/tests/auto/blackbox/tst_blackboxjoblimits.cpp
index 89b5f638e..acaf69a5b 100644
--- a/tests/auto/blackbox/tst_blackboxjoblimits.cpp
+++ b/tests/auto/blackbox/tst_blackboxjoblimits.cpp
@@ -39,6 +39,7 @@ public:
TestBlackboxJobLimits();
private slots:
+ void initTestCase();
void jobLimits_data();
void jobLimits();
};
@@ -48,6 +49,16 @@ TestBlackboxJobLimits::TestBlackboxJobLimits()
{
}
+void TestBlackboxJobLimits::initTestCase()
+{
+ TestBlackboxBase::initTestCase();
+
+ QDir::setCurrent(testDataDir + "/job-limits-init");
+ QCOMPARE(runQbs({"resolve"}), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Skip test in cross-compiled build");
+}
+
void TestBlackboxJobLimits::jobLimits_data()
{
QTest::addColumn<int>("projectJobCount");
@@ -143,6 +154,7 @@ void TestBlackboxJobLimits::jobLimits()
SettingsPtr theSettings = settings();
qbs::Internal::TemporaryProfile profile("jobLimitsProfile", theSettings.get());
profile.p.setValue("preferences.jobLimit.singleton", prefsJobCount);
+ profile.p.setValue("baseProfile", profileName());
theSettings->sync();
QbsRunParameters resolveParams("resolve");
resolveParams.profile = profile.p.name();
@@ -150,6 +162,7 @@ void TestBlackboxJobLimits::jobLimits()
<< ("project.productJobCount:" + QString::number(productJobCount))
<< ("project.moduleJobCount:" + QString::number(moduleJobCount));
QCOMPARE(runQbs(resolveParams), 0);
+
QbsRunParameters buildParams;
buildParams.expectFailure = !expectSuccess;
if (cliJobCount != -1)
@@ -165,7 +178,7 @@ void TestBlackboxJobLimits::jobLimits()
else
QVERIFY2(m_qbsStderr.contains("exclusive"), m_qbsStderr.constData());
if (exitCode == 0)
- QCOMPARE(m_qbsStdout.count("Running tool"), 5);
+ QCOMPARE(m_qbsStdout.count("running tool"), 5);
}
QTEST_MAIN(TestBlackboxJobLimits)
diff --git a/tests/auto/blackbox/tst_blackboxproviders.cpp b/tests/auto/blackbox/tst_blackboxproviders.cpp
new file mode 100644
index 000000000..cf6594229
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxproviders.cpp
@@ -0,0 +1,443 @@
+/****************************************************************************
+**
+** Copyright (C) 2023 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://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.
+**
+****************************************************************************/
+
+#include "tst_blackboxproviders.h"
+
+#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;
+
+#define WAIT_FOR_NEW_TIMESTAMP() waitForNewTimestamp(testDataDir)
+
+TestBlackboxProviders::TestBlackboxProviders()
+ : TestBlackboxBase(SRCDIR "/testdata-providers", "blackbox-providers")
+{
+}
+
+void TestBlackboxProviders::allowedValues()
+{
+ QFETCH(QStringList, arguments);
+ QFETCH(bool, expectFailure);
+
+ QDir::setCurrent(testDataDir + "/allowed-values");
+ rmDirR(relativeBuildDir());
+ QbsRunParameters params;
+ params.arguments = arguments;
+ params.expectFailure = expectFailure;
+
+ QVERIFY2(runQbs(params) == int(expectFailure), m_qbsStderr);
+}
+
+void TestBlackboxProviders::allowedValues_data()
+{
+ QTest::addColumn<QStringList>("arguments");
+ QTest::addColumn<bool>("expectFailure");
+
+ QTest::newRow("invalid js value") << QStringList{} << true;
+ QTest::newRow("invalid variant value")
+ << QStringList{"moduleProviders.provider.aProperty:three"} << true;
+ QTest::newRow("valid variant value")
+ << QStringList{"moduleProviders.provider.aProperty:one"} << false;
+}
+
+void TestBlackboxProviders::brokenProvider()
+{
+ QDir::setCurrent(testDataDir + "/broken-provider");
+ QbsRunParameters params;
+ params.expectFailure = true;
+ QVERIFY(runQbs(params) != 0);
+
+ QVERIFY(m_qbsStderr.contains("Error executing provider for module 'qbsothermodule'"));
+ QVERIFY(m_qbsStderr.contains("Error executing provider for module 'qbsmetatestmodule'"));
+ QCOMPARE(m_qbsStderr.count("This provider is broken"), 2);
+}
+
+void TestBlackboxProviders::conanProvider()
+{
+ QFETCH(bool, generateConanFiles);
+ QFETCH(bool, successExpected);
+
+ const auto executable = findExecutable({"conan"});
+ if (executable.isEmpty())
+ QSKIP("conan is not installed or not available in PATH.");
+
+ const auto generator = QDir::homePath() + "/.conan2/extensions/generators/qbsdeps.py";
+ if (!QFileInfo(generator).exists()) {
+ QSKIP(
+ "qbsdeps.py is not installed, call 'conan config install src/conan/ from qbs source'.");
+ }
+
+ const auto profilePath = QDir::homePath() + "/.conan2/profiles/qbs-test";
+ if (!QFileInfo(profilePath).exists())
+ QSKIP("conan profile is not installed, run './scripts/setup-conan-profiles.sh'.");
+
+ // install testlibdep first
+ QProcess conan;
+ QDir::setCurrent(testDataDir + "/conan-provider/testlibdep");
+ conan.start(executable, {"create", ".", "--profile:all=qbs-test"});
+ QVERIFY(waitForProcessSuccess(conan));
+
+ // install testlib second
+ QDir::setCurrent(testDataDir + "/conan-provider/testlib");
+ conan.start(executable, {"create", ".", "--profile:all=qbs-test"});
+ QVERIFY(waitForProcessSuccess(conan));
+
+ // install header lib third
+ QDir::setCurrent(testDataDir + "/conan-provider/testlibheader");
+ conan.start(executable, {"create", ".", "--profile:all=qbs-test"});
+ QVERIFY(waitForProcessSuccess(conan));
+
+ // now build an app using those libs
+ QDir::setCurrent(testDataDir + "/conan-provider");
+
+ rmDirR(relativeBuildDir());
+ rmDirR("build");
+
+ if (generateConanFiles) {
+ QStringList arguments{
+ "install", ".", "-g=QbsDeps", "--profile:all=qbs-test", "--output-folder=build"};
+ QProcess conan;
+ conan.start(executable, arguments);
+ QVERIFY(waitForProcessSuccess(conan));
+ }
+
+ QbsRunParameters buildParams(
+ "build",
+ {"--force-probe-execution",
+ "moduleProviders.conan.installDirectory:" + QDir::currentPath() + "/build"});
+ buildParams.expectFailure = !successExpected;
+ QCOMPARE(runQbs(buildParams) == 0, successExpected);
+}
+
+void TestBlackboxProviders::conanProvider_data()
+{
+ QTest::addColumn<bool>("generateConanFiles");
+ QTest::addColumn<bool>("successExpected");
+
+ QTest::addRow("no conan files generated") << false << false;
+ QTest::addRow("conan files generated") << true << true;
+}
+
+void TestBlackboxProviders::moduleProviders()
+{
+ QDir::setCurrent(testDataDir + "/module-providers");
+
+ // Resolving in dry-run mode must not leave any data behind.
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+ QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 2);
+ QVERIFY(!QFile::exists(relativeBuildDir()));
+
+ // Initial build.
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
+ QVERIFY(QFile::exists(relativeBuildDir()));
+ QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 2);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("The MY_DEFINE is app1"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are Z and Y"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("The MY_DEFINE is app2"), m_qbsStdout.constData());
+
+ // Rebuild with overridden module provider config. The output for product 2 must change,
+ // but no setup script must be re-run, because both config values have already been
+ // handled in the first run.
+ const QStringList resolveArgs("moduleProviders.mygenerator.chooseLettersFrom:beginning");
+ QCOMPARE(runQbs(QbsRunParameters("resolve", resolveArgs)), 0);
+ QVERIFY2(!m_qbsStdout.contains("Running setup script"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+
+ // Forcing Probe execution triggers a re-run of the setup script. But only once,
+ // because the module provider config is the same now.
+ QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList(resolveArgs)
+ << "--force-probe-execution")), 0);
+ QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 1);
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+
+ // Now re-run without the module provider config override. Again, the setup script must
+ // run once, for the config value that was not present in the last run.
+ QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 1);
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0);
+ QVERIFY2(m_qbsStdout.contains("The letters are Z and Y"), m_qbsStdout.constData());
+}
+
+// Checks regression - when loading 2 modules from the same provider, the second module should
+// come from provider cache
+void TestBlackboxProviders::moduleProvidersCache()
+{
+ QDir::setCurrent(testDataDir + "/module-providers-cache");
+
+ QbsRunParameters params("resolve", {"-v"});
+ QCOMPARE(runQbs(params), 0);
+ const auto qbsmetatestmoduleMessage = "Re-checking for module \"qbsmetatestmodule\" with "
+ "newly added search paths from module provider";
+ const auto qbsothermoduleMessage = "Re-checking for module \"qbsothermodule\" with "
+ "newly added search paths from module provider";
+ QCOMPARE(m_qbsStderr.count(qbsmetatestmoduleMessage), 1);
+ QCOMPARE(m_qbsStderr.count(qbsothermoduleMessage), 1);
+ QCOMPARE(m_qbsStderr.count("Re-using provider \"provider_a\" from cache"), 1);
+
+ // We didn't change providers, so both modules should come from cache.
+ params.arguments << "project.dummyProp:value";
+ QCOMPARE(runQbs(params), 0);
+ QCOMPARE(m_qbsStderr.count(qbsmetatestmoduleMessage), 1);
+ QCOMPARE(m_qbsStderr.count(qbsothermoduleMessage), 1);
+ QCOMPARE(m_qbsStderr.count("Re-using provider \"provider_a\" from cache"), 2);
+}
+
+void TestBlackboxProviders::nonEagerModuleProvider()
+{
+ QDir::setCurrent(testDataDir + "/non-eager-provider");
+
+ QbsRunParameters params("resolve");
+ QCOMPARE(runQbs(params), 0);
+ QVERIFY2(m_qbsStdout.contains(("Running setup script for qbsmetatestmodule")), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains(("Running setup script for qbsothermodule")), m_qbsStdout);
+ QVERIFY2(!m_qbsStdout.contains(("Running setup script for nonexistentmodule")), m_qbsStdout);
+
+ QVERIFY2(m_qbsStdout.contains(("p1.qbsmetatestmodule.prop: from_provider_a")),
+ m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains(("p1.qbsothermodule.prop: from_provider_a")),
+ m_qbsStdout);
+}
+
+void TestBlackboxProviders::probeInModuleProvider()
+{
+ QDir::setCurrent(testDataDir + "/probe-in-module-provider");
+
+ QbsRunParameters params;
+ params.command = "build";
+ params.arguments << "--force-probe-execution";
+ QCOMPARE(runQbs(params), 0);
+ QVERIFY2(m_qbsStdout.contains("Running probe"), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains("p.qbsmetatestmodule.boolProp: true"), m_qbsStdout);
+ WAIT_FOR_NEW_TIMESTAMP();
+ touch("probe-in-module-provider.qbs");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY2(m_qbsStdout.contains("p.qbsmetatestmodule.boolProp: true"), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains("p.qbsmetatestmodule.prop: \"value\""), m_qbsStdout);
+ QVERIFY2(!m_qbsStdout.contains("Running probe"), m_qbsStdout);
+}
+
+// Tests whether it is possible to set providers properties in a Product or from command-line
+void TestBlackboxProviders::providersProperties()
+{
+ QDir::setCurrent(testDataDir + "/providers-properties");
+
+ QbsRunParameters params("build");
+ params.arguments = QStringList("moduleProviders.provider_b.someProp: \"first,second\"");
+ QCOMPARE(runQbs(params), 0);
+ QVERIFY2(m_qbsStdout.contains("p.qbsmetatestmodule.listProp: [\"someValue\"]"), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains(
+ "p.qbsothermodule.listProp: [\"first\",\"second\"]"), m_qbsStdout);
+}
+
+// checks that we can set qbs module properties in providers and provider cache works corectly
+void TestBlackboxProviders::qbsModulePropertiesInProviders()
+{
+ QDir::setCurrent(testDataDir + "/qbs-module-properties-in-providers");
+
+ QbsRunParameters params("resolve");
+
+ QCOMPARE(runQbs(params), 0);
+
+ // We have 2 products in 2 configurations, but second product should use the cached value
+ // so we should have only 2 copies of the module, not 4.
+ QCOMPARE(m_qbsStdout.count("Running setup script for qbsmetatestmodule"), 2);
+
+ // Check that products get correct values from modules
+ QVERIFY2(m_qbsStdout.contains(("product1.qbsmetatestmodule.prop: /sysroot1")), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains(("product1.qbsmetatestmodule.prop: /sysroot2")), m_qbsStdout);
+
+ QVERIFY2(m_qbsStdout.contains(("product2.qbsmetatestmodule.prop: /sysroot1")), m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains(("product2.qbsmetatestmodule.prop: /sysroot2")), m_qbsStdout);
+}
+
+void TestBlackboxProviders::qbsModuleProviders_data()
+{
+ QTest::addColumn<QStringList>("arguments");
+ QTest::addColumn<QString>("firstProp");
+ QTest::addColumn<QString>("secondProp");
+
+ QTest::newRow("default") << QStringList() << "from_provider_a" << "undefined";
+ QTest::newRow("override")
+ << QStringList("projects.project.qbsModuleProviders:provider_b")
+ << "from_provider_b"
+ << "from_provider_b";
+ QTest::newRow("override list a")
+ << QStringList("projects.project.qbsModuleProviders:provider_a,provider_b")
+ << "from_provider_a"
+ << "from_provider_b";
+ QTest::newRow("override list b")
+ << QStringList("projects.project.qbsModuleProviders:provider_b,provider_a")
+ << "from_provider_b"
+ << "from_provider_b";
+}
+
+// Tests whether it is possible to set qbsModuleProviders in Product and Project items
+// and that the order of providers results in correct priority
+void TestBlackboxProviders::qbsModuleProviders()
+{
+ QFETCH(QStringList, arguments);
+ QFETCH(QString, firstProp);
+ QFETCH(QString, secondProp);
+
+ QDir::setCurrent(testDataDir + "/qbs-module-providers");
+
+ QbsRunParameters params("resolve");
+ params.arguments = arguments;
+ QCOMPARE(runQbs(params), 0);
+ QVERIFY2(m_qbsStdout.contains(("p1.qbsmetatestmodule.prop: " + firstProp).toUtf8()),
+ m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains(("p1.qbsothermodule.prop: " + secondProp).toUtf8()),
+ m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains(("p2.qbsmetatestmodule.prop: " + firstProp).toUtf8()),
+ m_qbsStdout);
+ QVERIFY2(m_qbsStdout.contains(("p2.qbsothermodule.prop: " + secondProp).toUtf8()),
+ m_qbsStdout);
+}
+
+void TestBlackboxProviders::qbsModuleProvidersCliOverride_data()
+{
+ QTest::addColumn<QStringList>("arguments");
+ QTest::addColumn<QString>("propertyValue");
+
+ QTest::newRow("default") << QStringList() << "undefined";
+ QTest::newRow("project-wide")
+ << QStringList("project.qbsModuleProviders:provider_a")
+ << "from_provider_a";
+ QTest::newRow("concrete project")
+ << QStringList("projects.innerProject.qbsModuleProviders:provider_a")
+ << "from_provider_a";
+ QTest::newRow("concrete product")
+ << QStringList("products.product.qbsModuleProviders:provider_a")
+ << "from_provider_a";
+ QTest::newRow("concrete project override project-wide")
+ << QStringList({
+ "project.qbsModuleProviders:provider_a",
+ "projects.innerProject.qbsModuleProviders:provider_b"})
+ << "from_provider_b";
+ QTest::newRow("concrete product override project-wide")
+ << QStringList({
+ "project.qbsModuleProviders:provider_a",
+ "products.product.qbsModuleProviders:provider_b"})
+ << "from_provider_b";
+}
+
+// Tests possible use-cases how to override providers from command-line
+void TestBlackboxProviders::qbsModuleProvidersCliOverride()
+{
+ QFETCH(QStringList, arguments);
+ QFETCH(QString, propertyValue);
+
+ QDir::setCurrent(testDataDir + "/qbs-module-providers-cli-override");
+
+ QbsRunParameters params("resolve");
+ params.arguments = arguments;
+ QCOMPARE(runQbs(params), 0);
+ QVERIFY2(m_qbsStdout.contains(("qbsmetatestmodule.prop: " + propertyValue).toUtf8()),
+ m_qbsStdout);
+}
+
+void TestBlackboxProviders::qbsModuleProvidersCompatibility_data()
+{
+ QTest::addColumn<QStringList>("arguments");
+ QTest::addColumn<QString>("propertyValue");
+
+ QTest::newRow("default") << QStringList() << "from_scoped_provider";
+ QTest::newRow("scoped by name") << QStringList("project.qbsModuleProviders:qbsmetatestmodule") << "from_scoped_provider";
+ QTest::newRow("named") << QStringList("project.qbsModuleProviders:named_provider") << "from_named_provider";
+}
+
+// Tests whether scoped providers can be used as named, i.e. new provider machinery
+// is compatible with the old one
+void TestBlackboxProviders::qbsModuleProvidersCompatibility()
+{
+ QFETCH(QStringList, arguments);
+ QFETCH(QString, propertyValue);
+
+ QDir::setCurrent(testDataDir + "/qbs-module-providers-compatibility");
+
+ QbsRunParameters params("resolve");
+ params.arguments = arguments;
+ QCOMPARE(runQbs(params), 0);
+ QVERIFY2(m_qbsStdout.contains(("qbsmetatestmodule.prop: " + propertyValue).toUtf8()),
+ m_qbsStdout);
+}
+
+void TestBlackboxProviders::qbspkgconfigModuleProvider()
+{
+ QDir::setCurrent(testDataDir + "/qbspkgconfig-module-provider/libs");
+ rmDirR(relativeBuildDir());
+
+ const auto commonParams = QbsRunParameters(QStringLiteral("install"), {
+ QStringLiteral("--install-root"),
+ QStringLiteral("install-root")
+ });
+ auto dynamicParams = commonParams;
+ dynamicParams.arguments << "config:library" << "projects.libs.isBundle:false";
+ QCOMPARE(runQbs(dynamicParams), 0);
+
+ QDir::setCurrent(testDataDir + "/qbspkgconfig-module-provider");
+ rmDirR(relativeBuildDir());
+
+ const auto sysroot = testDataDir + "/qbspkgconfig-module-provider/libs/install-root";
+
+ QbsRunParameters params;
+ params.arguments << "moduleProviders.qbspkgconfig.sysroot:" + sysroot;
+ QCOMPARE(runQbs(params), 0);
+}
+
+void TestBlackboxProviders::removalVersion()
+{
+ QDir::setCurrent(testDataDir + "/removal-version");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY(m_qbsStderr.contains(
+ "Property 'deprecated' was scheduled for removal in version 2.2.0, but is still present"));
+}
+
+QTEST_MAIN(TestBlackboxProviders)
diff --git a/tests/auto/blackbox/tst_blackboxproviders.h b/tests/auto/blackbox/tst_blackboxproviders.h
new file mode 100644
index 000000000..088cea6a3
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxproviders.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2023 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://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.
+**
+****************************************************************************/
+
+#ifndef TST_BLACKBOXPROVIDERS_H
+#define TST_BLACKBOXPROVIDERS_H
+
+#include "tst_blackboxbase.h"
+
+class TestBlackboxProviders : public TestBlackboxBase
+{
+ Q_OBJECT
+
+public:
+ TestBlackboxProviders();
+
+private slots:
+ void allowedValues();
+ void allowedValues_data();
+ void brokenProvider();
+ void conanProvider();
+ void conanProvider_data();
+ void moduleProviders();
+ void moduleProvidersCache();
+ void nonEagerModuleProvider();
+ void probeInModuleProvider();
+ void providersProperties();
+ void qbsModulePropertiesInProviders();
+ void qbsModuleProviders_data();
+ void qbsModuleProviders();
+ void qbsModuleProvidersCliOverride();
+ void qbsModuleProvidersCliOverride_data();
+ void qbsModuleProvidersCompatibility();
+ void qbsModuleProvidersCompatibility_data();
+ void qbspkgconfigModuleProvider();
+ void removalVersion();
+};
+
+#endif // TST_BLACKBOXPROVIDERS_H
diff --git a/tests/auto/blackbox/tst_blackboxqt.cpp b/tests/auto/blackbox/tst_blackboxqt.cpp
index 474fb95f3..b083a97e8 100644
--- a/tests/auto/blackbox/tst_blackboxqt.cpp
+++ b/tests/auto/blackbox/tst_blackboxqt.cpp
@@ -38,27 +38,10 @@
#define WAIT_FOR_NEW_TIMESTAMP() waitForNewTimestamp(testDataDir)
using qbs::Internal::HostOsInfo;
-using qbs::Profile;
TestBlackboxQt::TestBlackboxQt() : TestBlackboxBase (SRCDIR "/testdata-qt", "blackbox-qt")
{
-}
-
-void TestBlackboxQt::validateTestProfile()
-{
- const SettingsPtr s = settings();
- if (profileName() != "none" && !s->profiles().contains(profileName()))
- QFAIL(QByteArray("The build profile '" + profileName().toLocal8Bit() +
- "' could not be found. Please set it up on your machine."));
- const QStringList qmakeFilePaths = Profile(profileName(), s.get())
- .value("moduleProviders.Qt.qmakeFilePaths").toStringList();
- if (!qmakeFilePaths.empty())
- return;
- if (!findExecutable(QStringList{"qmake"}).isEmpty())
- return;
- QSKIP(QByteArray("The build profile '" + profileName().toLocal8Bit() +
- "' is not a valid Qt profile and Qt was not found "
- "in the global search paths."));
+ setNeedsQt();
}
void TestBlackboxQt::addQObjectMacroToGeneratedCppFile()
@@ -75,6 +58,9 @@ void TestBlackboxQt::addQObjectMacroToGeneratedCppFile()
void TestBlackboxQt::autoQrc()
{
QDir::setCurrent(testDataDir + "/auto-qrc");
+ QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app"})), 0);
QVERIFY2(m_qbsStdout.simplified().contains("resource data: resource1 resource2"),
m_qbsStdout.constData());
@@ -83,7 +69,9 @@ void TestBlackboxQt::autoQrc()
void TestBlackboxQt::cachedQml()
{
QDir::setCurrent(testDataDir + "/cached-qml");
- QCOMPARE(runQbs(), 0);
+ if ((runQbs() != 0) && m_qbsStderr.contains("Dependency 'Qt.qml' not found for product 'app'"))
+ QSKIP("Qt version too old");
+
QString dataDir = relativeBuildDir() + "/install-root/data";
QVERIFY2(m_qbsStdout.contains("qmlcachegen must work: true")
|| m_qbsStdout.contains("qmlcachegen must work: false"),
@@ -118,7 +106,7 @@ void TestBlackboxQt::combinedMoc()
void TestBlackboxQt::createProject()
{
QDir::setCurrent(testDataDir + "/create-project");
- QVERIFY(QFile::copy(SRCDIR "/../../../examples/helloworld-qt/main.cpp",
+ QVERIFY(QFile::copy(testSourceDir + "/../../../../examples/helloworld-qt/main.cpp",
QDir::currentPath() + "/main.cpp"));
QbsRunParameters createParams("create-project");
createParams.profile.clear();
@@ -145,6 +133,11 @@ void TestBlackboxQt::dbusInterfaces()
void TestBlackboxQt::forcedMoc()
{
QDir::setCurrent(testDataDir + "/forced-moc");
+ QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ if (m_qbsStdout.contains("using qt4"))
+ QSKIP("Qt version too old");
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QCOMPARE(runQbs(QbsRunParameters("run")), 0);
QVERIFY2(m_qbsStderr.contains("Hello from slot"), m_qbsStderr.constData());
}
@@ -153,6 +146,8 @@ void TestBlackboxQt::includedMocCpp()
{
QDir::setCurrent(testDataDir + "/included-moc-cpp");
QCOMPARE(runQbs(), 0);
+ if (m_qbsStdout.contains("using qt4"))
+ QSKIP("Qt version too old");
QVERIFY2(!m_qbsStdout.contains("compiling moc_myobject.cpp"), m_qbsStdout.constData());
WAIT_FOR_NEW_TIMESTAMP();
REPLACE_IN_FILE("myobject.cpp", "#include <moc_myobject.cpp", "// #include <moc_myobject.cpp");
@@ -204,12 +199,48 @@ void TestBlackboxQt::lrelease()
QVERIFY(!regularFileExists(relativeProductBuildDir("lrelease-test") + "/hu.qm"));
}
+void TestBlackboxQt::metaTypes_data()
+{
+ QTest::addColumn<bool>("generate");
+ QTest::addColumn<QString>("installDir");
+ QTest::newRow("don't generate") << false << QString();
+ QTest::newRow("don't generate with install info") << false << QString("blubb");
+ QTest::newRow("generate only") << true << QString();
+ QTest::newRow("generate and install") << true << QString("blubb");
+}
+
+void TestBlackboxQt::metaTypes()
+{
+ QDir::setCurrent(testDataDir + "/metatypes");
+ QFETCH(bool, generate);
+ QFETCH(QString, installDir);
+ const QStringList args{"modules.Qt.core.generateMetaTypesFile:"
+ + QString(generate ? "true" : "false"),
+ "modules.Qt.core.metaTypesInstallDir:" + installDir,
+ "-v", "--force-probe-execution"};
+ QCOMPARE(runQbs(QbsRunParameters("resolve", args)), 0);
+ const bool canGenerate = m_qbsStdout.contains("can generate");
+ const bool cannotGenerate = m_qbsStdout.contains("cannot generate");
+ QVERIFY(canGenerate != cannotGenerate);
+ const bool expectFiles = generate && canGenerate;
+ const bool expectInstalledFiles = expectFiles && !installDir.isEmpty();
+ QCOMPARE(runQbs(QStringList("--clean-install-root")), 0);
+ const QString productDir = relativeProductBuildDir("mylib");
+ const QString outputDir = productDir + "/qt.headers";
+ QVERIFY(!regularFileExists(outputDir + "/moc_unmocableclass.cpp.json"));
+ QCOMPARE(regularFileExists(outputDir + "/moc_mocableclass1.cpp.json"), expectFiles);
+ QCOMPARE(regularFileExists(outputDir + "/mocableclass2.moc.json"), expectFiles);
+ QCOMPARE(regularFileExists(productDir + "/mylib_metatypes.json"), expectFiles);
+ QCOMPARE(regularFileExists(relativeBuildDir() + "/install-root/some-prefix/" + installDir
+ + "/mylib_metatypes.json"), expectInstalledFiles);
+}
+
void TestBlackboxQt::mixedBuildVariants()
{
QDir::setCurrent(testDataDir + "/mixed-build-variants");
const SettingsPtr s = settings();
- Profile profile(profileName(), s.get());
- if (profile.value("qbs.toolchain").toStringList().contains("msvc")) {
+ qbs::Profile profile(profileName(), s.get());
+ if (profileToolchain(profile).contains("msvc")) {
QbsRunParameters params;
params.arguments << "qbs.buildVariant:debug";
params.expectFailure = true;
@@ -240,6 +271,12 @@ void TestBlackboxQt::mocFlags()
QVERIFY(runQbs(params) != 0);
}
+void TestBlackboxQt::mocCompilerDefines()
+{
+ QDir::setCurrent(testDataDir + "/moc-compiler-defines");
+ QCOMPARE(runQbs(), 0);
+}
+
void TestBlackboxQt::mocSameFileName()
{
QDir::setCurrent(testDataDir + "/moc-same-file-name");
@@ -247,19 +284,141 @@ void TestBlackboxQt::mocSameFileName()
QCOMPARE(m_qbsStdout.count("compiling moc_someclass.cpp"), 2);
}
+void TestBlackboxQt::noRelinkOnQDebug()
+{
+ QFETCH(QString, checkMode);
+ QFETCH(bool, expectRelink);
+
+ QVERIFY(QDir::setCurrent(testDataDir + "/no-relink-on-qdebug"));
+ rmDirR("default");
+
+ // Target check.
+ QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ QVERIFY2(m_qbsStdout.contains("is GCC: "), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("is MinGW: "), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("is Darwin: "), m_qbsStdout.constData());
+ const bool isGCCLike = m_qbsStdout.contains("is GCC: true");
+ const bool isMingw = m_qbsStdout.contains("is MinGW: true");
+ const bool isDarwin = m_qbsStdout.contains("is Darwin: true");
+ if (!isGCCLike)
+ expectRelink = false;
+ else if (isMingw || isDarwin)
+ expectRelink = true;
+
+ // Initial build.
+ QbsRunParameters params("resolve");
+ if (isGCCLike && !checkMode.isEmpty())
+ params.arguments << ("modules.cpp.exportedSymbolsCheckMode:" + checkMode);
+ QCOMPARE(runQbs(params), 0);
+ QCOMPARE(runQbs(), 0);
+ QCOMPARE(m_qbsStdout.count("linking"), 2);
+
+ // Inserting the qDebug() statement will pull in weak symbols.
+ WAIT_FOR_NEW_TIMESTAMP();
+ REPLACE_IN_FILE("lib.cpp", "// qDebug", "qDebug");
+ QCOMPARE(runQbs(), 0);
+ QCOMPARE(m_qbsStdout.count("linking"), expectRelink ? 2 : 1);
+
+ // Also check the opposite case.
+ WAIT_FOR_NEW_TIMESTAMP();
+ REPLACE_IN_FILE("lib.cpp", "qDebug", "// qDebug");
+ QCOMPARE(runQbs(), 0);
+ QCOMPARE(m_qbsStdout.count("linking"), expectRelink ? 2 : 1);
+}
+
+void TestBlackboxQt::noRelinkOnQDebug_data()
+{
+ QTest::addColumn<QString>("checkMode");
+ QTest::addColumn<bool>("expectRelink");
+ QTest::newRow("default") << QString() << false;
+ QTest::newRow("relaxed") << QString("ignore-undefined") << false;
+ QTest::newRow("strict") << QString("strict") << true;
+}
+
void TestBlackboxQt::pkgconfig()
{
QDir::setCurrent(testDataDir + "/pkgconfig");
+ QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QbsRunParameters params;
params.command = "run";
QCOMPARE(runQbs(params), 0);
- if (m_qbsStdout.contains("Skip this test"))
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
QSKIP("pkgconfig or Qt not found");
}
+void TestBlackboxQt::pkgconfigQt()
+{
+ QFETCH(QStringList, arguments);
+ QFETCH(bool, success);
+
+ QDir::setCurrent(testDataDir + "/pkgconfig-qt");
+ rmDirR(relativeBuildDir());
+
+ QbsRunParameters dumpParams("resolve", {"-f", "dump-libpath.qbs"});
+ QCOMPARE(runQbs(dumpParams), 0);
+ auto lines = QString::fromUtf8(m_qbsStdout).split('\n');
+ const QString needle = "libPath=";
+ qbs::Internal::removeIf(
+ lines, [&needle](const auto &line) { return !line.startsWith(needle); });
+ QCOMPARE(lines.size(), 1);
+ const auto libPath = lines[0].mid(needle.size());
+ auto prefix = QFileInfo(libPath).path();
+ if (prefix.endsWith("/lib") && !prefix.startsWith("/lib"))
+ prefix = QFileInfo(prefix).path();
+ const auto pkgConfigPath = libPath + "/pkgconfig/";
+ if (!QFileInfo(pkgConfigPath).exists())
+ QSKIP("No *.pc files found");
+
+ rmDirR(relativeBuildDir());
+ QbsRunParameters params("build", {"-f", "pkgconfig-qt.qbs"});
+ // need to override prefix for the downloaded Qt
+ params.environment.insert("PKG_CONFIG_QT5CORE_PREFIX", prefix);
+ params.environment.insert("PKG_CONFIG_QT6CORE_PREFIX", prefix);
+ params.arguments << "moduleProviders.qbspkgconfig.extraPaths:" + pkgConfigPath;
+ params.arguments << arguments;
+
+ QCOMPARE(runQbs(params) == 0, success);
+
+ if (!success)
+ QVERIFY(m_qbsStderr.contains("Dependency 'Qt.core' not found for product 'p'"));
+}
+
+void TestBlackboxQt::pkgconfigQt_data()
+{
+ QTest::addColumn<QStringList>("arguments");
+ QTest::addColumn<bool>("success");
+ QTest::newRow("pkgconfig") << QStringList() << true;
+ QTest::newRow("dummy")
+ << QStringList({"products.p.qbsModuleProviders:dummyProvider"}) << false;
+ QTest::newRow("cross-compiling")
+ << QStringList({"moduleProviders.qbspkgconfig.sysroot:/some/fake/sysroot"}) << false;
+}
+
+void TestBlackboxQt::pkgconfigNoQt()
+{
+ QDir::setCurrent(testDataDir + "/pkgconfig-qt");
+ rmDirR(relativeBuildDir());
+ QbsRunParameters params("build", {"-f", "pkgconfig-qt.qbs"});
+ params.arguments << "moduleProviders.qbspkgconfig.libDirs:nonexistent";
+ params.expectFailure = true;
+
+ QCOMPARE(runQbs(params) == 0, false);
+ QVERIFY2(m_qbsStderr.contains("Dependency 'Qt.core' not found for product 'p'"), m_qbsStderr);
+ // QBS-1777: basic check for JS exceptions in case of missing Qt
+ QVERIFY2(!m_qbsStderr.contains("Error executing provider for module 'Qt.core'"), m_qbsStderr);
+}
+
void TestBlackboxQt::pluginMetaData()
{
QDir::setCurrent(testDataDir + "/plugin-meta-data");
+ QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ if (m_qbsStdout.contains("using qt4"))
+ QSKIP("Qt version too old");
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
+
QVERIFY2(runQbs(QbsRunParameters("run", QStringList{"-p", "app"})) == 0,
m_qbsStderr.constData());
QVERIFY2(m_qbsStderr.contains("all ok!"), m_qbsStderr.constData());
@@ -286,7 +445,11 @@ void TestBlackboxQt::pluginSupport()
resolveParams.arguments << "modules.m1.useDummy:true";
resolveParams.expectFailure = true;
}
- QCOMPARE(runQbs(resolveParams) == 0, !invalidPlugin);
+ bool resolveResult = runQbs(resolveParams) == 0;
+ if (m_qbsStdout.contains("using qt4"))
+ QSKIP("Qt version too old");
+ QCOMPARE(resolveResult, !invalidPlugin);
+
if (invalidPlugin) {
QVERIFY2(m_qbsStderr.contains("Plugin 'dummy' of type 'imageformats' was requested, "
"but is not available"), m_qbsStderr.constData());
@@ -320,22 +483,36 @@ void TestBlackboxQt::pluginSupport()
}
}
+void TestBlackboxQt::qdoc()
+{
+ QDir::setCurrent(testDataDir + "/qdoc");
+ QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ if (m_qbsStdout.contains("Qt is too old"))
+ QSKIP("Skip test since qdoc3 does not work properly");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY(QFileInfo(relativeProductBuildDir("QDoc Test") + "/qdoctest.qch").exists());
+}
+
void TestBlackboxQt::qmlDebugging()
{
QDir::setCurrent(testDataDir + "/qml-debugging");
QCOMPARE(runQbs(), 0);
- const SettingsPtr s = settings();
- Profile profile(profileName(), s.get());
- if (!profile.value("qbs.toolchain").toStringList().contains("gcc"))
- return;
+
+ const bool isGcc = m_qbsStdout.contains("is gcc: true");
+ const bool isNotGcc = m_qbsStdout.contains("is gcc: false");
+ if (isNotGcc)
+ QSKIP("The remainder of this test only applies to gcc");
+ QVERIFY(isGcc);
+
QProcess nm;
nm.start("nm", QStringList(relativeExecutableFilePath("debuggable-app")));
- if (nm.waitForStarted()) { // Let's ignore hosts without nm.
- QVERIFY2(nm.waitForFinished(), qPrintable(nm.errorString()));
- QVERIFY2(nm.exitCode() == 0, nm.readAllStandardError().constData());
- const QByteArray output = nm.readAllStandardOutput();
- QVERIFY2(output.toLower().contains("debugginghelper"), output.constData());
- }
+ if (!nm.waitForStarted())
+ QSKIP("The remainder of this test requires nm");
+
+ QVERIFY2(nm.waitForFinished(), qPrintable(nm.errorString()));
+ QVERIFY2(nm.exitCode() == 0, nm.readAllStandardError().constData());
+ const QByteArray output = nm.readAllStandardOutput();
+ QVERIFY2(output.toLower().contains("debugginghelper"), output.constData());
}
void TestBlackboxQt::qobjectInObjectiveCpp()
@@ -347,6 +524,42 @@ void TestBlackboxQt::qobjectInObjectiveCpp()
QCOMPARE(runQbs(), 0);
}
+void TestBlackboxQt::qmlTypeRegistrar_data()
+{
+ QTest::addColumn<QString>("importName");
+ QTest::addColumn<QString>("installDir");
+ QTest::newRow("don't generate") << QString() << QString();
+ QTest::newRow("don't generate with install info") << QString() << QString("blubb");
+ QTest::newRow("generate only") << QString("People") << QString();
+ QTest::newRow("generate and install") << QString("People") << QString("blubb");
+}
+
+void TestBlackboxQt::qmlTypeRegistrar()
+{
+ QDir::setCurrent(testDataDir + "/qmltyperegistrar");
+ QFETCH(QString, importName);
+ QFETCH(QString, installDir);
+ rmDirR(relativeBuildDir());
+ const QStringList args{"modules.Qt.qml.importName:" + importName,
+ "modules.Qt.qml.typesInstallDir:" + installDir};
+ if ((runQbs(QbsRunParameters("resolve", args)) != 0) &&
+ m_qbsStderr.contains("Dependency 'Qt.qml' not found for product 'myapp'"))
+ QSKIP("Qt version too old");
+ const bool hasRegistrar = m_qbsStdout.contains("has registrar");
+ const bool doesNotHaveRegistrar = m_qbsStdout.contains("does not have registrar");
+ QVERIFY(hasRegistrar != doesNotHaveRegistrar);
+ if (doesNotHaveRegistrar)
+ QSKIP("Qt version too old");
+ QCOMPARE(runQbs(), 0);
+ const bool enabled = !importName.isEmpty();
+ QCOMPARE(m_qbsStdout.contains("running qmltyperegistrar"), enabled);
+ QCOMPARE(m_qbsStdout.contains("compiling myapp_qmltyperegistrations.cpp"), enabled);
+ const QString buildDir = relativeProductBuildDir("myapp");
+ QCOMPARE(regularFileExists(buildDir + "/myapp.qmltypes"), enabled);
+ QCOMPARE(regularFileExists(relativeBuildDir() + "/install-root/" + installDir
+ + "/myapp.qmltypes"), enabled && !installDir.isEmpty());
+}
+
void TestBlackboxQt::qtKeywords()
{
QDir::setCurrent(testDataDir + "/qt-keywords");
@@ -364,7 +577,9 @@ void TestBlackboxQt::qtKeywords()
void TestBlackboxQt::quickCompiler()
{
QDir::setCurrent(testDataDir + "/quick-compiler");
- QCOMPARE(runQbs(), 0);
+ if ((runQbs() != 0) &&
+ m_qbsStderr.contains("'Qt.quick' has version 4.8.7, but it needs to be at least 5.0.0."))
+ QSKIP("Qt version too old");
const bool hasCompiler = m_qbsStdout.contains("compiler available");
const bool doesNotHaveCompiler = m_qbsStdout.contains("compiler not available");
QVERIFY2(hasCompiler || doesNotHaveCompiler, m_qbsStdout.constData());
@@ -390,6 +605,9 @@ void TestBlackboxQt::quickCompiler()
void TestBlackboxQt::qtScxml()
{
QDir::setCurrent(testDataDir + "/qtscxml");
+ QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QCOMPARE(runQbs(), 0);
if (m_qbsStdout.contains("QtScxml not present"))
QSKIP("QtScxml module not present");
@@ -423,10 +641,10 @@ void TestBlackboxQt::staticQtPluginLinking()
QDir::setCurrent(testDataDir + "/static-qt-plugin-linking");
QCOMPARE(runQbs(QStringList("products.p.type:application")), 0);
const bool isStaticQt = m_qbsStdout.contains("Qt is static");
- QVERIFY2(m_qbsStdout.contains("Creating static import") == isStaticQt, m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("creating static import") == isStaticQt, m_qbsStdout.constData());
QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("products.p.type:staticlibrary"))), 0);
QCOMPARE(runQbs(), 0);
- QVERIFY2(!m_qbsStdout.contains("Creating static import"), m_qbsStdout.constData());
+ QVERIFY2(!m_qbsStdout.contains("creating static import"), m_qbsStdout.constData());
}
void TestBlackboxQt::trackAddMocInclude()
@@ -469,6 +687,11 @@ void TestBlackboxQt::track_qobject_change()
void TestBlackboxQt::track_qrc()
{
QDir::setCurrent(testDataDir + "/qrc");
+ QCOMPARE(runQbs(QbsRunParameters("resolve")), 0);
+ if (m_qbsStdout.contains("using qt4"))
+ QSKIP("Qt version too old");
+ if (m_qbsStdout.contains("targetPlatform differs from hostPlatform"))
+ QSKIP("Cannot run binaries in cross-compiled build");
QCOMPARE(runQbs(QbsRunParameters("run")), 0);
QVERIFY2(m_qbsStdout.contains("rcc"), m_qbsStdout.constData());
QVERIFY2(!m_qbsStdout.contains("compiling test.cpp"), m_qbsStdout.constData());
diff --git a/tests/auto/blackbox/tst_blackboxqt.h b/tests/auto/blackbox/tst_blackboxqt.h
index 180f9e0c0..da395b7d4 100644
--- a/tests/auto/blackbox/tst_blackboxqt.h
+++ b/tests/auto/blackbox/tst_blackboxqt.h
@@ -38,9 +38,6 @@ class TestBlackboxQt : public TestBlackboxBase
public:
TestBlackboxQt();
-protected:
- void validateTestProfile() override;
-
private slots:
void addQObjectMacroToGeneratedCppFile();
void autoQrc();
@@ -53,16 +50,27 @@ private slots:
void includedMocCpp();
void linkerVariant();
void lrelease();
+ void metaTypes_data();
+ void metaTypes();
void mixedBuildVariants();
void mocAndCppCombining();
void mocFlags();
+ void mocCompilerDefines();
void mocSameFileName();
+ void noRelinkOnQDebug();
+ void noRelinkOnQDebug_data();
void pkgconfig();
+ void pkgconfigQt();
+ void pkgconfigQt_data();
+ void pkgconfigNoQt();
void pluginMetaData();
void pluginSupport_data();
void pluginSupport();
+ void qdoc();
void qmlDebugging();
void qobjectInObjectiveCpp();
+ void qmlTypeRegistrar_data();
+ void qmlTypeRegistrar();
void qtKeywords();
void quickCompiler();
void qtScxml();
diff --git a/tests/auto/blackbox/tst_blackboxtutorial.cpp b/tests/auto/blackbox/tst_blackboxtutorial.cpp
new file mode 100644
index 000000000..49de448a1
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxtutorial.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://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.
+**
+****************************************************************************/
+
+#include "tst_blackboxtutorial.h"
+
+#include <QtCore/qdir.h>
+#include <QtCore/qdiriterator.h>
+
+static QStringList collectProjects(const QString &dirPath)
+{
+ QStringList result;
+ QDir dir(dirPath);
+ const auto subDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
+ for (const auto &subDir : subDirs) {
+ const auto path = dir.filePath(subDir);
+ if (!QFileInfo::exists(path + "/myproject.qbs"))
+ continue;
+ result.append(dir.relativeFilePath(path));
+ }
+ return result;
+}
+
+TestBlackboxTutorial::TestBlackboxTutorial()
+ : TestBlackboxBase(SRCDIR "/../../../tutorial/", "blackbox-tutorial")
+{}
+
+void TestBlackboxTutorial::tutorial_data()
+{
+ QTest::addColumn<QString>("project");
+
+ const auto projects = collectProjects(testDataDir);
+ for (const auto &project : projects) {
+ QTest::newRow(project.toUtf8().data()) << project;
+ }
+}
+
+void TestBlackboxTutorial::tutorial()
+{
+ QFETCH(QString, project);
+
+ QVERIFY(QDir::setCurrent(testDataDir + "/" + project));
+ QCOMPARE(runQbs(), 0);
+}
+
+QTEST_MAIN(TestBlackboxTutorial)
diff --git a/tests/auto/blackbox/tst_blackboxtutorial.h b/tests/auto/blackbox/tst_blackboxtutorial.h
new file mode 100644
index 000000000..2e84d6a96
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxtutorial.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://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.
+**
+****************************************************************************/
+
+#ifndef TST_BLACKBOXTUTORIAL_H
+#define TST_BLACKBOXTUTORIAL_H
+
+#include "tst_blackboxbase.h"
+
+class TestBlackboxTutorial : public TestBlackboxBase
+{
+ Q_OBJECT
+
+public:
+ TestBlackboxTutorial();
+
+private slots:
+ void tutorial_data();
+ void tutorial();
+};
+
+#endif // TST_BLACKBOXTUTORIAL_H
diff --git a/tests/auto/blackbox/tst_blackboxwindows.cpp b/tests/auto/blackbox/tst_blackboxwindows.cpp
new file mode 100644
index 000000000..57bd7f947
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxwindows.cpp
@@ -0,0 +1,307 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://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.
+**
+****************************************************************************/
+
+#include "tst_blackboxwindows.h"
+
+#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
+{
+ enum class CodeSignResult { Failed = 0, Signed, Unsigned };
+ CodeSignResult result = CodeSignResult::Failed;
+ bool timestamped = false;
+ QString hashAlgorithm;
+ QString subjectName;
+};
+
+Q_DECLARE_METATYPE(SigntoolInfo::CodeSignResult)
+
+static SigntoolInfo extractSigntoolInfo(const QString &signtoolPath, const QString &appPath)
+{
+ QProcess signtool;
+ signtool.start(signtoolPath, { QStringLiteral("verify"), QStringLiteral("/v"), appPath });
+ if (!signtool.waitForStarted() || !signtool.waitForFinished())
+ return {};
+ const auto output = signtool.readAllStandardError();
+ SigntoolInfo signtoolInfo;
+ if (output.contains("No signature found")) {
+ signtoolInfo.result = SigntoolInfo::CodeSignResult::Unsigned;
+ } else {
+ signtoolInfo.result = SigntoolInfo::CodeSignResult::Signed;
+ const auto output = signtool.readAllStandardOutput();
+ const auto lines = output.split('\n');
+ for (const auto &line: lines) {
+ {
+ const QRegularExpression re("^Hash of file \\((.+)\\):.+$");
+ const QRegularExpressionMatch match = re.match(line);
+ if (match.hasMatch()) {
+ signtoolInfo.hashAlgorithm = match.captured(1).toLocal8Bit();
+ continue;
+ }
+ }
+ {
+ const QRegularExpression re("Issued to: (.+)");
+ const QRegularExpressionMatch match = re.match(line);
+ if (match.hasMatch()) {
+ signtoolInfo.subjectName = match.captured(1).toLocal8Bit().trimmed();
+ continue;
+ }
+ }
+ if (line.startsWith("The signature is timestamped:")) {
+ signtoolInfo.timestamped = true;
+ break;
+ } else if (line.startsWith("File is not timestamped.")) {
+ break;
+ }
+ }
+ }
+ return signtoolInfo;
+}
+
+static QString extractSigntoolPath(const QByteArray &output)
+{
+ const QRegularExpression re("%%(.+)%%");
+ QRegularExpressionMatchIterator it = re.globalMatch(output);
+ if (!it.hasNext())
+ return {};
+ const QRegularExpressionMatch match = it.next();
+ return match.captured(1).toUtf8();
+}
+
+TestBlackboxWindows::TestBlackboxWindows()
+ : TestBlackboxBase (SRCDIR "/testdata-windows", "blackbox-windows")
+{
+}
+
+void TestBlackboxWindows::initTestCase()
+{
+ if (!HostOsInfo::isWindowsHost()) {
+ QSKIP("only applies on Windows");
+ return;
+ }
+
+ 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);
+ QFETCH(QString, hashAlgorithm);
+ QFETCH(QString, subjectName);
+ QFETCH(QString, signingTimestamp);
+
+ QDir::setCurrent(testDataDir + "/codesign");
+ QbsRunParameters params(QStringList{"qbs.installPrefix:''"});
+ params.arguments << QStringLiteral("project.enableSigning:%1").arg(
+ (result == SigntoolInfo::CodeSignResult::Signed) ? "true" : "false")
+ << QStringLiteral("project.hashAlgorithm:%1").arg(hashAlgorithm)
+ << QStringLiteral("project.subjectName:%1").arg(subjectName)
+ << QStringLiteral("project.signingTimestamp:%1").arg(signingTimestamp);
+
+ rmDirR(relativeBuildDir());
+ QCOMPARE(runQbs(params), 0);
+
+ if (!m_qbsStdout.contains("signtool path:"))
+ QSKIP("No current signtool path pattern exists");
+
+ const auto signtoolPath = extractSigntoolPath(m_qbsStdout);
+ QVERIFY(QFileInfo(signtoolPath).exists());
+
+ const QStringList outputBinaries = {"A.exe", "B.dll"};
+ for (const auto &outputBinary : outputBinaries) {
+ const auto outputBinaryPath = defaultInstallRoot + "/" + outputBinary;
+ QVERIFY(QFileInfo(outputBinaryPath).exists());
+
+ const SigntoolInfo signtoolInfo = extractSigntoolInfo(signtoolPath, outputBinaryPath);
+ QVERIFY(signtoolInfo.result != SigntoolInfo::CodeSignResult::Failed);
+ QCOMPARE(signtoolInfo.result, result);
+ QCOMPARE(signtoolInfo.hashAlgorithm, hashAlgorithm);
+ QCOMPARE(signtoolInfo.subjectName, subjectName);
+ QCOMPARE(signtoolInfo.timestamped, !signingTimestamp.isEmpty());
+ }
+}
+
+void TestBlackboxWindows::standaloneCodesign_data()
+{
+ QTest::addColumn<SigntoolInfo::CodeSignResult>("result");
+ QTest::addColumn<QString>("hashAlgorithm");
+ QTest::addColumn<QString>("subjectName");
+ QTest::addColumn<QString>("signingTimestamp");
+
+ QTest::newRow("standalone, unsigned")
+ << SigntoolInfo::CodeSignResult::Unsigned << "" << "" << "";
+ QTest::newRow("standalone, signed, sha1, qbs@community.test, no timestamp")
+ << SigntoolInfo::CodeSignResult::Signed << "sha1" << "qbs@community.test" << "";
+ QTest::newRow("standalone, signed, sha256, qbs@community.test, RFC3061 timestamp")
+ << SigntoolInfo::CodeSignResult::Signed << "sha256" << "qbs@community.test"
+ << "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(), Qt::SkipEmptyParts);
+
+ for (const QString &key : std::as_const(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 : std::as_const(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
new file mode 100644
index 000000000..ad8d60ca3
--- /dev/null
+++ b/tests/auto/blackbox/tst_blackboxwindows.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: https://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.
+**
+****************************************************************************/
+
+#ifndef TST_BLACKBOXWINDOWS_H
+#define TST_BLACKBOXWINDOWS_H
+
+#include "tst_blackboxbase.h"
+
+class TestBlackboxWindows : public TestBlackboxBase
+{
+ Q_OBJECT
+
+public:
+ TestBlackboxWindows();
+
+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/blackbox/tst_clangdb.cpp b/tests/auto/blackbox/tst_clangdb.cpp
index 3a6dd2d92..c4216ac13 100644
--- a/tests/auto/blackbox/tst_clangdb.cpp
+++ b/tests/auto/blackbox/tst_clangdb.cpp
@@ -36,7 +36,7 @@
#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
-#include <QtCore/qregexp.h>
+#include <QtCore/qregularexpression.h>
#include <QtCore/qjsonarray.h>
#include <QtCore/qjsondocument.h>
@@ -202,17 +202,19 @@ void TestClangDb::checkClangDetectsSourceCodeProblems()
// clang-check.exe does not understand MSVC command-line syntax
const SettingsPtr s = settings();
qbs::Profile profile(profileName(), s.get());
- if (profile.value("qbs.toolchain").toStringList().contains("msvc")) {
+ if (profileToolchain(profile).contains("msvc")) {
arguments << "-extra-arg-before=--driver-mode=cl";
- } else if (profile.value("qbs.toolchain").toStringList().contains("mingw")) {
+ } else if (profileToolchain(profile).contains("mingw")) {
arguments << "-extra-arg-before=--driver-mode=g++";
}
arguments << "-analyze" << "-p" << relativeBuildDir() << sourceFilePath;
QVERIFY(runProcess(executable, arguments, stdErr, stdOut) == 0);
const QString output = QString::fromLocal8Bit(stdErr);
- QVERIFY(output.contains(QRegExp(QStringLiteral("warning.*undefined"), Qt::CaseInsensitive)));
- QVERIFY(output.contains(QRegExp(QStringLiteral("warning.*never read"), Qt::CaseInsensitive)));
+ QVERIFY(output.contains(QRegularExpression(QStringLiteral("warning.*undefined"),
+ QRegularExpression::CaseInsensitiveOption)));
+ QVERIFY(output.contains(QRegularExpression(QStringLiteral("warning.*never read"),
+ QRegularExpression::CaseInsensitiveOption)));
}
QTEST_MAIN(TestClangDb)
diff --git a/tests/auto/buildgraph/CMakeLists.txt b/tests/auto/buildgraph/CMakeLists.txt
new file mode 100644
index 000000000..d8a9a4bbe
--- /dev/null
+++ b/tests/auto/buildgraph/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_qbs_test(buildgraph
+ SOURCES
+ tst_buildgraph.cpp
+ tst_buildgraph.h
+ DEPENDS
+ qbsquickjsheaders
+ )
diff --git a/tests/auto/buildgraph/buildgraph.pro b/tests/auto/buildgraph/buildgraph.pro
deleted file mode 100644
index 9230bb748..000000000
--- a/tests/auto/buildgraph/buildgraph.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = tst_buildgraph
-
-SOURCES = tst_buildgraph.cpp
-HEADERS = tst_buildgraph.h
-
-include(../auto.pri)
-include(../../../src/app/shared/logging/logging.pri)
-include(../../../src/lib/bundledlibs.pri)
-
-qbs_use_bundled_qtscript {
- CONFIG += qbs_do_not_link_bundled_qtscript
- include(../../../src/lib/scriptengine/use_scriptengine.pri)
-}
diff --git a/tests/auto/buildgraph/buildgraph.qbs b/tests/auto/buildgraph/buildgraph.qbs
index aa3cdc3f0..694d59578 100644
--- a/tests/auto/buildgraph/buildgraph.qbs
+++ b/tests/auto/buildgraph/buildgraph.qbs
@@ -1,6 +1,5 @@
-import qbs
-
-QbsAutotest {
+QbsUnittest {
+ Depends { name: "qbsconsolelogger" }
testName: "buildgraph"
condition: qbsbuildconfig.enableUnitTests
files: [
diff --git a/tests/auto/buildgraph/tst_buildgraph.cpp b/tests/auto/buildgraph/tst_buildgraph.cpp
index 20f2cc6a5..84a52c19b 100644
--- a/tests/auto/buildgraph/tst_buildgraph.cpp
+++ b/tests/auto/buildgraph/tst_buildgraph.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "tst_buildgraph.h"
+#include <app/shared/logging/consolelogger.h>
#include <buildgraph/artifact.h>
#include <buildgraph/buildgraph.h>
#include <buildgraph/cycledetector.h>
@@ -47,8 +48,6 @@
#include <logging/logger.h>
#include <tools/error.h>
-#include "../shared/logging/consolelogger.h"
-
#include <QtTest/qtest.h>
#include <memory>
diff --git a/tests/auto/cmdlineparser/CMakeLists.txt b/tests/auto/cmdlineparser/CMakeLists.txt
new file mode 100644
index 000000000..bf072e24d
--- /dev/null
+++ b/tests/auto/cmdlineparser/CMakeLists.txt
@@ -0,0 +1,23 @@
+set(PARSER_SOURCES
+ commandlineoption.cpp
+ commandlineoption.h
+ commandlineoptionpool.cpp
+ commandlineoptionpool.h
+ commandlineparser.cpp
+ commandlineparser.h
+ commandpool.cpp
+ commandpool.h
+ commandtype.h
+ parsercommand.cpp
+ parsercommand.h
+ )
+list_transform_prepend(PARSER_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../../../src/app/qbs/parser/")
+
+add_qbs_test(cmdlineparser
+ DEFINES
+ "QBS_VERSION=\"${QBS_VERSION}\""
+ INCLUDES
+ "${CMAKE_CURRENT_SOURCE_DIR}/../../../src"
+ SOURCES
+ tst_cmdlineparser.cpp ../../../src/app/qbs/qbstool.cpp ${PARSER_SOURCES}
+ )
diff --git a/tests/auto/cmdlineparser/cmdlineparser.pro b/tests/auto/cmdlineparser/cmdlineparser.pro
deleted file mode 100644
index a95676be5..000000000
--- a/tests/auto/cmdlineparser/cmdlineparser.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TARGET = tst_cmdlineparser
-
-SOURCES = tst_cmdlineparser.cpp ../../../src/app/qbs/qbstool.cpp
-
-include(../auto.pri)
-include(../../../src/app/qbs/parser/parser.pri)
-include(../../../src/app/shared/logging/logging.pri)
diff --git a/tests/auto/cmdlineparser/cmdlineparser.qbs b/tests/auto/cmdlineparser/cmdlineparser.qbs
index a45e61f5d..340a0c42e 100644
--- a/tests/auto/cmdlineparser/cmdlineparser.qbs
+++ b/tests/auto/cmdlineparser/cmdlineparser.qbs
@@ -1,8 +1,8 @@
-import qbs
import qbs.Utilities
QbsAutotest {
Depends { name: "qbsversion" }
+ Depends { name: "qbsconsolelogger" }
testName: "cmdlineparser"
files: ["tst_cmdlineparser.cpp", "../../../src/app/qbs/qbstool.cpp"]
cpp.defines: base.concat([
diff --git a/tests/auto/cmdlineparser/tst_cmdlineparser.cpp b/tests/auto/cmdlineparser/tst_cmdlineparser.cpp
index 15b9ec382..6a8b44f89 100644
--- a/tests/auto/cmdlineparser/tst_cmdlineparser.cpp
+++ b/tests/auto/cmdlineparser/tst_cmdlineparser.cpp
@@ -26,6 +26,8 @@
**
****************************************************************************/
+#include "../shared.h"
+
#include <app/qbs/parser/commandlineparser.h>
#include <app/shared/logging/consolelogger.h>
#include <tools/buildoptions.h>
@@ -33,7 +35,6 @@
#include <tools/hostosinfo.h>
#include <QtCore/qdir.h>
-#include <QtCore/qregexp.h>
#include <QtCore/qtemporaryfile.h>
#include <QtTest/qtest.h>
@@ -56,6 +57,25 @@ private slots:
m_fileArgs = QStringList() << "-f" << m_projectFile.fileName();
}
+ void testResolve_data()
+ {
+ QTest::addColumn<QStringList>("args");
+ QTest::addColumn<int>("expectedJobCount");
+
+ QTest::newRow("default job count") << QStringList() << BuildOptions::defaultMaxJobCount();
+ QTest::newRow("explicit job count") << QStringList("-j5") << 5;
+ }
+ void testResolve()
+ {
+ QFETCH(QStringList, args);
+ QFETCH(int, expectedJobCount);
+
+ CommandLineParser parser;
+ QVERIFY(parser.parseCommandLine(QStringList("resolve") << args << m_fileArgs));
+ QCOMPARE(parser.command(), ResolveCommandType);
+ QCOMPARE(parser.jobCount(profileName()), expectedJobCount);
+ }
+
void testValidCommandLine()
{
QStringList args;
diff --git a/tests/auto/language/CMakeLists.txt b/tests/auto/language/CMakeLists.txt
new file mode 100644
index 000000000..9c04b6c8d
--- /dev/null
+++ b/tests/auto/language/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_qbs_test(language
+ DEFINES
+ "QBS_VERSION=\"${QBS_VERSION}\""
+ DEPENDS
+ qbsquickjsheaders
+ Qt6Core5Compat
+ SOURCES
+ tst_language.cpp
+ tst_language.h
+ )
diff --git a/tests/auto/language/language.pro b/tests/auto/language/language.pro
deleted file mode 100644
index 86248d926..000000000
--- a/tests/auto/language/language.pro
+++ /dev/null
@@ -1,25 +0,0 @@
-TARGET = tst_language
-
-SOURCES = tst_language.cpp
-HEADERS = tst_language.h
-
-include(../auto.pri)
-include(../../../src/app/shared/logging/logging.pri)
-include(../../../src/lib/bundledlibs.pri)
-
-!qbs_use_bundled_qtscript: QT += script
-
-DATA_DIRS = testdata
-
-for(data_dir, DATA_DIRS) {
- files = $$files($$PWD/$$data_dir/*, true)
- win32:files ~= s|\\\\|/|g
- for(file, files):!exists($$file/*):FILES += $$file
-}
-
-OTHER_FILES += $$FILES
-
-qbs_use_bundled_qtscript {
- CONFIG += qbs_do_not_link_bundled_qtscript
- include(../../../src/lib/scriptengine/use_scriptengine.pri)
-}
diff --git a/tests/auto/language/language.qbs b/tests/auto/language/language.qbs
index f43ca0e44..3767477db 100644
--- a/tests/auto/language/language.qbs
+++ b/tests/auto/language/language.qbs
@@ -1,13 +1,8 @@
-import qbs
import qbs.Utilities
-QbsAutotest {
+QbsUnittest {
Depends { name: "qbsversion" }
- Depends {
- name: "Qt.script"
- condition: !qbsbuildconfig.useBundledQtScript
- required: false
- }
+ Depends { name: "qbsconsolelogger" }
testName: "language"
condition: qbsbuildconfig.enableUnitTests
diff --git a/tests/auto/language/testdata/ParentWithExport.qbs b/tests/auto/language/testdata/ParentWithExport.qbs
index 16f9a2cd1..b16097e69 100644
--- a/tests/auto/language/testdata/ParentWithExport.qbs
+++ b/tests/auto/language/testdata/ParentWithExport.qbs
@@ -1,6 +1,6 @@
Product {
Export {
Depends { name: "dummy" }
- dummy.defines: [product.name.toUpperCase()]
+ dummy.defines: [exportingProduct.name.toUpperCase()]
}
}
diff --git a/tests/auto/language/testdata/additional-product-types.qbs b/tests/auto/language/testdata/additional-product-types.qbs
index 686650f42..f84397da3 100644
--- a/tests/auto/language/testdata/additional-product-types.qbs
+++ b/tests/auto/language/testdata/additional-product-types.qbs
@@ -5,8 +5,8 @@ Product {
Depends { name: "dummy" }
Depends { name: "dummy2" }
- property bool hasTag1: type.contains("tag1")
- property bool hasTag2: type.contains("tag2")
- property bool hasTag3: type.contains("tag3")
- property bool hasTag4: type.contains("tag4")
+ property bool hasTag1: type.includes("tag1")
+ property bool hasTag2: type.includes("tag2")
+ property bool hasTag3: type.includes("tag3")
+ property bool hasTag4: type.includes("tag4")
}
diff --git a/tests/auto/language/testdata/chained-probes/modules/m/m.qbs b/tests/auto/language/testdata/chained-probes/modules/m/m.qbs
index 3c6bcd1c9..bf68e56b6 100644
--- a/tests/auto/language/testdata/chained-probes/modules/m/m.qbs
+++ b/tests/auto/language/testdata/chained-probes/modules/m/m.qbs
@@ -2,13 +2,13 @@ Module {
Probe {
id: probe1
property string probe1Prop
- configure: { probe1Prop = "probe1Val"; found = true; }
+ configure: { probe1Prop = "probe1Val"; found = true }
}
Probe {
id: probe2
property string inputProp: prop1
property string probe2Prop
- configure: { probe2Prop = inputProp + "probe2Val"; found = true; }
+ configure: { probe2Prop = inputProp + "probe2Val"; found = true }
}
property string prop1: probe1.probe1Prop
property string prop2: probe2.probe2Prop
diff --git a/tests/auto/language/testdata/conditionaldepends.qbs b/tests/auto/language/testdata/conditionaldepends.qbs
index 9a499da92..e4f9fae7d 100644
--- a/tests/auto/language/testdata/conditionaldepends.qbs
+++ b/tests/auto/language/testdata/conditionaldepends.qbs
@@ -14,25 +14,25 @@ Project {
Product {
name: "product_props_true"
property bool someTrueProp: true
- Depends { condition: someTrueProp; name: "dummy"}
+ Depends { condition: someTrueProp; name: "dummy" }
}
Product {
name: "product_props_false"
property bool someFalseProp: false
- Depends { condition: someFalseProp; name: "dummy"}
+ Depends { condition: someFalseProp; name: "dummy" }
}
property bool someTruePrjProp: true
Product {
name: "project_props_true"
- Depends { condition: project.someTruePrjProp; name: "dummy"}
+ Depends { condition: project.someTruePrjProp; name: "dummy" }
}
property bool someFalsePrjProp: false
Product {
name: "project_props_false"
- Depends { condition: project.someFalsePrjProp; name: "dummy"}
+ Depends { condition: project.someFalsePrjProp; name: "dummy" }
}
Product {
diff --git a/tests/auto/language/testdata/conditionaldepends_base.qbs b/tests/auto/language/testdata/conditionaldepends_base.qbs
index 5ab5b973a..74eb958d4 100644
--- a/tests/auto/language/testdata/conditionaldepends_base.qbs
+++ b/tests/auto/language/testdata/conditionaldepends_base.qbs
@@ -1,4 +1,4 @@
-Application {
+Product {
name: 'conditionaldepends_base'
property bool someProp: false
Depends {
diff --git a/tests/auto/language/testdata/dotted-names/dotted-names.qbs b/tests/auto/language/testdata/dotted-names/dotted-names.qbs
index cf5658384..714988f0b 100644
--- a/tests/auto/language/testdata/dotted-names/dotted-names.qbs
+++ b/tests/auto/language/testdata/dotted-names/dotted-names.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Project {
name: "theProject"
property bool includeDottedProduct
diff --git a/tests/auto/language/testdata/dotted-names/modules/x/y/xy.qbs b/tests/auto/language/testdata/dotted-names/modules/x/y/xy.qbs
index 71cfac9cb..eee46458d 100644
--- a/tests/auto/language/testdata/dotted-names/modules/x/y/xy.qbs
+++ b/tests/auto/language/testdata/dotted-names/modules/x/y/xy.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Module {
property string z: "default"
}
diff --git a/tests/auto/language/testdata/erroneous/duplicate-multiplex-value.qbs b/tests/auto/language/testdata/duplicate-multiplex-value.qbs
index 56da41af1..24b246604 100644
--- a/tests/auto/language/testdata/erroneous/duplicate-multiplex-value.qbs
+++ b/tests/auto/language/testdata/duplicate-multiplex-value.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Product {
name: "p"
multiplexByQbsProperties: "architectures"
diff --git a/tests/auto/language/testdata/erroneous/duplicate-multiplex-value2.qbs b/tests/auto/language/testdata/duplicate-multiplex-value2.qbs
index e412e5210..d6c057a9e 100644
--- a/tests/auto/language/testdata/erroneous/duplicate-multiplex-value2.qbs
+++ b/tests/auto/language/testdata/duplicate-multiplex-value2.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Product {
name: "p"
multiplexByQbsProperties: ["architectures", "buildVariants", "architectures"]
diff --git a/tests/auto/language/testdata/erroneous/ambiguous-multiplex-dependency.qbs b/tests/auto/language/testdata/erroneous/ambiguous-multiplex-dependency.qbs
new file mode 100644
index 000000000..6f60b1faf
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/ambiguous-multiplex-dependency.qbs
@@ -0,0 +1,14 @@
+Project {
+ Product {
+ name: "a"
+ multiplexByQbsProperties: ["architectures", "buildVariants"]
+ qbs.architectures: ["x86", "arm"]
+ qbs.buildVariants: ["debug", "release"]
+ }
+ Product {
+ name: "b"
+ Depends { name: "a" }
+ multiplexByQbsProperties: ["architectures"]
+ qbs.architectures: ["x86", "arm"]
+ }
+}
diff --git a/tests/auto/language/testdata/erroneous/conflicting_fileTagsFilter.qbs b/tests/auto/language/testdata/erroneous/conflicting_fileTagsFilter.qbs
index 97e11bb9b..3738e0cca 100644
--- a/tests/auto/language/testdata/erroneous/conflicting_fileTagsFilter.qbs
+++ b/tests/auto/language/testdata/erroneous/conflicting_fileTagsFilter.qbs
@@ -1,10 +1,11 @@
-Application {
+Product {
+ type: "app"
Group {
- fileTagsFilter: "application"
+ fileTagsFilter: "app"
qbs.install: true
}
Group {
- fileTagsFilter: "application"
+ fileTagsFilter: "app"
qbs.install: false
}
}
diff --git a/tests/auto/language/testdata/erroneous/dependency-profile-mismatch-2.qbs b/tests/auto/language/testdata/erroneous/dependency-profile-mismatch-2.qbs
new file mode 100644
index 000000000..d76907a35
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/dependency-profile-mismatch-2.qbs
@@ -0,0 +1,17 @@
+Project {
+ Profile {
+ name: "profile1"
+ }
+ Profile {
+ name: "profile2"
+ }
+
+ Product {
+ name: "dep"
+ qbs.profiles: ["profile1", "profile2"]
+ }
+ Product {
+ name: "main"
+ Depends { name: "dep"; profiles: ["profile47"]; }
+ }
+}
diff --git a/tests/auto/language/testdata/erroneous/dependency-profile-mismatch.qbs b/tests/auto/language/testdata/erroneous/dependency-profile-mismatch.qbs
new file mode 100644
index 000000000..e014fa9b1
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/dependency-profile-mismatch.qbs
@@ -0,0 +1,14 @@
+Project {
+ Profile {
+ name: "profile1"
+ }
+
+ Product {
+ name: "dep"
+ qbs.profiles: ["profile1"]
+ }
+ Product {
+ name: "main"
+ Depends { name: "dep"; profiles: ["profile47"]; }
+ }
+}
diff --git a/tests/auto/language/testdata/erroneous/dependency_cycle.qbs b/tests/auto/language/testdata/erroneous/dependency_cycle.qbs
index 83a6e35f6..80c678f89 100644
--- a/tests/auto/language/testdata/erroneous/dependency_cycle.qbs
+++ b/tests/auto/language/testdata/erroneous/dependency_cycle.qbs
@@ -1,15 +1,15 @@
Project {
- CppApplication {
+ Product {
name: "A"
Depends { name: "B" }
files: ["main.cpp"]
}
- CppApplication {
+ Product {
name: "B"
Depends { name: "C" }
files: ["main.cpp"]
}
- CppApplication {
+ Product {
name: "C"
Depends { name: "A" }
files: ["main.cpp"]
diff --git a/tests/auto/language/testdata/erroneous/dependency_cycle2.qbs b/tests/auto/language/testdata/erroneous/dependency_cycle2.qbs
index 335355480..4aff0b75c 100644
--- a/tests/auto/language/testdata/erroneous/dependency_cycle2.qbs
+++ b/tests/auto/language/testdata/erroneous/dependency_cycle2.qbs
@@ -1,20 +1,20 @@
Project {
- CppApplication {
+ Product {
name: "A"
Depends { name: "B" }
files: ["main.cpp"]
}
- CppApplication {
+ Product {
name: "B"
Depends { name: "C" }
files: ["main.cpp"]
}
- CppApplication {
+ Product {
name: "C"
Depends { name: "A" }
files: ["main.cpp"]
}
- CppApplication {
+ Product {
name: "D"
files: ["main.cpp"]
}
diff --git a/tests/auto/language/testdata/erroneous/dependency_cycle3a.qbs b/tests/auto/language/testdata/erroneous/dependency_cycle3a.qbs
new file mode 100644
index 000000000..a0660c074
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/dependency_cycle3a.qbs
@@ -0,0 +1,11 @@
+Project {
+ Product {
+ name: "B"
+ Depends { productTypes: ["a"] }
+ }
+ Product {
+ type: ["a"]
+ name: "A"
+ Depends { name: "B" }
+ }
+}
diff --git a/tests/auto/language/testdata/erroneous/frozen-object-list.qbs b/tests/auto/language/testdata/erroneous/frozen-object-list.qbs
new file mode 100644
index 000000000..8bbd2b413
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/frozen-object-list.qbs
@@ -0,0 +1,17 @@
+
+Product {
+ Probe {
+ id: probe
+ property varList output
+ configure: {
+ output = [{"key": "value"}];
+ found = true;
+ }
+ }
+
+ property var test: {
+ var result = probe.output;
+ result.push({});
+ return result;
+ }
+}
diff --git a/tests/auto/language/testdata/erroneous/frozen-object.qbs b/tests/auto/language/testdata/erroneous/frozen-object.qbs
new file mode 100644
index 000000000..0f891d04b
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/frozen-object.qbs
@@ -0,0 +1,18 @@
+
+Product {
+ Probe {
+ id: probe
+ property var output
+ configure: {
+ output = {"key": "value"}
+ found = true
+ }
+ }
+
+ property var test: {
+ "use strict"
+ var result = probe.output;
+ result.key = "newValue";
+ return result;
+ }
+}
diff --git a/tests/auto/language/testdata/erroneous/invalid_file.qbs b/tests/auto/language/testdata/erroneous/invalid_file.qbs
index c461b87ef..54ec27410 100644
--- a/tests/auto/language/testdata/erroneous/invalid_file.qbs
+++ b/tests/auto/language/testdata/erroneous/invalid_file.qbs
@@ -1,3 +1,3 @@
-Application {
+Product {
files: ["main.cpp", "other.h"]
}
diff --git a/tests/auto/language/testdata/erroneous/missing-colon.qbs b/tests/auto/language/testdata/erroneous/missing-colon.qbs
index e62eb7cfd..6e136bb56 100644
--- a/tests/auto/language/testdata/erroneous/missing-colon.qbs
+++ b/tests/auto/language/testdata/erroneous/missing-colon.qbs
@@ -1,3 +1,5 @@
-CppApplication {
- cpp.dynamicLibraries { }
+Product {
+ Depends { name: "dummy" }
+ qbsSearchPaths: ".."
+ dummy.cxxFlags { }
}
diff --git a/tests/auto/language/testdata/erroneous/missing-js-file.qbs b/tests/auto/language/testdata/erroneous/missing-js-file.qbs
new file mode 100644
index 000000000..a3274a35b
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/missing-js-file.qbs
@@ -0,0 +1,3 @@
+Product {
+ Depends { name: "missing-js-file-module" }
+}
diff --git a/tests/auto/language/testdata/erroneous/module-property-binding-in-project.qbs b/tests/auto/language/testdata/erroneous/module-property-binding-in-project.qbs
new file mode 100644
index 000000000..667088c17
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/module-property-binding-in-project.qbs
@@ -0,0 +1,3 @@
+Project {
+ qbs.sysroot: "/"
+}
diff --git a/tests/auto/language/testdata/erroneous/module-with-id.qbs b/tests/auto/language/testdata/erroneous/module-with-id.qbs
new file mode 100644
index 000000000..5b980100f
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/module-with-id.qbs
@@ -0,0 +1,4 @@
+Product {
+ name: "p"
+ Depends { name: "module-with-id" }
+}
diff --git a/tests/auto/language/testdata/erroneous/modules/missing-js-file-module/missing-js-file-module.qbs b/tests/auto/language/testdata/erroneous/modules/missing-js-file-module/missing-js-file-module.qbs
new file mode 100644
index 000000000..31302b5c2
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/modules/missing-js-file-module/missing-js-file-module.qbs
@@ -0,0 +1,3 @@
+import "missing-js-file.js" as MissingJsFile
+
+Module { }
diff --git a/tests/auto/language/testdata/erroneous/modules/missing-js-file-module/missing-js-file.js b/tests/auto/language/testdata/erroneous/modules/missing-js-file-module/missing-js-file.js
new file mode 100644
index 000000000..b66048a8f
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/modules/missing-js-file-module/missing-js-file.js
@@ -0,0 +1 @@
+var userfile = require("javascriptfile.js")
diff --git a/tests/auto/language/testdata/erroneous/modules/module-with-id/ModuleWithId.qbs b/tests/auto/language/testdata/erroneous/modules/module-with-id/ModuleWithId.qbs
new file mode 100644
index 000000000..d20b96784
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/modules/module-with-id/ModuleWithId.qbs
@@ -0,0 +1 @@
+ModuleWithIdParent { id: foo }
diff --git a/tests/auto/language/testdata/erroneous/modules/module-with-id/ModuleWithIdParent.qbs b/tests/auto/language/testdata/erroneous/modules/module-with-id/ModuleWithIdParent.qbs
new file mode 100644
index 000000000..5e45122de
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/modules/module-with-id/ModuleWithIdParent.qbs
@@ -0,0 +1 @@
+Module {}
diff --git a/tests/auto/language/testdata/erroneous/original-in-export-item.qbs b/tests/auto/language/testdata/erroneous/original-in-export-item.qbs
index 51fedb9a2..c83601cfb 100644
--- a/tests/auto/language/testdata/erroneous/original-in-export-item.qbs
+++ b/tests/auto/language/testdata/erroneous/original-in-export-item.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Project {
Product {
name: "a"
diff --git a/tests/auto/language/testdata/erroneous/original-in-export-item2.qbs b/tests/auto/language/testdata/erroneous/original-in-export-item2.qbs
index d932d4aee..1c9f3de4b 100644
--- a/tests/auto/language/testdata/erroneous/original-in-export-item2.qbs
+++ b/tests/auto/language/testdata/erroneous/original-in-export-item2.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Project {
Product {
name: "a"
diff --git a/tests/auto/language/testdata/erroneous/original-in-export-item3.qbs b/tests/auto/language/testdata/erroneous/original-in-export-item3.qbs
index d7bcb322e..d23ad0a08 100644
--- a/tests/auto/language/testdata/erroneous/original-in-export-item3.qbs
+++ b/tests/auto/language/testdata/erroneous/original-in-export-item3.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Project {
Product {
name: "a"
diff --git a/tests/auto/language/testdata/erroneous/original-in-module-prototype.qbs b/tests/auto/language/testdata/erroneous/original-in-module-prototype.qbs
index e7128092a..00661fb66 100644
--- a/tests/auto/language/testdata/erroneous/original-in-module-prototype.qbs
+++ b/tests/auto/language/testdata/erroneous/original-in-module-prototype.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Product {
Depends { name: "module-with-invalid-original" }
}
diff --git a/tests/auto/language/testdata/erroneous/properties-item-with-invalid-condition.qbs b/tests/auto/language/testdata/erroneous/properties-item-with-invalid-condition.qbs
index 5b1a41f1b..0b48731ae 100644
--- a/tests/auto/language/testdata/erroneous/properties-item-with-invalid-condition.qbs
+++ b/tests/auto/language/testdata/erroneous/properties-item-with-invalid-condition.qbs
@@ -1,7 +1,7 @@
Product {
Depends { name: "cpp" }
Properties {
- condition: cpp.nonexistingproperty.contains("somevalue")
+ condition: cpp.nonexistingproperty.includes("somevalue")
cpp.defines: ["ABC"]
}
}
diff --git a/tests/auto/language/testdata/eval-error-in-non-present-module.qbs b/tests/auto/language/testdata/eval-error-in-non-present-module.qbs
index c112bc6d4..6882a2216 100644
--- a/tests/auto/language/testdata/eval-error-in-non-present-module.qbs
+++ b/tests/auto/language/testdata/eval-error-in-non-present-module.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Product {
name: "p"
property bool moduleRequired
diff --git a/tests/auto/language/testdata/exports.qbs b/tests/auto/language/testdata/exports.qbs
index cc86b1e4a..0071aadce 100644
--- a/tests/auto/language/testdata/exports.qbs
+++ b/tests/auto/language/testdata/exports.qbs
@@ -1,7 +1,8 @@
import "exports_product.qbs" as ProductWithInheritedExportItem
Project {
- Application {
+ Product {
+ type: "app"
name: "myapp"
Depends { name: "mylib" }
Depends { name: "dummy" }
@@ -15,30 +16,35 @@ Project {
"subdir2/exports-mylib2.qbs"
]
- Application {
+ Product {
+ type: "app"
name: "A"
Depends { name: "qbs" }
Depends { name: "B" }
}
- StaticLibrary {
+ Product {
+ type: "lib"
name: "B"
Export {
Depends { name: "C" }
Depends { name: "qbs" }
}
}
- StaticLibrary {
+ Product {
+ type: "lib"
name: "C"
Export {
Depends { name: "D" }
Depends { name: "qbs" }
}
}
- StaticLibrary {
+ Product {
+ type: "lib"
name: "D"
}
- Application {
+ Product {
+ type: "app"
name: "myapp2"
Depends { name: "productWithInheritedExportItem" }
Depends { name: "qbs" }
@@ -46,7 +52,7 @@ Project {
ProductWithInheritedExportItem {
name: "productWithInheritedExportItem"
Export {
- dummy.cFlags: base.concat("PRODUCT_" + product.name.toUpperCase())
+ dummy.cFlags: base.concat("PRODUCT_" + exportingProduct.name.toUpperCase())
dummy.cxxFlags: ["-bar"]
Properties {
condition: true
@@ -54,7 +60,8 @@ Project {
}
}
}
- Application {
+ Product {
+ type: "app"
name: "myapp3"
Depends { name: "productWithInheritedExportItem"; versionAtLeast: "2.0" }
}
@@ -125,7 +132,7 @@ Project {
Export {
property bool depend: false
- property var config: product.config
+ property var config: exportingProduct.config
Depends { condition: depend; name: "cpp" }
Properties { condition: depend; cpp.includePaths: ["."] }
}
@@ -142,8 +149,9 @@ Project {
name: "broken_cycle1"
Export {
property bool depend: true
- Depends { name: "broken_cycle3"; condition: depend } }
+ Depends { name: "broken_cycle3"; condition: depend }
}
+ }
Product {
name: "broken_cycle2"
Export {
diff --git a/tests/auto/language/testdata/exports_product.qbs b/tests/auto/language/testdata/exports_product.qbs
index dc4c9f462..394d388d9 100644
--- a/tests/auto/language/testdata/exports_product.qbs
+++ b/tests/auto/language/testdata/exports_product.qbs
@@ -2,7 +2,7 @@ Product {
Export {
version: "2.0"
Depends { name: "dummy" }
- dummy.cFlags: ["BASE_" + product.name.toUpperCase()]
+ dummy.cFlags: ["BASE_" + exportingProduct.name.toUpperCase()]
dummy.cxxFlags: ["-foo"]
dummy.defines: ["ABC"]
}
diff --git a/tests/auto/language/testdata/getNativeSetting.qbs b/tests/auto/language/testdata/getNativeSetting.qbs
index 975aefebc..73af01316 100644
--- a/tests/auto/language/testdata/getNativeSetting.qbs
+++ b/tests/auto/language/testdata/getNativeSetting.qbs
@@ -1,15 +1,17 @@
import qbs.FileInfo
import qbs.Utilities
+import qbs.Host
+
Project {
Product {
name: "p1"
targetName: {
- if (qbs.hostOS.contains("macos")) {
+ if (Host.os().includes("macos")) {
return Utilities.getNativeSetting("/System/Library/CoreServices/SystemVersion.plist", "ProductName");
- } else if (qbs.hostOS.contains("windows")) {
+ } else if (Host.os().includes("windows")) {
var productName = Utilities.getNativeSetting("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName");
- if (productName.contains("Windows")) {
+ if (productName.includes("Windows")) {
return "Windows";
}
return undefined;
diff --git a/tests/auto/language/testdata/groupconditions.qbs b/tests/auto/language/testdata/groupconditions.qbs
index b7f383d45..4f55db9cd 100644
--- a/tests/auto/language/testdata/groupconditions.qbs
+++ b/tests/auto/language/testdata/groupconditions.qbs
@@ -43,7 +43,7 @@ Project {
Product {
name: "condition_accessing_module_property"
Group {
- condition: qbs.targetOS.contains("narf")
+ condition: qbs.targetOS.includes("narf")
files: ["main.cpp"]
qbs.install: false
}
diff --git a/tests/auto/language/testdata/inherited-properties-items/imports/DebugName.qbs b/tests/auto/language/testdata/inherited-properties-items/imports/DebugName.qbs
index 5ac15658c..d129dc9db 100644
--- a/tests/auto/language/testdata/inherited-properties-items/imports/DebugName.qbs
+++ b/tests/auto/language/testdata/inherited-properties-items/imports/DebugName.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Properties {
condition: qbs.buildVariant === "debug"
name: "product_debug"
diff --git a/tests/auto/language/testdata/inherited-properties-items/imports/ReleaseName.qbs b/tests/auto/language/testdata/inherited-properties-items/imports/ReleaseName.qbs
index e33c5652b..57ab96a7e 100644
--- a/tests/auto/language/testdata/inherited-properties-items/imports/ReleaseName.qbs
+++ b/tests/auto/language/testdata/inherited-properties-items/imports/ReleaseName.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Properties {
condition: qbs.buildVariant === "release"
name: "product_release"
diff --git a/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items-product.qbs b/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items-product.qbs
index c20f045c8..6d148ba53 100644
--- a/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items-product.qbs
+++ b/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items-product.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Product {
name: "product_default"
DebugName {}
diff --git a/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items.qbs b/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items.qbs
index 40d41c2fb..52f7ffc00 100644
--- a/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items.qbs
+++ b/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Project {
qbsSearchPaths: sourceDirectory
references: "inherited-properties-items-product.qbs"
diff --git a/tests/auto/language/testdata/invalid-prop-on-non-required-module/invalid-prop-on-non-required-module.qbs b/tests/auto/language/testdata/invalid-prop-on-non-required-module/invalid-prop-on-non-required-module.qbs
new file mode 100644
index 000000000..80ae6ad93
--- /dev/null
+++ b/tests/auto/language/testdata/invalid-prop-on-non-required-module/invalid-prop-on-non-required-module.qbs
@@ -0,0 +1,19 @@
+Project {
+ property bool useExistingModule
+
+ Product {
+ name: "a"
+ condition: project.useExistingModule
+ Depends { name: "deploader" }
+ Depends { name: "dep" }
+ dep.nosuchprop: true
+ }
+
+ Product {
+ name: "b"
+ condition: !project.useExistingModule
+ Depends { name: "deploader" }
+ Depends { name: "random"; required: false }
+ random.nosuchprop: true
+ }
+}
diff --git a/tests/auto/language/testdata/invalid-prop-on-non-required-module/modules/dep/dep.qbs b/tests/auto/language/testdata/invalid-prop-on-non-required-module/modules/dep/dep.qbs
new file mode 100644
index 000000000..5e45122de
--- /dev/null
+++ b/tests/auto/language/testdata/invalid-prop-on-non-required-module/modules/dep/dep.qbs
@@ -0,0 +1 @@
+Module {}
diff --git a/tests/auto/language/testdata/invalid-prop-on-non-required-module/modules/deploader/deploader.qbs b/tests/auto/language/testdata/invalid-prop-on-non-required-module/modules/deploader/deploader.qbs
new file mode 100644
index 000000000..15a1b5309
--- /dev/null
+++ b/tests/auto/language/testdata/invalid-prop-on-non-required-module/modules/deploader/deploader.qbs
@@ -0,0 +1,7 @@
+Module {
+ // This indirection exists to properly model QBS-1776.
+ // "deploader" corresponds to "bundle", and "dep" corresponds to "codesign"
+ Depends { condition: project.useExistingModule; name: "dep"; required: false }
+
+ Depends { condition: !project.useExistingModule; name: "random"; required: false }
+}
diff --git a/tests/auto/language/testdata/jsextensions.js b/tests/auto/language/testdata/jsextensions.js
index df74a263b..5c5821e86 100644
--- a/tests/auto/language/testdata/jsextensions.js
+++ b/tests/auto/language/testdata/jsextensions.js
@@ -57,9 +57,9 @@ var a = ["one", "two", "three"];
initTestContext("Array.prototype.contains");
for (var k in a)
verify(k !== "contains");
-verify(a.contains("one"));
-verify(a.contains("two"));
-verify(a.contains("three"));
-verify(!a.contains("four"));
+verify(a.includes("one"));
+verify(a.includes("two"));
+verify(a.includes("three"));
+verify(!a.includes("four"));
})() // END function wrapper
diff --git a/tests/auto/language/testdata/local-profile-as-top-level-profile.qbs b/tests/auto/language/testdata/local-profile-as-top-level-profile.qbs
new file mode 100644
index 000000000..9bca3c599
--- /dev/null
+++ b/tests/auto/language/testdata/local-profile-as-top-level-profile.qbs
@@ -0,0 +1,7 @@
+Product {
+ Profile {
+ name: "test-profile"
+ qbs.architecture: "arm"
+ qbs.targetPlatform: "macos"
+ }
+}
diff --git a/tests/auto/language/testdata/erroneous/module-depends-on-product.qbs b/tests/auto/language/testdata/module-depends-on-product.qbs
index a7db9e036..a7db9e036 100644
--- a/tests/auto/language/testdata/erroneous/module-depends-on-product.qbs
+++ b/tests/auto/language/testdata/module-depends-on-product.qbs
diff --git a/tests/auto/language/testdata/module-name-collisions/complex-collision.qbs b/tests/auto/language/testdata/module-name-collisions/complex-collision.qbs
new file mode 100644
index 000000000..cd55aa946
--- /dev/null
+++ b/tests/auto/language/testdata/module-name-collisions/complex-collision.qbs
@@ -0,0 +1,4 @@
+Product {
+ Depends { name: "prefix1.middle1" }
+ Depends { name: "prefix1.middle1.suffix1" }
+}
diff --git a/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/middle1.qbs b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/middle1.qbs
new file mode 100644
index 000000000..5e45122de
--- /dev/null
+++ b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/middle1.qbs
@@ -0,0 +1 @@
+Module {}
diff --git a/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/suffix1/suffix1.qbs b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/suffix1/suffix1.qbs
new file mode 100644
index 000000000..5e45122de
--- /dev/null
+++ b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/suffix1/suffix1.qbs
@@ -0,0 +1 @@
+Module {}
diff --git a/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/suffix2/suffix2.qbs b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/suffix2/suffix2.qbs
new file mode 100644
index 000000000..5e45122de
--- /dev/null
+++ b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle1/suffix2/suffix2.qbs
@@ -0,0 +1 @@
+Module {}
diff --git a/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle2/suffix/suffix.qbs b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle2/suffix/suffix.qbs
new file mode 100644
index 000000000..5e45122de
--- /dev/null
+++ b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/middle2/suffix/suffix.qbs
@@ -0,0 +1 @@
+Module {}
diff --git a/tests/auto/language/testdata/module-name-collisions/modules/prefix1/prefix1.qbs b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/prefix1.qbs
new file mode 100644
index 000000000..84957060c
--- /dev/null
+++ b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/prefix1.qbs
@@ -0,0 +1,2 @@
+Module {
+}
diff --git a/tests/auto/language/testdata/erroneous/modules/prefix1/suffix/suffix.qbs b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/suffix/suffix.qbs
index 218a4feb7..218a4feb7 100644
--- a/tests/auto/language/testdata/erroneous/modules/prefix1/suffix/suffix.qbs
+++ b/tests/auto/language/testdata/module-name-collisions/modules/prefix1/suffix/suffix.qbs
diff --git a/tests/auto/language/testdata/module-name-collisions/modules/prefix2/prefix2.qbs b/tests/auto/language/testdata/module-name-collisions/modules/prefix2/prefix2.qbs
new file mode 100644
index 000000000..a5aaa6f8b
--- /dev/null
+++ b/tests/auto/language/testdata/module-name-collisions/modules/prefix2/prefix2.qbs
@@ -0,0 +1,3 @@
+Module {
+ Depends { name: "prefix2.suffix" }
+}
diff --git a/tests/auto/language/testdata/module-name-collisions/modules/prefix2/suffix/suffix.qbs b/tests/auto/language/testdata/module-name-collisions/modules/prefix2/suffix/suffix.qbs
new file mode 100644
index 000000000..84957060c
--- /dev/null
+++ b/tests/auto/language/testdata/module-name-collisions/modules/prefix2/suffix/suffix.qbs
@@ -0,0 +1,2 @@
+Module {
+}
diff --git a/tests/auto/language/testdata/module-name-collisions/no-collision1.qbs b/tests/auto/language/testdata/module-name-collisions/no-collision1.qbs
new file mode 100644
index 000000000..e5a94ad66
--- /dev/null
+++ b/tests/auto/language/testdata/module-name-collisions/no-collision1.qbs
@@ -0,0 +1,4 @@
+Product {
+ Depends { name: "prefix1.middle1.suffix1" }
+ Depends { name: "prefix1.middle1.suffix2" }
+}
diff --git a/tests/auto/language/testdata/module-name-collisions/no-collision2.qbs b/tests/auto/language/testdata/module-name-collisions/no-collision2.qbs
new file mode 100644
index 000000000..664ec1729
--- /dev/null
+++ b/tests/auto/language/testdata/module-name-collisions/no-collision2.qbs
@@ -0,0 +1,4 @@
+Product {
+ Depends { name: "prefix1.middle1" }
+ Depends { name: "prefix1.middle2.suffix" }
+}
diff --git a/tests/auto/language/testdata/erroneous/same-module-prefix1.qbs b/tests/auto/language/testdata/module-name-collisions/simple-collision1.qbs
index 8aba31c2a..8aba31c2a 100644
--- a/tests/auto/language/testdata/erroneous/same-module-prefix1.qbs
+++ b/tests/auto/language/testdata/module-name-collisions/simple-collision1.qbs
diff --git a/tests/auto/language/testdata/erroneous/same-module-prefix2.qbs b/tests/auto/language/testdata/module-name-collisions/simple-collision2.qbs
index 6679091c2..6679091c2 100644
--- a/tests/auto/language/testdata/erroneous/same-module-prefix2.qbs
+++ b/tests/auto/language/testdata/module-name-collisions/simple-collision2.qbs
diff --git a/tests/auto/language/testdata/module-parameters/module-parameters.qbs b/tests/auto/language/testdata/module-parameters/module-parameters.qbs
new file mode 100644
index 000000000..48169d601
--- /dev/null
+++ b/tests/auto/language/testdata/module-parameters/module-parameters.qbs
@@ -0,0 +1,35 @@
+Project {
+ property bool overrideFromModule
+ property bool overrideFromExport
+ property bool overrideFromProduct
+
+ Product {
+ name: "dep"
+ Export {
+ Depends {
+ name: "higher";
+ condition: project.overrideFromExport
+ lower.param: "fromExportDepends"
+ }
+ Parameters { lower.param: "fromParameters" }
+ }
+ }
+ Product {
+ name: "main"
+
+ Depends {
+ name: "dep"
+ condition: project.overrideFromProduct
+ lower.param: "fromProductDepends"
+ }
+ Depends {
+ name: "higher"
+ condition: project.overrideFromProduct
+ lower.param: "fromProductDepends"
+ }
+ Depends { name: "dep"; condition: !project.overrideFromProduct }
+ Depends { name: "higher"; condition: !project.overrideFromProduct }
+ Depends { name: "highest" }
+ Depends { name: "broken"; required: false }
+ }
+}
diff --git a/tests/auto/language/testdata/module-parameters/modules/broken/broken.qbs b/tests/auto/language/testdata/module-parameters/modules/broken/broken.qbs
new file mode 100644
index 000000000..ae7b4c4ef
--- /dev/null
+++ b/tests/auto/language/testdata/module-parameters/modules/broken/broken.qbs
@@ -0,0 +1,4 @@
+Module {
+ Depends { name: "higher"; lower.param: "shouldNeverAppear" }
+ validate: { throw "As the name indicates, this module is broken."; }
+}
diff --git a/tests/auto/language/testdata/module-parameters/modules/higher/higher.qbs b/tests/auto/language/testdata/module-parameters/modules/higher/higher.qbs
new file mode 100644
index 000000000..006e05a93
--- /dev/null
+++ b/tests/auto/language/testdata/module-parameters/modules/higher/higher.qbs
@@ -0,0 +1,4 @@
+Module {
+ Depends { name: "lower" }
+ Parameters { lower.param: "fromParameters" }
+}
diff --git a/tests/auto/language/testdata/module-parameters/modules/highest/highest.qbs b/tests/auto/language/testdata/module-parameters/modules/highest/highest.qbs
new file mode 100644
index 000000000..83b0a0a03
--- /dev/null
+++ b/tests/auto/language/testdata/module-parameters/modules/highest/highest.qbs
@@ -0,0 +1,7 @@
+Module {
+ Depends {
+ name: "higher"
+ condition: project.overrideFromModule
+ lower.param: "fromModuleDepends"
+ }
+}
diff --git a/tests/auto/language/testdata/module-parameters/modules/lower/lower.qbs b/tests/auto/language/testdata/module-parameters/modules/lower/lower.qbs
new file mode 100644
index 000000000..11436ecd8
--- /dev/null
+++ b/tests/auto/language/testdata/module-parameters/modules/lower/lower.qbs
@@ -0,0 +1,3 @@
+Module {
+ Parameter { property string param: "origin" }
+}
diff --git a/tests/auto/language/testdata/modulepropertiesingroups.qbs b/tests/auto/language/testdata/modulepropertiesingroups.qbs
index e3857bdf4..49f24c0ca 100644
--- a/tests/auto/language/testdata/modulepropertiesingroups.qbs
+++ b/tests/auto/language/testdata/modulepropertiesingroups.qbs
@@ -80,4 +80,13 @@ Project {
}
}
}
+
+ Product {
+ name: "module-property-in-group-condition"
+ Depends { name: "cpp" }
+ Group {
+ condition: qbs.architecture === "x86_64"
+ cpp.includePaths: "."
+ }
+ }
}
diff --git a/tests/auto/language/testdata/modules/broken/broken.qbs b/tests/auto/language/testdata/modules/broken/broken.qbs
index b960117cf..a80547340 100644
--- a/tests/auto/language/testdata/modules/broken/broken.qbs
+++ b/tests/auto/language/testdata/modules/broken/broken.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Module {
Probe {
id: theProbe
diff --git a/tests/auto/language/testdata/modules/dummy/dummy.qbs b/tests/auto/language/testdata/modules/dummy/dummy.qbs
index b1791ac96..623abc413 100644
--- a/tests/auto/language/testdata/modules/dummy/dummy.qbs
+++ b/tests/auto/language/testdata/modules/dummy/dummy.qbs
@@ -16,7 +16,7 @@ DummyBase {
property string zort: "zort in dummy"
property pathList includePaths
property path somePath
- property stringList listProp: product.type.contains("blubb") ? ["123"] : ["456"]
+ property stringList listProp: product.type.includes("blubb") ? ["123"] : ["456"]
property bool controllingProp: false
property stringList listProp2: controllingProp
diff --git a/tests/auto/language/testdata/modules/dummyqt/core/dummycore.qbs b/tests/auto/language/testdata/modules/dummyqt/core/dummycore.qbs
index 746c7e37b..2764af9c2 100644
--- a/tests/auto/language/testdata/modules/dummyqt/core/dummycore.qbs
+++ b/tests/auto/language/testdata/modules/dummyqt/core/dummycore.qbs
@@ -1,11 +1,10 @@
Module {
- id: qtcore
property int versionMajor: 5
property int versionMinor: 0
property int versionPatch: 0
property string version: versionMajor.toString() + "." + versionMinor.toString() + "." + versionPatch.toString()
property string coreProperty: "coreProperty"
- property string coreVersion: qtcore.version
+ property string coreVersion: version
property string zort: "zort in dummyqt.core"
Depends { name: "dummy" }
diff --git a/tests/auto/language/testdata/erroneous/modules/module-with-product-dependency/module-with-product-dependency.qbs b/tests/auto/language/testdata/modules/module-with-product-dependency/module-with-product-dependency.qbs
index 5781bd6de..5781bd6de 100644
--- a/tests/auto/language/testdata/erroneous/modules/module-with-product-dependency/module-with-product-dependency.qbs
+++ b/tests/auto/language/testdata/modules/module-with-product-dependency/module-with-product-dependency.qbs
diff --git a/tests/auto/language/testdata/modules/multiple_backends/backend1.qbs b/tests/auto/language/testdata/modules/multiple_backends/backend1.qbs
index 794c67827..4f78a89ae 100644
--- a/tests/auto/language/testdata/modules/multiple_backends/backend1.qbs
+++ b/tests/auto/language/testdata/modules/multiple_backends/backend1.qbs
@@ -1,4 +1,4 @@
Module {
- condition: qbs.targetOS.contains("os1")
+ condition: qbs.targetOS.includes("os1")
property string prop: "backend 1"
}
diff --git a/tests/auto/language/testdata/modules/multiple_backends/backend2.qbs b/tests/auto/language/testdata/modules/multiple_backends/backend2.qbs
index 2073c4d0b..e7a44d4c7 100644
--- a/tests/auto/language/testdata/modules/multiple_backends/backend2.qbs
+++ b/tests/auto/language/testdata/modules/multiple_backends/backend2.qbs
@@ -1,5 +1,5 @@
Module {
- condition: qbs.targetOS.contains("os2")
+ condition: qbs.targetOS.includes("os2")
property string prop: "backend 2"
property string backend2Prop
}
diff --git a/tests/auto/language/testdata/modules/multiple_backends/backend3.qbs b/tests/auto/language/testdata/modules/multiple_backends/backend3.qbs
index 16228108b..762c12f20 100644
--- a/tests/auto/language/testdata/modules/multiple_backends/backend3.qbs
+++ b/tests/auto/language/testdata/modules/multiple_backends/backend3.qbs
@@ -1,5 +1,5 @@
Module {
- condition: qbs.targetOS.contains("os2") && qbs.toolchain.contains("tc")
+ condition: qbs.targetOS.includes("os2") && qbs.toolchain.includes("tc")
priority: 1
property string backend3Prop
}
diff --git a/tests/auto/language/testdata/multiplexed-exports.qbs b/tests/auto/language/testdata/multiplexed-exports.qbs
index f98ceff95..3252145f1 100644
--- a/tests/auto/language/testdata/multiplexed-exports.qbs
+++ b/tests/auto/language/testdata/multiplexed-exports.qbs
@@ -6,7 +6,7 @@ Project {
property string includeDir: qbs.buildVariant === "debug" ? "/d" : "/r"
Export {
Depends { name: "cpp" }
- cpp.includePaths: product.includeDir
+ cpp.includePaths: exportingProduct.includeDir
}
}
Product {
diff --git a/tests/auto/language/testdata/probes-and-multiplexing.qbs b/tests/auto/language/testdata/probes-and-multiplexing.qbs
new file mode 100644
index 000000000..38de08aee
--- /dev/null
+++ b/tests/auto/language/testdata/probes-and-multiplexing.qbs
@@ -0,0 +1,15 @@
+Product {
+ multiplexByQbsProperties: "architectures"
+ qbs.architectures: ["x86", "x86_64", "arm"]
+ property string archFromProbe: theProbe.archOut
+ Probe {
+ id: theProbe
+ property string archIn: qbs.architecture
+ property string archOut
+ configure: { archOut = archIn; }
+ }
+ Group {
+ name: "theGroup"
+ qbs.sysroot: "/" + theProbe.archOut
+ }
+}
diff --git a/tests/auto/language/testdata/profilevaluesandoverriddenvalues.qbs b/tests/auto/language/testdata/profilevaluesandoverriddenvalues.qbs
index 3aaa0cfa9..a0f189403 100644
--- a/tests/auto/language/testdata/profilevaluesandoverriddenvalues.qbs
+++ b/tests/auto/language/testdata/profilevaluesandoverriddenvalues.qbs
@@ -1,5 +1,5 @@
Project {
- Application {
+ Product {
name: "product1"
property bool dummyProp: {
if (!(dummy.cFlags instanceof Array))
diff --git a/tests/auto/language/testdata/qbs-properties-in-project-condition.qbs b/tests/auto/language/testdata/qbs-properties-in-project-condition.qbs
index 31f648233..9d27df254 100644
--- a/tests/auto/language/testdata/qbs-properties-in-project-condition.qbs
+++ b/tests/auto/language/testdata/qbs-properties-in-project-condition.qbs
@@ -1,5 +1,5 @@
Project {
- condition: qbs.targetOS.contains("whatever")
+ condition: qbs.targetOS.includes("whatever")
Product {
name: "never reached"
diff --git a/tests/auto/language/testdata/rfc1034identifier.qbs b/tests/auto/language/testdata/rfc1034identifier.qbs
index 4d320f899..e52dcc6b2 100644
--- a/tests/auto/language/testdata/rfc1034identifier.qbs
+++ b/tests/auto/language/testdata/rfc1034identifier.qbs
@@ -3,7 +3,7 @@ import qbs.Utilities
CppApplication {
name: Utilities.rfc1034Identifier("this!has@special#characters$uh-oh,Undersc0r3s_Are.Bad")
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.infoPlist: { return {"CFBundleIdentifier": "$(PRODUCT_NAME:rfc1034identifier)"}; }
}
}
diff --git a/tests/auto/language/testdata/subdir/exports-mylib.qbs b/tests/auto/language/testdata/subdir/exports-mylib.qbs
index 92f39483a..68ea30384 100644
--- a/tests/auto/language/testdata/subdir/exports-mylib.qbs
+++ b/tests/auto/language/testdata/subdir/exports-mylib.qbs
@@ -8,8 +8,8 @@ StaticLibrary {
Export {
Depends { name: "dummy" }
Depends { name: "mylib2" }
- dummy.defines: [product.definePrefix + product.name.toUpperCase()]
+ dummy.defines: [exportingProduct.definePrefix + exportingProduct.name.toUpperCase()]
dummy.includePaths: ["./lib"]
- dummy.somePath: product.aPath
+ dummy.somePath: exportingProduct.aPath
}
}
diff --git a/tests/auto/language/testdata/subdir2/exports-mylib2.qbs b/tests/auto/language/testdata/subdir2/exports-mylib2.qbs
index ac8b9ebe4..b16b47821 100644
--- a/tests/auto/language/testdata/subdir2/exports-mylib2.qbs
+++ b/tests/auto/language/testdata/subdir2/exports-mylib2.qbs
@@ -5,7 +5,7 @@ StaticLibrary {
property string definePrefix: "USE_"
Export {
Depends { name: "dummy" }
- dummy.defines: [product.definePrefix + product.name.toUpperCase()]
+ dummy.defines: [exportingProduct.definePrefix + exportingProduct.name.toUpperCase()]
dummy.includePaths: ["./lib"]
}
}
diff --git a/tests/auto/language/testdata/suppressed-and-non-suppressed-errors.qbs b/tests/auto/language/testdata/suppressed-and-non-suppressed-errors.qbs
index 4d5219157..684cc67b3 100644
--- a/tests/auto/language/testdata/suppressed-and-non-suppressed-errors.qbs
+++ b/tests/auto/language/testdata/suppressed-and-non-suppressed-errors.qbs
@@ -1,5 +1,5 @@
Project {
- CppApplication {
+ Product {
name: "mysterious creature"
files: ["easter bunny"]
}
diff --git a/tests/auto/language/testdata/throw.qbs b/tests/auto/language/testdata/throw.qbs
new file mode 100644
index 000000000..e9a97efb5
--- /dev/null
+++ b/tests/auto/language/testdata/throw.qbs
@@ -0,0 +1,16 @@
+Project {
+ property string throwType
+ property bool dummy: {
+ if (throwType === "bool")
+ throw true;
+ if (throwType === "int")
+ throw 43;
+ if (throwType === "string")
+ throw "an error";
+ if (throwType === "list")
+ throw ["an", "error"];
+ if (throwType === "object")
+ throw { result: "crash", reason: "overheating" };
+ throw "type missing";
+ }
+}
diff --git a/tests/auto/language/testdata/use-internal-profile.qbs b/tests/auto/language/testdata/use-internal-profile.qbs
new file mode 100644
index 000000000..c2e20ff19
--- /dev/null
+++ b/tests/auto/language/testdata/use-internal-profile.qbs
@@ -0,0 +1,13 @@
+Project {
+ name: "theproject"
+
+ Profile {
+ name: "theprofile"
+ dummy.defines: name
+ }
+
+ Product {
+ name: "theproduct"
+ Depends { name: "dummy" }
+ }
+} \ No newline at end of file
diff --git a/tests/auto/language/tst_language.cpp b/tests/auto/language/tst_language.cpp
index 31aebfa3a..6a3344842 100644
--- a/tests/auto/language/tst_language.cpp
+++ b/tests/auto/language/tst_language.cpp
@@ -43,6 +43,7 @@
#include "../shared.h"
+#include <app/shared/logging/consolelogger.h>
#include <language/evaluator.h>
#include <language/filecontext.h>
#include <language/identifiersearch.h>
@@ -52,6 +53,7 @@
#include <language/propertymapinternal.h>
#include <language/scriptengine.h>
#include <language/value.h>
+#include <loader/projectresolver.h>
#include <parser/qmljslexer_p.h>
#include <parser/qmljsparser_p.h>
#include <tools/scripttools.h>
@@ -64,8 +66,7 @@
#include <tools/settings.h>
#include <tools/stlutils.h>
-#include "../shared/logging/consolelogger.h"
-
+#include <QtCore/qjsonobject.h>
#include <QtCore/qprocess.h>
#include <algorithm>
@@ -79,28 +80,43 @@ using namespace qbs;
using namespace qbs::Internal;
static QString testDataDir() {
- return FileInfo::resolvePath(QStringLiteral(SRCDIR),
- QStringLiteral("../../../tests/auto/language/testdata"));
+ return testDataSourceDir(SRCDIR "/testdata");
}
static QString testProject(const char *fileName) {
return testDataDir() + QLatin1Char('/') + QLatin1String(fileName);
}
+class JSSourceValueCreator
+{
+ FileContextPtr m_fileContext;
+ std::vector<std::unique_ptr<QString>> m_strings;
+public:
+ JSSourceValueCreator(const FileContextPtr &fileContext)
+ : m_fileContext(fileContext)
+ {
+ }
+
+ JSSourceValuePtr create(const QString &sourceCode)
+ {
+ JSSourceValuePtr value = JSSourceValue::create();
+ value->setFile(m_fileContext);
+ auto str = std::make_unique<QString>(sourceCode);
+ value->setSourceCode(*str.get());
+ m_strings.push_back(std::move(str));
+ return value;
+ }
+};
+
TestLanguage::TestLanguage(ILogSink *logSink, Settings *settings)
: m_logSink(logSink)
, m_settings(settings)
, m_wildcardsTestDirPath(QDir::tempPath() + QLatin1String("/_wildcards_test_dir_"))
{
- qsrand(QTime::currentTime().msec());
+ m_rand.seed(QTime::currentTime().msec());
qRegisterMetaType<QList<bool> >("QList<bool>");
- defaultParameters.setBuildRoot(m_tempDir.path() + "/buildroot");
- defaultParameters.setPropertyCheckingMode(ErrorHandlingMode::Strict);
- defaultParameters.setSettingsDirectory(m_settings->baseDirectory());
}
-TestLanguage::~TestLanguage()
-{
-}
+TestLanguage::~TestLanguage() = default;
QHash<QString, ResolvedProductPtr> TestLanguage::productsFromProject(ResolvedProjectPtr project)
{
@@ -144,8 +160,7 @@ void TestLanguage::handleInitCleanupDataTags(const char *projectFileName, bool *
*handled = true;
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject(projectFileName));
- project = loader->loadProject(defaultParameters);
+ resolveProject(projectFileName);
QVERIFY(!!project);
} catch (const ErrorInfo &e) {
exceptionCaught = true;
@@ -160,9 +175,31 @@ void TestLanguage::handleInitCleanupDataTags(const char *projectFileName, bool *
}
}
+TopLevelProjectPtr TestLanguage::resolveProject(const char *relProjectFilePath)
+{
+ if (relProjectFilePath)
+ defaultParameters.setProjectFilePath(testProject(relProjectFilePath));
+ defaultParameters.expandBuildConfiguration();
+ ProjectResolver resolver(defaultParameters, m_engine.get(), m_logger);
+ return project = resolver.resolve();
+}
+
void TestLanguage::init()
{
+ // clear caches, otherwise StoredVariantValues may end up being at the same address
+ // as the destroyed value
+ m_engine->reset();
m_logSink->setLogLevel(LoggerInfo);
+ defaultParameters = {};
+ defaultParameters.setBuildRoot(m_tempDir.path() + "/buildroot");
+ defaultParameters.setPropertyCheckingMode(ErrorHandlingMode::Strict);
+ defaultParameters.setSettingsDirectory(m_settings->baseDirectory());
+ defaultParameters.setTopLevelProfile(profileName());
+ defaultParameters.setMaxJobCount(1);
+ defaultParameters.setConfigurationName("default");
+ defaultParameters.setEnvironment(QProcessEnvironment::systemEnvironment());
+ defaultParameters.setSearchPaths({SRCDIR "/../../../share/qbs"});
+
QVERIFY(m_tempDir.isValid());
}
@@ -177,28 +214,16 @@ void TestLanguage::init()
void TestLanguage::initTestCase()
{
m_logger = Logger(m_logSink);
- m_engine = ScriptEngine::create(m_logger, EvalContext::PropertyEvaluation, this);
- loader = new Loader(m_engine, m_logger);
- loader->setSearchPaths(QStringList()
- << QStringLiteral(SRCDIR "/../../../share/qbs"));
- defaultParameters.setTopLevelProfile(profileName());
- defaultParameters.setConfigurationName("default");
- defaultParameters.expandBuildConfiguration();
- defaultParameters.setEnvironment(QProcessEnvironment::systemEnvironment());
- QVERIFY(QFileInfo(m_wildcardsTestDirPath).isAbsolute());
-}
+ m_engine = ScriptEngine::create(m_logger, EvalContext::PropertyEvaluation);
-void TestLanguage::cleanupTestCase()
-{
- delete loader;
+ QVERIFY(QFileInfo(m_wildcardsTestDirPath).isAbsolute());
}
void TestLanguage::additionalProductTypes()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("additional-product-types.qbs"));
- project = loader->loadProject(defaultParameters);
+ resolveProject("additional-product-types.qbs");
QVERIFY(!!project);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
const ResolvedProductConstPtr product = products.value("p");
@@ -219,8 +244,7 @@ void TestLanguage::baseProperty()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("baseproperty.qbs"));
- project = loader->loadProject(defaultParameters);
+ resolveProject("baseproperty.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
ResolvedProductPtr product = products.value("product1");
@@ -237,10 +261,8 @@ void TestLanguage::baseProperty()
void TestLanguage::baseValidation()
{
- qbs::SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("base-validate/base-validate.qbs"));
try {
- project = loader->loadProject(params);
+ resolveProject("base-validate/base-validate.qbs");
QVERIFY2(false, "exception expected");
} catch (const qbs::ErrorInfo &e) {
QVERIFY2(e.toString().contains("Parent succeeded, child failed."),
@@ -250,11 +272,9 @@ void TestLanguage::baseValidation()
void TestLanguage::brokenDependencyCycle()
{
- qbs::SetupProjectParameters params = defaultParameters;
QFETCH(QString, projectFileName);
- params.setProjectFilePath(testProject(qPrintable(projectFileName)));
try {
- project = loader->loadProject(params);
+ resolveProject(qPrintable(projectFileName));
} catch (const qbs::ErrorInfo &e) {
QVERIFY2(false, qPrintable(e.toString()));
}
@@ -271,12 +291,10 @@ void TestLanguage::buildConfigStringListSyntax()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters parameters = defaultParameters;
QVariantMap overriddenValues;
overriddenValues.insert("project.someStrings", "foo,bar,baz");
- parameters.setOverriddenValues(overriddenValues);
- parameters.setProjectFilePath(testProject("buildconfigstringlistsyntax.qbs"));
- project = loader->loadProject(parameters);
+ defaultParameters.setOverriddenValues(overriddenValues);
+ resolveProject("buildconfigstringlistsyntax.qbs");
QVERIFY(!!project);
QCOMPARE(project->projectProperties().value("someStrings").toStringList(),
QStringList() << "foo" << "bar" << "baz");
@@ -291,9 +309,7 @@ void TestLanguage::builtinFunctionInSearchPathsProperty()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters parameters = defaultParameters;
- parameters.setProjectFilePath(testProject("builtinFunctionInSearchPathsProperty.qbs"));
- QVERIFY(!!loader->loadProject(parameters));
+ QVERIFY(resolveProject("builtinFunctionInSearchPathsProperty.qbs"));
} catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
@@ -305,11 +321,12 @@ void TestLanguage::chainedProbes()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters parameters = defaultParameters;
- parameters.setProjectFilePath(testProject("chained-probes/chained-probes.qbs"));
- const TopLevelProjectConstPtr project = loader->loadProject(parameters);
+ resolveProject("chained-probes/chained-probes.qbs");
QVERIFY(!!project);
QCOMPARE(project->products.size(), size_t(1));
+ const QString prop1Val = project->products.front()->moduleProperties
+ ->moduleProperty("m", "prop1").toString();
+ QCOMPARE(prop1Val, QLatin1String("probe1Val"));
const QString prop2Val = project->products.front()->moduleProperties
->moduleProperty("m", "prop2").toString();
QCOMPARE(prop2Val, QLatin1String("probe1Valprobe2Val"));
@@ -325,9 +342,7 @@ void TestLanguage::versionCompare()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters parameters = defaultParameters;
- parameters.setProjectFilePath(testProject("versionCompare.qbs"));
- QVERIFY(!!loader->loadProject(parameters));
+ QVERIFY(resolveProject("versionCompare.qbs"));
} catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
@@ -339,8 +354,7 @@ void TestLanguage::canonicalArchitecture()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("canonicalArchitecture.qbs"));
- project = loader->loadProject(defaultParameters);
+ resolveProject("canonicalArchitecture.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
ResolvedProductPtr product = products.value(QStringLiteral("x86"));
@@ -356,8 +370,7 @@ void TestLanguage::rfc1034Identifier()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("rfc1034identifier.qbs"));
- project = loader->loadProject(defaultParameters);
+ resolveProject("rfc1034identifier.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
ResolvedProductPtr product = products.value(QStringLiteral("this-has-special-characters-"
@@ -370,17 +383,47 @@ void TestLanguage::rfc1034Identifier()
QCOMPARE(exceptionCaught, false);
}
+void TestLanguage::throwThings_data()
+{
+ QTest::addColumn<QString>("type");
+ QTest::addColumn<QString>("result");
+ QTest::addRow("bool") << "bool" << "true";
+ QTest::addRow("int") << "int" << "43";
+ QTest::addRow("string") << "string" << "an error";
+ QTest::addRow("list") << "list" << R"([
+ "an",
+ "error"
+])";
+ QTest::addRow("object") << "object" << R"({
+ "reason": "overheating",
+ "result": "crash"
+})";
+}
+
+void TestLanguage::throwThings()
+{
+ QFETCH(QString, type);
+ QFETCH(QString, result);
+ bool exceptionCaught = false;
+ try {
+ defaultParameters.setOverriddenValues({{"project.throwType", type}});
+ resolveProject("throw.qbs");
+ } catch (const ErrorInfo &e) {
+ exceptionCaught = true;
+ QVERIFY2(e.toString().contains(result), qPrintable(e.toString()));
+ }
+ QVERIFY(exceptionCaught);
+}
+
void TestLanguage::conditionalDepends()
{
bool exceptionCaught = false;
ResolvedProductPtr product;
ResolvedModuleConstPtr dependency;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("conditionaldepends.qbs"));
- params.setOverriddenValues({std::make_pair(QString("products."
+ defaultParameters.setOverriddenValues({std::make_pair(QString("products."
"multilevel_module_props_overridden.dummy3.loadDummy"), true)});
- project = loader->loadProject(params);
+ resolveProject("conditionaldepends.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
@@ -479,17 +522,38 @@ void TestLanguage::conditionalDepends()
QCOMPARE(exceptionCaught, false);
}
+void TestLanguage::convertStringList()
+{
+ FileContextPtr fileContext = FileContext::create();
+ fileContext->setFilePath("/dev/null");
+ JSSourceValueCreator sourceValueCreator(fileContext);
+ ItemPool pool;
+ Item *scope = Item::create(&pool, ItemType::Scope);
+ scope->setProperty("x", sourceValueCreator.create("[\"a\", \"b\"]"));
+
+ Evaluator evaluator(m_engine.get());
+ auto variantValue = evaluator.variantValue(scope, "x");
+ // despite we have a stringList prop, we evaluate it as a QVariantList
+ QCOMPARE(variantValue.userType(), QMetaType::Type::QVariantList);
+ // and we have to convert it explicitly
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ variantValue.convert(QMetaType(QMetaType::QStringList));
+#else
+ variantValue.convert(QMetaType::QStringList);
+#endif
+ QCOMPARE(variantValue.userType(), QMetaType::Type::QStringList);
+ QCOMPARE(variantValue, QStringList({"a", "b"}));
+}
+
void TestLanguage::delayedError()
{
QFETCH(bool, productEnabled);
try {
QFETCH(QString, projectFileName);
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject(projectFileName.toLatin1()));
QVariantMap overriddenValues;
overriddenValues.insert("project.enableProduct", productEnabled);
- params.setOverriddenValues(overriddenValues);
- project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues(overriddenValues);
+ resolveProject(projectFileName.toLatin1());
QCOMPARE(productEnabled, false);
QVERIFY(!!project);
QCOMPARE(project->products.size(), size_t(1));
@@ -521,8 +585,6 @@ void TestLanguage::dependencyOnAllProfiles()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("dependencyOnAllProfiles.qbs"));
TemporaryProfile p1("p1", m_settings);
p1.p.setValue("qbs.architecture", "arch1");
TemporaryProfile p2("p2", m_settings);
@@ -530,14 +592,14 @@ void TestLanguage::dependencyOnAllProfiles()
QVariantMap overriddenValues;
overriddenValues.insert("project.profile1", "p1");
overriddenValues.insert("project.profile2", "p2");
- params.setOverriddenValues(overriddenValues);
- project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues(overriddenValues);
+ resolveProject("dependencyOnAllProfiles.qbs");
QVERIFY(!!project);
QCOMPARE(project->products.size(), size_t(3));
const ResolvedProductConstPtr mainProduct = productsFromProject(project).value("main");
QVERIFY(!!mainProduct);
QCOMPARE(mainProduct->dependencies.size(), size_t { 2 });
- for (const ResolvedProductConstPtr &p : mainProduct->dependencies) {
+ for (const ResolvedProductPtr &p : mainProduct->dependencies) {
QCOMPARE(p->name, QLatin1String("dep"));
QVERIFY(p->profile() == "p1" || p->profile() == "p2");
}
@@ -552,9 +614,7 @@ void TestLanguage::derivedSubProject()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("derived-sub-project/project.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(params);
+ resolveProject("derived-sub-project/project.qbs");
QVERIFY(!!project);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
@@ -569,9 +629,7 @@ void TestLanguage::disabledSubProject()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("disabled-subproject.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(params);
+ resolveProject("disabled-subproject.qbs");
QVERIFY(!!project);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 0);
@@ -600,16 +658,14 @@ void TestLanguage::dottedNames()
{
QFETCH(bool, expectSuccess);
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("dotted-names/dotted-names.qbs"));
QFETCH(bool, useProduct);
QFETCH(bool, useModule);
const QVariantMap overridden{
std::make_pair("projects.theProject.includeDottedProduct", useProduct),
std::make_pair("projects.theProject.includeDottedModule", useModule)
};
- params.setOverriddenValues(overridden);
- TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues(overridden);
+ resolveProject("dotted-names/dotted-names.qbs");
QVERIFY(expectSuccess);
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
@@ -626,13 +682,44 @@ void TestLanguage::dottedNames()
}
}
+void TestLanguage::duplicateMultiplexValues_data()
+{
+ QTest::addColumn<bool>("dummy");
+ QTest::newRow("duplicate-multiplex-value") << true;
+ QTest::newRow("duplicate-multiplex-value2") << true;
+}
+
+void TestLanguage::duplicateMultiplexValues()
+{
+ bool exceptionCaught = false;
+ try {
+ resolveProject(qPrintable(QString::fromLocal8Bit(QTest::currentDataTag())
+ + QLatin1String(".qbs")));
+ QVERIFY(project);
+ const std::vector<ResolvedProductPtr> products = project->allProducts();
+ QCOMPARE(products.size(), 2);
+ bool x86 = false;
+ bool arm = false;
+ for (const ResolvedProductPtr &p : products) {
+ if (p->moduleProperties->moduleProperty("qbs", "architecture").toString() == "x86")
+ x86 = true;
+ else if (p->moduleProperties->moduleProperty("qbs", "architecture").toString() == "arm")
+ arm = true;
+ }
+ QVERIFY(x86);
+ QVERIFY(arm);
+ } catch (const ErrorInfo &e) {
+ exceptionCaught = true;
+ qDebug() << e.toString();
+ }
+ QVERIFY(!exceptionCaught);
+}
+
void TestLanguage::emptyJsFile()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("empty-js-file.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(params);
+ resolveProject("empty-js-file.qbs");
QVERIFY(!!project);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
@@ -647,14 +734,12 @@ void TestLanguage::enumerateProjectProperties()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("enum-project-props.qbs"));
- auto project = loader->loadProject(params);
+ resolveProject("enum-project-props.qbs");
QVERIFY(!!project);
auto products = productsFromProject(project);
QCOMPARE(products.size(), 1);
auto product = products.values().front();
- auto files = product->groups.front()->allFiles();
+ auto files = product->groups.front()->files;
QCOMPARE(product->groups.size(), size_t(1));
QCOMPARE(files.size(), size_t(1));
auto fileName = FileInfo::fileName(files.front()->absoluteFilePath);
@@ -672,7 +757,7 @@ void TestLanguage::evalErrorInNonPresentModule_data()
QTest::addColumn<QString>("errorMessage");
QTest::newRow("module required")
- << true << "broken.qbs:4:5 Element at index 0 of list property 'broken' "
+ << true << "broken.qbs:2:5 Element at index 0 of list property 'broken' "
"does not have string type";
QTest::newRow("module not required") << false << QString();
}
@@ -682,19 +767,16 @@ void TestLanguage::evalErrorInNonPresentModule()
QFETCH(bool, moduleRequired);
QFETCH(QString, errorMessage);
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("eval-error-in-non-present-module.qbs"));
QVariantMap overridden{std::make_pair("products.p.moduleRequired", moduleRequired)};
- params.setOverriddenValues(overridden);
- TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues(overridden);
+ resolveProject("eval-error-in-non-present-module.qbs");
QVERIFY(errorMessage.isEmpty());
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
const ResolvedProductPtr product = products.value("p");
QVERIFY(!!product);
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
QVERIFY(!errorMessage.isEmpty());
QVERIFY2(e.toString().contains(errorMessage), qPrintable(e.toString()));
}
@@ -704,14 +786,12 @@ void TestLanguage::defaultValue()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("defaultvalue/egon.qbs"));
QFETCH(QString, prop1Value);
QVariantMap overridden;
if (!prop1Value.isEmpty())
overridden.insert("modules.lower.prop1", prop1Value);
- params.setOverriddenValues(overridden);
- TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues(overridden);
+ resolveProject("defaultvalue/egon.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 2);
@@ -725,8 +805,7 @@ void TestLanguage::defaultValue()
propertyValue = product->moduleProperties->property(propertyName);
QFETCH(QVariant, expectedListPropValue);
QCOMPARE(propertyValue.toStringList(), expectedListPropValue.toStringList());
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -754,17 +833,14 @@ void TestLanguage::environmentVariable()
try {
// Create new environment:
const QString varName = QStringLiteral("PRODUCT_NAME");
- const QString productName = QLatin1String("MyApp") + QString::number(qrand());
+ const QString productName = QLatin1String("MyApp") + QString::number(m_rand.generate());
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert(varName, productName);
QProcessEnvironment origEnv = defaultParameters.environment(); // store orig environment
defaultParameters.setEnvironment(env);
- defaultParameters.setProjectFilePath(testProject("environmentvariable.qbs"));
- project = loader->loadProject(defaultParameters);
-
- defaultParameters.setEnvironment(origEnv); // reset environment
+ resolveProject("environmentvariable.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
@@ -781,9 +857,7 @@ void TestLanguage::errorInDisabledProduct()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("error-in-disabled-product.qbs"));
- auto project = loader->loadProject(params);
+ resolveProject("error-in-disabled-product.qbs");
QVERIFY(!!project);
auto products = productsFromProject(project);
QCOMPARE(products.size(), 5);
@@ -807,11 +881,11 @@ void TestLanguage::erroneousFiles_data()
QTest::newRow("importloop1")
<< "Loop detected when importing";
QTest::newRow("nonexistentouter")
- << "Can't find variable: outer";
+ << "'outer' is not defined";
QTest::newRow("invalid_file")
<< "does not exist";
QTest::newRow("invalid-parameter-rhs")
- << "ReferenceError: Can't find variable: access";
+ << "'access' is not defined";
QTest::newRow("invalid-parameter-type")
<< "Value assigned to property 'stringParameter' does not have type 'string'.";
QTest::newRow("invalid_property_type")
@@ -828,6 +902,8 @@ void TestLanguage::erroneousFiles_data()
<< "Cyclic dependencies detected.";
QTest::newRow("dependency_cycle3")
<< "Cyclic dependencies detected.";
+ QTest::newRow("dependency_cycle3a")
+ << "Cyclic dependencies detected.";
QTest::newRow("dependency_cycle4")
<< "Cyclic dependencies detected.";
QTest::newRow("references_cycle")
@@ -876,30 +952,24 @@ void TestLanguage::erroneousFiles_data()
QTest::newRow("wrongQbsVersionFormat")
<< "The value '.*' of Project.minimumQbsVersion is not a valid version string.";
QTest::newRow("properties-item-with-invalid-condition")
- << "properties-item-with-invalid-condition.qbs:4:19.*TypeError: Result of expression "
- "'cpp.nonexistingproperty'";
+ << "properties-item-with-invalid-condition.qbs:4:19.*"
+ "cannot read property 'includes' of undefined";
QTest::newRow("misused-inherited-property") << "Binding to non-item property";
QTest::newRow("undeclared_property_in_Properties_item") << "Item 'blubb' is not declared";
- QTest::newRow("same-module-prefix1") << "The name of module 'prefix1' is equal to the first "
- "component of the name of module 'prefix1.suffix'";
- QTest::newRow("same-module-prefix2") << "The name of module 'prefix2' is equal to the first "
- "component of the name of module 'prefix2.suffix'";
QTest::newRow("conflicting-properties-in-export-items")
<< "Export item in inherited item redeclares property 'theProp' with different type.";
QTest::newRow("invalid-property-option")
<< "PropertyOptions item refers to non-existing property 's0meProp'";
QTest::newRow("missing-colon")
- << "Invalid item 'cpp.dynamicLibraries'. Did you mean to set a module property?";
+ << "Invalid item 'dummy.cxxFlags'. Did you mean to set a module property?";
QTest::newRow("syntax-error-in-probe")
- << "syntax-error-in-probe.qbs:4:20.*ReferenceError";
+ << "syntax-error-in-probe.qbs:4:20.*'fngkgsdjfgklkf' is not defined";
QTest::newRow("wrong-toplevel-item")
<< "wrong-toplevel-item.qbs:1:1.*The top-level item must be of type 'Project' or "
"'Product', but it is of type 'Artifact'.";
QTest::newRow("conflicting-module-instances")
<< "There is more than one equally prioritized candidate for module "
"'conflicting-instances'.";
- QTest::newRow("module-depends-on-product")
- << "module-with-product-dependency.qbs:2:5.*Modules cannot depend on products.";
QTest::newRow("overwrite-inherited-readonly-property")
<< "overwrite-inherited-readonly-property.qbs"
":2:21.*Cannot set read-only property 'readOnlyString'.";
@@ -916,25 +986,38 @@ void TestLanguage::erroneousFiles_data()
<< "module-with-invalid-original.qbs:2:24.*The special value 'original' cannot be used "
"on the right-hand side of a property declaration.";
QTest::newRow("original-in-export-item")
- << "original-in-export-item.qbs:7:32.*The special value 'original' cannot be used "
+ << "original-in-export-item.qbs:5:32.*The special value 'original' cannot be used "
"on the right-hand side of a property declaration.";
QTest::newRow("original-in-export-item2")
- << "original-in-export-item2.qbs:6:9.*Item 'x.y' is not declared. Did you forget "
+ << "original-in-export-item2.qbs:4:9.*Item 'x.y' is not declared. Did you forget "
"to add a Depends item";
QTest::newRow("original-in-export-item3")
<< "original-in-export-item3.qbs:6:9.*Item 'x.y' is not declared. Did you forget "
"to add a Depends item";
QTest::newRow("mismatching-multiplex-dependency")
- << "mismatching-multiplex-dependency.qbs:7:5.*Dependency from product "
- "'b \\{\"architecture\":\"mips\"\\}' to product 'a \\{\"architecture\":\"mips\"\\}'"
- " not fulfilled.";
- QTest::newRow("duplicate-multiplex-value")
- << "duplicate-multiplex-value.qbs:3:1.*Duplicate entry 'x86' in qbs.architectures.";
- QTest::newRow("duplicate-multiplex-value2")
- << "duplicate-multiplex-value2.qbs:3:1.*Duplicate entry 'architecture' in "
- "Product.multiplexByQbsProperties.";
+ << "mismatching-multiplex-dependency.qbs:9:9.*Dependency from product "
+ "'b \\{\"architecture\":\"mips\"\\}' to product 'a'"
+ " not fulfilled. There are no eligible multiplex candidates.";
+ QTest::newRow("ambiguous-multiplex-dependency")
+ << "ambiguous-multiplex-dependency.qbs:10:9.*Dependency from product 'b "
+ "\\{\"architecture\":\"x86\"\\}' to product 'a' is ambiguous. Eligible multiplex "
+ "candidates: a \\{\"architecture\":\"x86\",\"buildVariant\":\"debug\"\\}, "
+ "a \\{\"architecture\":\"x86\",\"buildVariant\":\"release\"\\}.";
+ QTest::newRow("dependency-profile-mismatch")
+ << "dependency-profile-mismatch.qbs:10:5.*Product 'main' depends on 'dep', "
+ "which does not exist for the requested profile 'profile47'.";
+ QTest::newRow("dependency-profile-mismatch-2")
+ << "dependency-profile-mismatch-2.qbs:15:9 Dependency from product 'main' to "
+ "product 'dep' not fulfilled. There are no eligible multiplex candidates.";
QTest::newRow("invalid-references")
<< "invalid-references.qbs:2:17.*Cannot open '.*nosuchproject.qbs'";
+ QTest::newRow("missing-js-file")
+ << "missing-js-file-module.qbs.*Cannot open '.*javascriptfile.js'";
+ QTest::newRow("frozen-object") << "'key' is read-only";
+ QTest::newRow("frozen-object-list") << "object is not extensible";
+ QTest::newRow("module-property-binding-in-project")
+ << "Module properties cannot be set in Project items";
+ QTest::newRow("module-with-id") << "Module items cannot have an id property";
}
void TestLanguage::erroneousFiles()
@@ -942,10 +1025,10 @@ void TestLanguage::erroneousFiles()
QFETCH(QString, errorMessage);
QString fileName = QString::fromLocal8Bit(QTest::currentDataTag()) + QLatin1String(".qbs");
try {
- defaultParameters.setProjectFilePath(testProject("/erroneous/") + fileName);
- loader->loadProject(defaultParameters);
+ resolveProject(qPrintable("/erroneous/" + fileName));
} catch (const ErrorInfo &e) {
- if (!e.toString().contains(QRegExp(errorMessage))) {
+ const QRegularExpression reg(errorMessage, QRegularExpression::DotMatchesEverythingOption);
+ if (!e.toString().contains(reg)) {
qDebug() << "Message: " << e.toString();
qDebug() << "Expected: " << errorMessage;
QFAIL("Unexpected error message.");
@@ -961,8 +1044,7 @@ void TestLanguage::exports()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("exports.qbs"));
- TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("exports.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 22);
@@ -1007,6 +1089,7 @@ void TestLanguage::exports()
product = products.value("B");
QVERIFY(!!product);
QVERIFY(product->dependencies.empty());
+ QCOMPARE(product->exportedModule.productDependencies, std::vector<QString>{"C"});
product = products.value("C");
QVERIFY(!!product);
QVERIFY(product->dependencies.empty());
@@ -1051,7 +1134,7 @@ void TestLanguage::exports()
propertyName = QStringList() << "dummy" << "defines";
propertyValue = product->moduleProperties->property(propertyName);
QCOMPARE(propertyValue.toStringList(),
- QStringList() << "LIBA" << "LIBB" << "LIBC" << "LIBD");
+ QStringList() << "LIBD" << "LIBC" << "LIBA" << "LIBB");
propertyName = QStringList() << "dummy" << "productName";
propertyValue = product->moduleProperties->property(propertyName);
QCOMPARE(propertyValue.toString(), QString("libE"));
@@ -1059,7 +1142,7 @@ void TestLanguage::exports()
product = products.value("depender");
QVERIFY(!!product);
QCOMPARE(product->modules.size(), size_t(2));
- for (const ResolvedModuleConstPtr &m : product->modules) {
+ for (const ResolvedModulePtr &m : product->modules) {
QVERIFY2(m->name == QString("qbs") || m->name == QString("dependency"),
qPrintable(m->name));
}
@@ -1070,13 +1153,12 @@ void TestLanguage::exports()
product = products.value("broken_cycle3");
QVERIFY(!!product);
QCOMPARE(product->modules.size(), size_t(3));
- for (const ResolvedModuleConstPtr &m : product->modules) {
+ for (const ResolvedModulePtr &m : product->modules) {
QVERIFY2(m->name == QString("qbs") || m->name == QString("broken_cycle1")
|| m->name == QString("broken_cycle2"),
qPrintable(m->name));
}
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -1087,8 +1169,7 @@ void TestLanguage::fileContextProperties()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("filecontextproperties.qbs"));
- project = loader->loadProject(defaultParameters);
+ resolveProject("filecontextproperties.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
ResolvedProductPtr product = products.value("product1");
@@ -1134,14 +1215,12 @@ void TestLanguage::fileInProductAndModule()
QFETCH(bool, addFileToProduct);
QFETCH(bool, successExpected);
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("file-in-product-and-module.qbs"));
- params.setOverriddenValues(QVariantMap{
+ defaultParameters.setOverriddenValues(QVariantMap{
std::make_pair("modules.module_with_file.file1IsTarget", file1IsTarget),
std::make_pair("modules.module_with_file.file2IsTarget", file2IsTarget),
std::make_pair("products.p.addFileToProduct", addFileToProduct),
});
- project = loader->loadProject(params);
+ resolveProject("file-in-product-and-module.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
@@ -1156,16 +1235,19 @@ void TestLanguage::getNativeSetting()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("getNativeSetting.qbs"));
- project = loader->loadProject(defaultParameters);
+ resolveProject("getNativeSetting.qbs");
QString expectedTargetName;
- if (HostOsInfo::isMacosHost())
- expectedTargetName = QStringLiteral("Mac OS X");
- else if (HostOsInfo::isWindowsHost())
+ if (HostOsInfo::isMacosHost()) {
+ if (HostOsInfo::hostOsVersion() >= qbs::Version(11))
+ expectedTargetName = QStringLiteral("macOS");
+ else
+ expectedTargetName = QStringLiteral("Mac OS X");
+ } else if (HostOsInfo::isWindowsHost()) {
expectedTargetName = QStringLiteral("Windows");
- else
+ } else {
expectedTargetName = QStringLiteral("Unix");
+ }
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products;
@@ -1228,8 +1310,7 @@ void TestLanguage::groupName()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("groupname.qbs"));
- TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("groupname.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 2);
@@ -1256,8 +1337,7 @@ void TestLanguage::groupName()
group = product->groups.at(2);
QVERIFY(!!group);
QCOMPARE(group->name, QString("Group 2"));
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -1267,8 +1347,7 @@ void TestLanguage::groupName()
void TestLanguage::homeDirectory()
{
try {
- defaultParameters.setProjectFilePath(testProject("homeDirectory.qbs"));
- ResolvedProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("homeDirectory.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
@@ -1293,8 +1372,7 @@ void TestLanguage::homeDirectory()
FileInfo::resolvePath(product->sourceDirectory, QStringLiteral("a/~/bb")));
QCOMPARE(product->productProperties.value("user").toString(),
FileInfo::resolvePath(product->sourceDirectory, QStringLiteral("~foo/bar")));
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
qDebug() << e.toString();
}
}
@@ -1373,8 +1451,7 @@ void TestLanguage::idUsage()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("idusage.qbs"));
- TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("idusage.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 5);
@@ -1398,8 +1475,7 @@ void TestLanguage::idUsage()
QVERIFY(!!product5);
QCOMPARE(product5->moduleProperties->moduleProperty("deepdummy.deep.moat", "zort")
.toString(), QString("zort in dummy"));
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -1410,10 +1486,8 @@ void TestLanguage::idUniqueness()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("id-uniqueness.qbs"));
- loader->loadProject(defaultParameters);
- }
- catch (const ErrorInfo &e) {
+ resolveProject("id-uniqueness.qbs");
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
const QList<ErrorItem> items = e.items();
QCOMPARE(items.size(), 3);
@@ -1428,15 +1502,13 @@ void TestLanguage::importCollection()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("import-collection/project.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("import-collection/project.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
const ResolvedProductConstPtr product = products.value("da product");
QCOMPARE(product->productProperties.value("targetName").toString(),
QLatin1String("C1f1C1f2C2f1C2f2"));
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -1455,19 +1527,15 @@ void TestLanguage::inheritedPropertiesItems()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
QFETCH(QString, buildVariant);
QFETCH(QString, productName);
- params.setProjectFilePath
- (testProject("inherited-properties-items/inherited-properties-items.qbs"));
- params.setOverriddenValues(QVariantMap{std::make_pair("qbs.buildVariant", buildVariant)});
- TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues(QVariantMap{std::make_pair("qbs.buildVariant", buildVariant)});
+ resolveProject("inherited-properties-items/inherited-properties-items.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
QVERIFY(!!products.value(productName));
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -1478,13 +1546,11 @@ void TestLanguage::invalidBindingInDisabledItem()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("invalidBindingInDisabledItem.qbs"));
- TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("invalidBindingInDisabledItem.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 2);
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -1498,13 +1564,10 @@ void TestLanguage::invalidOverrides()
const bool successExpected = expectedErrorMessage.isEmpty();
bool exceptionCaught = false;
try {
- qbs::SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("invalid-overrides.qbs"));
- params.setOverriddenValues(QVariantMap{std::make_pair(key, true)});
- const TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues(QVariantMap{std::make_pair(key, true)});
+ resolveProject("invalid-overrides.qbs");
QVERIFY(!!project);
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
if (successExpected)
qDebug() << e.toString();
@@ -1548,31 +1611,32 @@ void TestLanguage::invalidOverrides_data()
<< "products.MyOtherProduct.cpp.useRPaths" << QString();
}
-class JSSourceValueCreator
+void TestLanguage::invalidPropOnNonRequiredModule_data()
{
- FileContextPtr m_fileContext;
- QList<QString *> m_strings;
-public:
- JSSourceValueCreator(const FileContextPtr &fileContext)
- : m_fileContext(fileContext)
- {
- }
+ QTest::addColumn<bool>("useExistingModule");
+ QTest::addColumn<bool>("errorExpected");
- ~JSSourceValueCreator()
- {
- qDeleteAll(m_strings);
- }
+ QTest::newRow("existing module") << true << true;
+ QTest::newRow("non-existing module") << false << false;
+}
- JSSourceValuePtr create(const QString &sourceCode)
- {
- JSSourceValuePtr value = JSSourceValue::create();
- value->setFile(m_fileContext);
- const auto str = new QString(sourceCode);
- m_strings.push_back(str);
- value->setSourceCode(QStringRef(str));
- return value;
+void TestLanguage::invalidPropOnNonRequiredModule()
+{
+ QFETCH(bool, useExistingModule);
+ QFETCH(bool, errorExpected);
+
+ try {
+ defaultParameters.setOverriddenValues(
+ {std::make_pair("project.useExistingModule", useExistingModule)});
+ resolveProject("invalid-prop-on-non-required-module");
+ QVERIFY(!errorExpected);
+ } catch (const ErrorInfo &e) {
+ const QString errorString = e.toString();
+ QVERIFY2(errorExpected, qPrintable(errorString));
+ QVERIFY2(errorString.contains("Property 'nosuchprop' is not declared"),
+ qPrintable(errorString));
}
-};
+}
void TestLanguage::itemPrototype()
{
@@ -1588,13 +1652,14 @@ void TestLanguage::itemPrototype()
item->setProperty("y", sourceValueCreator.create("x + 1"));
item->setProperty("z", sourceValueCreator.create("2"));
- Evaluator evaluator(m_engine);
- QCOMPARE(evaluator.property(proto, "x").toVariant().toInt(), 1);
- QCOMPARE(evaluator.property(proto, "y").toVariant().toInt(), 1);
- QVERIFY(!evaluator.property(proto, "z").isValid());
- QCOMPARE(evaluator.property(item, "x").toVariant().toInt(), 1);
- QCOMPARE(evaluator.property(item, "y").toVariant().toInt(), 2);
- QCOMPARE(evaluator.property(item, "z").toVariant().toInt(), 2);
+ Evaluator evaluator(m_engine.get());
+ JSContext * const ctx = m_engine->context();
+ QCOMPARE(getJsVariant(ctx, evaluator.property(proto, "x")).toInt(), 1);
+ QCOMPARE(getJsVariant(ctx, evaluator.property(proto, "y")).toInt(), 1);
+ QVERIFY(JS_IsUndefined(evaluator.property(proto, "z")));
+ QCOMPARE(getJsVariant(ctx, evaluator.property(item, "x")).toInt(), 1);
+ QCOMPARE(getJsVariant(ctx, evaluator.property(item, "y")).toInt(), 2);
+ QCOMPARE(getJsVariant(ctx, evaluator.property(item, "z")).toInt(), 2);
}
void TestLanguage::itemScope()
@@ -1612,11 +1677,12 @@ void TestLanguage::itemScope()
item->setScope(scope2);
item->setProperty("z", sourceValueCreator.create("x + y"));
- Evaluator evaluator(m_engine);
- QCOMPARE(evaluator.property(scope1, "x").toVariant().toInt(), 1);
- QCOMPARE(evaluator.property(scope2, "y").toVariant().toInt(), 2);
- QVERIFY(!evaluator.property(scope2, "x").isValid());
- QCOMPARE(evaluator.property(item, "z").toVariant().toInt(), 3);
+ Evaluator evaluator(m_engine.get());
+ JSContext * const ctx = m_engine->context();
+ QCOMPARE(getJsVariant(ctx, evaluator.property(scope1, "x")).toInt(), 1);
+ QCOMPARE(getJsVariant(ctx, evaluator.property(scope2, "y")).toInt(), 2);
+ QVERIFY(JS_IsUndefined(evaluator.property(scope2, "x")));
+ QCOMPARE(getJsVariant(ctx, evaluator.property(item, "z")).toInt(), 3);
}
void TestLanguage::jsExtensions()
@@ -1626,10 +1692,10 @@ void TestLanguage::jsExtensions()
QTextStream ts(&file);
QString code = ts.readAll();
QVERIFY(!code.isEmpty());
- QScriptValue evaluated = m_engine->evaluate(code, file.fileName(), 1);
- if (m_engine->hasErrorOrException(evaluated)) {
- qDebug() << m_engine->uncaughtExceptionBacktrace();
- QFAIL(qPrintable(m_engine->lastErrorString(evaluated)));
+ m_engine->evaluate(JsValueOwner::Caller, code, file.fileName(), 1);
+ if (JsException ex = m_engine->checkAndClearException({})) {
+ qDebug() << ex.stackTrace();
+ QFAIL(qPrintable(ex.message()));
}
}
@@ -1648,35 +1714,45 @@ void TestLanguage::jsImportUsedInMultipleScopes()
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("jsimportsinmultiplescopes.qbs"));
- params.setOverriddenValues({std::make_pair(QStringLiteral("qbs.buildVariant"),
- buildVariant)});
- params.expandBuildConfiguration();
- TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues({std::make_pair(QStringLiteral("qbs.buildVariant"),
+ buildVariant)});
+ resolveProject("jsimportsinmultiplescopes.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
ResolvedProductPtr product = products.values().front();
QVERIFY(!!product);
QCOMPARE(product->name, expectedProductName);
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
QVERIFY(!exceptionCaught);
}
+void TestLanguage::localProfileAsTopLevelProfile()
+{
+ bool exceptionCaught = false;
+ try {
+ defaultParameters.setTopLevelProfile("test-profile");
+ resolveProject("local-profile-as-top-level-profile.qbs");
+ QVERIFY(!!project);
+ QCOMPARE(int(project->products.size()), 1);
+ const PropertyMapConstPtr &props = project->products.front()->moduleProperties;
+ QCOMPARE(props->qbsPropertyValue("architecture"), "arm");
+ QCOMPARE(props->qbsPropertyValue("targetPlatform"), "macos");
+ } catch (const ErrorInfo &e) {
+ exceptionCaught = true;
+ qDebug() << e.toString();
+ }
+ QCOMPARE(exceptionCaught, false);
+}
+
void TestLanguage::moduleMergingVariantValues()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath
- (testProject("module-merging-variant-values/module-merging-variant-values.qbs"));
- params.expandBuildConfiguration();
- const TopLevelProjectPtr project = loader->loadProject(params);
+ resolveProject("module-merging-variant-values/module-merging-variant-values.qbs");
QVERIFY(!!project);
QCOMPARE(int(project->products.size()), 2);
} catch (const ErrorInfo &e) {
@@ -1686,6 +1762,185 @@ void TestLanguage::moduleMergingVariantValues()
QCOMPARE(exceptionCaught, false);
}
+void TestLanguage::moduleNameCollisions_data()
+{
+ QTest::addColumn<QString>("projectFile");
+ QTest::addColumn<bool>("collisionExpected");
+
+ QTest::newRow("simple collision (one order)") << "simple-collision1.qbs" << true;
+ QTest::newRow("simple collision (other order)") << "simple-collision2.qbs" << true;
+ QTest::newRow("collision with more components") << "complex-collision.qbs" << true;
+ QTest::newRow("no collision (same length)") << "no-collision1.qbs" << false;
+ QTest::newRow("no collision (different length)") << "no-collision2.qbs" << false;
+}
+
+void TestLanguage::moduleNameCollisions()
+{
+ QFETCH(QString, projectFile);
+ QFETCH(bool, collisionExpected);
+
+ try {
+ const QString compositeProjectFilePath = QString("module-name-collisions/") + projectFile;
+ QVERIFY(resolveProject(qPrintable(compositeProjectFilePath)));
+ QVERIFY(!collisionExpected);
+ } catch (const ErrorInfo &e) {
+ const QString errorString = e.toString();
+ QVERIFY2(collisionExpected, qPrintable(errorString));
+ QVERIFY2(errorString.contains("not allowed"), qPrintable(errorString));
+ }
+}
+
+void TestLanguage::moduleParameters_data()
+{
+ QTest::addColumn<QVariantMap>("inputProperties");
+ QTest::addColumn<QVariantMap>("expectedModuleParameters");
+ QTest::addColumn<bool>("errorExpected");
+
+ QTest::newRow("no overrides")
+ << QVariantMap{
+ std::make_pair("project.overrideFromModule", "false"),
+ std::make_pair("project.overrideFromExport", "false"),
+ std::make_pair("project.overrideFromProduct", "false")}
+ << QVariantMap{
+ std::make_pair("higher",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromParameters")})}),
+ std::make_pair("dep",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromParameters")})})}
+ << false;
+ QTest::newRow("override from product")
+ << QVariantMap{
+ std::make_pair("project.overrideFromModule", "false"),
+ std::make_pair("project.overrideFromExport", "false"),
+ std::make_pair("project.overrideFromProduct", "true")}
+ << QVariantMap{
+ std::make_pair("higher",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromProductDepends")})}),
+ std::make_pair("dep",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromProductDepends")})})}
+ << false;
+ QTest::newRow("override from export")
+ << QVariantMap{
+ std::make_pair("project.overrideFromModule", "false"),
+ std::make_pair("project.overrideFromExport", "true"),
+ std::make_pair("project.overrideFromProduct", "false")}
+ << QVariantMap{
+ std::make_pair("higher",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromExportDepends")})}),
+ std::make_pair("dep",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromParameters")})})}
+ << false;
+ QTest::newRow("override from export and product")
+ << QVariantMap{
+ std::make_pair("project.overrideFromModule", "false"),
+ std::make_pair("project.overrideFromExport", "true"),
+ std::make_pair("project.overrideFromProduct", "true")}
+ << QVariantMap{
+ std::make_pair("higher",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromProductDepends")})}),
+ std::make_pair("dep",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromProductDepends")})})}
+ << false;
+ QTest::newRow("override from module")
+ << QVariantMap{
+ std::make_pair("project.overrideFromModule", "true"),
+ std::make_pair("project.overrideFromExport", "false"),
+ std::make_pair("project.overrideFromProduct", "false")}
+ << QVariantMap{
+ std::make_pair("higher",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromModuleDepends")})}),
+ std::make_pair("dep",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromParameters")})})}
+ << false;
+ QTest::newRow("override from module and product")
+ << QVariantMap{
+ std::make_pair("project.overrideFromModule", "true"),
+ std::make_pair("project.overrideFromExport", "false"),
+ std::make_pair("project.overrideFromProduct", "true")}
+ << QVariantMap{
+ std::make_pair("higher",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromProductDepends")})}),
+ std::make_pair("dep",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromProductDepends")})})}
+ << false;
+ QTest::newRow("override from module and export")
+ << QVariantMap{
+ std::make_pair("project.overrideFromModule", "true"),
+ std::make_pair("project.overrideFromExport", "true"),
+ std::make_pair("project.overrideFromProduct", "false")}
+ << QVariantMap{
+ std::make_pair("higher",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromExportDepends")})}),
+ std::make_pair("dep",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromParameters")})})}
+ << true;
+ QTest::newRow("override from module, export and product")
+ << QVariantMap{
+ std::make_pair("project.overrideFromModule", "true"),
+ std::make_pair("project.overrideFromExport", "true"),
+ std::make_pair("project.overrideFromProduct", "true")}
+ << QVariantMap{
+ std::make_pair("higher",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromProductDepends")})}),
+ std::make_pair("dep",
+ QVariantMap{std::make_pair("lower",
+ QVariantMap{std::make_pair("param", "fromProductDepends")})})}
+ << false;
+}
+
+void TestLanguage::moduleParameters()
+{
+ QFETCH(QVariantMap, inputProperties);
+ QFETCH(QVariantMap, expectedModuleParameters);
+ QFETCH(bool, errorExpected);
+
+ try {
+ defaultParameters.setOverriddenValues(inputProperties);
+ resolveProject("module-parameters/module-parameters.qbs");
+ QVERIFY(!errorExpected);
+ QVERIFY(project);
+ QCOMPARE(int(project->products.size()), 2);
+ const ResolvedProductPtr mainProduct = productsFromProject(project).value("main");
+ QVERIFY(mainProduct);
+ QCOMPARE(int(mainProduct->moduleParameters.size()), 2);
+ for (auto it = expectedModuleParameters.cbegin(); it != expectedModuleParameters.cend();
+ ++it) {
+ const auto findInProduct = [&](const QString &moduleName) {
+ for (auto it = mainProduct->moduleParameters.cbegin();
+ it != mainProduct->moduleParameters.cend(); ++it) {
+ if (it.key()->name == moduleName)
+ return it.value();
+ }
+ return QVariantMap();
+ };
+ const QVariantMap actual = findInProduct(it.key());
+ const QVariantMap expected = it.value().toMap();
+ const bool same = qVariantMapsEqual(actual, expected);
+ if (!same) {
+ qDebug().noquote() << "---" << expected;
+ qDebug().noquote() << "+++" << actual;
+ }
+ QVERIFY(same);
+ }
+ } catch (const ErrorInfo &e) {
+ QVERIFY2(errorExpected, qPrintable(e.toString()));
+ }
+}
+
void TestLanguage::modulePrioritizationBySearchPath_data()
{
QTest::addColumn<QStringList>("searchPaths");
@@ -1701,12 +1956,10 @@ void TestLanguage::modulePrioritizationBySearchPath()
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("module-prioritization-by-search-path/project.qbs"));
- params.setOverriddenValues({std::make_pair(QStringLiteral("project.qbsSearchPaths"),
- searchPaths)});
- params.expandBuildConfiguration();
- TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues(
+ {std::make_pair(QStringLiteral("project.qbsSearchPaths"),
+ searchPaths)});
+ resolveProject("module-prioritization-by-search-path/project.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
@@ -1715,8 +1968,7 @@ void TestLanguage::modulePrioritizationBySearchPath()
const QString actualVariant = product->moduleProperties->moduleProperty
("conflicting-instances", "moduleVariant").toString();
QCOMPARE(actualVariant, expectedVariant);
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -1730,10 +1982,10 @@ void TestLanguage::moduleProperties_data()
QTest::newRow("init") << QString() << QVariant();
QTest::newRow("merge_lists")
<< "defines"
- << QVariant(QStringList() << "THE_PRODUCT" << "QT_CORE" << "QT_GUI" << "QT_NETWORK");
+ << QVariant(QStringList() << "THE_PRODUCT" << "QT_NETWORK" << "QT_GUI" << "QT_CORE");
QTest::newRow("merge_lists_and_values")
<< "defines"
- << QVariant(QStringList() << "THE_PRODUCT" << "QT_CORE" << "QT_GUI" << "QT_NETWORK");
+ << QVariant(QStringList() << "THE_PRODUCT" << "QT_NETWORK" << "QT_GUI" << "QT_CORE");
QTest::newRow("merge_lists_with_duplicates")
<< "cxxFlags"
<< QVariant(QStringList() << "-foo" << "BAR" << "-foo" << "BAZ");
@@ -1782,7 +2034,7 @@ void TestLanguage::modulePropertiesInGroups()
defaultParameters.setProjectFilePath(testProject("modulepropertiesingroups.qbs"));
bool exceptionCaught = false;
try {
- TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject();
QVERIFY(!!project);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
ResolvedProductPtr product = products.value("grouptest");
@@ -1793,7 +2045,7 @@ void TestLanguage::modulePropertiesInGroups()
GroupConstPtr g2;
GroupConstPtr g21;
GroupConstPtr g211;
- for (const GroupConstPtr &g : product->groups) {
+ for (const GroupPtr &g : product->groups) {
if (g->name == "g1")
g1= g;
else if (g->name == "g2")
@@ -1910,7 +2162,7 @@ void TestLanguage::modulePropertiesInGroups()
QCOMPARE(g2Gmod1List1, QStringList() << "gmod1_list1_proto" << "g2");
const auto &g2Gmod1List2 = moduleProperty(g2Props, "gmod.gmod1", "gmod1_list2")
.toStringList();
- QCOMPARE(g2Gmod1List2, QStringList() << "grouptest" << "g2" << "gmod1_list2_proto");
+ QCOMPARE(g2Gmod1List2, QStringList() << "grouptest" << "gmod1_string_proto" << "gmod1_list2_proto");
const int g2P0 = moduleProperty(g2Props, "gmod.gmod1", "p0").toInt();
QCOMPARE(g2P0, 6);
const int g2DepProp = moduleProperty(g2Props, "gmod.gmod1", "depProp").toInt();
@@ -1928,7 +2180,7 @@ void TestLanguage::modulePropertiesInGroups()
QCOMPARE(g21Gmod1List1, QStringList() << "gmod1_list1_proto" << "g2");
const auto &g21Gmod1List2 = moduleProperty(g21Props, "gmod.gmod1", "gmod1_list2")
.toStringList();
- QEXPECT_FAIL(0, "no re-eval when no module props set", Continue);
+ QEXPECT_FAIL(nullptr, "no re-eval when no module props set", Continue);
QCOMPARE(g21Gmod1List2, QStringList() << "grouptest" << "g2.1" << "gmod1_list2_proto");
const int g21P0 = moduleProperty(g21Props, "gmod.gmod1", "p0").toInt();
QCOMPARE(g21P0, 6);
@@ -1938,7 +2190,7 @@ void TestLanguage::modulePropertiesInGroups()
QCOMPARE(g21Gmod2String, QString("g2"));
const auto &g21Gmod2List = moduleProperty(g21Props, "gmod2", "gmod2_list")
.toStringList();
- QEXPECT_FAIL(0, "no re-eval when no module props set", Continue);
+ QEXPECT_FAIL(nullptr, "no re-eval when no module props set", Continue);
QCOMPARE(g21Gmod2List, QStringList() << "g2" << "commonName_in_gmod1"
<< "g2.1_gmod4_g2.1_gmod3" << "g2.1_gmod3" << "gmod2_list_proto");
@@ -1955,11 +2207,11 @@ void TestLanguage::modulePropertiesInGroups()
QCOMPARE(g211DepProp, 2);
const auto &g211Gmod2String
= moduleProperty(g211Props, "gmod2", "gmod2_string").toString();
- QEXPECT_FAIL(0, "re-eval not triggered", Continue);
+ QEXPECT_FAIL(nullptr, "re-eval not triggered", Continue);
QCOMPARE(g211Gmod2String, QString("g2.1.1"));
const auto &g211Gmod2List = moduleProperty(g211Props, "gmod2", "gmod2_list")
.toStringList();
- QEXPECT_FAIL(0, "re-eval not triggered", Continue);
+ QEXPECT_FAIL(nullptr, "re-eval not triggered", Continue);
QCOMPARE(g211Gmod2List, QStringList() << "g2.1.1" << "commonName_in_gmod1"
<< "g2.1.1_gmod4_g2.1.1_gmod3" << "g2.1.1_gmod3" << "gmod2_list_proto");
@@ -1967,7 +2219,7 @@ void TestLanguage::modulePropertiesInGroups()
QVERIFY(!!product);
g1.reset();
g11.reset();
- for (const GroupConstPtr &g : product->groups) {
+ for (const GroupPtr &g : product->groups) {
if (g->name == "g1")
g1= g;
else if (g->name == "g1.1")
@@ -1994,17 +2246,14 @@ void TestLanguage::modulePropertyOverridesPerProduct()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setOverriddenValues({
+ defaultParameters.setOverriddenValues({
std::make_pair("modules.dummy.rpaths", QStringList({"/usr/lib"})),
std::make_pair("modules.dummy.someString", "m"),
std::make_pair("products.b.dummy.someString", "b"),
std::make_pair("products.c.dummy.someString", "c"),
std::make_pair("products.c.dummy.rpaths", QStringList({"/home", "/tmp"}))
});
- params.setProjectFilePath(
- testProject("module-property-overrides-per-product.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(params);
+ resolveProject("module-property-overrides-per-product.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 3);
@@ -2037,8 +2286,7 @@ void TestLanguage::modulePropertyOverridesPerProduct()
QCOMPARE(listPropertyValue(a), productPropertyValue(a));
QCOMPARE(listPropertyValue(b), productPropertyValue(b));
QCOMPARE(listPropertyValue(c), productPropertyValue(c));
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -2050,7 +2298,7 @@ void TestLanguage::moduleScope()
bool exceptionCaught = false;
try {
defaultParameters.setProjectFilePath(testProject("modulescope.qbs"));
- TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject();
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
@@ -2070,13 +2318,30 @@ void TestLanguage::moduleScope()
QCOMPARE(intModuleValue("f"), 2); // overridden
QCOMPARE(intModuleValue("g"), 156); // overridden, dependent on product properties
QCOMPARE(intModuleValue("h"), 158); // overridden, base dependent on product properties
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
QCOMPARE(exceptionCaught, false);
+}
+void TestLanguage::moduleWithProductDependency()
+{
+ bool exceptionCaught = false;
+ try {
+ defaultParameters.setProjectFilePath(testProject("module-depends-on-product.qbs"));
+ resolveProject();
+ QVERIFY(project);
+ QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
+ QCOMPARE(products.size(), 2);
+ ResolvedProductPtr product = products.value("p1");
+ QVERIFY(product);
+ QCOMPARE(int(product->dependencies.size()), 1);
+ } catch (const ErrorInfo &e) {
+ exceptionCaught = true;
+ qDebug() << e.toString();
+ }
+ QCOMPARE(exceptionCaught, false);
}
void TestLanguage::modules_data()
@@ -2135,9 +2400,7 @@ void TestLanguage::multiplexedExports()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("multiplexed-exports.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(params);
+ resolveProject("multiplexed-exports.qbs");
QVERIFY(!!project);
const auto products = project->allProducts();
QCOMPARE(products.size(), size_t(4));
@@ -2171,11 +2434,9 @@ void TestLanguage::multiplexingByProfile()
{
QFETCH(QString, projectFileName);
QFETCH(bool, successExpected);
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testDataDir() + "/multiplexing-by-profile/" + projectFileName);
try {
- params.setDryRun(true);
- const TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setDryRun(true);
+ resolveProject(qPrintable("/multiplexing-by-profile/" + projectFileName));
QVERIFY(successExpected);
QVERIFY(!!project);
} catch (const ErrorInfo &e) {
@@ -2199,11 +2460,9 @@ void TestLanguage::nonApplicableModulePropertyInProfile()
QFETCH(QString, toolchain);
QFETCH(bool, successExpected);
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("non-applicable-module-property-in-profile.qbs"));
- params.setOverriddenValues(QVariantMap{std::make_pair("project.targetOS", targetOS),
+ defaultParameters.setOverriddenValues({std::make_pair("project.targetOS", targetOS),
std::make_pair("project.toolchain", toolchain)});
- const TopLevelProjectPtr project = loader->loadProject(params);
+ resolveProject("non-applicable-module-property-in-profile.qbs");
QVERIFY(!!project);
QVERIFY(successExpected);
} catch (const ErrorInfo &e) {
@@ -2233,8 +2492,6 @@ void TestLanguage::nonRequiredProducts()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("non-required-products.qbs"));
QFETCH(bool, subProjectEnabled);
QFETCH(bool, dependeeEnabled);
QVariantMap overriddenValues;
@@ -2242,8 +2499,8 @@ void TestLanguage::nonRequiredProducts()
overriddenValues.insert("projects.subproject.condition", false);
else if (!dependeeEnabled)
overriddenValues.insert("products.dependee.condition", false);
- params.setOverriddenValues(overriddenValues);
- const TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues(overriddenValues);
+ resolveProject("non-required-products.qbs");
QVERIFY(!!project);
const auto products = productsFromProject(project);
QCOMPARE(products.size(), 4 + !!subProjectEnabled);
@@ -2262,8 +2519,7 @@ void TestLanguage::nonRequiredProducts()
QVERIFY2(product, name);
QVERIFY2(!product->enabled, name);
}
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -2284,7 +2540,7 @@ void TestLanguage::outerInGroup()
bool exceptionCaught = false;
try {
defaultParameters.setProjectFilePath(testProject("outerInGroup.qbs"));
- TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject();
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
@@ -2305,8 +2561,7 @@ void TestLanguage::outerInGroup()
artifact = group->files.front();
installDir = artifact->properties->qbsPropertyValue("installDir");
QCOMPARE(installDir.toString(), QString("/somewhere/else"));
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -2319,16 +2574,14 @@ void TestLanguage::overriddenPropertiesAndPrototypes()
try {
QFETCH(QString, osName);
QFETCH(QString, backendName);
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("overridden-properties-and-prototypes.qbs"));
- params.setOverriddenValues({std::make_pair("modules.qbs.targetPlatform", osName)});
- TopLevelProjectConstPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues({std::make_pair("modules.qbs.targetPlatform",
+ osName)});
+ resolveProject("overridden-properties-and-prototypes.qbs");
QVERIFY(!!project);
QCOMPARE(project->products.size(), size_t(1));
QCOMPARE(project->products.front()->moduleProperties->moduleProperty(
"multiple_backends", "prop").toString(), backendName);
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -2347,11 +2600,9 @@ void TestLanguage::overriddenVariantProperty()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
const QVariantMap objectValue{std::make_pair("x", 1), std::make_pair("y", 2)};
- params.setOverriddenValues({std::make_pair("products.p.myObject", objectValue)});
- params.setProjectFilePath(testProject("overridden-variant-property.qbs"));
- TopLevelProjectConstPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues({std::make_pair("products.p.myObject", objectValue)});
+ resolveProject("overridden-variant-property.qbs");
QVERIFY(!!project);
QCOMPARE(project->products.size(), size_t(1));
QCOMPARE(project->products.front()->productProperties.value("myObject").toMap(),
@@ -2368,9 +2619,8 @@ void TestLanguage::parameterTypes()
bool exceptionCaught = false;
try {
defaultParameters.setProjectFilePath(testProject("parameter-types.qbs"));
- loader->loadProject(defaultParameters);
- }
- catch (const ErrorInfo &e) {
+ resolveProject();
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -2381,8 +2631,7 @@ void TestLanguage::pathProperties()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("pathproperties.qbs"));
- project = loader->loadProject(defaultParameters);
+ resolveProject("pathproperties.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
ResolvedProductPtr product = products.value("product1");
@@ -2408,6 +2657,35 @@ void TestLanguage::pathProperties()
QCOMPARE(exceptionCaught, false);
}
+void TestLanguage::probesAndMultiplexing()
+{
+ bool exceptionCaught = false;
+ try {
+ resolveProject("probes-and-multiplexing.qbs");
+ QVERIFY(project);
+ QCOMPARE(int(project->products.size()), 3);
+ QStringList architectures{"x86", "x86_64", "arm"};
+ for (const ResolvedProductPtr &product : project->products) {
+ const QString arch = product->moduleProperties->moduleProperty("qbs", "architecture")
+ .toString();
+ QVERIFY2(architectures.removeOne(arch), qPrintable(arch));
+ QCOMPARE(product->productProperties.value("archFromProbe").toString(), arch);
+ bool foundGroup = false;
+ for (const GroupPtr &group : product->groups) {
+ if (group->name == "theGroup") {
+ foundGroup = true;
+ QCOMPARE(group->properties->moduleProperty("qbs", "sysroot"), "/" + arch);
+ }
+ }
+ QVERIFY(foundGroup);
+ }
+ } catch (const ErrorInfo &e) {
+ exceptionCaught = true;
+ qDebug() << e.toString();
+ }
+ QCOMPARE(exceptionCaught, false);
+}
+
void TestLanguage::profileValuesAndOverriddenValues()
{
bool exceptionCaught = false;
@@ -2418,14 +2696,11 @@ void TestLanguage::profileValuesAndOverriddenValues()
profile.setValue("dummy.cFlags", "IN_PROFILE");
profile.setValue("dummy.cxxFlags", "IN_PROFILE");
profile.setValue("qbs.architecture", "x86");
- SetupProjectParameters parameters = defaultParameters;
- parameters.setTopLevelProfile(profile.name());
+ defaultParameters.setTopLevelProfile(profile.name());
QVariantMap overriddenValues;
overriddenValues.insert("modules.dummy.cFlags", "OVERRIDDEN");
- parameters.setOverriddenValues(overriddenValues);
- parameters.setProjectFilePath(testProject("profilevaluesandoverriddenvalues.qbs"));
- parameters.expandBuildConfiguration();
- project = loader->loadProject(parameters);
+ defaultParameters.setOverriddenValues(overriddenValues);
+ resolveProject("profilevaluesandoverriddenvalues.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
ResolvedProductPtr product = products.value("product1");
@@ -2455,7 +2730,7 @@ void TestLanguage::projectFileLookup()
try {
SetupProjectParameters params;
params.setProjectFilePath(projectFileInput);
- Loader::setupProjectFilePath(params);
+ params.finalizeProjectFilePath();
QVERIFY(!failureExpected);
QCOMPARE(params.projectFilePath(), projectFileOutput);
} catch (const ErrorInfo &) {
@@ -2469,7 +2744,7 @@ void TestLanguage::projectFileLookup_data()
QTest::addColumn<QString>("projectFileOutput");
QTest::addColumn<bool>("failureExpected");
- const QString baseDir = QLatin1String(SRCDIR) + "/testdata";
+ const QString baseDir = testDataDir();
const QString multiProjectsDir = baseDir + "/dirwithmultipleprojects";
const QString noProjectsDir = baseDir + "/dirwithnoprojects";
const QString oneProjectDir = baseDir + "/dirwithoneproject";
@@ -2486,8 +2761,7 @@ void TestLanguage::productConditions()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("productconditions.qbs"));
- TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("productconditions.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 6);
@@ -2515,8 +2789,7 @@ void TestLanguage::productConditions()
product = products.value("product_probe_condition_true");
QVERIFY(!!product);
QVERIFY(product->enabled);
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -2527,8 +2800,7 @@ void TestLanguage::productDirectories()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("productdirectories.qbs"));
- ResolvedProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("productdirectories.qbs");
QVERIFY(!!project);
QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 1);
@@ -2539,8 +2811,7 @@ void TestLanguage::productDirectories()
QCOMPARE(config.value(QStringLiteral("buildDirectory")).toString(),
product->buildDirectory());
QCOMPARE(config.value(QStringLiteral("sourceDirectory")).toString(), testDataDir());
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
exceptionCaught = true;
qDebug() << e.toString();
}
@@ -2686,8 +2957,7 @@ void TestLanguage::propertiesBlockInGroup()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("properties-block-in-group.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("properties-block-in-group.qbs");
QVERIFY(!!project);
QCOMPARE(project->allProducts().size(), size_t(1));
const ResolvedProductConstPtr product = project->allProducts().front();
@@ -2711,13 +2981,11 @@ void TestLanguage::propertiesItemInModule()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(
- testProject("properties-item-in-module.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("properties-item-in-module.qbs");
QVERIFY(!!project);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 2);
- for (const ResolvedProductConstPtr &p : products) {
+ for (const ResolvedProductPtr &p : products) {
QCOMPARE(p->moduleProperties->moduleProperty("dummy", "productName").toString(),
p->name);
}
@@ -2732,16 +3000,14 @@ void TestLanguage::propertyAssignmentInExportedGroup()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(
- testProject("property-assignment-in-exported-group.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("property-assignment-in-exported-group.qbs");
QVERIFY(!!project);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 2);
- for (const ResolvedProductConstPtr &p : products) {
+ for (const ResolvedProductPtr &p : products) {
QCOMPARE(p->moduleProperties->moduleProperty("dummy", "someString").toString(),
QString());
- for (const GroupConstPtr &g : p->groups) {
+ for (const GroupPtr &g : p->groups) {
const QString propValue
= g->properties->moduleProperty("dummy", "someString").toString();
if (g->name == "exported_group")
@@ -2761,8 +3027,7 @@ void TestLanguage::qbs1275()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(testProject("qbs1275.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("qbs1275.qbs");
QVERIFY(!!project);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.count(), 5);
@@ -2777,10 +3042,9 @@ void TestLanguage::qbsPropertiesInProjectCondition()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(
- testProject("qbs-properties-in-project-condition.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("qbs-properties-in-project-condition.qbs");
QVERIFY(!!project);
+ QVERIFY(!project->enabled);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 0);
} catch (const ErrorInfo &e) {
@@ -2794,16 +3058,14 @@ void TestLanguage::qbsPropertyConvenienceOverride()
{
bool exceptionCaught = false;
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("qbs-property-convenience-override.qbs"));
- params.setOverriddenValues({std::make_pair("qbs.installPrefix", "/opt")});
- TopLevelProjectConstPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues({std::make_pair("qbs.installPrefix", "/opt")});
+ resolveProject("qbs-property-convenience-override.qbs");
QVERIFY(!!project);
QCOMPARE(project->products.size(), size_t(1));
QCOMPARE(project->products.front()->moduleProperties->qbsPropertyValue("installPrefix")
.toString(), QString("/opt"));
- }
- catch (const ErrorInfo &e) {
+ } catch (const ErrorInfo &e) {
+ exceptionCaught = true;
qDebug() << e.toString();
}
QCOMPARE(exceptionCaught, false);
@@ -2814,11 +3076,9 @@ void TestLanguage::relaxedErrorMode()
m_logSink->setLogLevel(LoggerMinLevel);
QFETCH(bool, strictMode);
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("relaxed-error-mode/relaxed-error-mode.qbs"));
- params.setProductErrorMode(strictMode ? ErrorHandlingMode::Strict
- : ErrorHandlingMode::Relaxed);
- const TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setProductErrorMode(strictMode ? ErrorHandlingMode::Strict
+ : ErrorHandlingMode::Relaxed);
+ resolveProject("relaxed-error-mode/relaxed-error-mode.qbs");
QVERIFY(!strictMode);
const auto productMap = productsFromProject(project);
const ResolvedProductConstPtr brokenProduct = productMap.value("broken");
@@ -2841,7 +3101,7 @@ void TestLanguage::relaxedErrorMode()
QVERIFY(missingFile->enabled);
QCOMPARE(missingFile->groups.size(), size_t(1));
QVERIFY(missingFile->groups.front()->enabled);
- QCOMPARE(missingFile->groups.front()->allFiles().size(), size_t(2));
+ QCOMPARE(missingFile->groups.front()->files.size(), size_t(2));
const ResolvedProductConstPtr fine = productMap.value("fine");
QVERIFY(fine->enabled);
QCOMPARE(fine->allFiles().size(), size_t(1));
@@ -2863,10 +3123,7 @@ void TestLanguage::requiredAndNonRequiredDependencies()
QFETCH(QString, projectFile);
QFETCH(bool, exceptionExpected);
try {
- SetupProjectParameters params = defaultParameters;
- const QString projectFilePath = "required-and-nonrequired-dependencies/" + projectFile;
- params.setProjectFilePath(testProject(projectFilePath.toLocal8Bit()));
- const TopLevelProjectConstPtr project = loader->loadProject(params);
+ resolveProject(qPrintable("required-and-nonrequired-dependencies/" + projectFile));
QVERIFY(!!project);
QVERIFY(!exceptionExpected);
} catch (const ErrorInfo &e) {
@@ -2893,10 +3150,7 @@ void TestLanguage::requiredAndNonRequiredDependencies_data()
void TestLanguage::suppressedAndNonSuppressedErrors()
{
try {
- SetupProjectParameters params = defaultParameters;
- const QString projectFilePath = "suppressed-and-non-suppressed-errors.qbs";
- params.setProjectFilePath(testProject(projectFilePath.toLocal8Bit()));
- const TopLevelProjectConstPtr project = loader->loadProject(params);
+ resolveProject("suppressed-and-non-suppressed-errors.qbs");
QFAIL("failure expected");
} catch (const ErrorInfo &e) {
QVERIFY2(e.toString().contains("easter bunny"), qPrintable(e.toString()));
@@ -2908,12 +3162,10 @@ void TestLanguage::throwingProbe()
{
QFETCH(bool, enableProbe);
try {
- SetupProjectParameters params = defaultParameters;
- params.setProjectFilePath(testProject("throwing-probe.qbs"));
QVariantMap properties;
properties.insert(QStringLiteral("products.theProduct.enableProbe"), enableProbe);
- params.setOverriddenValues(properties);
- const TopLevelProjectPtr project = loader->loadProject(params);
+ defaultParameters.setOverriddenValues(properties);
+ resolveProject("throwing-probe.qbs");
QVERIFY(!!project);
QVERIFY(!enableProbe);
} catch (const ErrorInfo &e) {
@@ -2955,9 +3207,7 @@ void TestLanguage::recursiveProductDependencies()
{
bool exceptionCaught = false;
try {
- defaultParameters.setProjectFilePath(
- testProject("recursive-dependencies/recursive-dependencies.qbs"));
- const TopLevelProjectPtr project = loader->loadProject(defaultParameters);
+ resolveProject("recursive-dependencies/recursive-dependencies.qbs");
QVERIFY(!!project);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
QCOMPARE(products.size(), 4);
@@ -3014,6 +3264,19 @@ void TestLanguage::fileTags()
QCOMPARE(fileTags, expectedFileTags);
}
+void TestLanguage::useInternalProfile()
+{
+ const QString profile(QStringLiteral("theprofile"));
+ defaultParameters.setTopLevelProfile(profile);
+ resolveProject("use-internal-profile.qbs");
+ QVERIFY(!!project);
+ QCOMPARE(project->profile(), profile);
+ QCOMPARE(project->products.size(), size_t(1));
+ const ResolvedProductConstPtr product = project->products[0];
+ QCOMPARE(product->profile(), profile);
+ QCOMPARE(product->moduleProperties->moduleProperty("dummy", "defines").toString(), profile);
+}
+
void TestLanguage::wildcards_data()
{
QTest::addColumn<bool>("useGroup");
@@ -3182,8 +3445,8 @@ void TestLanguage::wildcards()
QFile projectFile(projectFilePath);
QVERIFY(projectFile.open(QIODevice::WriteOnly));
QTextStream s(&projectFile);
- s << "import qbs.base 1.0" << endl << endl
- << "Application {" << endl
+ using Qt::endl;
+ s << "Application {" << endl
<< " name: \"MyProduct\"" << endl;
if (useGroup) {
s << " Group {" << endl
@@ -3201,7 +3464,7 @@ void TestLanguage::wildcards()
}
// create files
- for (QString filePath : qAsConst(filesToCreate)) {
+ for (QString filePath : std::as_const(filesToCreate)) {
filePath.prepend(m_wildcardsTestDirPath + '/');
QFileInfo fi(filePath);
if (!QDir(fi.path()).exists())
@@ -3215,7 +3478,7 @@ void TestLanguage::wildcards()
ResolvedProductPtr product;
try {
defaultParameters.setProjectFilePath(projectFilePath);
- project = loader->loadProject(defaultParameters);
+ resolveProject();
QVERIFY(!!project);
const QHash<QString, ResolvedProductPtr> products = productsFromProject(project);
product = products.value("MyProduct");
@@ -3234,10 +3497,10 @@ void TestLanguage::wildcards()
group = product->groups.front();
}
QVERIFY(!!group);
- QCOMPARE(group->files.size(), size_t(0));
+ QCOMPARE(group->files.size(), expected.size()); // we assume all files are wildcards
QVERIFY(!!group->wildcards);
QStringList actualFilePaths;
- for (const SourceArtifactConstPtr &artifact : group->wildcards->files) {
+ for (const SourceArtifactPtr &artifact : group->files) {
QString str = artifact->absoluteFilePath;
int idx = str.indexOf(m_wildcardsTestDirPath);
if (idx != -1)
@@ -3261,4 +3524,3 @@ int main(int argc, char *argv[])
TestLanguage tl(ConsoleLogger::instance().logSink(), s.get());
return QTest::qExec(&tl, argc, argv);
}
-
diff --git a/tests/auto/language/tst_language.h b/tests/auto/language/tst_language.h
index 3fe6d8f2a..870b7d1f8 100644
--- a/tests/auto/language/tst_language.h
+++ b/tests/auto/language/tst_language.h
@@ -41,10 +41,12 @@
#define TST_LANGUAGE_H
#include <language/forward_decls.h>
-#include <language/loader.h>
+#include <language/scriptengine.h>
#include <logging/ilogsink.h>
+#include <logging/logger.h>
#include <tools/setupprojectparameters.h>
+#include <QtCore/qrandom.h>
#include <QtCore/qtemporarydir.h>
#include <QtTest/qtest.h>
@@ -55,27 +57,9 @@ public:
TestLanguage(qbs::ILogSink *logSink, qbs::Settings *settings);
~TestLanguage();
-private:
- qbs::ILogSink *m_logSink;
- qbs::Settings * const m_settings;
- qbs::Internal::Logger m_logger;
- qbs::Internal::ScriptEngine *m_engine;
- qbs::Internal::Loader *loader;
- qbs::Internal::TopLevelProjectPtr project;
- qbs::SetupProjectParameters defaultParameters;
- const QString m_wildcardsTestDirPath;
-
- QHash<QString, qbs::Internal::ResolvedProductPtr> productsFromProject(
- qbs::Internal::ResolvedProjectPtr project);
- qbs::Internal::ResolvedModuleConstPtr findModuleByName(
- qbs::Internal::ResolvedProductPtr product, const QString &name);
- QVariant productPropertyValue(qbs::Internal::ResolvedProductPtr product, QString propertyName);
- void handleInitCleanupDataTags(const char *projectFileName, bool *handled);
-
private slots:
void init();
void initTestCase();
- void cleanupTestCase();
void additionalProductTypes();
void baseProperty();
@@ -87,6 +71,7 @@ private slots:
void chainedProbes();
void canonicalArchitecture();
void conditionalDepends();
+ void convertStringList();
void delayedError();
void delayedError_data();
void dependencyOnAllProfiles();
@@ -94,6 +79,8 @@ private slots:
void disabledSubProject();
void dottedNames_data();
void dottedNames();
+ void duplicateMultiplexValues_data();
+ void duplicateMultiplexValues();
void emptyJsFile();
void enumerateProjectProperties();
void evalErrorInNonPresentModule_data();
@@ -123,12 +110,19 @@ private slots:
void invalidBindingInDisabledItem();
void invalidOverrides();
void invalidOverrides_data();
+ void invalidPropOnNonRequiredModule_data();
+ void invalidPropOnNonRequiredModule();
void itemPrototype();
void itemScope();
void jsExtensions();
void jsImportUsedInMultipleScopes_data();
void jsImportUsedInMultipleScopes();
+ void localProfileAsTopLevelProfile();
void moduleMergingVariantValues();
+ void moduleNameCollisions_data();
+ void moduleNameCollisions();
+ void moduleParameters_data();
+ void moduleParameters();
void modulePrioritizationBySearchPath_data();
void modulePrioritizationBySearchPath();
void moduleProperties_data();
@@ -136,6 +130,7 @@ private slots:
void modulePropertiesInGroups();
void modulePropertyOverridesPerProduct();
void moduleScope();
+ void moduleWithProductDependency();
void modules_data();
void modules();
void multiplexedExports();
@@ -151,6 +146,7 @@ private slots:
void overriddenVariantProperty();
void parameterTypes();
void pathProperties();
+ void probesAndMultiplexing();
void productConditions();
void productDirectories();
void profileValuesAndOverriddenValues();
@@ -176,12 +172,31 @@ private slots:
void qualifiedId();
void recursiveProductDependencies();
void rfc1034Identifier();
+ void throwThings_data();
+ void throwThings();
+ void useInternalProfile();
void versionCompare();
void wildcards_data();
void wildcards();
private:
+ QHash<QString, qbs::Internal::ResolvedProductPtr> productsFromProject(
+ qbs::Internal::ResolvedProjectPtr project);
+ qbs::Internal::ResolvedModuleConstPtr findModuleByName(
+ qbs::Internal::ResolvedProductPtr product, const QString &name);
+ QVariant productPropertyValue(qbs::Internal::ResolvedProductPtr product, QString propertyName);
+ void handleInitCleanupDataTags(const char *projectFileName, bool *handled);
+ qbs::Internal::TopLevelProjectPtr resolveProject(const char *relProjectFilePath = nullptr);
+
+ qbs::ILogSink * const m_logSink;
+ qbs::Settings * const m_settings;
+ qbs::Internal::Logger m_logger;
+ std::unique_ptr<qbs::Internal::ScriptEngine> m_engine;
+ qbs::Internal::TopLevelProjectPtr project;
+ qbs::SetupProjectParameters defaultParameters;
+ const QString m_wildcardsTestDirPath;
QTemporaryDir m_tempDir;
+ QRandomGenerator m_rand;
};
#endif // TST_LANGUAGE_H
diff --git a/tests/auto/pkgconfig/CMakeLists.txt b/tests/auto/pkgconfig/CMakeLists.txt
new file mode 100644
index 000000000..74a13a8ab
--- /dev/null
+++ b/tests/auto/pkgconfig/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_qbs_test(pkgconfig
+ SOURCES
+ tst_pkgconfig.cpp
+ tst_pkgconfig.h
+ DEPENDS
+ qbspkgconfig
+ qbsquickjsheaders
+ )
diff --git a/tests/auto/pkgconfig/pkgconfig.qbs b/tests/auto/pkgconfig/pkgconfig.qbs
new file mode 100644
index 000000000..d42a5233b
--- /dev/null
+++ b/tests/auto/pkgconfig/pkgconfig.qbs
@@ -0,0 +1,19 @@
+import qbs
+import qbs.Utilities
+
+QbsUnittest {
+ Depends { name: "qbspkgconfig" }
+ condition: qbsbuildconfig.enableUnitTests
+ testName: "pkgconfig"
+ files: ["../shared.h", "tst_pkgconfig.h", "tst_pkgconfig.cpp"]
+ cpp.defines: base.concat([
+ "SRCDIR=" + Utilities.cStringQuote(path),
+ ])
+
+ Group {
+ name: "testdata"
+ prefix: "testdata/"
+ files: ["**/*"]
+ fileTags: []
+ }
+}
diff --git a/tests/auto/pkgconfig/testdata/base.name.json b/tests/auto/pkgconfig/testdata/base.name.json
new file mode 100644
index 000000000..a10e905ac
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/base.name.json
@@ -0,0 +1,20 @@
+{
+ "Name": "Base Name test",
+ "Description": "Checks correct baseName detection",
+ "Version": "1.0.0",
+ "Vars": {
+ "prefix": "/usr",
+ "exec_prefix": "/usr",
+ "libdir": "/usr/lib",
+ "includedir": "/usr/include"
+ },
+ "Libs": [
+ {"Type": "LibraryName", "Value": "simple"}
+ ],
+ "LibsPrivate": [
+ {"Type": "LibraryName", "Value": "m"}
+ ],
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "/usr/include"}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/base.name.pc b/tests/auto/pkgconfig/testdata/base.name.pc
new file mode 100644
index 000000000..2bb3e275e
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/base.name.pc
@@ -0,0 +1,12 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: Base Name test
+Description: Checks correct baseName detection
+Version: 1.0.0
+Requires:
+Libs: -lsimple
+Libs.private: -lm
+Cflags: -I${includedir}
diff --git a/tests/auto/pkgconfig/testdata/empty-variable.json b/tests/auto/pkgconfig/testdata/empty-variable.json
new file mode 100644
index 000000000..b96689979
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/empty-variable.json
@@ -0,0 +1,21 @@
+{
+ "Name": "Empty Variable test",
+ "Description": "Checks that empty variables are handled correcty",
+ "Version": "1.0.0",
+ "Vars": {
+ "rootprefix": "",
+ "prefix": "/usr",
+ "exec_prefix": "//usr",
+ "libdir": "//usr/lib",
+ "includedir": "//usr/include"
+ },
+ "Libs": [
+ {"Type": "LibraryName", "Value": "simple"}
+ ],
+ "LibsPrivate": [
+ {"Type": "LibraryName", "Value": "m"}
+ ],
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "//usr/include"}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/empty-variable.pc b/tests/auto/pkgconfig/testdata/empty-variable.pc
new file mode 100644
index 000000000..581382b7e
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/empty-variable.pc
@@ -0,0 +1,13 @@
+rootprefix=
+prefix=/usr
+exec_prefix=${rootprefix}/${prefix}
+libdir=${exec_prefix}/lib
+includedir=${rootprefix}/${prefix}/include
+
+Name: Empty Variable test
+Description: Checks that empty variables are handled correcty
+Version: 1.0.0
+Requires:
+Libs: -lsimple
+Libs.private: -lm
+Cflags: -I${includedir}
diff --git a/tests/auto/pkgconfig/testdata/lib/pkgconfig/prefix.pc b/tests/auto/pkgconfig/testdata/lib/pkgconfig/prefix.pc
new file mode 100644
index 000000000..64b980803
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/lib/pkgconfig/prefix.pc
@@ -0,0 +1,13 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=/usr/include
+usrdir=/usrdir
+
+Name: Prefix test
+Description: This tests prefix auto detection
+Version: 1.0.0
+Requires:
+Libs: -lprefix
+Libs.private: -lm
+Cflags: -I${includedir}
diff --git a/tests/auto/pkgconfig/testdata/non-l-required.json b/tests/auto/pkgconfig/testdata/non-l-required.json
new file mode 100644
index 000000000..d2dd90f06
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/non-l-required.json
@@ -0,0 +1,12 @@
+{
+ "Name": "Non-l flags required test package",
+ "Description": "Test package for checking order of non-L Libs & Cflags",
+ "Version": "1.0.0",
+ "Libs": [
+ {"Type": "StaticLibraryName", "Value": "/non-l-required.a"},
+ {"Type": "LinkerFlag", "Value": "-pthread"}
+ ],
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "/non-l-required/include"}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/non-l-required.pc b/tests/auto/pkgconfig/testdata/non-l-required.pc
new file mode 100644
index 000000000..7e398e2e1
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/non-l-required.pc
@@ -0,0 +1,5 @@
+Name: Non-l flags required test package
+Description: Test package for checking order of non-L Libs & Cflags
+Version: 1.0.0
+Libs: /non-l-required.a -pthread
+Cflags: -I/non-l-required/include
diff --git a/tests/auto/pkgconfig/testdata/private-dep.pc b/tests/auto/pkgconfig/testdata/private-dep.pc
new file mode 100644
index 000000000..cb401391d
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/private-dep.pc
@@ -0,0 +1,6 @@
+Name: Requires test package
+Description: Dummy pkgconfig test package for testing Requires/Requires.private
+Version: 1.0.0
+Libs: -L/private-dep/lib -lprivate-dep
+Cflags: -I/private-dep/include
+
diff --git a/tests/auto/pkgconfig/testdata/public-dep.pc b/tests/auto/pkgconfig/testdata/public-dep.pc
new file mode 100644
index 000000000..e450e46f1
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/public-dep.pc
@@ -0,0 +1,6 @@
+Name: Requires test package
+Description: Dummy pkgconfig test package for testing Requires/Requires.private
+Version: 1.0.0
+Requires.private:
+Libs: -L/public-dep/lib -lpublic-dep
+Cflags: -I/public-dep/include
diff --git a/tests/auto/pkgconfig/testdata/requires-test.json b/tests/auto/pkgconfig/testdata/requires-test.json
new file mode 100644
index 000000000..32acf4b91
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/requires-test.json
@@ -0,0 +1,18 @@
+{
+ "Name": "Requires test package",
+ "Description": "Dummy pkgconfig test package for testing Requires/Requires.private",
+ "Version": "1.0.0",
+ "Libs": [
+ {"Type": "LibraryPath", "Value": "/requires-test/lib"},
+ {"Type": "LibraryName", "Value": "requires-test"}
+ ],
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "/requires-test/include"}
+ ],
+ "Requires": [
+ {"Comparison": "GreaterThanEqual", "Name": "public-dep", "Version": "1"}
+ ],
+ "RequiresPrivate": [
+ {"Comparison": "GreaterThanEqual", "Name": "private-dep", "Version": "1"}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/requires-test.pc b/tests/auto/pkgconfig/testdata/requires-test.pc
new file mode 100644
index 000000000..e483db2db
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/requires-test.pc
@@ -0,0 +1,8 @@
+Name: Requires test package
+Description: Dummy pkgconfig test package for testing Requires/Requires.private
+Version: 1.0.0
+Requires: public-dep >= 1
+Requires.private: private-dep >= 1
+Libs: -L/requires-test/lib -lrequires-test
+Cflags: -I/requires-test/include
+
diff --git a/tests/auto/pkgconfig/testdata/simple.json b/tests/auto/pkgconfig/testdata/simple.json
new file mode 100644
index 000000000..d58556e74
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/simple.json
@@ -0,0 +1,20 @@
+{
+ "Name": "Simple test",
+ "Description": "Dummy pkgconfig test package for testing pkgconfig",
+ "Version": "1.0.0",
+ "Vars": {
+ "prefix": "/usr",
+ "exec_prefix": "/usr",
+ "libdir": "/usr/lib",
+ "includedir": "/usr/include"
+ },
+ "Libs": [
+ {"Type": "LibraryName", "Value": "simple"}
+ ],
+ "LibsPrivate": [
+ {"Type": "LibraryName", "Value": "m"}
+ ],
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "/usr/include"}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/simple.pc b/tests/auto/pkgconfig/testdata/simple.pc
new file mode 100644
index 000000000..2daa0350f
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/simple.pc
@@ -0,0 +1,12 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: Simple test
+Description: Dummy pkgconfig test package for testing pkgconfig
+Version: 1.0.0
+Requires:
+Libs: -lsimple
+Libs.private: -lm
+Cflags: -I${includedir}
diff --git a/tests/auto/pkgconfig/testdata/special-flags.json b/tests/auto/pkgconfig/testdata/special-flags.json
new file mode 100644
index 000000000..1949820a6
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/special-flags.json
@@ -0,0 +1,30 @@
+{
+ "Name": "Special flags test",
+ "Description": "Dummy pkgconfig test package for testing pkgconfig",
+ "Version": "1.0.0",
+ "Vars": {
+ "prefix": "/usr",
+ "exec_prefix": "/usr",
+ "libdir": "/usr/lib",
+ "includedir": "/usr/include"
+ },
+ "Libs": [
+ {"Type": "LibraryPath", "Value": "/foo"},
+ {"Type": "Framework", "Value": "Foo"},
+ {"Type": "LibraryName", "Value": "simple"},
+ {"Type": "LibraryPath", "Value": "/bar"},
+ {"Type": "Framework", "Value": "Bar"},
+ {"Type": "LinkerFlag", "Value": "-Wl,-framework"},
+ {"Type": "LinkerFlag", "Value": "-Wl,Baz"}
+ ],
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "/foo"},
+ {"Type": "CompilerFlag", "Value": "-g"},
+ {"Type": "SystemIncludePath", "Value": "/system1"},
+ {"Type": "DirAfterIncludePath", "Value": "/after1"},
+ {"Type": "CompilerFlag", "Value": "-ffoo"},
+ {"Type": "IncludePath", "Value": "/bar"},
+ {"Type": "DirAfterIncludePath", "Value": "/after2"},
+ {"Type": "SystemIncludePath", "Value": "/system2"}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/special-flags.pc b/tests/auto/pkgconfig/testdata/special-flags.pc
new file mode 100644
index 000000000..0bdaeb1b0
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/special-flags.pc
@@ -0,0 +1,11 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: Special flags test
+Description: Dummy pkgconfig test package for testing pkgconfig
+Version: 1.0.0
+Requires:
+Libs: -L/foo -framework Foo -lsimple -L/bar -framework Bar -Wl,-framework -Wl,Baz
+Cflags: -I/foo -g -isystem /system1 -idirafter /after1 -ffoo -I/bar -idirafter /after2 -isystem /system2
diff --git a/tests/auto/pkgconfig/testdata/sysroot.json b/tests/auto/pkgconfig/testdata/sysroot.json
new file mode 100644
index 000000000..7e8b3f6bb
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/sysroot.json
@@ -0,0 +1,21 @@
+{
+ "Name": "Test for sysroot",
+ "Description": "Test package for testing sysroot",
+ "Version": "1.0.0",
+ "Vars": {
+ "prefix": "/opt",
+ "exec_prefix": "/opt",
+ "libdir": "/opt/lib",
+ "includedir": "/opt/include",
+ "sysroot": "/newroot"
+ },
+ "Libs": [
+ {"Type": "LibraryPath", "Value": "/newroot/opt/lib"},
+ {"Type": "LibraryName", "Value": "system"}
+ ],
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "/newroot/opt/include"},
+ {"Type": "DirAfterIncludePath", "Value": "/newroot/opt/include/after"},
+ {"Type": "SystemIncludePath", "Value": "/newroot/opt/include/system"}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/sysroot.pc b/tests/auto/pkgconfig/testdata/sysroot.pc
new file mode 100644
index 000000000..d2f78987f
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/sysroot.pc
@@ -0,0 +1,12 @@
+prefix=/opt
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+sysroot=${pc_sysrootdir}
+
+Name: Test for sysroot
+Description: Test package for testing sysroot
+Version: 1.0.0
+Requires:
+Libs: -L${libdir} -lsystem
+Cflags: -I${includedir} -idirafter ${includedir}/after -isystem ${includedir}/system
diff --git a/tests/auto/pkgconfig/testdata/system.json b/tests/auto/pkgconfig/testdata/system.json
new file mode 100644
index 000000000..89007e7ec
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/system.json
@@ -0,0 +1,17 @@
+{
+ "Name": "System library",
+ "Description": "Test package",
+ "Version": "1.0.0",
+ "Vars": {
+ "prefix": "/usr",
+ "exec_prefix": "/usr",
+ "libdir": "/usr/lib",
+ "includedir": "/usr/include"
+ },
+ "Libs": [
+ {"Type": "LibraryName", "Value": "system"}
+ ],
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "/usr/include"}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/system.pc b/tests/auto/pkgconfig/testdata/system.pc
new file mode 100644
index 000000000..2cef2ed9b
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/system.pc
@@ -0,0 +1,10 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: System library
+Description: Test package
+Version: 1.0.0
+Libs: -L${libdir} -lsystem
+Cflags: -I${includedir}
diff --git a/tests/auto/pkgconfig/testdata/tilde.json b/tests/auto/pkgconfig/testdata/tilde.json
new file mode 100644
index 000000000..01ea5d050
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/tilde.json
@@ -0,0 +1,11 @@
+{
+ "Name": "tilde",
+ "Description": "tilde test module",
+ "Version": "1.0",
+ "Libs": [
+ {"Type": "LibraryPath", "Value": "~"}
+ ],
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "~"}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/tilde.pc b/tests/auto/pkgconfig/testdata/tilde.pc
new file mode 100644
index 000000000..c3babc120
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/tilde.pc
@@ -0,0 +1,5 @@
+Name: tilde
+Description: tilde test module
+Version: 1.0
+Libs: -L~
+Cflags: -I~
diff --git a/tests/auto/pkgconfig/testdata/variables.json b/tests/auto/pkgconfig/testdata/variables.json
new file mode 100644
index 000000000..7565b6804
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/variables.json
@@ -0,0 +1,17 @@
+{
+ "Name": "Complex variables",
+ "Description": "Test complex variable output",
+ "Version": "1.0",
+ "Vars": {
+ "prefix": "/local",
+ "exec_prefix": "/local",
+ "libdir": "/local/lib",
+ "includedir": "\"/local/include\"",
+ "cppflags": "-I\"/local/include\"/foo -DFOO=\\\"/bar\\\""
+ },
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "/local/include"},
+ {"Type": "IncludePath", "Value": "/local/include/foo"},
+ {"Type": "Define", "Value": "FOO=\"/bar\""}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/variables.pc b/tests/auto/pkgconfig/testdata/variables.pc
new file mode 100644
index 000000000..b27ab78e1
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/variables.pc
@@ -0,0 +1,11 @@
+prefix=/local
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir="${prefix}/include"
+cppflags=-I${includedir}/foo \
+ -DFOO=\"/bar\"
+
+Name: Complex variables
+Description: Test complex variable output
+Version: 1.0
+Cflags: -I${includedir} ${cppflags}
diff --git a/tests/auto/pkgconfig/testdata/whitespace.json b/tests/auto/pkgconfig/testdata/whitespace.json
new file mode 100644
index 000000000..dcfa3ece3
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/whitespace.json
@@ -0,0 +1,24 @@
+{
+ "Name": "Whitespace test",
+ "Description": "Dummy pkgconfig test package for testing pkgconfig",
+ "Version": "1.0.0",
+ "Vars": {
+ "prefix": "/usr",
+ "exec_prefix": "/usr",
+ "libdir": "\"/usr/white space/lib\"",
+ "includedir": "\"/usr/white space/include\""
+ },
+ "Libs": [
+ {"Type": "LibraryPath", "Value": "/usr/white space/lib"},
+ {"Type": "LibraryName", "Value": "foo bar"},
+ {"Type": "LibraryName", "Value": "bar baz"},
+ {"Type": "LinkerFlag", "Value": "-r:foo"}
+ ],
+ "Cflags": [
+ {"Type": "IncludePath", "Value": "/usr/white space/include"},
+ {"Type": "IncludePath", "Value": "$(top_builddir)"},
+ {"Type": "IncludePath", "Value": "include dir"},
+ {"Type": "IncludePath", "Value": "other include dir"},
+ {"Type": "Define", "Value": "lala=misc"}
+ ]
+}
diff --git a/tests/auto/pkgconfig/testdata/whitespace.pc b/tests/auto/pkgconfig/testdata/whitespace.pc
new file mode 100644
index 000000000..693bbc4d0
--- /dev/null
+++ b/tests/auto/pkgconfig/testdata/whitespace.pc
@@ -0,0 +1,11 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir="${exec_prefix}/white space/lib"
+includedir="${prefix}/white space/include"
+
+Name: Whitespace test
+Description: Dummy pkgconfig test package for testing pkgconfig
+Version: 1.0.0
+Requires:
+Libs: -L${libdir} -lfoo\ bar "-lbar baz" -r:foo
+Cflags: -I${includedir} -I$(top_builddir) -Iinclude\ dir "-Iother include dir" -Dlala=misc
diff --git a/tests/auto/pkgconfig/tst_pkgconfig.cpp b/tests/auto/pkgconfig/tst_pkgconfig.cpp
new file mode 100644
index 000000000..86d954259
--- /dev/null
+++ b/tests/auto/pkgconfig/tst_pkgconfig.cpp
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tst_pkgconfig.h"
+
+#include "../shared.h"
+
+#include <tools/fileinfo.h>
+#include <tools/hostosinfo.h>
+#include <pkgconfig.h>
+#include <pcparser.h>
+#include <jsextensions/pkgconfigjs.h>
+
+#include <QJsonArray>
+#include <QJsonDocument>
+
+using HostOsInfo = qbs::Internal::HostOsInfo;
+using PcPackage = qbs::PcPackage;
+using PkgConfig = qbs::PkgConfig;
+using Options = qbs::PkgConfig::Options;
+
+TestPkgConfig::TestPkgConfig()
+ : m_sourceDataDir(testDataSourceDir(SRCDIR "/testdata"))
+ , m_workingDataDir(testWorkDir(QStringLiteral("pkgconfig")))
+{
+}
+
+void TestPkgConfig::initTestCase()
+{
+ QString errorMessage;
+ qbs::Internal::removeDirectoryWithContents(m_workingDataDir, &errorMessage);
+ QVERIFY2(qbs::Internal::copyFileRecursion(m_sourceDataDir,
+ m_workingDataDir, false, true, &errorMessage),
+ qPrintable(errorMessage));
+}
+
+void TestPkgConfig::fileName()
+{
+ QCOMPARE(qbs::Internal::fileName(""), "");
+ QCOMPARE(qbs::Internal::fileName("file.txt"), "file.txt");
+ QCOMPARE(qbs::Internal::fileName("/home/user/file.txt"), "file.txt");
+ QCOMPARE(qbs::Internal::fileName("/"), "");
+#if defined(Q_OS_WIN)
+ QCOMPARE(qbs::Internal::fileName("c:file.txt"), "file.txt");
+ QCOMPARE(qbs::Internal::fileName("c:"), "");
+#endif
+}
+
+void TestPkgConfig::completeBaseName()
+{
+ QCOMPARE(qbs::Internal::completeBaseName(""), "");
+ QCOMPARE(qbs::Internal::completeBaseName("file.txt"), "file");
+ QCOMPARE(qbs::Internal::completeBaseName("archive.tar.gz"), "archive.tar");
+ QCOMPARE(qbs::Internal::completeBaseName("/home/user/file.txt"), "file");
+#if defined(Q_OS_WIN)
+ QCOMPARE(qbs::Internal::completeBaseName("c:file.txt"), "file");
+ QCOMPARE(qbs::Internal::completeBaseName("c:archive.tar.gz"), "archive.tar");
+ QCOMPARE(qbs::Internal::completeBaseName("c:"), "");
+#endif
+}
+
+void TestPkgConfig::parentPath()
+{
+ QCOMPARE(qbs::Internal::parentPath(""), "");
+ QCOMPARE(qbs::Internal::parentPath("file.txt"), ".");
+ QCOMPARE(qbs::Internal::parentPath("/home/user/file.txt"), "/home/user");
+ QCOMPARE(qbs::Internal::parentPath("/home/user/"), "/home/user");
+ QCOMPARE(qbs::Internal::parentPath("/home"), "/");
+ QCOMPARE(qbs::Internal::parentPath("/"), "/");
+#if defined(Q_OS_WIN)
+ QCOMPARE(qbs::Internal::parentPath("c:/folder/file.txt"), "c:/folder");
+ QCOMPARE(qbs::Internal::parentPath("c:/folder/"), "c:/folder");
+ QCOMPARE(qbs::Internal::parentPath("c:/folder"), "c:/");
+ QCOMPARE(qbs::Internal::parentPath("c:/"), "c:/");
+ QCOMPARE(qbs::Internal::parentPath("c:"), "c:");
+#endif
+}
+
+void TestPkgConfig::pkgConfig()
+{
+ QFETCH(QString, pcFileName);
+ QFETCH(QString, jsonFileName);
+ QFETCH(QVariantMap, optionsMap);
+
+ if (jsonFileName.isEmpty())
+ jsonFileName = pcFileName;
+
+ Options options = qbs::Internal::PkgConfigJs::convertOptions(
+ QProcessEnvironment::systemEnvironment(), optionsMap);
+ options.libDirs.push_back(m_workingDataDir.toStdString());
+
+ PkgConfig pkgConfig(std::move(options));
+
+ QFile jsonFile(m_workingDataDir + "/" + jsonFileName + ".json");
+ QVERIFY(jsonFile.open(QIODevice::ReadOnly));
+ QJsonParseError error{};
+ const auto json = QJsonDocument::fromJson(jsonFile.readAll(), &error).toVariant().toMap();
+ QCOMPARE(error.error, QJsonParseError::NoError);
+
+ const auto &packageOr = pkgConfig.getPackage(pcFileName.toStdString());
+ QVERIFY(packageOr.isValid());
+ const auto &package = packageOr.asPackage();
+ QCOMPARE(QString::fromStdString(package.baseFileName), pcFileName);
+ QCOMPARE(QString::fromStdString(package.name), json.value("Name").toString());
+ QCOMPARE(QString::fromStdString(package.description), json.value("Description").toString());
+ QCOMPARE(QString::fromStdString(package.version), json.value("Version").toString());
+
+ auto variables = json["Vars"].toMap();
+ variables["pcfiledir"] = QFileInfo(m_workingDataDir).absoluteFilePath();
+
+ QCOMPARE(size_t(variables.size()), package.variables.size());
+ for (const auto &[key, value]: package.variables) {
+ QCOMPARE(QString::fromStdString(value),
+ variables.value(QString::fromStdString(key)).toString());
+ }
+
+ const auto jsonLibs = json.value("Libs").toJsonArray().toVariantList();
+ QCOMPARE(package.libs.size(), size_t(jsonLibs.size()));
+ for (size_t i = 0; i < package.libs.size(); ++i) {
+ const auto &item = package.libs[i];
+ const auto jsonItem = jsonLibs.at(i).toMap();
+
+ QCOMPARE(item.type,
+ *PcPackage::Flag::typeFromString(jsonItem.value("Type").toString().toStdString()));
+ QCOMPARE(QString::fromStdString(item.value), jsonItem.value("Value").toString());
+ }
+
+ const auto jsonLibsPrivate = json.value("LibsPrivate").toJsonArray().toVariantList();
+ QCOMPARE(package.libsPrivate.size(), size_t(jsonLibsPrivate.size()));
+ for (size_t i = 0; i < package.libsPrivate.size(); ++i) {
+ const auto &item = package.libsPrivate[i];
+ const auto jsonItem = jsonLibsPrivate.at(i).toMap();
+
+ QCOMPARE(item.type,
+ *PcPackage::Flag::typeFromString(jsonItem.value("Type").toString().toStdString()));
+ QCOMPARE(QString::fromStdString(item.value), jsonItem.value("Value").toString());
+ }
+
+ const auto jsonCFlags = json.value("Cflags").toJsonArray().toVariantList();
+ QCOMPARE(package.cflags.size(), size_t(jsonCFlags.size()));
+ for (size_t i = 0; i < package.cflags.size(); ++i) {
+ const auto &item = package.cflags[i];
+ const auto jsonItem = jsonCFlags.at(i).toMap();
+
+ QCOMPARE(item.type,
+ *PcPackage::Flag::typeFromString(jsonItem.value("Type").toString().toStdString()));
+ QCOMPARE(QString::fromStdString(item.value), jsonItem.value("Value").toString());
+ }
+
+ for (const auto &item: package.requiresPublic)
+ qInfo() << "requires" << item.name.c_str() << item.version.c_str();
+
+ const auto jsonRequires = json.value("Requires").toJsonArray().toVariantList();
+ QCOMPARE(package.requiresPublic.size(), size_t(jsonRequires.size()));
+ for (size_t i = 0; i < package.requiresPublic.size(); ++i) {
+ const auto &item = package.requiresPublic[i];
+ const auto jsonItem = jsonRequires.at(i).toMap();
+
+ QCOMPARE(item.comparison,
+ *PcPackage::RequiredVersion::comparisonFromString(
+ jsonItem.value("Comparison").toString().toStdString()));
+ QCOMPARE(QString::fromStdString(item.name), jsonItem.value("Name").toString());
+ QCOMPARE(QString::fromStdString(item.version), jsonItem.value("Version").toString());
+ }
+
+ const auto jsonRequiresPrivate = json.value("RequiresPrivate").toJsonArray().toVariantList();
+ QCOMPARE(package.requiresPrivate.size(), size_t(jsonRequiresPrivate.size()));
+ for (size_t i = 0; i < package.requiresPrivate.size(); ++i) {
+ const auto &item = package.requiresPrivate[i];
+ const auto jsonItem = jsonRequiresPrivate.at(i).toMap();
+
+ QCOMPARE(item.comparison,
+ *PcPackage::RequiredVersion::comparisonFromString(
+ jsonItem.value("Comparison").toString().toStdString()));
+ QCOMPARE(QString::fromStdString(item.name), jsonItem.value("Name").toString());
+ QCOMPARE(QString::fromStdString(item.version), jsonItem.value("Version").toString());
+ }
+}
+
+void TestPkgConfig::pkgConfig_data()
+{
+ QTest::addColumn<QString>("pcFileName");
+ QTest::addColumn<QString>("jsonFileName");
+ QTest::addColumn<QVariantMap>("optionsMap");
+
+ QTest::newRow("empty-variable")
+ << QStringLiteral("empty-variable") << QString() << QVariantMap();
+ QTest::newRow("non-l-required")
+ << QStringLiteral("non-l-required") << QString() << QVariantMap();
+ QTest::newRow("simple")
+ << QStringLiteral("simple") << QString() << QVariantMap();
+ QTest::newRow("requires-test")
+ << QStringLiteral("requires-test") << QString() << QVariantMap();
+ QTest::newRow("special-flags")
+ << QStringLiteral("special-flags") << QString() << QVariantMap();
+ QTest::newRow("system")
+ << QStringLiteral("system") << QString() << QVariantMap();
+ QTest::newRow("sysroot")
+ << QStringLiteral("sysroot") << QString() << QVariantMap({{"sysroot", "/newroot"}});
+ QTest::newRow("tilde")
+ << QStringLiteral("tilde") << QString() << QVariantMap();
+ QTest::newRow("variables")
+ << QStringLiteral("variables") << QString() << QVariantMap();
+ QTest::newRow("whitespace")
+ << QStringLiteral("whitespace") << QString() << QVariantMap();
+ QTest::newRow("base.name")
+ << QStringLiteral("base.name") << QString() << QVariantMap();
+}
+
+void TestPkgConfig::benchSystem()
+{
+ if (HostOsInfo::hostOs() == HostOsInfo::HostOsWindows)
+ QSKIP("Not available on Windows");
+ QBENCHMARK {
+ PkgConfig pkgConfig;
+ QVERIFY(!pkgConfig.packages().empty());
+ }
+}
+
+void TestPkgConfig::prefix()
+{
+ const auto prefixDir = m_workingDataDir;
+ const auto libDir = m_workingDataDir + "/lib";
+ const auto includeDir = m_workingDataDir + "/include";
+ const auto pkgconfigDir = libDir + "/pkgconfig";
+ Options options = qbs::Internal::PkgConfigJs::convertOptions(
+ QProcessEnvironment::systemEnvironment(), {});
+ options.definePrefix = true;
+ options.libDirs.push_back(pkgconfigDir.toStdString());
+ PkgConfig pkgConfig(std::move(options));
+ const auto &packageOr = pkgConfig.getPackage("prefix");
+ QVERIFY(packageOr.isValid());
+ const auto &package = packageOr.asPackage();
+ QCOMPARE(package.variables.at("prefix"), prefixDir.toStdString());
+ QCOMPARE(package.variables.at("exec_prefix"), prefixDir.toStdString());
+ QCOMPARE(package.variables.at("libdir"), libDir.toStdString());
+ QCOMPARE(package.variables.at("includedir"), includeDir.toStdString());
+ QCOMPARE(package.variables.at("usrdir"), "/usrdir");
+}
+
+QTEST_MAIN(TestPkgConfig)
diff --git a/tests/auto/pkgconfig/tst_pkgconfig.h b/tests/auto/pkgconfig/tst_pkgconfig.h
new file mode 100644
index 000000000..47654e1ec
--- /dev/null
+++ b/tests/auto/pkgconfig/tst_pkgconfig.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBS_TST_API_H
+#define QBS_TST_API_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qvariant.h>
+
+class TestPkgConfig : public QObject
+{
+ Q_OBJECT
+
+public:
+ TestPkgConfig();
+
+private slots:
+ void initTestCase();
+ void fileName();
+ void completeBaseName();
+ void parentPath();
+ void pkgConfig();
+ void pkgConfig_data();
+ void benchSystem();
+ void prefix();
+
+private:
+ const QString m_sourceDataDir;
+ const QString m_workingDataDir;
+};
+
+#endif // Include guard.
diff --git a/tests/auto/shared.h b/tests/auto/shared.h
index e251d506c..408594be0 100644
--- a/tests/auto/shared.h
+++ b/tests/auto/shared.h
@@ -31,6 +31,7 @@
#include <tools/hostosinfo.h>
#include <tools/profile.h>
#include <tools/settings.h>
+#include <tools/toolchains.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qcryptographichash.h>
@@ -46,6 +47,8 @@
#include <memory>
+
+
#define REPLACE_IN_FILE(filePath, oldContent, newContent) \
do { \
QFile f((filePath)); \
@@ -155,8 +158,11 @@ inline QByteArray diffText(const QByteArray &actual, const QByteArray &expected)
n++;
}
auto addLines = [&result, &n] (const QList<QByteArray> &lines) {
- for (const QByteArray &line : qAsConst(lines)) {
- result += QStringLiteral("%1: %2\n").arg(n).arg(QString::fromUtf8(line));
+ for (const QByteArray &line : std::as_const(lines)) {
+ result += QStringLiteral("%1: %2\n")
+ .arg(n)
+ .arg(QString::fromUtf8(line))
+ .toUtf8();
n++;
}
};
@@ -268,14 +274,22 @@ inline void copyFileAndUpdateTimestamp(const QString &source, const QString &tar
touch(target);
}
+inline QStringList profileToolchain(const qbs::Profile &profile)
+{
+ const auto toolchainType = profile.value(QStringLiteral("qbs.toolchainType")).toString();
+ if (!toolchainType.isEmpty())
+ return qbs::canonicalToolchain(toolchainType);
+ return profile.value(QStringLiteral("qbs.toolchain")).toStringList();
+}
+
inline QString objectFileName(const QString &baseName, const QString &profileName)
{
const SettingsPtr s = settings();
qbs::Profile profile(profileName, s.get());
- const auto tc = profile.value("qbs.toolchainType").toString();
- const auto tcList = profile.value("qbs.toolchain").toStringList();
- const bool isMsvc = tc == "msvc" || tcList.contains("msvc")
- || (tc.isEmpty() && tcList.isEmpty() && qbs::Internal::HostOsInfo::isWindowsHost());
+
+ const auto tcList = profileToolchain(profile);
+ const bool isMsvc = tcList.contains("msvc")
+ || (tcList.isEmpty() && qbs::Internal::HostOsInfo::isWindowsHost());
const QString suffix = isMsvc ? "obj" : "o";
return baseName + '.' + suffix;
}
@@ -285,6 +299,30 @@ inline QString inputDirHash(const QString &dir)
return QCryptographicHash::hash(dir.toLatin1(), QCryptographicHash::Sha1).toHex().left(16);
}
+inline QString testDataSourceDir(const QString &dir)
+{
+ QDir result;
+ QString testSourceRootDirFromEnv = QDir::fromNativeSeparators(qEnvironmentVariable("QBS_TEST_SOURCE_ROOT"));
+ if (testSourceRootDirFromEnv.isEmpty()) {
+ result.setPath(dir);
+ } else {
+ QDir testSourceRootDir(dir);
+ while (testSourceRootDir.dirName() != "tests")
+ testSourceRootDir = QFileInfo(testSourceRootDir, "").dir();
+
+ QString relativeDataPath = testSourceRootDir.relativeFilePath(dir);
+ QString absoluteDataPath = QDir(testSourceRootDirFromEnv).absoluteFilePath(relativeDataPath);
+ result.setPath(absoluteDataPath);
+ }
+
+ if (!result.exists())
+ qFatal("Expected data folder '%s' to be present, but it does not exist. You may set "
+ "QBS_TEST_SOURCE_ROOT to the 'tests' folder in your qbs repository to configure "
+ "a custom location.", qPrintable(result.absolutePath()));
+
+ return result.absolutePath();
+}
+
inline QString testWorkDir(const QString &testName)
{
QString dir = QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv("QBS_TEST_WORK_ROOT")));
@@ -294,12 +332,14 @@ inline QString testWorkDir(const QString &testName)
if (!dir.endsWith(QLatin1Char('/')))
dir += QLatin1Char('/');
}
- return dir + testName + "/testWorkDir";
+ return QDir::cleanPath(dir + testName + "/testWorkDir");
}
inline bool copyDllExportHeader(const QString &srcDataDir, const QString &targetDataDir)
{
QFile sourceFile(srcDataDir + "/../../dllexport.h");
+ if (!sourceFile.exists())
+ return true;
const QString targetPath = targetDataDir + "/dllexport.h";
QFile::remove(targetPath);
return sourceFile.copy(targetPath);
@@ -311,8 +351,7 @@ inline qbs::Internal::HostOsInfo::HostOs targetOs()
const qbs::Profile buildProfile(profileName(), s.get());
const QString targetPlatform = buildProfile.value("qbs.targetPlatform").toString();
if (!targetPlatform.isEmpty()) {
- const std::vector<std::string> targetOS = qbs::Internal::HostOsInfo::canonicalOSIdentifiers(
- targetPlatform.toStdString());
+ const auto targetOS = qbs::Internal::HostOsInfo::canonicalOSIdentifiers(targetPlatform);
if (qbs::Internal::contains(targetOS, "windows"))
return qbs::Internal::HostOsInfo::HostOsWindows;
if (qbs::Internal::contains(targetOS, "linux"))
diff --git a/tests/auto/tools/CMakeLists.txt b/tests/auto/tools/CMakeLists.txt
new file mode 100644
index 000000000..a75d998a3
--- /dev/null
+++ b/tests/auto/tools/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_qbs_test(tools
+ DEFINES
+ "QBS_VERSION=\"${QBS_VERSION}\""
+ SOURCES
+ tst_tools.cpp
+ tst_tools.h
+ )
diff --git a/tests/auto/tools/tools.pro b/tests/auto/tools/tools.pro
deleted file mode 100644
index ba293f417..000000000
--- a/tests/auto/tools/tools.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-TARGET = tst_tools
-
-SOURCES = tst_tools.cpp ../../../src/app/qbs/qbstool.cpp
-HEADERS = tst_tools.h
-
-include(../auto.pri)
diff --git a/tests/auto/tools/tools.qbs b/tests/auto/tools/tools.qbs
index 64cced80e..781d6edae 100644
--- a/tests/auto/tools/tools.qbs
+++ b/tests/auto/tools/tools.qbs
@@ -1,7 +1,6 @@
-import qbs
import qbs.Utilities
-QbsAutotest {
+QbsUnittest {
Depends { name: "qbsversion" }
testName: "tools"
diff --git a/tests/auto/tools/tst_tools.cpp b/tests/auto/tools/tst_tools.cpp
index edf5a1308..a872bdd0d 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"))
{
@@ -298,10 +308,10 @@ void TestTools::testSettingsMigration()
QFETCH(bool, hasOldSettings);
Settings settings(baseDir);
if (hasOldSettings) {
- QVERIFY(QFileInfo(settings.baseDirectory() + "/qbs/" QBS_VERSION "/profiles/right.txt")
+ // checks that we do not copy old "profiles/" dir anymore
+ QVERIFY(!QFileInfo(settings.baseDirectory() + "/qbs/" QBS_VERSION "/profiles/right.txt")
.exists());
- QCOMPARE(settings.value("key", Settings::UserScope).toString(),
- settings.baseDirectory() + "/qbs/" QBS_VERSION "/profilesright");
+ QVERIFY(!settings.value("key", Settings::UserScope).toString().isEmpty());
} else {
QVERIFY(!QFileInfo(settings.baseDirectory() + "/qbs/" QBS_VERSION "/profiles").exists());
QVERIFY(settings.allKeys(Settings::UserScope).empty());
@@ -673,6 +683,30 @@ void TestTools::set_containsSet()
QVERIFY(set3.contains(set4));
}
+void TestTools::set_find()
+{
+ Set<QString> set1;
+
+ for (int i = 0; i < 500; ++i) {
+ QVERIFY(set1.find(QString::number(i)) == set1.end());
+ set1.insert(QString::number(i));
+ const auto it = set1.find(QString::number(i));
+ QVERIFY(it != set1.end());
+ QVERIFY(*it == QString::number(i));
+ }
+
+ QCOMPARE(set1.size(), size_t { 500 });
+
+ for (int j = 0; j < 500; ++j) {
+ int i = (j * 17) % 500;
+ const auto it = set1.find(QString::number(i));
+ QVERIFY(it != set1.end());
+ QVERIFY(*it == QString::number(i));
+ set1.remove(QString::number(i));
+ QVERIFY(set1.find(QString::number(i)) == set1.end());
+ }
+}
+
void TestTools::set_begin()
{
Set<int> set1;
@@ -1275,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 bd8538be2..619174976 100644
--- a/tests/auto/tools/tst_tools.h
+++ b/tests/auto/tools/tst_tools.h
@@ -79,6 +79,7 @@ private slots:
void set_remove();
void set_contains();
void set_containsSet();
+ void set_find();
void set_begin();
void set_end();
void set_insert();
@@ -99,6 +100,9 @@ private slots:
void stringutils_endsWith();
void stringutils_trimmed();
+ void hash_tuple();
+ void hash_range();
+
private:
QString setupSettingsDir1();
QString setupSettingsDir2();