aboutsummaryrefslogtreecommitdiffstats
path: root/QtMSBuild/Tasks/HostExec_LinuxWSL.cs
blob: bed32190245ccc44ae3a1091ab89e1468fc842eb (plain)
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