diff options
author | Lauro Moura <lauromoura@expertisesolutions.com.br> | 2017-11-23 21:56:11 -0300 |
---|---|---|
committer | Lauro Moura <lauromoura@expertisesolutions.com.br> | 2017-11-29 15:56:57 -0300 |
commit | c1da0634e04eec2e0c839aab301fe14ffcedc956 (patch) | |
tree | c33319eb060b8c9f68866db0494fa88dd0465174 | |
parent | 0fbaebe9f95b22780ce76eeca99a73e9ce7d7ed2 (diff) | |
download | efl-c1da0634e04eec2e0c839aab301fe14ffcedc956.tar.gz |
efl_mono: Add msbuild file generator
Buildsystem integration will come in a future commit.
-rw-r--r-- | src/bin/efl_mono_msbuild_gen/.gitignore | 1 | ||||
-rw-r--r-- | src/bin/efl_mono_msbuild_gen/main.cc | 262 |
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 @@ + +#include <iostream> +#include <fstream> + +#include <stdlib.h> +#include <unistd.h> +#include <getopt.h> +#include <libgen.h> + +#include <string> +#include <algorithm> +#include <stdexcept> +#include <iosfwd> + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <Eina.hh> + + +namespace efl_mono_msbuild_gen { + +/// Program options. +struct options_type +{ + std::string out_file; + std::string out_assembly; + std::string target_type; + std::string platform; + std::vector<std::string> cs_files; + std::vector<std::string> defines; + std::vector<std::string> references; + std::vector<std::string> lib_paths; +}; + +efl::eina::log_domain domain("efl_mono_msbuild_gen"); + +namespace { + +void +_print_version() +{ + std::cerr + << "EFL Mono MSBuild Generator (EFL " + << PACKAGE_VERSION << ")" << std::endl; +} + +static void +_usage(const char *progname) +{ + std::cerr + << progname + << " [options] [files]" << std::endl + << "Options:" << std::endl + << " -o, --out-file <file> The output file name. [default: <classname>.eo.hh]" << std::endl + << " -v, --version Print the version." << std::endl + << " -h, --help Print this help." << std::endl; + exit(EXIT_FAILURE); +} + +static void +_assert_not_dup(std::string option, std::string value) +{ + if (value != "") + { + EINA_CXX_DOM_LOG_ERR(efl_mono_msbuild_gen::domain) << + "Option -" + option + " already set (" + value + ")"; + } +} + +static bool +opts_check(efl_mono_msbuild_gen::options_type const& opts) +{ + if (opts.out_file.empty()) + { + EINA_CXX_DOM_LOG_ERR(efl_mono_msbuild_gen::domain) + << "Nowhere to generate?" << std::endl; + } + else + return true; // valid. + return false; +} + +static efl_mono_msbuild_gen::options_type +opts_get(int argc, char **argv) +{ + efl_mono_msbuild_gen::options_type opts; + + const struct option long_options[] = + { + { "out-file", required_argument, 0, 'o' }, + { "assembly", required_argument, 0, 'a' }, + { "target-type", required_argument, 0, 't' }, + { "platform", required_argument, 0, 'p' }, + { "define", required_argument, 0, 'd' }, + { "reference", required_argument, 0, 'r' }, + { "lib-path", required_argument, 0, 'l' }, + { "version", no_argument, 0, 'v' }, + { "help", no_argument, 0, 'h' }, + { 0, 0, 0, 0 } + }; + const char* options = "o:a:t:p:d:r:l:vh"; + + int c, idx; + while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1) + { + if (c == 'o') + { + _assert_not_dup("o", opts.out_file); + opts.out_file = optarg; + } + else if (c == 'a') + { + _assert_not_dup("a", opts.out_assembly); + opts.out_assembly = optarg; + } + else if (c == 't') + { + _assert_not_dup("t", opts.target_type); + opts.target_type = optarg; + } + else if (c == 'p') + { + _assert_not_dup("p", opts.platform); + opts.platform = optarg; + } + else if (c == 'd') + { + opts.defines.push_back(optarg); + } + else if (c == 'r') + { + opts.references.push_back(optarg); + } + else if (c == 'l') + { + opts.lib_paths.push_back(optarg); + } + else if (c == 'h') + { + _usage(argv[0]); + } + else if (c == 'v') + { + _print_version(); + if (argc == 2) exit(EXIT_SUCCESS); + } + } + + for (int i = optind; i < argc; ++i) + { + opts.cs_files.push_back(argv[i]); + } + + if (!efl_mono_msbuild_gen::opts_check(opts)) + { + _usage(argv[0]); + assert(false && "Wrong options passed in command-line"); + } + + return opts; +} + +static void +run(options_type const& opts) +{ + std::ofstream os (opts.out_file.c_str()); + if(!os.is_open()) + { + throw std::runtime_error(std::string{"Couldn't open output file "} + opts.out_file); + } + + os << "<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"; + + os << " <PropertyGroup>\n"; + if (opts.target_type == "library") + os << " <OutputType>Library</OutputType>\n"; + //os << " <Version>" << opts.version << "</Version>\n"; // TODO + if (!opts.defines.empty()) + { + os << " <DefineConstants>$(DefineConstants)"; + for (auto const& def : opts.defines) + { + os << ";" << def; + } + os << "</DefineConstants>\n"; + } + os << " </PropertyGroup>\n"; + + if (!opts.cs_files.empty()) + { + os << " <ItemGroup>\n"; + for (auto fname : opts.cs_files) + { + std::replace(fname.begin(), fname.end(), '/', '\\'); + os << " <CSFile Include=\"" << fname << "\" />\n"; + } + os << " </ItemGroup>\n"; + } + + if (!opts.references.empty()) + { + os << " <ItemGroup>\n"; + for (auto libname : opts.references) + { + os << " <Reference Include=\"" << libname << "\" />\n"; + } + os << " </ItemGroup>\n"; + } + + if (!opts.lib_paths.empty()) + { + os << " <ItemGroup>\n"; + for (auto libpath : opts.lib_paths) + { + std::replace(libpath.begin(), libpath.end(), '/', '\\'); + os << " <LibPath Include=\"" << libpath << "\" />\n"; + } + os << " </ItemGroup>\n"; + } + + os << " <Target Name=\"Build\">\n"; + os << " <CSC Sources=\"@(CSFile)\" References=\"@(Reference)\" AdditionalLibPaths=\"$(LibPath)\" DefineConstants=\"$(DefineConstants)\" "; + { + if (!opts.out_assembly.empty()) + { + os << "OutputAssembly=\"" << opts.out_assembly << "\" "; + } + if (!opts.target_type.empty()) + { + os << "TargetType=\"" << opts.target_type << "\" "; + } + if (!opts.platform.empty()) + { + os << "Platform=\"" << opts.platform << "\" "; + } + } + os << "/>\n"; + os << " </Target>\n"; + + os << "</Project>\n"; +} + +} // anonymous namespace +} // namespace efl_mono_msbuild_gen + +int main(int argc, char **argv) +{ + try + { + efl::eina::eina_init eina_init; + efl_mono_msbuild_gen::options_type opts = efl_mono_msbuild_gen::opts_get(argc, argv); + efl_mono_msbuild_gen::run(opts); + } + catch(std::exception const& e) + { + EINA_CXX_DOM_LOG_ERR(efl_mono_msbuild_gen::domain) << "EFL Mono MSBuild generation for the following reason: " << e.what() << std::endl; + return -1; + } + return 0; +} |