1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#region Task TaskName="HostExec" Condition="('$(VisualStudioVersion)' == '16.0' OR '$(VisualStudioVersion)' == '17.0') AND '$(ApplicationType)' == 'Linux' AND '$(PlatformToolset)' == 'WSL_1_0'"
#region Reference
//$(VCTargetsPath)\Application Type\Linux\1.0\Microsoft.Build.Linux.Tasks.dll
#endregion
#region Using
using System.Collections.Generic;
using System.Linq;
using Microsoft.Build.Framework;
#endregion
#region Comment
/////////////////////////////////////////////////////////////////////////////////////////////////
/// TASK HostExec
/// * Linux build over WSL
/////////////////////////////////////////////////////////////////////////////////////////////////
// Run command in build host.
// Parameters:
// in string Command: Command to run on the build host
// in string RedirectStdOut: Path to file to receive redirected output messages
// * can be NUL to discard messages
// in string RedirectStdErr: Path to file to receive redirected error messages
// * can be NUL to discard messages
// * can be STDOUT to apply the same redirection as output messages
// in string WorkingDirectory: Path to directory where command will be run
// in ITaskItem[] Inputs: List of local -> host path mappings for command inputs
// * item format: cf. HostTranslatePaths task
// in ITaskItem[] Outputs: List of host -> local path mappings for command outputs
// * item format: cf. HostTranslatePaths task
// in string RemoteTarget: Set by ResolveRemoteDir in SSH mode; null otherwise
// in string RemoteProjectDir: Set by ResolveRemoteDir in SSH mode; null otherwise
// in bool IgnoreExitCode: Set flag to disable build error if command failed
// out int ExitCode: status code at command exit
#endregion
namespace QtVsTools.QtMsBuild.Tasks
{
public static class HostExec_LinuxWSL
{
public static QtMSBuild.ITaskLoggingHelper Log { get; set; }
public static IBuildEngine BuildEngine { get; set; }
public static ITaskHost HostObject { get; set; }
public static bool Execute(
#region Parameters
System.String Command,
out System.Int32 ExitCode,
System.String Message = null,
System.String RedirectStdOut = null,
System.String RedirectStdErr = null,
System.String WorkingDirectory = null,
Microsoft.Build.Framework.ITaskItem[] Inputs = null,
Microsoft.Build.Framework.ITaskItem[] Outputs = null,
System.String RemoteTarget = null,
System.String RemoteProjectDir = null,
System.Boolean IgnoreExitCode = false)
#endregion
{
#if (VS2019 || VS2022)
#region Code
if (!string.IsNullOrEmpty(Message))
Log.LogMessage(MessageImportance.High, Message);
Command = "(" + Command + ")";
if (RedirectStdOut == "NUL" || RedirectStdOut == "/dev/null")
Command += " 1> /dev/null";
else if (!string.IsNullOrEmpty(RedirectStdOut))
Command += " 1> " + RedirectStdOut;
if (RedirectStdErr == "NUL" || RedirectStdErr == "/dev/null")
Command += " 2> /dev/null";
else if (RedirectStdErr == "STDOUT")
Command += " 2>&1";
else if (!string.IsNullOrEmpty(RedirectStdErr))
Command += " 2> " + RedirectStdErr;
var createDirs = new List<string>();
if (Inputs != null) {
createDirs.AddRange(Inputs
.Select(x => string.Format("\x24(dirname {0})", x.GetMetadata("Value"))));
}
if (Outputs != null) {
createDirs.AddRange(Outputs
.Select(x => string.Format("\x24(dirname {0})", x.GetMetadata("Value"))));
}
if (!string.IsNullOrEmpty(WorkingDirectory)) {
createDirs.Add(WorkingDirectory);
Command = string.Format("cd {0}; {1}", WorkingDirectory, Command);
}
if (createDirs.Any()) {
Command = string.Format("{0}; {1}",
string.Join("; ", createDirs.Select(x => string.Format("mkdir -p {0}", x))),
Command);
}
var taskExec = new Microsoft.Build.Linux.WSL.Tasks.ExecuteCommand
{
BuildEngine = BuildEngine,
HostObject = HostObject,
ProjectDir = @"$(ProjectDir)",
IntermediateDir = @"$(IntDir)",
WSLPath = @"$(WSLPath)",
Command = Command
};
Log.LogMessage("\r\n==== HostExec: Microsoft.Build.Linux.WSL.Tasks.ExecuteCommand");
Log.LogMessage("ProjectDir: {0}", taskExec.ProjectDir);
Log.LogMessage("IntermediateDir: {0}", taskExec.IntermediateDir);
Log.LogMessage("WSLPath: {0}", taskExec.WSLPath);
Log.LogMessage("Command: {0}", taskExec.Command);
bool ok = taskExec.Execute();
Log.LogMessage("== {0} ExitCode: {1}\r\n", ok ? "OK" : "FAIL", taskExec.ExitCode);
ExitCode = taskExec.ExitCode;
if (!ok && !IgnoreExitCode) {
Log.LogError("Host command failed.");
return false;
}
#endregion
#else
ExitCode = 0;
#endif
return true;
}
}
}
#endregion
|