From eabb3f5b9b0d32adda71d4dd7e56796f7ea3bdd2 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 18 Dec 2022 18:03:41 +0200 Subject: [PATCH] Add ability to generate Visual Studio solution files Currently very minimal, and VS treats the solution as modified immediately after loading it. --- source/builtintools.cpp | 2 ++ source/sourcepackage.cpp | 4 +++ source/vssolutionfile.cpp | 32 +++++++++++++++++++++++ source/vssolutionfile.h | 16 ++++++++++++ source/vssolutiongenerator.cpp | 48 ++++++++++++++++++++++++++++++++++ source/vssolutiongenerator.h | 31 ++++++++++++++++++++++ 6 files changed, 133 insertions(+) create mode 100644 source/vssolutionfile.cpp create mode 100644 source/vssolutionfile.h create mode 100644 source/vssolutiongenerator.cpp create mode 100644 source/vssolutiongenerator.h diff --git a/source/builtintools.cpp b/source/builtintools.cpp index 42ad33f..c2c11e6 100644 --- a/source/builtintools.cpp +++ b/source/builtintools.cpp @@ -4,6 +4,7 @@ #include "pkgconfiggenerator.h" #include "tar.h" #include "vcxprojectgenerator.h" +#include "vssolutiongenerator.h" BuiltinTools::BuiltinTools(Builder &builder) { @@ -11,5 +12,6 @@ BuiltinTools::BuiltinTools(Builder &builder) add_tool(new Tar(builder)); add_tool(new PkgConfigGenerator(builder)); add_tool(new VcxProjectGenerator(builder)); + add_tool(new VsSolutionGenerator(builder)); add_tool(new CompileCommandsGenerator(builder)); } diff --git a/source/sourcepackage.cpp b/source/sourcepackage.cpp index f51f4ab..b98cd75 100644 --- a/source/sourcepackage.cpp +++ b/source/sourcepackage.cpp @@ -19,6 +19,7 @@ #include "sourcepackage.h" #include "tool.h" #include "vcxprojectfile.h" +#include "vssolutionfile.h" using namespace std; using namespace Msp; @@ -151,7 +152,10 @@ void SourcePackage::do_prepare() export_binfo.standards = build_info.standards; if(arch.get_system()=="windows") + { new VcxProjectFile(builder, *this); + new VsSolutionFile(builder, *this); + } new CompileCommandsJson(builder, *this); } diff --git a/source/vssolutionfile.cpp b/source/vssolutionfile.cpp new file mode 100644 index 0000000..fd13d5f --- /dev/null +++ b/source/vssolutionfile.cpp @@ -0,0 +1,32 @@ +#include +#include "builder.h" +#include "sourcepackage.h" +#include "vssolutionfile.h" + +using namespace std; +using namespace Msp; + +VsSolutionFile::VsSolutionFile(Builder &b, const SourcePackage &p): + FileTarget(b, p, p.get_source_directory()/(p.get_name()+".sln")) +{ + tool = &builder.get_toolchain().get_tool("VSSG"); +} + +void VsSolutionFile::find_dependencies() +{ + if(FileTarget *project = builder.get_vfs().get_target(package->get_source_directory()/(package->get_name()+".vcxproj"))) + add_dependency(*project); + + Package::Requirements reqs = package->get_required_packages(); + for(Package::Requirements::iterator i=reqs.begin(); i!=reqs.end(); ++i) + if(const SourcePackage *spkg = dynamic_cast(*i)) + { + if(FileTarget *project = builder.get_vfs().get_target(spkg->get_source_directory()/(spkg->get_name()+".vcxproj"))) + add_dependency(*project); + + const Package::Requirements &rreqs = spkg->get_required_packages(); + for(Package::Requirements::const_iterator j=rreqs.begin(); j!=rreqs.end(); ++j) + if(find(reqs, *j)==reqs.end()) + reqs.push_back(*j); + } +} diff --git a/source/vssolutionfile.h b/source/vssolutionfile.h new file mode 100644 index 0000000..d35b4b9 --- /dev/null +++ b/source/vssolutionfile.h @@ -0,0 +1,16 @@ +#ifndef VSSOLUTIONFILE_H_ +#define VSSOLUTIONFILE_H_ + +#include "filetarget.h" + +class VsSolutionFile: public FileTarget +{ +public: + VsSolutionFile(Builder &, const SourcePackage &); + + virtual const char *get_type() const { return "VsSolutionFile"; } +protected: + virtual void find_dependencies(); +}; + +#endif diff --git a/source/vssolutiongenerator.cpp b/source/vssolutiongenerator.cpp new file mode 100644 index 0000000..90adc69 --- /dev/null +++ b/source/vssolutiongenerator.cpp @@ -0,0 +1,48 @@ +#include +#include +#include "sourcepackage.h" +#include "vcxprojectfile.h" +#include "vssolutionfile.h" +#include "vssolutiongenerator.h" + +using namespace std; +using namespace Msp; + +VsSolutionGenerator::VsSolutionGenerator(Builder &b): + Tool(b, "VSSG") +{ } + +Target *VsSolutionGenerator::create_target(const list &, const string &) +{ + throw logic_error("Not implemented"); +} + +Task *VsSolutionGenerator::run(const Target &target) const +{ + const VsSolutionFile &solution = dynamic_cast(target); + Worker *worker = new Worker(solution); + return new InternalTask(worker); +} + + +VsSolutionGenerator::Worker::Worker(const VsSolutionFile &t): + target(t) +{ } + +void VsSolutionGenerator::Worker::main() +{ + IO::BufferedFile out(target.get_path().str(), IO::M_WRITE); + IO::print(out, "Microsoft Visual Studio Solution File, Format Version 12.00\n"); + IO::print(out, "MinimumVisualStudioVersion = 10.0.40219.1\n"); + + const Target::Dependencies &deps = target.get_dependencies(); + for(Target::Dependencies::const_iterator i=deps.begin(); i!=deps.end(); ++i) + if(const VcxProjectFile *project = dynamic_cast(*i)) + { + const SourcePackage *pkg = project->get_package(); + IO::print(out, "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"%s\", \"%s\", \"{%s}\"\nEndProject\n", + pkg->get_name(), project->get_path(), project->get_guid()); + } + + status = Task::SUCCESS; +} diff --git a/source/vssolutiongenerator.h b/source/vssolutiongenerator.h new file mode 100644 index 0000000..8eaca7c --- /dev/null +++ b/source/vssolutiongenerator.h @@ -0,0 +1,31 @@ +#ifndef VSSOLUTIONGENERATOR_H_ +#define VSSOLUTIONGENERATOR_H_ + +#include "internaltask.h" +#include "tool.h" + +class VsSolutionFile; + +class VsSolutionGenerator: public Tool +{ +private: + class Worker: public InternalTask::Worker + { + private: + const VsSolutionFile ⌖ + + public: + Worker(const VsSolutionFile &); + + private: + virtual void main(); + }; + +public: + VsSolutionGenerator(Builder &); + + virtual Target *create_target(const std::list &, const std::string &); + virtual Task *run(const Target &) const; +}; + +#endif -- 2.45.2