Repository navigation
Expand file tree
/
Copy pathCMakeConfigureTask.cs
More file actions
266 lines (235 loc) · 8.67 KB
/
Copy pathCMakeConfigureTask.cs
File metadata and controls
266 lines (235 loc) · 8.67 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Tasks;
using NAnt.Core.Types;
using NAnt.Core.Util;
namespace NAnt.CMake.Tasks
{
[TaskName("cmake-configure")]
public class CMakeConfigureTask : ExternalProgramBase
{
#region Private Instance Fields
private DirectoryInfo mBuildDirectory;
private string mBuildType;
private string mGenerator;
private FileInfo mPreloadScript;
private string mCmakePath = "cmake";
private string mCmakeArgs;
#endregion Private Instance Fields
#region Public Instance Properties
/// <summary>
/// The source directory (relative to basedir). This is the directory that contains the top-level cmake script(<c>CMakeLists.txt</c>)
/// </summary>
/// <value>
/// The directory that contains the top-level cmake script.
/// </value>
/// <remarks>
/// <para>
/// The source directory will be evaluated relative to the project's
/// base directory if it is relative.
/// </para>
/// </remarks>
[TaskAttribute("sourcedir", Required = true)]
[StringValidator(AllowEmpty = false)]
public DirectoryInfo SourceDirectory { get; set; }
/// <summary>
/// The build directory (relative to basedir). The directory where the project will be build in. Will be created relative to basedir.
/// </summary>
/// <value>
/// The directory where the project will be build in.
/// </value>
/// <remarks>
/// <para>
/// The build directory will be evaluated relative to the project's
/// base directory if it is relative.
/// </para>
/// </remarks>
[TaskAttribute("builddir")]
public DirectoryInfo BuildDirectory
{
get
{
if (mBuildDirectory == null)
{
return base.BaseDirectory;
}
return mBuildDirectory;
}
set { mBuildDirectory = value; }
}
/// <summary>
/// This statically specifies what build type (configuration) will be built in this build tree.
/// Common values are <empty>, Debug, Release, RelWithDebInfo and MinSizeRl
/// </summary>
/// <value>
/// The desired build type (configuration).
/// </value>
/// <remarks>
/// <para>
/// An empty value is usually used with multi configuration generators such as Visual Studio.
/// The Debug/Release values are
/// usually used with single configuration generators such as Ninja or Unix Makefiles.
/// If the value is not empty, the CMake cache variable <c>CMAKE_BUILD_TYPE</c>
/// will pre-populated with the value before CMake invocation.
/// </para>
/// </remarks>
[TaskAttribute("buildtype")]
public string BuildType
{
get { return mBuildType; }
set { mBuildType = StringUtils.ConvertEmptyToNull(value); }
}
/// <summary>
/// CMake´s <a href="http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#cmake-generators" target="_blank">buildscript generator</a>
/// to use (e.g. <code>Unix Makefiles</code>). Leave empty to let CMake choose a generator.
/// </summary>
/// <value>
/// The desired build script generator to use.
/// </value>
[TaskAttribute("generator")]
public string Generator
{
get { return mGenerator; }
set { mGenerator = StringUtils.ConvertEmptyToNull(value); }
}
/// <summary>
/// Optional path to a pre-load script file to populate the CMake cache.
/// </summary>
/// <remarks>
/// If not empty, this value will be passed as the value of cmake`s <c>-C</c> commandline option.
/// </remarks>
[TaskAttribute("preloadscript")]
public FileInfo PreloadScript
{
get { return mPreloadScript; }
set { mPreloadScript = value; }
}
/// <summary>
/// Path to cmake execute
/// </summary>
[TaskAttribute("cmakepath")]
[StringValidator(AllowEmpty = false)]
public string CmakePath
{
get { return mCmakePath; }
set { mCmakePath = value; }
}
/// <summary>
/// Environment variables to pass to the program.
/// </summary>
[BuildElement("environment")]
public EnvironmentSet EnvironmentSet { get; } = new EnvironmentSet();
[TaskAttribute("cmakeargs")]
public string CmakeArgs
{
get { return mCmakeArgs; }
set { mCmakeArgs = StringUtils.ConvertEmptyToNull(value); }
}
#endregion Public Instance Properties
#region Override implementation of ExternalProgramBase
/// <summary>
/// Perform additional checks after the task has been initialized.
/// </summary>
protected override void Initialize()
{
base.Initialize();
try
{
// just check if cmake path is a valid filename
if (Path.IsPathRooted(CmakePath))
{
// do nothing
}
}
catch (Exception ex)
{
throw new BuildException(string.Format(CultureInfo.InvariantCulture,
"'{0}' is not a valid value for attribute 'cmakepath' of <{1}>",
CmakePath, Name), Location, ex);
}
}
/// <summary>
/// Gets the filename of the external program to start.
/// </summary>
public override string ProgramFileName
{
get
{
if (Path.IsPathRooted(CmakePath))
{
return CmakePath;
}
// resolve program to full path relative to project directory
string fullPath = Project.GetFullPath(CmakePath);
// check if the program exists in that location
if (File.Exists(fullPath))
{
// return full path to program (which we know exists)
return fullPath;
}
return CmakePath;
}
}
public override string ProgramArguments {
get
{
ArgumentCollection arguments = new ArgumentCollection();
// Source directory
arguments.Add(new Argument { Directory = SourceDirectory });
// Preload script
if (PreloadScript != null)
{
arguments.Add(new Argument("-C"));
arguments.Add(new Argument(mPreloadScript));
}
// Generator
if (Generator != null)
{
arguments.Add(new Argument("-G"));
arguments.Add(new Argument(mGenerator));
}
// Build type
if (BuildType != null)
{
arguments.Add(new Argument($"-DCMAKE_BUILD_TYPE={BuildType}"));
}
// CmakeArgs
StringBuilder args = new StringBuilder(arguments.ToString());
if (CmakeArgs != null)
{
args.Append(' ');
args.Append(CmakeArgs);
}
return args.ToString();
}
}
protected override void PrepareProcess(Process process)
{
base.PrepareProcess(process);
// set working directory to build directory
process.StartInfo.WorkingDirectory = BuildDirectory.FullName;
// set environment variables
foreach (EnvironmentVariable variable in EnvironmentSet.EnvironmentVariables)
{
if (variable.IfDefined && !variable.UnlessDefined)
{
if (variable.Value == null)
{
process.StartInfo.EnvironmentVariables[variable.VariableName] = "";
}
else
{
process.StartInfo.EnvironmentVariables[variable.VariableName] = variable.Value;
}
}
}
}
#endregion Override implementation of ExternalProgramBase
}
}