<?xml version="1.0" encoding="utf-8"?>
|
<!--
|
/****************************************************************************
|
**
|
** Copyright (C) 2021 The Qt Company Ltd.
|
** Contact: https://www.qt.io/licensing/
|
**
|
** This file is part of the Qt VS Tools.
|
**
|
** $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$
|
**
|
****************************************************************************/
|
-->
|
|
<!--
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
// Generate imports of QML static plugins
|
// -->
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<!--
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
// Import pre-requisites
|
// -->
|
<Import
|
Condition="'$(QtMsBuildTargets_BeforeQmlStatic)' != ''"
|
Project="$(QtMsBuildTargets_BeforeQmlStatic)"/>
|
|
<!--
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
// Qt/MSBuild global properties
|
// * add QtQmlStatic to the list of targets to run during build
|
// * add QtQmlStaticLink to the list of targets to run when calculating linker input
|
// -->
|
<PropertyGroup>
|
<QtBuildTargets>$(QtBuildTargets);QtQmlStatic</QtBuildTargets>
|
<ComputeLinkInputsTargets>$(ComputeLinkInputsTargets);QtQmlStaticLink</ComputeLinkInputsTargets>
|
</PropertyGroup>
|
|
<!--
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
/// TARGET QtQmlStaticLink
|
/// => runs only once
|
/// => always runs if building against a static build of Qt
|
/// => targets that must run first: QtQmlStatic, ComputeCLGeneratedLinkInputs
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
// Add QML static plugin libs to Link input.
|
// -->
|
<Target
|
Name="QtQmlStaticLink"
|
Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
DependsOnTargets="QtQmlStatic;ComputeCLGeneratedLinkInputs">
|
<ItemGroup>
|
<Link>
|
<AdditionalDependencies Condition="'@(QtQmlImportLib)' != ''"
|
>%(Link.AdditionalDependencies);@(QtQmlImportLib)</AdditionalDependencies>
|
</Link>
|
</ItemGroup>
|
</Target>
|
|
<!--
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
/// TARGET QtQmlStatic
|
/// => runs only once
|
/// => always runs if building against a static build of Qt
|
/// => targets that must run first: QtQmlImportsParseJson, QtQmlGetImportCpp
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
// Entry point for generating imports of QML static plugins.
|
// -->
|
<Target
|
Name="QtQmlStatic"
|
Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
DependsOnTargets="QtQmlImportsParseJson;QtQmlGetImportCpp">
|
<ItemGroup>
|
<!-- for each required import, create a reference to the corresponding import lib -->
|
<QtQmlImportLib
|
Condition="'$(QtBuildConfig)' == 'debug'"
|
Include="@(QtQmlImport->'%(Path)\%(Plugin)d.lib')"/>
|
<QtQmlImportLib
|
Condition="'$(QtBuildConfig)' != 'debug'"
|
Include="@(QtQmlImport->'%(Path)\%(Plugin).lib')"/>
|
</ItemGroup>
|
</Target>
|
|
<!--
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
/// TARGET QtQmlGetImportCpp
|
/// => runs only once
|
/// => skipped if generated C++ is up-to-date, relative to all JSON output files
|
/// => targets that must run first: QtQmlImportsParseJson
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
// Generate C++ source file with imports of QML static plugins.
|
// -->
|
<Target
|
Name="QtQmlGetImportCpp"
|
Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
DependsOnTargets="QtQmlImportsParseJson"
|
Inputs="@(QtQml->'%(ImportJson)')"
|
Outputs="$(QtQmlPluginImportCpp)">
|
|
<!-- file header -->
|
<PropertyGroup>
|
<QmlPluginImportCppHeader>
|
<![CDATA[
|
// This file is autogenerated by Qt/MSBuild. It imports static plugin classes for
|
// static plugins used by QML imports.
|
#include <QtPlugin>]]>
|
</QmlPluginImportCppHeader>
|
</PropertyGroup>
|
|
<!-- file contents: header + imports -->
|
<ItemGroup>
|
<QmlPluginImportCpp Include="$(QmlPluginImportCppHeader)" />
|
<QmlPluginImportCpp Include="@(QtQmlImport->'Q_IMPORT_PLUGIN(%(ClassName))')" />
|
</ItemGroup>
|
|
<!-- write .cpp file -->
|
<WriteLinesToFile
|
File="$(QtQmlPluginImportCpp)"
|
Lines="@(QmlPluginImportCpp)" />
|
|
<!-- clean-up -->
|
<PropertyGroup>
|
<QmlPluginImportCppHeader/>
|
</PropertyGroup>
|
<ItemGroup>
|
<QtQmlPluginImportCpp Remove="@(QtQmlPluginImportCpp)" />
|
</ItemGroup>
|
</Target>
|
|
<!--
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
/// TARGET QtQmlImportsParseJson
|
/// => runs only once
|
/// => always runs if building agains a static build of Qt
|
/// => targets that must run first: QtQmlScanImports
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
// Parse JSON output of qmlimportscanner.
|
// * ATTN: "Naïve" parser: assumes JSON is formatted with each value in a single line
|
// -->
|
<Target
|
Name="QtQmlImportsParseJson"
|
Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
DependsOnTargets="QtQmlScanImports">
|
|
<!-- constants -->
|
<PropertyGroup>
|
<StrClassName>"classname": </StrClassName>
|
<StrPath>"path": </StrPath>
|
<StrPlugin>"plugin": </StrPlugin>
|
</PropertyGroup>
|
|
<!-- load text of all JSON output files -->
|
<ReadLinesFromFile File="%(QtQml.ImportJson)">
|
<Output TaskParameter="Lines" ItemName="JsonText"/>
|
</ReadLinesFromFile>
|
|
<ItemGroup>
|
<!-- list of all lines starting with '"classname": ' -->
|
<JsonClassName
|
Include="@(JsonText)"
|
Condition="$([System.String]::Copy('%(JsonText.Identity)').StartsWith('$(StrClassName)'))" />
|
<!-- extract value -->
|
<JsonClassName>
|
<ClassName>$([System.String]::Copy('%(JsonClassName.Identity)').Substring($(StrClassName.Length)).Trim(',').Trim('"'))</ClassName>
|
</JsonClassName>
|
|
<!-- list of all lines starting with '"path": ' -->
|
<JsonPath
|
Include="@(JsonText)"
|
Condition="$([System.String]::Copy('%(JsonText.Identity)').StartsWith('$(StrPath)'))" />
|
<!-- extract value -->
|
<JsonPath>
|
<Path>$([System.String]::Copy('%(JsonPath.Identity)').Substring($(StrPath.Length)).Trim(',').Trim('"'))</Path>
|
</JsonPath>
|
|
<!-- list of all lines starting with '"plugin": ' -->
|
<JsonPlugin
|
Include="@(JsonText)"
|
Condition="$([System.String]::Copy('%(JsonText.Identity)').StartsWith('$(StrPlugin)'))" />
|
<!-- extract value -->
|
<JsonPlugin>
|
<Plugin>$([System.String]::Copy('%(JsonPlugin.Identity)').Substring($(StrPlugin.Length)).Trim(',').Trim('"'))</Plugin>
|
</JsonPlugin>
|
</ItemGroup>
|
|
<!-- join lists of extracted values into single list of imports -->
|
<Join LeftItems="@(JsonClassName)" RightItems="@(JsonPath)" On="ROW_NUMBER">
|
<Output TaskParameter="Result" ItemName="JsonAux"/>
|
</Join>
|
<Join LeftItems="@(JsonAux)" RightItems="@(JsonPlugin)" On="ROW_NUMBER">
|
<Output TaskParameter="Result" ItemName="Json"/>
|
</Join>
|
<!-- remove duplicate import items -->
|
<RemoveDuplicates Inputs="@(Json->'%(ClassName)')">
|
<Output TaskParameter="Filtered" ItemName="QtQmlImport"/>
|
</RemoveDuplicates>
|
|
<!-- @(QtQmlImport) => list of required imports -->
|
|
<!-- clean-up -->
|
<PropertyGroup>
|
<StrClassName/>
|
<StrPath/>
|
<StrPlugin/>
|
</PropertyGroup>
|
<ItemGroup>
|
<JsonText Remove="@(JsonText)" />
|
<JsonClassName Remove="@(JsonClassName)"/>
|
<JsonPath Remove="@(JsonPath)"/>
|
<JsonPlugin Remove="@(JsonPlugin)"/>
|
<JsonAux Remove="@(JsonAux)" />
|
<Json Remove="@(Json)" />
|
</ItemGroup>
|
</Target>
|
|
<!--
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
/// TARGET QtQmlScanImports
|
/// => runs once for each QML file
|
/// => skipped if corresponding JSON output file is up-to-date
|
/// => targets that must run first: QtQmlStaticPrepare
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
// Run qmlimportscanner tool.
|
// -->
|
<Target
|
Name="QtQmlScanImports"
|
Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
DependsOnTargets="QtQmlStaticPrepare"
|
Inputs="%(QtQml.Identity)"
|
Outputs="%(QtQml.ImportJson)">
|
|
<!-- create QML work dir -->
|
<MakeDir Directories="$(QtQmlIntDir)" />
|
|
<!-- map local paths to build host paths -->
|
<ItemGroup>
|
<LocalPath Include="QtQmlFile">
|
<Name>Path</Name>
|
<Item>%(QtQml.Identity)</Item>
|
<Value>%(QtQml.Identity)</Value>
|
</LocalPath>
|
<LocalPath Include="QtQmlImportJson">
|
<Name>Path</Name>
|
<Item>%(QtQml.ImportJson)</Item>
|
<Value>%(QtQml.ImportJson)</Value>
|
</LocalPath>
|
<LocalPath Include="QtInstallQml">
|
<Name>Path</Name>
|
<Item>$(QMake_QT_INSTALL_QML_)</Item>
|
<Value>$(QMake_QT_INSTALL_QML_)</Value>
|
</LocalPath>
|
</ItemGroup>
|
<HostTranslatePaths Items="@(LocalPath)" Names="Path">
|
<Output TaskParameter="Result" ItemName="HostPath"/>
|
</HostTranslatePaths>
|
<ItemGroup>
|
<QtQmlFile Include="@(HostPath->WithMetadataValue('Identity', 'QtQmlFile'))">
|
<LocalPath>%(Item)</LocalPath>
|
<HostPath>%(Value)</HostPath>
|
</QtQmlFile>
|
<QtQmlImportJson Include="@(HostPath->WithMetadataValue('Identity', 'QtQmlImportJson'))">
|
<LocalPath>%(Item)</LocalPath>
|
<HostPath>%(Value)</HostPath>
|
</QtQmlImportJson>
|
<QtInstallQml Include="@(HostPath->WithMetadataValue('Identity', 'QtInstallQml'))">
|
<LocalPath>%(Item)</LocalPath>
|
<HostPath>%(Value)</HostPath>
|
</QtInstallQml>
|
</ItemGroup>
|
|
<!-- qmlimportscanner command line -->
|
<PropertyGroup>
|
<Cmd><![CDATA["$(QtToolsPath)/qmlimportscanner.exe"]]></Cmd>
|
<Cmd><![CDATA[$(Cmd) -qmlFiles @(QtQmlFile->'%(HostPath)')]]></Cmd>
|
<Cmd><![CDATA[$(Cmd) -importPath @(QtInstallQml->'%(HostPath)')]]></Cmd>
|
</PropertyGroup>
|
|
<!-- run qmlimportscanner -->
|
<HostExec
|
Command="$(Cmd)" RedirectStdOut="@(QtQmlImportJson->'%(HostPath)')"
|
Inputs="@(QtQmlFile->'%(HostPath)')"
|
Outputs="@(QtQmlImportJson->'%(HostPath)')"
|
RemoteTarget="$(ResolvedRemoteTarget)"
|
RemoteProjectDir="$(_ResolvedRemoteProjectDir)" />
|
</Target>
|
|
<!--
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
/// TARGET QtQmlStaticPrepare
|
/// => runs once for each QML file
|
/// => skipped if $(QtStaticPlugins) is false
|
/// => skipped if there are no QML files in the project
|
/// => targets that must run first: QtQmlCreateItems
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
// Calculate path of .json file with the output of qmlimportscanner for each QML file.
|
// * Format: <QML work dir> '\' SHA1(<path to QML file>) '_' <QML file name> '.json'
|
// -->
|
<Target
|
Name="QtQmlStaticPrepare"
|
Condition="'$(QtStaticPlugins)' == 'true' AND '@(QtQml)' != ''"
|
DependsOnTargets="QtQmlCreateItems"
|
Inputs="%(QtQml.Identity)"
|
Outputs="@(QtQml->'####### Do not skip this target #######')">
|
<!-- calculate SHA1 of QML file path, relative to project dir -->
|
<Hash ItemsToHash="@(QtQml)">
|
<Output TaskParameter="HashResult" PropertyName="QtQmlIdentityHash"/>
|
</Hash>
|
<!-- set path to corresponding JSON file -->
|
<ItemGroup>
|
<QtQml>
|
<ImportJson>$([MSBuild]::MakeRelative(
|
'$(ProjectDir)','$(QtQmlIntDir)\$(QtQmlIdentityHash)_%(Filename).json'))</ImportJson>
|
</QtQml>
|
</ItemGroup>
|
</Target>
|
|
<!--
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
// Import dependants
|
// -->
|
<Import
|
Condition="'$(QtMsBuildTargets_AfterQmlStatic)' != ''"
|
Project="$(QtMsBuildTargets_AfterQmlStatic)"/>
|
|
</Project>
|