diff options
22 files changed, 405 insertions, 6 deletions
diff --git a/changelogs/changes-1.10.0.md b/changelogs/changes-1.10.0.md index ce4bf5007..a125431fc 100644 --- a/changelogs/changes-1.10.0.md +++ b/changelogs/changes-1.10.0.md @@ -3,6 +3,7 @@ Git and Subversion are supported initially. * Added initial support for the Universal Windows Platform. * Improved a lot of error messages. +* Building Inno Setup, NSIS, or WiX installers now depends on installable artifacts by default. # Language * Profiles can now be defined within a project using the `Profile` item. diff --git a/doc/reference/modules/innosetup-module.qdoc b/doc/reference/modules/innosetup-module.qdoc index 7f86ed072..416ccb89b 100644 --- a/doc/reference/modules/innosetup-module.qdoc +++ b/doc/reference/modules/innosetup-module.qdoc @@ -157,5 +157,11 @@ \li 1.7 \li The rule that creates Inno Setup executable files attaches this tag (as well as the "application" tag) to its output artifact. + \row + \li \c{"innosetup.input"} + \li n/a + \li 1.10 + \li The rule that creates Inno Setup executable files will be dependent on artifacts + with this tag. \endtable */ diff --git a/doc/reference/modules/nsis-module.qdoc b/doc/reference/modules/nsis-module.qdoc index f409d17bc..c66add6d4 100644 --- a/doc/reference/modules/nsis-module.qdoc +++ b/doc/reference/modules/nsis-module.qdoc @@ -181,5 +181,11 @@ \li 1.2 \li The rule that creates the NSIS setup executable attaches this tag to its output artifact. + \row + \li \c{"nsis.input"} + \li - + \li 1.10 + \li The rule that creates the NSIS setup executable will be dependent on artifacts + with this tag. \endtable */ diff --git a/doc/reference/modules/wix-module.qdoc b/doc/reference/modules/wix-module.qdoc index 1a7309654..84be797f2 100644 --- a/doc/reference/modules/wix-module.qdoc +++ b/doc/reference/modules/wix-module.qdoc @@ -269,5 +269,11 @@ \li 1.2 \li This tag is attached to WiX source files. Each source file will be compiled into one WiX object file. + \row + \li \c{"wix.input"} + \li - + \li 1.10 + \li The rule that creates the Microsoft Installer setup file or WiX setup executable + will be dependent on artifacts with this tag. \endtable */ diff --git a/share/qbs/imports/qbs/base/InnoSetup.qbs b/share/qbs/imports/qbs/base/InnoSetup.qbs index 5ea076eb3..732ca06b0 100644 --- a/share/qbs/imports/qbs/base/InnoSetup.qbs +++ b/share/qbs/imports/qbs/base/InnoSetup.qbs @@ -28,7 +28,10 @@ ** ****************************************************************************/ -Product { +import qbs + +Installer { Depends { name: "innosetup"; condition: qbs.targetOS.contains("windows") } type: ["innosetup.exe"] + auxiliaryInputs: ["innosetup.input"] } diff --git a/share/qbs/imports/qbs/base/Installer.qbs b/share/qbs/imports/qbs/base/Installer.qbs new file mode 100644 index 000000000..701034f62 --- /dev/null +++ b/share/qbs/imports/qbs/base/Installer.qbs @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +import qbs + +Product { + property bool dependsOnInstallables: true + property stringList auxiliaryInputs: [] + + Group { + condition: dependsOnInstallables + fileTagsFilter: ["installable"] + fileTags: auxiliaryInputs + } +} diff --git a/share/qbs/imports/qbs/base/NSISSetup.qbs b/share/qbs/imports/qbs/base/NSISSetup.qbs index 1362f2713..183577bd5 100644 --- a/share/qbs/imports/qbs/base/NSISSetup.qbs +++ b/share/qbs/imports/qbs/base/NSISSetup.qbs @@ -28,7 +28,10 @@ ** ****************************************************************************/ -Product { +import qbs + +Installer { Depends { name: "nsis"; condition: qbs.targetOS.contains("windows") } type: ["nsissetup"] + auxiliaryInputs: ["nsis.input"] } diff --git a/share/qbs/imports/qbs/base/WindowsInstallerPackage.qbs b/share/qbs/imports/qbs/base/WindowsInstallerPackage.qbs index 791fc9473..554149337 100644 --- a/share/qbs/imports/qbs/base/WindowsInstallerPackage.qbs +++ b/share/qbs/imports/qbs/base/WindowsInstallerPackage.qbs @@ -28,7 +28,10 @@ ** ****************************************************************************/ -Product { +import qbs + +Installer { Depends { name: "wix"; condition: qbs.targetOS.contains("windows") } type: ["msi"] + auxiliaryInputs: ["wix.input"] } diff --git a/share/qbs/modules/innosetup/InnoSetupModule.qbs b/share/qbs/modules/innosetup/InnoSetupModule.qbs index 70e36f77b..a2f85d51b 100644 --- a/share/qbs/modules/innosetup/InnoSetupModule.qbs +++ b/share/qbs/modules/innosetup/InnoSetupModule.qbs @@ -99,6 +99,7 @@ Module { Rule { id: innoSetupCompiler inputs: ["innosetup.iss"] + auxiliaryInputs: ["innosetup.input"] Artifact { fileTags: ["innosetup.exe", "application"] diff --git a/share/qbs/modules/nsis/NSISModule.qbs b/share/qbs/modules/nsis/NSISModule.qbs index c4a1339ea..b893cfa45 100644 --- a/share/qbs/modules/nsis/NSISModule.qbs +++ b/share/qbs/modules/nsis/NSISModule.qbs @@ -145,6 +145,7 @@ Module { id: nsisCompiler multiplex: true inputs: ["nsi"] + auxiliaryInputs: ["nsis.input"] Artifact { fileTags: ["nsissetup", "application"] diff --git a/share/qbs/modules/wix/WiXModule.qbs b/share/qbs/modules/wix/WiXModule.qbs index 94955eab4..f95a03bfc 100644 --- a/share/qbs/modules/wix/WiXModule.qbs +++ b/share/qbs/modules/wix/WiXModule.qbs @@ -179,7 +179,7 @@ Module { Rule { id: candleCompiler inputs: ["wxs"] - auxiliaryInputs: ['wxi'] + auxiliaryInputs: ["wxi", "wix.input"] Artifact { fileTags: ["wixobj"] @@ -334,6 +334,7 @@ Module { id: lightLinker multiplex: true inputs: ["wixobj", "wxl"] + auxiliaryInputs: ["wix.input"] inputsFromDependencies: product.type.contains("wixsetup") ? ["msi"] : [] outputArtifacts: { diff --git a/tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs b/tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs new file mode 100644 index 000000000..fc13ced59 --- /dev/null +++ b/tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs @@ -0,0 +1,73 @@ +import qbs +import qbs.FileInfo + +Project { + InnoSetup { + Depends { name: "app" } + Depends { name: "lib" } + name: "QbsSetup" + targetName: "qbs.setup.test" + version: "1.5" + files: [ + "test.iss" + ] + innosetup.verboseOutput: true + innosetup.defines: [ + "MyProgram=" + name, + "MyProgramVersion=" + version, + "buildDirectory=" + project.buildDirectory + ] + innosetup.compilerFlags: ["/V9"] + destinationDirectory: project.buildDirectory + } + Application { + Depends { name: "cpp" } + name: "app" + files: ["main.c"] + Group { + fileTagsFilter: product.type + qbs.install: true + } + destinationDirectory: project.buildDirectory + } + DynamicLibrary { + Depends { name: "cpp" } + name: "lib" + files: ["main.c"] + Group { + fileTagsFilter: product.type + qbs.install: true + } + Rule { + // This rule tries to provoke the installer into building too early (and the test + // verifies that it does not) by causing the build of the installables to take + // a lot longer. + inputs: ["qbs"] + outputFileTags: ["c"] + outputArtifacts: { + var artifacts = []; + for (var i = 0; i < 96; ++i) + artifacts.push({ filePath: "c" + i + ".c", fileTags: ["c"] }); + return artifacts; + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() { + for (var i = 0; i < outputs["c"].length; ++i) { + var tf; + try { + tf = new TextFile(outputs["c"][i].filePath, TextFile.WriteOnly); + tf.writeLine("int main" + i + "() { return 0; }"); + } finally { + if (tf) + tf.close(); + } + } + }; + return [cmd]; + } + } + destinationDirectory: project.buildDirectory + } +} diff --git a/tests/auto/blackbox/testdata/innosetupDependencies/main.c b/tests/auto/blackbox/testdata/innosetupDependencies/main.c new file mode 100644 index 000000000..76e819701 --- /dev/null +++ b/tests/auto/blackbox/testdata/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/innosetupDependencies/test.iss new file mode 100644 index 000000000..430f9941b --- /dev/null +++ b/tests/auto/blackbox/testdata/innosetupDependencies/test.iss @@ -0,0 +1,8 @@ +[Setup] +AppName={#MyProgram} +AppVersion={#MyProgramVersion} +DefaultDirName={pf}\{#MyProgram} + +[Files] +Source: "{#buildDirectory}\app.exe"; DestDir: "{app}" +Source: "{#buildDirectory}\lib.dll"; DestDir: "{app}" diff --git a/tests/auto/blackbox/testdata/nsisDependencies/hello.nsi b/tests/auto/blackbox/testdata/nsisDependencies/hello.nsi new file mode 100644 index 000000000..4079d40d3 --- /dev/null +++ b/tests/auto/blackbox/testdata/nsisDependencies/hello.nsi @@ -0,0 +1,8 @@ +Page directory +Page instfiles + +Section "" + SetOutPath "$INSTDIR" + File "${buildDirectory}\app.exe" + File "${buildDirectory}\lib.dll" +SectionEnd diff --git a/tests/auto/blackbox/testdata/nsisDependencies/main.c b/tests/auto/blackbox/testdata/nsisDependencies/main.c new file mode 100644 index 000000000..76e819701 --- /dev/null +++ b/tests/auto/blackbox/testdata/nsisDependencies/main.c @@ -0,0 +1 @@ +int main() { return 0; } diff --git a/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs b/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs new file mode 100644 index 000000000..a68921b93 --- /dev/null +++ b/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs @@ -0,0 +1,67 @@ +import qbs +import qbs.FileInfo + +Project { + condition: qbs.targetOS.contains("windows") + + NSISSetup { + Depends { name: "app" } + Depends { name: "lib" } + name: "inst" + files: ["hello.nsi"] + nsis.defines: ["buildDirectory=" + FileInfo.toWindowsSeparators(project.buildDirectory)] + destinationDirectory: project.buildDirectory + } + + Application { + Depends { name: "cpp" } + name: "app" + files: ["main.c"] + Group { + fileTagsFilter: product.type + qbs.install: true + } + destinationDirectory: project.buildDirectory + } + + DynamicLibrary { + Depends { name: "cpp" } + name: "lib" + files: ["main.c"] + Group { + fileTagsFilter: product.type + qbs.install: true + } + Rule { + // This rule tries to provoke the installer into building too early (and the test + // verifies that it does not) by causing the build of the installables to take + // a lot longer. + inputs: ["qbs"] + outputFileTags: ["c"] + outputArtifacts: { + var artifacts = []; + for (var i = 0; i < 96; ++i) + artifacts.push({ filePath: "c" + i + ".c", fileTags: ["c"] }); + return artifacts; + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() { + for (var i = 0; i < outputs["c"].length; ++i) { + var tf; + try { + tf = new TextFile(outputs["c"][i].filePath, TextFile.WriteOnly); + tf.writeLine("int main" + i + "() { return 0; }"); + } finally { + if (tf) + tf.close(); + } + } + }; + return [cmd]; + } + } + destinationDirectory: project.buildDirectory + } +} diff --git a/tests/auto/blackbox/testdata/wixDependencies/QbsSetup.wxs b/tests/auto/blackbox/testdata/wixDependencies/QbsSetup.wxs new file mode 100644 index 000000000..ec839a269 --- /dev/null +++ b/tests/auto/blackbox/testdata/wixDependencies/QbsSetup.wxs @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> + <Product Id="*" Name="QbsSetup" Language="1033" Version="1.0.0.0" Manufacturer="Qt Project" UpgradeCode="f60f643e-b002-44d5-b3f4-edafd078314c"> + <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" /> + + <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> + <MediaTemplate /> + + <Feature Id="ProductFeature" Title="QbsSetup" Level="1"> + <ComponentGroupRef Id="ProductComponents" /> + </Feature> + </Product> + + <Fragment> + <Directory Id="TARGETDIR" Name="SourceDir"> + <?ifdef Win64 ?> + <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?> + <?else ?> + <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?> + <?endif ?> + <Directory Id="$(var.PlatformProgramFilesFolder)"> + <Directory Id="INSTALLFOLDER" Name="QbsSetup" /> + </Directory> + </Directory> + </Fragment> + + <Fragment> + <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER"> + <Component Id="ProductComponent"> + <File Source="$(var.project.buildDirectory)/app.exe" /> + </Component> + <Component Id="ProductComponent2"> + <File Source="$(var.project.buildDirectory)/lib.dll" /> + </Component> + </ComponentGroup> + </Fragment> +</Wix> diff --git a/tests/auto/blackbox/testdata/wixDependencies/main.c b/tests/auto/blackbox/testdata/wixDependencies/main.c new file mode 100644 index 000000000..76e819701 --- /dev/null +++ b/tests/auto/blackbox/testdata/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/wixDependencies/wixDependencies.qbs new file mode 100644 index 000000000..e913124e9 --- /dev/null +++ b/tests/auto/blackbox/testdata/wixDependencies/wixDependencies.qbs @@ -0,0 +1,66 @@ +import qbs +import qbs.FileInfo + +Project { + WindowsInstallerPackage { + Depends { name: "app" } + Depends { name: "lib" } + name: "QbsSetup" + targetName: "qbs" + files: ["QbsSetup.wxs"] + wix.extensions: ["WixBalExtension", "WixUIExtension"] + destinationDirectory: project.buildDirectory + } + + Application { + Depends { name: "cpp" } + name: "app" + files: ["main.c"] + Group { + fileTagsFilter: product.type + qbs.install: true + } + destinationDirectory: project.buildDirectory + } + + DynamicLibrary { + Depends { name: "cpp" } + name: "lib" + files: ["main.c"] + Group { + fileTagsFilter: product.type + qbs.install: true + } + Rule { + // This rule tries to provoke the installer into building too early (and the test + // verifies that it does not) by causing the build of the installables to take + // a lot longer. + inputs: ["qbs"] + outputFileTags: ["c"] + outputArtifacts: { + var artifacts = []; + for (var i = 0; i < 96; ++i) + artifacts.push({ filePath: "c" + i + ".c", fileTags: ["c"] }); + return artifacts; + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() { + for (var i = 0; i < outputs["c"].length; ++i) { + var tf; + try { + tf = new TextFile(outputs["c"][i].filePath, TextFile.WriteOnly); + tf.writeLine("int main" + i + "() { return 0; }"); + } finally { + if (tf) + tf.close(); + } + } + }; + return [cmd]; + } + } + destinationDirectory: project.buildDirectory + } +} diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index f4092c666..21db45279 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -4613,7 +4613,7 @@ void TestBlackbox::auxiliaryInputsFromDependencies() QVERIFY2(m_qbsStdout.contains("generating dummy.out"), m_qbsStdout.constData()); } -void TestBlackbox::nsis() +static bool haveMakeNsis() { QStringList regKeys; regKeys << QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS") @@ -4638,7 +4638,12 @@ void TestBlackbox::nsis() } } - if (!haveMakeNsis) { + return haveMakeNsis; +} + +void TestBlackbox::nsis() +{ + if (!haveMakeNsis()) { QSKIP("makensis is not installed"); return; } @@ -4651,6 +4656,19 @@ void TestBlackbox::nsis() QVERIFY(!QFile::exists(defaultInstallRoot + "/you-should-not-see-a-file-with-this-name.exe")); } +void TestBlackbox::nsisDependencies() +{ + if (!haveMakeNsis()) { + QSKIP("makensis is not installed"); + return; + } + + bool targetIsWindows = targetOs() == HostOsInfo::HostOsWindows; + QDir::setCurrent(testDataDir + "/nsisDependencies"); + QCOMPARE(runQbs(), 0); + QCOMPARE(m_qbsStdout.contains("compiling hello.nsi"), targetIsWindows); +} + void TestBlackbox::enableExceptions() { QFETCH(QString, file); @@ -4812,6 +4830,30 @@ void TestBlackbox::wix() } } +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(); @@ -4964,6 +5006,25 @@ void TestBlackbox::innoSetup() 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::outputArtifactAutoTagging() { QDir::setCurrent(testDataDir + QLatin1String("/output-artifact-auto-tagging")); diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 3f7215995..218c10a7a 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -103,6 +103,7 @@ private slots: void importsConflict(); void includeLookup(); void innoSetup(); + void innoSetupDependencies(); void inputsFromDependencies(); void installable(); void installedApp(); @@ -149,6 +150,7 @@ private slots: void nonBrokenFilesInBrokenProduct(); void nonDefaultProduct(); void nsis(); + void nsisDependencies(); void outputArtifactAutoTagging(); void overrideProjectProperties(); void pchChangeTracking(); @@ -232,6 +234,7 @@ private slots: void wildCardsAndRules(); void wildcardRenaming(); void wix(); + void wixDependencies(); void zip(); void zip_data(); void zipInvalid(); |