summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2017-11-23 21:56:11 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2017-11-29 15:56:57 -0300
commitc1da0634e04eec2e0c839aab301fe14ffcedc956 (patch)
treec33319eb060b8c9f68866db0494fa88dd0465174
parent0fbaebe9f95b22780ce76eeca99a73e9ce7d7ed2 (diff)
efl_mono: Add msbuild file generator
Buildsystem integration will come in a future commit.
-rw-r--r--src/bin/efl_mono_msbuild_gen/.gitignore1
-rw-r--r--src/bin/efl_mono_msbuild_gen/main.cc262
2 files changed, 263 insertions, 0 deletions
diff --git a/src/bin/efl_mono_msbuild_gen/.gitignore b/src/bin/efl_mono_msbuild_gen/.gitignore
new file mode 100644
index 0000000000..421f9eb915
--- /dev/null
+++ b/src/bin/efl_mono_msbuild_gen/.gitignore
@@ -0,0 +1 @@
/efl_mono_msbuild_gen
diff --git a/src/bin/efl_mono_msbuild_gen/main.cc b/src/bin/efl_mono_msbuild_gen/main.cc
new file mode 100644
index 0000000000..bf3d4db413
--- /dev/null
+++ b/src/bin/efl_mono_msbuild_gen/main.cc
@@ -0,0 +1,262 @@
1
2#include <iostream>
3#include <fstream>
4
5#include <stdlib.h>
6#include <unistd.h>
7#include <getopt.h>
8#include <libgen.h>
9
10#include <string>
11#include <algorithm>
12#include <stdexcept>
13#include <iosfwd>
14
15#ifdef HAVE_CONFIG_H
16# include <config.h>
17#endif
18
19#include <Eina.hh>
20
21
22namespace efl_mono_msbuild_gen {
23
24/// Program options.
25struct options_type
26{
27 std::string out_file;
28 std::string out_assembly;
29 std::string target_type;
30 std::string platform;
31 std::vector<std::string> cs_files;
32 std::vector<std::string> defines;
33 std::vector<std::string> references;
34 std::vector<std::string> lib_paths;
35};
36
37efl::eina::log_domain domain("efl_mono_msbuild_gen");
38
39namespace {
40
41void
42_print_version()
43{
44 std::cerr
45 << "EFL Mono MSBuild Generator (EFL "
46 << PACKAGE_VERSION << ")" << std::endl;
47}
48
49static void
50_usage(const char *progname)
51{
52 std::cerr
53 << progname
54 << " [options] [files]" << std::endl
55 << "Options:" << std::endl
56 << " -o, --out-file <file> The output file name. [default: <classname>.eo.hh]" << std::endl
57 << " -v, --version Print the version." << std::endl
58 << " -h, --help Print this help." << std::endl;
59 exit(EXIT_FAILURE);
60}
61
62static void
63_assert_not_dup(std::string option, std::string value)
64{
65 if (value != "")
66 {
67 EINA_CXX_DOM_LOG_ERR(efl_mono_msbuild_gen::domain) <<
68 "Option -" + option + " already set (" + value + ")";
69 }
70}
71
72static bool
73opts_check(efl_mono_msbuild_gen::options_type const& opts)
74{
75 if (opts.out_file.empty())
76 {
77 EINA_CXX_DOM_LOG_ERR(efl_mono_msbuild_gen::domain)
78 << "Nowhere to generate?" << std::endl;
79 }
80 else
81 return true; // valid.
82 return false;
83}
84
85static efl_mono_msbuild_gen::options_type
86opts_get(int argc, char **argv)
87{
88 efl_mono_msbuild_gen::options_type opts;
89
90 const struct option long_options[] =
91 {
92 { "out-file", required_argument, 0, 'o' },
93 { "assembly", required_argument, 0, 'a' },
94 { "target-type", required_argument, 0, 't' },
95 { "platform", required_argument, 0, 'p' },
96 { "define", required_argument, 0, 'd' },
97 { "reference", required_argument, 0, 'r' },
98 { "lib-path", required_argument, 0, 'l' },
99 { "version", no_argument, 0, 'v' },
100 { "help", no_argument, 0, 'h' },
101 { 0, 0, 0, 0 }
102 };
103 const char* options = "o:a:t:p:d:r:l:vh";
104
105 int c, idx;
106 while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1)
107 {
108 if (c == 'o')
109 {
110 _assert_not_dup("o", opts.out_file);
111 opts.out_file = optarg;
112 }
113 else if (c == 'a')
114 {
115 _assert_not_dup("a", opts.out_assembly);
116 opts.out_assembly = optarg;
117 }
118 else if (c == 't')
119 {
120 _assert_not_dup("t", opts.target_type);
121 opts.target_type = optarg;
122 }
123 else if (c == 'p')
124 {
125 _assert_not_dup("p", opts.platform);
126 opts.platform = optarg;
127 }
128 else if (c == 'd')
129 {
130 opts.defines.push_back(optarg);
131 }
132 else if (c == 'r')
133 {
134 opts.references.push_back(optarg);
135 }
136 else if (c == 'l')
137 {
138 opts.lib_paths.push_back(optarg);
139 }
140 else if (c == 'h')
141 {
142 _usage(argv[0]);
143 }
144 else if (c == 'v')
145 {
146 _print_version();
147 if (argc == 2) exit(EXIT_SUCCESS);
148 }
149 }
150
151 for (int i = optind; i < argc; ++i)
152 {
153 opts.cs_files.push_back(argv[i]);
154 }
155
156 if (!efl_mono_msbuild_gen::opts_check(opts))
157 {
158 _usage(argv[0]);
159 assert(false && "Wrong options passed in command-line");
160 }
161
162 return opts;
163}
164
165static void
166run(options_type const& opts)
167{
168 std::ofstream os (opts.out_file.c_str());
169 if(!os.is_open())
170 {
171 throw std::runtime_error(std::string{"Couldn't open output file "} + opts.out_file);
172 }
173
174 os << "<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n";
175
176 os << " <PropertyGroup>\n";
177 if (opts.target_type == "library")
178 os << " <OutputType>Library</OutputType>\n";
179 //os << " <Version>" << opts.version << "</Version>\n"; // TODO
180 if (!opts.defines.empty())
181 {
182 os << " <DefineConstants>$(DefineConstants)";
183 for (auto const& def : opts.defines)
184 {
185 os << ";" << def;
186 }
187 os << "</DefineConstants>\n";
188 }
189 os << " </PropertyGroup>\n";
190
191 if (!opts.cs_files.empty())
192 {
193 os << " <ItemGroup>\n";
194 for (auto fname : opts.cs_files)
195 {
196 std::replace(fname.begin(), fname.end(), '/', '\\');
197 os << " <CSFile Include=\"" << fname << "\" />\n";
198 }
199 os << " </ItemGroup>\n";
200 }
201
202 if (!opts.references.empty())
203 {
204 os << " <ItemGroup>\n";
205 for (auto libname : opts.references)
206 {
207 os << " <Reference Include=\"" << libname << "\" />\n";
208 }
209 os << " </ItemGroup>\n";
210 }
211
212 if (!opts.lib_paths.empty())
213 {
214 os << " <ItemGroup>\n";
215 for (auto libpath : opts.lib_paths)
216 {
217 std::replace(libpath.begin(), libpath.end(), '/', '\\');
218 os << " <LibPath Include=\"" << libpath << "\" />\n";
219 }
220 os << " </ItemGroup>\n";
221 }
222
223 os << " <Target Name=\"Build\">\n";
224 os << " <CSC Sources=\"@(CSFile)\" References=\"@(Reference)\" AdditionalLibPaths=\"$(LibPath)\" DefineConstants=\"$(DefineConstants)\" ";
225 {
226 if (!opts.out_assembly.empty())
227 {
228 os << "OutputAssembly=\"" << opts.out_assembly << "\" ";
229 }
230 if (!opts.target_type.empty())
231 {
232 os << "TargetType=\"" << opts.target_type << "\" ";
233 }
234 if (!opts.platform.empty())
235 {
236 os << "Platform=\"" << opts.platform << "\" ";
237 }
238 }
239 os << "/>\n";
240 os << " </Target>\n";
241
242 os << "</Project>\n";
243}
244
245} // anonymous namespace
246} // namespace efl_mono_msbuild_gen
247
248int main(int argc, char **argv)
249{
250 try
251 {
252 efl::eina::eina_init eina_init;
253 efl_mono_msbuild_gen::options_type opts = efl_mono_msbuild_gen::opts_get(argc, argv);
254 efl_mono_msbuild_gen::run(opts);
255 }
256 catch(std::exception const& e)
257 {
258 EINA_CXX_DOM_LOG_ERR(efl_mono_msbuild_gen::domain) << "EFL Mono MSBuild generation for the following reason: " << e.what() << std::endl;
259 return -1;
260 }
261 return 0;
262}