<?xml version="1.0" encoding="utf-8"?> <!-- /*************************************************************************************************** Copyright (C) 2023 The Qt Company Ltd. SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only ***************************************************************************************************/ --> <!-- /////////////////////////////////////////////////////////////////////////////////////////////////// /// Definitions specific to rcc /////////////////////////////////////////////////////////////////////////////////////////////////// // --> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// // Import pre-requisites // --> <Import Condition="'$(QtMsBuildTargets_BeforeRcc)' != ''" Project="$(QtMsBuildTargets_BeforeRcc)"/> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// // Qt/MSBuild global properties // --> <PropertyGroup> <QtBuildTargets>QtRcc;$(QtBuildTargets)</QtBuildTargets> </PropertyGroup> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// // Setup item type and property page // --> <Choose> <When Condition="'$(QtVsProjectSettings)' == 'true' AND '$(QtVsProjectClProperties)' == 'true'"> <ItemGroup> <PropertyPageSchema Include="$(MSBuildThisFileDirectory)qtrcc_v3.xml" /> </ItemGroup> </When> <Otherwise> <ItemGroup> <PropertyPageSchema Include="$(MSBuildThisFileDirectory)qtrcc.xml" /> </ItemGroup> </Otherwise> </Choose> <ItemGroup> <AvailableItemName Include="QtRcc"> <Targets>Qt;_ClCompile</Targets> </AvailableItemName> </ItemGroup> <PropertyGroup> <QtRccRuleName>QtRule40_Rcc</QtRccRuleName> </PropertyGroup> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// /// TARGET QtRccInit ///////////////////////////////////////////////////////////////////////////////////////////////// // Initialize default metadata // --> <Target Name="QtRccInit"> <!--// Initialize %(OutputFile) --> <ItemGroup Condition="'$(QtVsProjectSettings)' == 'true' AND '@(QtRcc)' != ''"> <QtRccAux Include="@(QtRcc)"> <OutputFile >$([System.IO.Path]::Combine('%(QtRcc.QtRccDir)','%(QtRcc.QtRccFileName)'))</OutputFile> </QtRccAux> <QtRcc Remove="@(QtRcc)"/> <QtRcc Include="@(QtRccAux)"/> <QtRccAux Remove="@(QtRccAux)"/> </ItemGroup> </Target> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// /// TARGET QtRccSetDependencies ///////////////////////////////////////////////////////////////////////////////////////////////// // Add resource files as dependencies of the QRC file // --> <Target Name="QtRccSetDependencies" DependsOnTargets="QtRccInit" Inputs="%(QtRcc.Identity)" Outputs="@(QtRcc->'####### Don't skip this target #######')"> <ItemGroup> <selected_files Include="$(SelectedFiles)"/> </ItemGroup> <!--// Parse QRC --> <ListQrc QrcFilePath="%(QtRcc.FullPath)"> <Output TaskParameter="Result" ItemName="res_file"/> </ListQrc> <!--// Add dependencies --> <ItemGroup Condition="'@(QtRcc)' != '' AND '@(res_file)' != ''"> <QtRcc> <ResourceFiles>@(res_file)</ResourceFiles> <AdditionalDependencies >%(QtRcc.AdditionalDependencies);@(res_file->'%(FullPath)')</AdditionalDependencies> </QtRcc> </ItemGroup> <!--// Clean-up --> <PropertyGroup> <QtRccExeQuoted/> <QtRccQuoted/> <RccListQuoted/> </PropertyGroup> <ItemGroup> <res_file Remove="@(res_file)"/> </ItemGroup> </Target> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// /// TARGET QtRccPrepare ///////////////////////////////////////////////////////////////////////////////////////////////// // Prepare items for processing // --> <Target Name="QtRccPrepare" DependsOnTargets="QtRccSetDependencies" Inputs="%(QtRcc.Identity)" Outputs="@(QtRcc->'####### Don't skip this target #######')"> <Message Importance="High" Condition="'$(QtDebug)' == 'true'" Text="## QtRccPrepare @(QtRcc)"/> <PropertyGroup> <selected_files>[@(selected_files->'%(Identity)','][')]</selected_files> <file>[@(QtRcc->'%(Identity)')]</file> <output_file>@(QtRcc->'%(OutputFile)')</output_file> <is_selected Condition="$(selected_files.Contains('$(file)'))">true</is_selected> <is_selected Condition="!$(selected_files.Contains('$(file)'))">false</is_selected> </PropertyGroup> <!--// Delete output file to force build of source if it was manually selected to build // (e.g. by the 'Compile' option in the context menu for the file) --> <Delete Files="$(output_file)" Condition="'$(SelectedFiles)' != '' AND '$(is_selected)' == 'true'" /> <!--// If a source was manually selected to build, remove all other sources --> <ItemGroup Condition="'@(selected_files)' != ''"> <QtRcc Remove="@(QtRcc)" Condition="'$(SelectedFiles)' != '' AND '$(is_selected)' != 'true'" /> </ItemGroup> <!--// Remove sources excluded from build --> <ItemGroup> <QtRcc Remove="@(QtRcc)" Condition="'$(SelectedFiles)' == '' AND '%(QtRcc.ExcludedFromBuild)' == 'true'"/> </ItemGroup> <!--// Clean-up --> <PropertyGroup> <selected_files/> <file/> <output_file/> <is_selected/> </PropertyGroup> </Target> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// /// TARGET QtRccSetModified ///////////////////////////////////////////////////////////////////////////////////////////////// // Set InputModified flag for modified files (i.e. Inputs newer than Outputs) // --> <Target Name="QtRccSetModified" DependsOnTargets="QtRccPrepare" Condition="'@(QtRcc)' != ''" Inputs="%(QtRcc.FullPath);%(QtRcc.AdditionalDependencies)" Outputs="@(QtRcc->'%(OutputFile)')"> <Message Importance="High" Condition="'$(QtDebug)' == 'true'" Text="## QtRccSetModified @(QtRcc)" /> <CreateProperty Value="true"> <!-- // Using ValueSetByTask ensures $(input_changed) is only set to 'true' when the target // is actually executed and not when MSBuild is figuring out which targets to run --> <Output TaskParameter="ValueSetByTask" PropertyName="input_changed" /> </CreateProperty> <ItemGroup> <QtRcc> <InputChanged>$(input_changed)</InputChanged> </QtRcc> </ItemGroup> </Target> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// /// TARGET QtRccOverrideCpp ///////////////////////////////////////////////////////////////////////////////////////////////// // // --> <!--<Import Project="qtrcc_cl.targets"/>--> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// /// TARGET QtRcc ///////////////////////////////////////////////////////////////////////////////////////////////// // Process each QRC file and produce the corresponding QtWork items // --> <PropertyGroup> <QtRccDependsOn> QtPrepare; QtRccPrepare; QtRccSetModified; $(QtRccDependsOn) </QtRccDependsOn> </PropertyGroup> <Target Name="QtRcc" DependsOnTargets="$(QtRccDependsOn)" BeforeTargets="$(QtRccBeforeTargets)" AfterTargets="$(QtRccAfterTargets)" Condition="'@(QtRcc)' != ''" Inputs="%(QtRcc.FullPath);%(QtRcc.AdditionalDependencies);$(MSBuildProjectFile)" Outputs="@(QtRcc->'%(OutputFile)')"> <Message Importance="High" Condition="'$(QtDebug)' == 'true'" Text="## QtRcc @(QtRcc)" /> <CreateProperty Value="true"> <Output TaskParameter="ValueSetByTask" PropertyName="dependencies_changed" /> </CreateProperty> <PropertyGroup> <two_pass Condition="'%(QtRcc.TwoPass)' == 'true'">true</two_pass> </PropertyGroup> <!-- /////////////////////////////////////////////////////////////////////////////////////////////// // Convert string lists in source item properties to lists of items // --> <Flatten Items="@(QtRcc)" Metadata="InputFile; OutputFile; TempFile; InitFuncName; Root; Compression; NoCompression; CompressThreshold; BinaryOutput; NoZstd; PassNumber; NoNamespace; Verbose; List; Project; FormatVersion"> <Output TaskParameter="Result" ItemName="LocalOptions" /> </Flatten> <!-- /////////////////////////////////////////////////////////////////////////////////////////////// // Translate local paths to build host paths // --> <HostTranslatePaths Items="@(LocalOptions)" Names="InputFile; OutputFile; TempFile; Root"> <Output TaskParameter="Result" ItemName="options" /> </HostTranslatePaths> <ItemGroup> <!-- ///////////////////////////////////////////////////////////////////////////////////////////// // Remove quotes from all paths // Escape trailing back-slash in paths // Add quotes to paths containing spaces // --> <options> <Value Condition="'%(Name)' == 'InputFile' OR '%(Name)' == 'OutputFile' OR '%(Name)' == 'TempFile' OR '%(Name)' == 'Root'" >$([System.String]::Copy('%(Value)').Replace('"', ''))</Value> </options> <options> <Value Condition="('%(Name)' == 'InputFile' OR '%(Name)' == 'OutputFile' OR '%(Name)' == 'TempFile' OR '%(Name)' == 'Root') AND $([System.String]::Copy('%(Value)').Contains(' ')) AND $([System.String]::Copy('%(Value)').EndsWith('\'))" >%(Value)\</Value> </options> <options> <Value Condition="('%(Name)' == 'InputFile' OR '%(Name)' == 'OutputFile' OR '%(Name)' == 'TempFile' OR '%(Name)' == 'Root') AND $([System.String]::Copy('%(Value)').Contains(' '))" >"%(Value)"</Value> </options> <!-- /////////////////////////////////////////////////////////////////////////////////////////////// // Generate tool command line arguments // --> <!--// inputs Input files (*.qrc) --> <options> <Value Condition="'%(Name)' == 'InputFile'">%(Value)</Value> </options> <!--// -o, -output <file> Write output to <file> --> <options> <Value Condition="'%(Name)' == 'OutputFile' AND '$(two_pass)' != 'true'">-o %(Value)</Value> </options> <options> <Value Condition="'%(Name)' == 'OutputFile' AND '$(two_pass)' == 'true'"></Value> </options> <!--// -t, -temp <file> Use temporary <file> for big resources --> <options> <Value Condition="'%(Name)' == 'TempFile'">--temp %(Value)</Value> </options> <!--// -name <name> Create an external initialization function with <name> --> <options> <Value Condition="'%(Name)' == 'InitFuncName'">--name %(Value)</Value> </options> <!--// -root <path> Prefix resource access path with root path --> <options> <Value Condition="'%(Name)' == 'Root'">--root %(Value)</Value> </options> <!--// -compress <level> Compress input files by <level> --> <options> <Value Condition="'%(Name)' == 'Compression' AND '%(Value)' == 'level1'">--compress 1</Value> </options> <options> <Value Condition="'%(Name)' == 'Compression' AND '%(Value)' == 'level2'">--compress 2</Value> </options> <options> <Value Condition="'%(Name)' == 'Compression' AND '%(Value)' == 'level3'">--compress 3</Value> </options> <options> <Value Condition="'%(Name)' == 'Compression' AND '%(Value)' == 'level4'">--compress 4</Value> </options> <options> <Value Condition="'%(Name)' == 'Compression' AND '%(Value)' == 'level5'">--compress 5</Value> </options> <options> <Value Condition="'%(Name)' == 'Compression' AND '%(Value)' == 'level6'">--compress 6</Value> </options> <options> <Value Condition="'%(Name)' == 'Compression' AND '%(Value)' == 'level7'">--compress 7</Value> </options> <options> <Value Condition="'%(Name)' == 'Compression' AND '%(Value)' == 'level8'">--compress 8</Value> </options> <options> <Value Condition="'%(Name)' == 'Compression' AND '%(Value)' == 'level9'">--compress 9</Value> </options> <options> <Value Condition="'%(Name)' == 'Compression' AND !$([System.String]::Copy('%(Value)').StartsWith('--compress'))"></Value> </options> <!--// -no-compress Disable all compression --> <options> <Value Condition="'%(Name)' == 'NoCompression' AND '%(Value)' != 'true'"></Value> </options> <options> <Value Condition="'%(Name)' == 'NoCompression' AND '%(Value)' == 'true'">--no-compress</Value> </options> <!--// -threshold <level> Threshold to consider compressing files --> <options> <Value Condition="'%(Name)' == 'CompressThreshold'">--threshold %(Value)</Value> </options> <!--// -binary Output a binary file for use as a dynamic source --> <options> <Value Condition="'%(Name)' == 'BinaryOutput' AND '%(Value)' != 'true'"></Value> </options> <options> <Value Condition="'%(Name)' == 'BinaryOutput' AND '%(Value)' == 'true'">--binary</Value> </options> <!--// -no-zstd Disable usage of zstd compression --> <options> <Value Condition="'%(Name)' == 'NoZstd' AND '%(Value)' != 'true'"></Value> </options> <options> <Value Condition="'%(Name)' == 'NoZstd' AND '%(Value)' == 'true'">--no-zstd</Value> </options> <!--// -pass <number> Pass number for big resources --> <options> <Value Condition="'%(Name)' == 'PassNumber'">--pass %(Value)</Value> </options> <!--// -namespace Turn off namespace macros --> <options> <Value Condition="'%(Name)' == 'NoNamespace' AND '%(Value)' != 'true'"></Value> </options> <options> <Value Condition="'%(Name)' == 'NoNamespace' AND '%(Value)' == 'true'">--namespace</Value> </options> <!--// -verbose Enable verbose mode --> <options> <Value Condition="'%(Name)' == 'Verbose' AND '%(Value)' != 'true'"></Value> </options> <options> <Value Condition="'%(Name)' == 'Verbose' AND '%(Value)' == 'true'">--verbose</Value> </options> <!--// -list Only list .qrc file entries, do not generate code --> <options> <Value Condition="'%(Name)' == 'List' AND '%(Value)' != 'true'"></Value> </options> <options> <Value Condition="'%(Name)' == 'List' AND '%(Value)' == 'true'">--list</Value> </options> <!--// -project Output a resource file containing all files from the // current directory --> <options> <Value Condition="'%(Name)' == 'Project' AND '%(Value)' != 'true'"></Value> </options> <options> <Value Condition="'%(Name)' == 'Project' AND '%(Value)' == 'true'">--project</Value> </options> <!--// -format-version <number> The RCC format version to write --> <options> <Value Condition="'%(Name)' == 'FormatVersion'">--format-version %(Value)</Value> </options> </ItemGroup> <PropertyGroup> <options>@(options->'%(Value)', ' ')</options> </PropertyGroup> <!-- /////////////////////////////////////////////////////////////////////////////////////////////// // Aux properties // --> <PropertyGroup> <!--// Force modified flag if source was manually selected to build --> <input_changed Condition="'$(SelectedFiles)' == ''" >%(QtRcc.InputChanged)</input_changed> <input_changed Condition="'$(SelectedFiles)' != ''" >true</input_changed> <!--// Run work in parallel processes --> <run_parallel Condition="'@(QtRcc)' != '' AND '%(QtRcc.ParallelProcess)' == 'true' AND '$(SelectedFiles)' == ''" >true</run_parallel> <!--// Run work in single process --> <run_single Condition="'@(QtRcc)' != '' AND ('%(QtRcc.ParallelProcess)' != 'true' OR '$(SelectedFiles)' != '')" >true</run_single> <!--// Get relative path to output --> <output_relative >$([MSBuild]::MakeRelative($(ProjectDir), %(QtRcc.OutputFile)).TrimStart('\'))</output_relative> </PropertyGroup> <!-- /////////////////////////////////////////////////////////////////////////////////////////////// // Create work item // --> <ItemGroup Condition="'$(run_parallel)' == 'true' OR '$(run_single)' == 'true'"> <QtWork Include="@(QtRcc)"> <WorkType>rcc</WorkType> <ToolPath Condition="'$(QtVsProjectSettings)' == 'true'">$(QtToolsPath)/rcc</ToolPath> <ToolPath Condition="'$(QtVsProjectSettings)' != 'true'">%(QtRcc.QTDIR)\bin\rcc.exe</ToolPath> <Options>$(options)</Options> <Message>%(QtRcc.ExecutionDescription)</Message> <DependenciesChanged>$(dependencies_changed)</DependenciesChanged> <InputChanged>$(input_changed)</InputChanged> <ParallelBuild Condition="'$(run_parallel)' == 'true'">true</ParallelBuild> <ParallelBuild Condition="'$(run_single)' == 'true'">false</ParallelBuild> <!-- /////////////////////////////////////////////////////////////////////////////////////////// // Two-pass ("resources_big"): pass 1 --> <Message Condition="'%(QtRcc.TwoPass)' == 'true'">%(QtRcc.ExecutionDescription) [pass 1]</Message> <RccPass Condition="'%(QtRcc.TwoPass)' == 'true'">1</RccPass> <RccOptions Condition="'%(QtRcc.TwoPass)' == 'true'">$(options)</RccOptions> <Options Condition="'%(QtRcc.TwoPass)' == 'true'" >$(options) -pass 1 -o "%(OutputFile)"</Options> <Optimization Condition="'%(QtRcc.TwoPass)' == 'true'">Disabled</Optimization> <!-- /////////////////////////////////////////////////////////////////////////////////////////// // C++ dynamic source --> <ClCompile Condition="'%(QtRcc.DynamicSource)' == 'output'">$(output_relative)</ClCompile> </QtWork> </ItemGroup> <!-- /////////////////////////////////////////////////////////////////////////////////////////////// // Clean-up // --> <PropertyGroup> <options/> <dependencies_changed/> <input_changed/> <run_parallel/> <run_single/> <output_relative/> <two_pass/> </PropertyGroup> <ItemGroup> <LocalOptions Remove="@(LocalOptions)"/> <options Remove="@(options)"/> <selected_files Remove="@(selected_files)"/> </ItemGroup> </Target> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// /// TARGET QtRccPass2 ///////////////////////////////////////////////////////////////////////////////////////////////// // Two-pass ("resources_big"): pass 2 // --> <Target Name="QtRccPass2" DependsOnTargets="QtRccPass2_GetObjs;QtRccPass2_Exec"/> <Target Name="QtRccPass2_GetObjs" DependsOnTargets="ComputeCLOutputs"> <ItemGroup> <QtRccObj Include="@(Obj->WithMetadataValue('RccPass', '1'))"> <RccPass>2</RccPass> </QtRccObj> </ItemGroup> </Target> <Target Name="QtRccPass2_Exec" DependsOnTargets="QtRccPass2_GetObjs" Condition="'@(QtRccObj)' != ''"> <Move SourceFiles="%(QtRccObj.Identity)" DestinationFiles="%(QtRccObj.Identity)_TMP"/> <Exec Command="@(QtRccObj->'ECHO %(ExecutionDescription) [pass 2] & %(ToolPath) %(RccOptions) -pass 2 -temp "%(Identity)_TMP" -o "%(Identity)"')" IgnoreExitCode="true"/> <ItemGroup> <Obj Remove="@(QtRccObj->'%(Identity)')"/> <Obj Include="@(QtRccObj)"/> <QtRccObj Remove="@(QtRccObj)"/> </ItemGroup> </Target> <Target Name="QtRccPass2_Link" DependsOnTargets="QtRccPass2"/> <Target Name="QtRccPass2_Lib" DependsOnTargets="QtRccPass2"/> <PropertyGroup> <ComputeLinkInputsTargets> $(ComputeLinkInputsTargets); ;QtRccPass2_Link; </ComputeLinkInputsTargets> <ComputeLibInputsTargets> $(ComputeLibInputsTargets); ;QtRccPass2_Lib; </ComputeLibInputsTargets> </PropertyGroup> <!-- ///////////////////////////////////////////////////////////////////////////////////////////////// // Import dependants // --> <Import Condition="'$(QtMsBuildTargets_AfterRcc)' != ''" Project="$(QtMsBuildTargets_AfterRcc)"/> </Project>