From 84da3f6c94dbe7e36aaf088890fda5fcf3b3efb0 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 22 Aug 2021 14:33:13 +0300 Subject: [PATCH] Add support for generating Visual C++ projects --- source/builder.cpp | 9 +++ source/builder.h | 1 + source/sourcepackage.cpp | 4 ++ source/systemtools.cpp | 5 ++ source/vcxprojectfile.cpp | 9 +++ source/vcxprojectfile.h | 14 ++++ source/vcxprojectgenerator.cpp | 126 +++++++++++++++++++++++++++++++++ source/vcxprojectgenerator.h | 31 ++++++++ 8 files changed, 199 insertions(+) create mode 100644 source/vcxprojectfile.cpp create mode 100644 source/vcxprojectfile.h create mode 100644 source/vcxprojectgenerator.cpp create mode 100644 source/vcxprojectgenerator.h diff --git a/source/builder.cpp b/source/builder.cpp index 6eeaa2f..3ad6146 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -59,6 +59,15 @@ void Builder::set_architecture(const string &name) } } +vector Builder::get_build_types() const +{ + vector keys; + keys.reserve(build_types.size()); + for(BuildTypeMap::const_iterator i=build_types.begin(); i!=build_types.end(); ++i) + keys.push_back(i->first); + return keys; +} + void Builder::set_build_type(const string &name) { build_type = &get_item(build_types, name); diff --git a/source/builder.h b/source/builder.h index d12cf00..9ea6677 100644 --- a/source/builder.h +++ b/source/builder.h @@ -74,6 +74,7 @@ public: const Architecture &get_current_arch() const { return *current_arch; } const Architecture &get_native_arch() const { return native_arch; } void set_build_type(const std::string &); + std::vector get_build_types() const; const BuildType &get_build_type() const { return *build_type; } BuildGraph &get_build_graph() { return build_graph; } void set_prefix(const Msp::FS::Path &); diff --git a/source/sourcepackage.cpp b/source/sourcepackage.cpp index 0a69d7a..c4061a4 100644 --- a/source/sourcepackage.cpp +++ b/source/sourcepackage.cpp @@ -17,6 +17,7 @@ #include "sourcegenerator.h" #include "sourcepackage.h" #include "tool.h" +#include "vcxprojectfile.h" using namespace std; using namespace Msp; @@ -145,6 +146,9 @@ void SourcePackage::do_prepare() builder.get_build_graph().get_target("install")->add_dependency(*builder.get_toolchain().get_tool("CP").create_target(*pc)); } } + + if(arch.get_system()=="windows") + new VcxProjectFile(builder, *this); } void SourcePackage::save_caches() diff --git a/source/systemtools.cpp b/source/systemtools.cpp index 77fe2be..c35b4ae 100644 --- a/source/systemtools.cpp +++ b/source/systemtools.cpp @@ -6,6 +6,7 @@ #include "gnulinker.h" #include "mingwdlltool.h" #include "systemtools.h" +#include "vcxprojectgenerator.h" using namespace std; @@ -27,6 +28,10 @@ SystemTools::SystemTools(Builder &builder, const Architecture &arch) add_tool(new GnuLinker(builder, arch)); add_tool(new GnuArchiver(builder, arch)); + if(arch.get_system()=="windows") + { add_tool(new MingwDllTool(builder, arch)); + add_tool(new VcxProjectGenerator(builder)); + } } diff --git a/source/vcxprojectfile.cpp b/source/vcxprojectfile.cpp new file mode 100644 index 0000000..7b09db0 --- /dev/null +++ b/source/vcxprojectfile.cpp @@ -0,0 +1,9 @@ +#include "builder.h" +#include "sourcepackage.h" +#include "vcxprojectfile.h" + +VcxProjectFile::VcxProjectFile(Builder &b, const SourcePackage &p): + FileTarget(b, p, p.get_source_directory()/(p.get_name()+".vcxproj")) +{ + tool = &builder.get_toolchain().get_tool("VCXG"); +} diff --git a/source/vcxprojectfile.h b/source/vcxprojectfile.h new file mode 100644 index 0000000..b5a90d1 --- /dev/null +++ b/source/vcxprojectfile.h @@ -0,0 +1,14 @@ +#ifndef VCXPROJECTFILE_H_ +#define VCXPROJECTFILE_H_ + +#include "filetarget.h" + +class VcxProjectFile: public FileTarget +{ +public: + VcxProjectFile(Builder &, const SourcePackage &); + + virtual const char *get_type() const { return "VcxProjectFile"; } +}; + +#endif diff --git a/source/vcxprojectgenerator.cpp b/source/vcxprojectgenerator.cpp new file mode 100644 index 0000000..b5c42c5 --- /dev/null +++ b/source/vcxprojectgenerator.cpp @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include "builder.h" +#include "csourcefile.h" +#include "executable.h" +#include "sourcepackage.h" +#include "vcxprojectfile.h" +#include "vcxprojectgenerator.h" + +using namespace std; +using namespace Msp; + +VcxProjectGenerator::VcxProjectGenerator(Builder &b): + Tool(b, "VCXG") +{ } + +Target *VcxProjectGenerator::create_target(const list &, const string &) +{ + throw logic_error("Not implemented"); +} + +Task *VcxProjectGenerator::run(const Target &target) const +{ + const VcxProjectFile &project = dynamic_cast(target); + Worker *worker = new Worker(project); + return new InternalTask(worker); +} + + +VcxProjectGenerator::Worker::Worker(const VcxProjectFile &t): + target(t) +{ } + +void VcxProjectGenerator::Worker::main() +{ + const SourcePackage &spkg = *target.get_package(); + Builder &builder = spkg.get_builder(); + + IO::BufferedFile out(target.get_path().str(), IO::M_WRITE); + IO::print(out, "\n"); + + IO::print(out, "\t\n"); + vector build_types = builder.get_build_types(); + const char *platforms[] = { "x86-32", "x86-64", 0 }; + for(const char **i=platforms; *i; ++i) + for(vector::const_iterator j=build_types.begin(); j!=build_types.end(); ++j) + { + IO::print(out, "\t\t\n", *j, *i); + IO::print(out, "\t\t\t%s\n", *j); + IO::print(out, "\t\t\t%s\n", *i); + IO::print(out, "\t\t\n"); + } + IO::print(out, "\t\n"); + + IO::print(out, "\t\n"); + IO::print(out, "\t\t15.0\n"); + IO::print(out, "\t\tMakeFileProj\n"); + IO::print(out, "\t\n"); + + IO::print(out, "\t\n"); + + const Target *world = builder.get_build_graph().get_target("world"); + const Target::Dependencies &world_deps = world->get_dependencies(); + const Executable *exe = 0; + for(Target::Dependencies::const_iterator i=world_deps.begin(); (!exe && i!=world_deps.end()); ++i) + if((*i)->get_package()==&spkg) + exe = dynamic_cast(*i); + + const char *argv0 = Application::get_argv0(); + for(const char **i=platforms; *i; ++i) + for(vector::const_iterator j=build_types.begin(); j!=build_types.end(); ++j) + { + IO::print(out, "\t\n", *j, *i); + IO::print(out, "\t\tMakeFile\n"); + IO::print(out, "\t\t%s --arch=%s --build-type=%s\n", argv0, *i, *j); + IO::print(out, "\t\t%s --arch=%s --build-type=%s -c\n", argv0, *i, *j); + IO::print(out, "\t\t%s --arch=%s --build-type=%s -B\n", argv0, *i, *j); + if(exe) + IO::print(out, "\t\t%s\n", exe->get_path()); + IO::print(out, "\t\n"); + } + + IO::print(out, "\t\n"); + + const BuildGraph::TargetMap &targets = builder.get_build_graph().get_targets(); + vector sources; + vector includes; + vector others; + for(BuildGraph::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i) + if(i->second->get_package()==&spkg && !i->second->is_buildable()) + if(const FileTarget *file = dynamic_cast(i->second)) + { + if(dynamic_cast(file)) + { + string ext = tolower(FS::extpart(FS::basename(file->get_path()))); + if(ext==".h" || ext==".hpp") + includes.push_back(file); + else + sources.push_back(file); + } + else + others.push_back(file); + } + + IO::print(out, "\t\n"); + for(vector::const_iterator i=sources.begin(); i!=sources.end(); ++i) + IO::print(out, "\t\t\n", (*i)->get_path()); + IO::print(out, "\t\n"); + + IO::print(out, "\t\n"); + for(vector::const_iterator i=includes.begin(); i!=includes.end(); ++i) + IO::print(out, "\t\t\n", (*i)->get_path()); + IO::print(out, "\t\n"); + + IO::print(out, "\t\n"); + for(vector::const_iterator i=others.begin(); i!=others.end(); ++i) + IO::print(out, "\t\t\n", (*i)->get_path()); + IO::print(out, "\t\n"); + + IO::print(out, "\t\n"); + IO::print(out, "\n"); + + status = Task::SUCCESS; +} diff --git a/source/vcxprojectgenerator.h b/source/vcxprojectgenerator.h new file mode 100644 index 0000000..919b8ec --- /dev/null +++ b/source/vcxprojectgenerator.h @@ -0,0 +1,31 @@ +#ifndef VCXPROJECTGENERATOR_H_ +#define VCXPROJECTGENERATOR_H_ + +#include "internaltask.h" +#include "tool.h" + +class VcxProjectFile; + +class VcxProjectGenerator: public Tool +{ +private: + class Worker: public InternalTask::Worker + { + private: + const VcxProjectFile ⌖ + + public: + Worker(const VcxProjectFile &); + + private: + virtual void main(); + }; + +public: + VcxProjectGenerator(Builder &); + + virtual Target *create_target(const std::list &, const std::string &); + virtual Task *run(const Target &) const; +}; + +#endif -- 2.45.2