]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / thrift / lib / csharp / ThriftMSBuildTask / ThriftBuild.cs
CommitLineData
f67539c2
TL
1/**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 * Contains some contributions under the Thrift Software License.
20 * Please see doc/old-thrift-license.txt in the Thrift distribution for
21 * details.
22 */
23
24using System;
25using System.Collections.Generic;
26using System.Linq;
27using System.Text;
28using Microsoft.Build.Framework;
29using Microsoft.Build.Utilities;
30using Microsoft.Build.Tasks;
31using System.IO;
32using System.Diagnostics;
33
34namespace ThriftMSBuildTask
35{
36 /// <summary>
37 /// MSBuild Task to generate csharp from .thrift files, and compile the code into a library: ThriftImpl.dll
38 /// </summary>
39 public class ThriftBuild : Task
40 {
41 /// <summary>
42 /// The full path to the thrift.exe compiler
43 /// </summary>
44 [Required]
45 public ITaskItem ThriftExecutable
46 {
47 get;
48 set;
49 }
50
51 /// <summary>
52 /// The full path to a thrift.dll C# library
53 /// </summary>
54 [Required]
55 public ITaskItem ThriftLibrary
56 {
57 get;
58 set;
59 }
60
61 /// <summary>
62 /// A direcotry containing .thrift files
63 /// </summary>
64 [Required]
65 public ITaskItem ThriftDefinitionDir
66 {
67 get;
68 set;
69 }
70
71 /// <summary>
72 /// The name of the auto-gen and compiled thrift library. It will placed in
73 /// the same directory as ThriftLibrary
74 /// </summary>
75 [Required]
76 public ITaskItem OutputName
77 {
78 get;
79 set;
80 }
81
82 /// <summary>
83 /// The full path to the compiled ThriftLibrary. This allows msbuild tasks to use this
84 /// output as a variable for use elsewhere.
85 /// </summary>
86 [Output]
87 public ITaskItem ThriftImplementation
88 {
89 get { return thriftImpl; }
90 }
91
92 private ITaskItem thriftImpl;
93 private const string lastCompilationName = "LAST_COMP_TIMESTAMP";
94
95 //use the Message Build Task to write something to build log
96 private void LogMessage(string text, MessageImportance importance)
97 {
98 Message m = new Message();
99 m.Text = text;
100 m.Importance = importance.ToString();
101 m.BuildEngine = this.BuildEngine;
102 m.Execute();
103 }
104
105 //recursively find .cs files in srcDir, paths should initially be non-null and empty
106 private void FindSourcesHelper(string srcDir, List<string> paths)
107 {
108 string[] files = Directory.GetFiles(srcDir, "*.cs");
109 foreach (string f in files)
110 {
111 paths.Add(f);
112 }
113 string[] dirs = Directory.GetDirectories(srcDir);
114 foreach (string dir in dirs)
115 {
116 FindSourcesHelper(dir, paths);
117 }
118 }
119
120 /// <summary>
121 /// Quote paths with spaces
122 /// </summary>
123 private string SafePath(string path)
124 {
125 if (path.Contains(' ') && !path.StartsWith("\""))
126 {
127 return "\"" + path + "\"";
128 }
129 return path;
130 }
131
132 private ITaskItem[] FindSources(string srcDir)
133 {
134 List<string> files = new List<string>();
135 FindSourcesHelper(srcDir, files);
136 ITaskItem[] items = new ITaskItem[files.Count];
137 for (int i = 0; i < items.Length; i++)
138 {
139 items[i] = new TaskItem(files[i]);
140 }
141 return items;
142 }
143
144 private string LastWriteTime(string defDir)
145 {
146 string[] files = Directory.GetFiles(defDir, "*.thrift");
147 DateTime d = (new DirectoryInfo(defDir)).LastWriteTime;
148 foreach(string file in files)
149 {
150 FileInfo f = new FileInfo(file);
151 DateTime curr = f.LastWriteTime;
152 if (DateTime.Compare(curr, d) > 0)
153 {
154 d = curr;
155 }
156 }
157 return d.ToFileTimeUtc().ToString();
158 }
159
160 public override bool Execute()
161 {
162 string defDir = SafePath(ThriftDefinitionDir.ItemSpec);
163 //look for last compilation timestamp
164 string lastBuildPath = Path.Combine(defDir, lastCompilationName);
165 DirectoryInfo defDirInfo = new DirectoryInfo(defDir);
166 string lastWrite = LastWriteTime(defDir);
167 if (File.Exists(lastBuildPath))
168 {
169 string lastComp = File.ReadAllText(lastBuildPath);
170 //don't recompile if the thrift library has been updated since lastComp
171 FileInfo f = new FileInfo(ThriftLibrary.ItemSpec);
172 string thriftLibTime = f.LastWriteTimeUtc.ToFileTimeUtc().ToString();
173 if (lastComp.CompareTo(thriftLibTime) < 0)
174 {
175 //new thrift library, do a compile
176 lastWrite = thriftLibTime;
177 }
178 else if (lastComp == lastWrite || (lastComp == thriftLibTime && lastComp.CompareTo(lastWrite) > 0))
179 {
180 //the .thrift dir hasn't been written to since last compilation, don't need to do anything
181 LogMessage("ThriftImpl up-to-date", MessageImportance.High);
182 return true;
183 }
184 }
185
186 //find the directory of the thriftlibrary (that's where output will go)
187 FileInfo thriftLibInfo = new FileInfo(SafePath(ThriftLibrary.ItemSpec));
188 string thriftDir = thriftLibInfo.Directory.FullName;
189
190 string genDir = Path.Combine(thriftDir, "gen-csharp");
191 if (Directory.Exists(genDir))
192 {
193 try
194 {
195 Directory.Delete(genDir, true);
196 }
197 catch { /*eh i tried, just over-write now*/}
198 }
199
200 //run the thrift executable to generate C#
201 foreach (string thriftFile in Directory.GetFiles(defDir, "*.thrift"))
202 {
203 LogMessage("Generating code for: " + thriftFile, MessageImportance.Normal);
204 Process p = new Process();
205 p.StartInfo.FileName = SafePath(ThriftExecutable.ItemSpec);
206 p.StartInfo.Arguments = "--gen csharp -o " + SafePath(thriftDir) + " -r " + thriftFile;
207 p.StartInfo.UseShellExecute = false;
208 p.StartInfo.CreateNoWindow = true;
209 p.StartInfo.RedirectStandardOutput = false;
210 p.Start();
211 p.WaitForExit();
212 if (p.ExitCode != 0)
213 {
214 LogMessage("thrift.exe failed to compile " + thriftFile, MessageImportance.High);
215 return false;
216 }
217 if (p.ExitCode != 0)
218 {
219 LogMessage("thrift.exe failed to compile " + thriftFile, MessageImportance.High);
220 return false;
221 }
222 }
223
224 Csc csc = new Csc();
225 csc.TargetType = "library";
226 csc.References = new ITaskItem[] { new TaskItem(ThriftLibrary.ItemSpec) };
227 csc.EmitDebugInformation = true;
228 string outputPath = Path.Combine(thriftDir, OutputName.ItemSpec);
229 csc.OutputAssembly = new TaskItem(outputPath);
230 csc.Sources = FindSources(Path.Combine(thriftDir, "gen-csharp"));
231 csc.BuildEngine = this.BuildEngine;
232 LogMessage("Compiling generated cs...", MessageImportance.Normal);
233 if (!csc.Execute())
234 {
235 return false;
236 }
237
238 //write file to defDir to indicate a build was successfully completed
239 File.WriteAllText(lastBuildPath, lastWrite);
240
241 thriftImpl = new TaskItem(outputPath);
242
243 return true;
244 }
245 }
246}