efl

Форк
0
277 строк · 7.2 Кб
1
/*
2
 * Copyright 2019 by its authors. See AUTHORS.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
#include <iostream>
18
#include <fstream>
19

20
#include <stdlib.h>
21
#include <unistd.h>
22
#include <getopt.h>
23
#include <libgen.h>
24

25
#include <string>
26
#include <algorithm>
27
#include <stdexcept>
28
#include <iosfwd>
29

30
#ifdef HAVE_CONFIG_H
31
# include <config.h>
32
#endif
33

34
#include <Eina.hh>
35

36

37
namespace efl_mono_msbuild_gen {
38

39
/// Program options.
40
struct options_type
41
{
42
   std::string out_file;
43
   std::string out_assembly;
44
   std::string target_type;
45
   std::string platform;
46
   std::vector<std::string> cs_files;
47
   std::vector<std::string> defines;
48
   std::vector<std::string> references;
49
   std::vector<std::string> lib_paths;
50
};
51

52
efl::eina::log_domain domain("efl_mono_msbuild_gen");
53

54
namespace {
55

56
void
57
_print_version()
58
{
59
   std::cerr
60
     << "EFL Mono MSBuild Generator (EFL "
61
     << PACKAGE_VERSION << ")" << std::endl;
62
}
63

64
static void
65
_usage(const char *progname)
66
{
67
   std::cerr
68
     << progname
69
     << " [options] [files]" << std::endl
70
     << "Options:" << std::endl
71
     << "  -o, --out-file <file>   The output file name. [default: <classname>.eo.hh]" << std::endl
72
     << "  -v, --version           Print the version." << std::endl
73
     << "  -h, --help              Print this help." << std::endl;
74
   exit(EXIT_FAILURE);
75
}
76

77
static void
78
_assert_not_dup(std::string option, std::string value)
79
{
80
   if (value != "")
81
     {
82
        EINA_CXX_DOM_LOG_ERR(efl_mono_msbuild_gen::domain) <<
83
          "Option -" + option + " already set (" + value + ")";
84
     }
85
}
86

87
static bool
88
opts_check(efl_mono_msbuild_gen::options_type const& opts)
89
{
90
   if (opts.out_file.empty())
91
     {
92
        EINA_CXX_DOM_LOG_ERR(efl_mono_msbuild_gen::domain)
93
          << "Nowhere to generate?" << std::endl;
94
     }
95
   else
96
     return true; // valid.
97
   return false;
98
}
99

100
static efl_mono_msbuild_gen::options_type
101
opts_get(int argc, char **argv)
102
{
103
   efl_mono_msbuild_gen::options_type opts;
104

105
   const struct option long_options[] =
106
     {
107
       { "out-file",  required_argument, 0,  'o' },
108
       { "assembly",  required_argument, 0,  'a' },
109
       { "target-type", required_argument, 0,  't' },
110
       { "platform",  required_argument, 0,  'p' },
111
       { "define",    required_argument, 0,  'd' },
112
       { "reference", required_argument, 0,  'r' },
113
       { "lib-path",  required_argument, 0,  'l' },
114
       { "version",   no_argument,       0,  'v' },
115
       { "help",      no_argument,       0,  'h' },
116
       { 0,           0,                 0,   0  }
117
     };
118
   const char* options = "o:a:t:p:d:r:l:vh";
119

120
   int c, idx;
121
   while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1)
122
     {
123
        if (c == 'o')
124
          {
125
             _assert_not_dup("o", opts.out_file);
126
             opts.out_file = optarg;
127
          }
128
        else if (c == 'a')
129
          {
130
             _assert_not_dup("a", opts.out_assembly);
131
             opts.out_assembly = optarg;
132
          }
133
        else if (c == 't')
134
          {
135
             _assert_not_dup("t", opts.target_type);
136
             opts.target_type = optarg;
137
          }
138
        else if (c == 'p')
139
          {
140
             _assert_not_dup("p", opts.platform);
141
             opts.platform = optarg;
142
          }
143
        else if (c == 'd')
144
          {
145
             opts.defines.push_back(optarg);
146
          }
147
        else if (c == 'r')
148
          {
149
             opts.references.push_back(optarg);
150
          }
151
        else if (c == 'l')
152
          {
153
             opts.lib_paths.push_back(optarg);
154
          }
155
        else if (c == 'h')
156
          {
157
             _usage(argv[0]);
158
          }
159
        else if (c == 'v')
160
          {
161
             _print_version();
162
             if (argc == 2) exit(EXIT_SUCCESS);
163
          }
164
     }
165

166
   for (int i = optind; i < argc; ++i)
167
     {
168
        opts.cs_files.push_back(argv[i]);
169
     }
170

171
   if (!efl_mono_msbuild_gen::opts_check(opts))
172
     {
173
        _usage(argv[0]);
174
        assert(false && "Wrong options passed in command-line");
175
     }
176

177
   return opts;
178
}
179

180
static void
181
run(options_type const& opts)
182
{
183
   std::ofstream os (opts.out_file.c_str());
184
   if(!os.is_open())
185
     {
186
        throw std::runtime_error(std::string{"Couldn't open output file "} + opts.out_file);
187
     }
188

189
   os << "<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n";
190

191
   os << "  <PropertyGroup>\n";
192
   if (opts.target_type == "library")
193
     os << "    <OutputType>Library</OutputType>\n";
194
   //os << "    <Version>" << opts.version << "</Version>\n"; // TODO
195
   if (!opts.defines.empty())
196
     {
197
        os << "    <DefineConstants>$(DefineConstants)";
198
        for (auto const& def : opts.defines)
199
          {
200
              os << ";" << def;
201
          }
202
        os << "</DefineConstants>\n";
203
     }
204
   os << "  </PropertyGroup>\n";
205

206
   if (!opts.cs_files.empty())
207
     {
208
        os << "  <ItemGroup>\n";
209
        for (auto fname : opts.cs_files)
210
          {
211
             std::replace(fname.begin(), fname.end(), '/', '\\');
212
             os << "    <CSFile Include=\"" << fname << "\" />\n";
213
          }
214
        os << "  </ItemGroup>\n";
215
     }
216

217
   if (!opts.references.empty())
218
     {
219
        os << "  <ItemGroup>\n";
220
        for (auto libname : opts.references)
221
          {
222
             os << "    <Reference Include=\"" << libname << "\" />\n";
223
          }
224
        os << "  </ItemGroup>\n";
225
     }
226

227
   if (!opts.lib_paths.empty())
228
     {
229
        os << "  <ItemGroup>\n";
230
        for (auto libpath : opts.lib_paths)
231
          {
232
             std::replace(libpath.begin(), libpath.end(), '/', '\\');
233
             os << "    <LibPath Include=\"" << libpath << "\" />\n";
234
          }
235
        os << "  </ItemGroup>\n";
236
     }
237

238
   os << "  <Target Name=\"Build\">\n";
239
   os << "    <CSC Sources=\"@(CSFile)\" References=\"@(Reference)\" AdditionalLibPaths=\"$(LibPath)\" DefineConstants=\"$(DefineConstants)\" ";
240
   {
241
      if (!opts.out_assembly.empty())
242
        {
243
           os << "OutputAssembly=\"" << opts.out_assembly << "\" ";
244
        }
245
      if (!opts.target_type.empty())
246
        {
247
           os << "TargetType=\"" << opts.target_type << "\" ";
248
        }
249
      if (!opts.platform.empty())
250
        {
251
           os << "Platform=\"" << opts.platform << "\" ";
252
        }
253
   }
254
   os << "/>\n";
255
   os << "  </Target>\n";
256

257
   os << "</Project>\n";
258
}
259

260
} // anonymous namespace
261
} // namespace efl_mono_msbuild_gen
262

263
int main(int argc, char **argv)
264
{
265
   try
266
     {
267
        efl::eina::eina_init eina_init;
268
        efl_mono_msbuild_gen::options_type opts = efl_mono_msbuild_gen::opts_get(argc, argv);
269
        efl_mono_msbuild_gen::run(opts);
270
     }
271
   catch(std::exception const& e)
272
     {
273
        EINA_CXX_DOM_LOG_ERR(efl_mono_msbuild_gen::domain) << "EFL Mono MSBuild generation for the following reason: "  << e.what() << std::endl;
274
        return -1;
275
     }
276
   return 0;
277
}
278

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.