]> git.tdb.fi Git - builder.git/commitdiff
Add ability to generate Visual Studio solution files
authorMikko Rasa <tdb@tdb.fi>
Sun, 18 Dec 2022 16:03:41 +0000 (18:03 +0200)
committerMikko Rasa <tdb@tdb.fi>
Mon, 19 Dec 2022 00:06:49 +0000 (02:06 +0200)
Currently very minimal, and VS treats the solution as modified
immediately after loading it.

source/builtintools.cpp
source/sourcepackage.cpp
source/vssolutionfile.cpp [new file with mode: 0644]
source/vssolutionfile.h [new file with mode: 0644]
source/vssolutiongenerator.cpp [new file with mode: 0644]
source/vssolutiongenerator.h [new file with mode: 0644]

index 42ad33fdb9309b07ea7fd93474055dccac17b738..c2c11e647c75d102c03508e30650ba7bf3f7afed 100644 (file)
@@ -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));
 }
index f51f4abbc5b48a12ad57dcb689ade1861c694999..b98cd75f02c49108e047b8bebc42b2321d1b86bc 100644 (file)
@@ -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 (file)
index 0000000..fd13d5f
--- /dev/null
@@ -0,0 +1,32 @@
+#include <msp/core/algorithm.h>
+#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<const SourcePackage *>(*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 (file)
index 0000000..d35b4b9
--- /dev/null
@@ -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 (file)
index 0000000..90adc69
--- /dev/null
@@ -0,0 +1,48 @@
+#include <msp/io/file.h>
+#include <msp/io/print.h>
+#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<Target *> &, const string &)
+{
+       throw logic_error("Not implemented");
+}
+
+Task *VsSolutionGenerator::run(const Target &target) const
+{
+       const VsSolutionFile &solution = dynamic_cast<const VsSolutionFile &>(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<const VcxProjectFile *>(*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 (file)
index 0000000..8eaca7c
--- /dev/null
@@ -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 &target;
+
+       public:
+               Worker(const VsSolutionFile &);
+
+       private:
+               virtual void main();
+       };
+
+public:
+       VsSolutionGenerator(Builder &);
+
+       virtual Target *create_target(const std::list<Target *> &, const std::string &);
+       virtual Task *run(const Target &) const;
+};
+
+#endif