#include "basetools.h"
#include "compilecommandsjson.h"
#include "pkgconfigfile.h"
-#include "vcxprojectfile.h"
-#include "vssolutionfile.h"
void BasePlugin::add_tools(Toolchain &toolchain, const Architecture &) const
{
builder.get_build_graph().get_target("install")->add_dependency(*builder.get_toolchain().get_tool("CP").create_target(*pc));
}
- if(native_arch.get_system()=="windows")
- {
- new VcxProjectFile(builder, spkg);
- new VsSolutionFile(builder, spkg);
- }
-
new CompileCommandsJson(builder, spkg);
}
#include "compilecommandsgenerator.h"
#include "pkgconfiggenerator.h"
#include "tar.h"
-#include "vcxprojectgenerator.h"
-#include "vssolutiongenerator.h"
BaseTools::BaseTools(Builder &builder)
{
add_tool(new Copy(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));
}
+++ /dev/null
-#include <msp/builder/builder.h>
-#include <msp/builder/sourcepackage.h>
-#include <msp/crypto/md5.h>
-#include <msp/strings/format.h>
-#include "vcxprojectfile.h"
-
-using namespace Msp;
-
-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");
-
- char digest[16];
- Crypto::MD5(package->get_name()).get_digest(digest, sizeof(digest));
- digest[6] = 3;
- digest[8] = (digest[6]&0x3F)|0x80;
- for(unsigned j=0; j<sizeof(digest); ++j)
- {
- if(j==4 || j==6 || j==8 || j==10)
- guid += '-';
- guid += format("%02x", static_cast<unsigned char>(digest[j]));
- }
-}
+++ /dev/null
-#ifndef VCXPROJECTFILE_H_
-#define VCXPROJECTFILE_H_
-
-#include <msp/builder/filetarget.h>
-
-class VcxProjectFile: public FileTarget
-{
-private:
- std::string guid;
-
-public:
- VcxProjectFile(Builder &, const SourcePackage &);
-
- const char *get_type() const override { return "VcxProjectFile"; }
-
- const std::string &get_guid() const { return guid; }
-};
-
-#endif
+++ /dev/null
-#include <msp/builder/builder.h>
-#include <msp/builder/csourcefile.h>
-#include <msp/builder/executable.h>
-#include <msp/builder/sourcepackage.h>
-#include <msp/core/application.h>
-#include <msp/fs/utils.h>
-#include <msp/io/print.h>
-#include <msp/strings/utils.h>
-#include "vcxprojectfile.h"
-#include "vcxprojectgenerator.h"
-
-using namespace std;
-using namespace Msp;
-
-VcxProjectGenerator::VcxProjectGenerator(Builder &b):
- Tool(b, "VCXG")
-{
- set_run_internal(_run);
-}
-
-Target *VcxProjectGenerator::create_target(const vector<Target *> &, const string &)
-{
- throw logic_error("Not implemented");
-}
-
-bool VcxProjectGenerator::_run(const VcxProjectFile &project)
-{
- const SourcePackage &spkg = *project.get_package();
- Builder &builder = spkg.get_builder();
-
- IO::BufferedFile out(project.get_path().str(), IO::M_WRITE);
- IO::print(out, "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n");
-
- IO::print(out, "\t<ItemGroup Label=\"ProjectConfigurations\">\n");
- vector<string> build_types = builder.get_build_types();
- const char *platforms[] = { "Win32", "x64" };
- for(const char *p: platforms)
- for(const string &b: build_types)
- {
- IO::print(out, "\t\t<ProjectConfiguration Include=\"%s|%s\">\n", b, p);
- IO::print(out, "\t\t\t<Configuration>%s</Configuration>\n", b);
- IO::print(out, "\t\t\t<Platform>%s</Platform>\n", p);
- IO::print(out, "\t\t</ProjectConfiguration>\n");
- }
- IO::print(out, "\t</ItemGroup>\n");
-
- IO::print(out, "\t<PropertyGroup Label=\"Globals\">\n");
- IO::print(out, "\t\t<VCProjectVersion>15.0</VCProjectVersion>\n");
- IO::print(out, "\t\t<Keyword>MakeFileProj</Keyword>\n");
- IO::print(out, "\t\t<ProjectGuid>{%s}</ProjectGuid>\n", project.get_guid());
- IO::print(out, "\t</PropertyGroup>\n");
-
- IO::print(out, "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n");
-
- const Executable *exe = 0;
- for(const Target *t: builder.get_build_graph().get_target("world")->get_dependencies())
- if(t->get_package()==&spkg)
- if((exe = dynamic_cast<const Executable *>(t)))
- break;
-
- const char *argv0 = Application::get_argv0();
- const string &toolchain = builder.get_current_arch().get_toolchain();
- for(const char *p: platforms)
- for(const string &b: build_types)
- {
- string base_cmd = format("%s --arch=%s-%s --build-type=%s --prefix=%s", argv0, p, toolchain, b, builder.get_prefix());
- IO::print(out, "\t<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='%s|%s'\" Label=\"Configuration\">\n", b, p);
- IO::print(out, "\t\t<ConfigurationType>MakeFile</ConfigurationType>\n");
- IO::print(out, "\t\t<NMakeBuildCommandLine>%s</NMakeBuildCommandLine>\n", base_cmd);
- IO::print(out, "\t\t<NMakeCleanCommandLine>%s -c</NMakeCleanCommandLine>\n", base_cmd);
- IO::print(out, "\t\t<NMakeReBuildCommandLine>%s -B</NMakeReBuildCommandLine>\n", base_cmd);
- if(exe)
- IO::print(out, "\t\t<NMakeOutput>%s</NMakeOutput>\n", exe->get_path());
- IO::print(out, "\t</PropertyGroup>\n");
- }
-
- IO::print(out, "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n");
-
- vector<const FileTarget *> sources;
- vector<const FileTarget *> includes;
- vector<const FileTarget *> others;
- BuildInfo build_info;
- for(const auto &kvp: builder.get_build_graph().get_targets())
- if(kvp.second->get_package()==&spkg)
- {
- if(kvp.second->is_buildable())
- {
- BuildInfo tgt_binfo;
- kvp.second->collect_build_info(tgt_binfo);
- build_info.update_from(tgt_binfo, BuildInfo::CHAINED);
- }
- else if(const FileTarget *file = dynamic_cast<const FileTarget *>(kvp.second))
- {
- if(dynamic_cast<const CSourceFile *>(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);
- }
- }
-
- if(!build_info.incpath.empty())
- {
- IO::print(out, "\t<PropertyGroup>\n");
- string path_str;
- for(const FS::Path &p: build_info.incpath)
- append(path_str, ";", p.str());
- IO::print(out, "\t\t<NMakeIncludeSearchPath>%s</NMakeIncludeSearchPath>\n", path_str);
- IO::print(out, "\t</PropertyGroup>\n");
- }
-
- IO::print(out, "\t<ItemGroup>\n");
- for(const FileTarget *s: sources)
- IO::print(out, "\t\t<ClCompile Include=\"%s\" />\n", s->get_path());
- IO::print(out, "\t</ItemGroup>\n");
-
- IO::print(out, "\t<ItemGroup>\n");
- for(const FileTarget *i: includes)
- IO::print(out, "\t\t<ClInclude Include=\"%s\" />\n", i->get_path());
- IO::print(out, "\t</ItemGroup>\n");
-
- IO::print(out, "\t<ItemGroup>\n");
- for(const FileTarget *t: others)
- IO::print(out, "\t\t<None Include=\"%s\" />\n", t->get_path());
- IO::print(out, "\t</ItemGroup>\n");
-
- IO::print(out, "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n");
- IO::print(out, "</Project>\n");
-
- return true;
-}
+++ /dev/null
-#ifndef VCXPROJECTGENERATOR_H_
-#define VCXPROJECTGENERATOR_H_
-
-#include <msp/builder/tool.h>
-
-class VcxProjectFile;
-
-class VcxProjectGenerator: public Tool
-{
-public:
- VcxProjectGenerator(Builder &);
-
- Target *create_target(const std::vector<Target *> &, const std::string &) override;
-
-private:
- static bool _run(const VcxProjectFile &);
-};
-
-#endif
+++ /dev/null
-#include <msp/builder/builder.h>
-#include <msp/builder/sourcepackage.h>
-#include <msp/core/algorithm.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()
-{
- find_dependencies(*package);
-}
-
-void VsSolutionFile::find_dependencies(const SourcePackage &spkg)
-{
- if(FileTarget *project = builder.get_vfs().get_target(spkg.get_source_directory()/(spkg.get_name()+".vcxproj")))
- if(!any_equals(depends, static_cast<Target *>(project)))
- {
- add_dependency(*project);
-
- for(const Package *r: spkg.get_required_packages())
- if(const SourcePackage *s = dynamic_cast<const SourcePackage *>(r))
- find_dependencies(*s);
- }
-}
+++ /dev/null
-#ifndef VSSOLUTIONFILE_H_
-#define VSSOLUTIONFILE_H_
-
-#include <msp/builder/filetarget.h>
-
-class VsSolutionFile: public FileTarget
-{
-public:
- VsSolutionFile(Builder &, const SourcePackage &);
-
- const char *get_type() const override { return "VsSolutionFile"; }
-protected:
- void find_dependencies() override;
- void find_dependencies(const SourcePackage &);
-};
-
-#endif
+++ /dev/null
-#include <cstring>
-#include <msp/builder/builder.h>
-#include <msp/builder/sourcepackage.h>
-#include <msp/io/file.h>
-#include <msp/io/print.h>
-#include "vcxprojectfile.h"
-#include "vssolutionfile.h"
-#include "vssolutiongenerator.h"
-
-using namespace std;
-using namespace Msp;
-
-VsSolutionGenerator::VsSolutionGenerator(Builder &b):
- Tool(b, "VSSG")
-{
- set_run_internal(_run);
-}
-
-Target *VsSolutionGenerator::create_target(const vector<Target *> &, const string &)
-{
- throw logic_error("Not implemented");
-}
-
-bool VsSolutionGenerator::_run(const VsSolutionFile &solution)
-{
- const SourcePackage &spkg = *solution.get_package();
- Builder &builder = spkg.get_builder();
-
- IO::BufferedFile out(solution.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");
-
- vector<const VcxProjectFile *> projects;
- for(const Target *t: solution.get_dependencies())
- if(const VcxProjectFile *project = dynamic_cast<const VcxProjectFile *>(t))
- projects.push_back(project);
-
- for(const VcxProjectFile *p: projects)
- {
- const SourcePackage *pkg = p->get_package();
- IO::print(out, "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"%s\", \"%s\", \"{%s}\"\nEndProject\n",
- pkg->get_name(), p->get_path(), p->get_guid());
- }
-
- vector<string> build_types = builder.get_build_types();
- const char *platforms[] = { "x86", "x64" };
-
- IO::print(out, "Global\n");
- IO::print(out, "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n");
- for(const string &t: build_types)
- for(const char *p: platforms)
- IO::print(out, "\t\t%s|%s = %s|%s\n", t, p, t, p);
- IO::print(out, "\tEndGlobalSection\n");
- IO::print(out, "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n");
- for(const VcxProjectFile *p: projects)
- for(const string &t: build_types)
- for(const char *f: platforms)
- {
- const char *project_platform = (!strcmp(f, "x86") ? "Win32" : f);
- IO::print(out, "\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n", p->get_guid(), t, f, t, project_platform);
- if(p->get_package()==&spkg)
- IO::print(out, "\t\t{%s}.%s|%s.Build.0 = %s|%s\n", p->get_guid(), t, f, t, project_platform);
- }
- IO::print(out, "\tEndGlobalSection\n");
- IO::print(out, "EndGlobal\n");
-
- return true;
-}
+++ /dev/null
-#ifndef VSSOLUTIONGENERATOR_H_
-#define VSSOLUTIONGENERATOR_H_
-
-#include <msp/builder/tool.h>
-
-class VsSolutionFile;
-
-class VsSolutionGenerator: public Tool
-{
-public:
- VsSolutionGenerator(Builder &);
-
- Target *create_target(const std::vector<Target *> &, const std::string &) override;
-
-private:
- static bool _run(const VsSolutionFile &);
-};
-
-#endif
#include "msvcarchiver.h"
#include "msvccompiler.h"
#include "msvclinker.h"
+#include "vcxprojectgenerator.h"
+#include "vssolutiongenerator.h"
using namespace std;
using namespace Msp;
add_tool(new MsvcCompiler(builder, arch, "CXX", *this));
add_tool(new MsvcLinker(builder, arch, *this));
add_tool(new MsvcArchiver(builder, arch, *this));
+
+ add_tool(new VcxProjectGenerator(builder));
+ add_tool(new VsSolutionGenerator(builder));
}
void MicrosoftTools::find_vc_bin_dir(Builder &builder, const Architecture &arch)
#include <msp/builder/architecture.h>
+#include <msp/builder/builder.h>
#include "microsofttools.h"
#include "msvcplugin.h"
+#include "vcxprojectfile.h"
+#include "vssolutionfile.h"
void MsvcPlugin::add_tools(Toolchain &toolchain, const Architecture &arch) const
{
toolchain.add_toolchain(new MicrosoftTools(builder, arch));
}
+void MsvcPlugin::create_targets(SourcePackage &spkg) const
+{
+ const Architecture &native_arch = builder.get_native_arch();
+
+ if(native_arch.get_system()=="windows")
+ {
+ new VcxProjectFile(builder, spkg);
+ new VsSolutionFile(builder, spkg);
+ }
+}
+
extern "C"
Plugin *create_plugin(Builder &builder)
MsvcPlugin(Builder &b): Plugin(b) { }
void add_tools(Toolchain &, const Architecture &) const override;
+ void create_targets(SourcePackage &) const override;
};
#endif
--- /dev/null
+#include <msp/builder/builder.h>
+#include <msp/builder/sourcepackage.h>
+#include <msp/crypto/md5.h>
+#include <msp/strings/format.h>
+#include "vcxprojectfile.h"
+
+using namespace Msp;
+
+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");
+
+ char digest[16];
+ Crypto::MD5(package->get_name()).get_digest(digest, sizeof(digest));
+ digest[6] = 3;
+ digest[8] = (digest[6]&0x3F)|0x80;
+ for(unsigned j=0; j<sizeof(digest); ++j)
+ {
+ if(j==4 || j==6 || j==8 || j==10)
+ guid += '-';
+ guid += format("%02x", static_cast<unsigned char>(digest[j]));
+ }
+}
--- /dev/null
+#ifndef VCXPROJECTFILE_H_
+#define VCXPROJECTFILE_H_
+
+#include <msp/builder/filetarget.h>
+
+class VcxProjectFile: public FileTarget
+{
+private:
+ std::string guid;
+
+public:
+ VcxProjectFile(Builder &, const SourcePackage &);
+
+ const char *get_type() const override { return "VcxProjectFile"; }
+
+ const std::string &get_guid() const { return guid; }
+};
+
+#endif
--- /dev/null
+#include <msp/builder/builder.h>
+#include <msp/builder/csourcefile.h>
+#include <msp/builder/executable.h>
+#include <msp/builder/sourcepackage.h>
+#include <msp/core/application.h>
+#include <msp/fs/utils.h>
+#include <msp/io/print.h>
+#include <msp/strings/utils.h>
+#include "vcxprojectfile.h"
+#include "vcxprojectgenerator.h"
+
+using namespace std;
+using namespace Msp;
+
+VcxProjectGenerator::VcxProjectGenerator(Builder &b):
+ Tool(b, "VCXG")
+{
+ set_run_internal(_run);
+}
+
+Target *VcxProjectGenerator::create_target(const vector<Target *> &, const string &)
+{
+ throw logic_error("Not implemented");
+}
+
+bool VcxProjectGenerator::_run(const VcxProjectFile &project)
+{
+ const SourcePackage &spkg = *project.get_package();
+ Builder &builder = spkg.get_builder();
+
+ IO::BufferedFile out(project.get_path().str(), IO::M_WRITE);
+ IO::print(out, "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n");
+
+ IO::print(out, "\t<ItemGroup Label=\"ProjectConfigurations\">\n");
+ vector<string> build_types = builder.get_build_types();
+ const char *platforms[] = { "Win32", "x64" };
+ for(const char *p: platforms)
+ for(const string &b: build_types)
+ {
+ IO::print(out, "\t\t<ProjectConfiguration Include=\"%s|%s\">\n", b, p);
+ IO::print(out, "\t\t\t<Configuration>%s</Configuration>\n", b);
+ IO::print(out, "\t\t\t<Platform>%s</Platform>\n", p);
+ IO::print(out, "\t\t</ProjectConfiguration>\n");
+ }
+ IO::print(out, "\t</ItemGroup>\n");
+
+ IO::print(out, "\t<PropertyGroup Label=\"Globals\">\n");
+ IO::print(out, "\t\t<VCProjectVersion>15.0</VCProjectVersion>\n");
+ IO::print(out, "\t\t<Keyword>MakeFileProj</Keyword>\n");
+ IO::print(out, "\t\t<ProjectGuid>{%s}</ProjectGuid>\n", project.get_guid());
+ IO::print(out, "\t</PropertyGroup>\n");
+
+ IO::print(out, "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n");
+
+ const Executable *exe = 0;
+ for(const Target *t: builder.get_build_graph().get_target("world")->get_dependencies())
+ if(t->get_package()==&spkg)
+ if((exe = dynamic_cast<const Executable *>(t)))
+ break;
+
+ const char *argv0 = Application::get_argv0();
+ const string &toolchain = builder.get_current_arch().get_toolchain();
+ for(const char *p: platforms)
+ for(const string &b: build_types)
+ {
+ string base_cmd = format("%s --arch=%s-%s --build-type=%s --prefix=%s", argv0, p, toolchain, b, builder.get_prefix());
+ IO::print(out, "\t<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='%s|%s'\" Label=\"Configuration\">\n", b, p);
+ IO::print(out, "\t\t<ConfigurationType>MakeFile</ConfigurationType>\n");
+ IO::print(out, "\t\t<NMakeBuildCommandLine>%s</NMakeBuildCommandLine>\n", base_cmd);
+ IO::print(out, "\t\t<NMakeCleanCommandLine>%s -c</NMakeCleanCommandLine>\n", base_cmd);
+ IO::print(out, "\t\t<NMakeReBuildCommandLine>%s -B</NMakeReBuildCommandLine>\n", base_cmd);
+ if(exe)
+ IO::print(out, "\t\t<NMakeOutput>%s</NMakeOutput>\n", exe->get_path());
+ IO::print(out, "\t</PropertyGroup>\n");
+ }
+
+ IO::print(out, "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n");
+
+ vector<const FileTarget *> sources;
+ vector<const FileTarget *> includes;
+ vector<const FileTarget *> others;
+ BuildInfo build_info;
+ for(const auto &kvp: builder.get_build_graph().get_targets())
+ if(kvp.second->get_package()==&spkg)
+ {
+ if(kvp.second->is_buildable())
+ {
+ BuildInfo tgt_binfo;
+ kvp.second->collect_build_info(tgt_binfo);
+ build_info.update_from(tgt_binfo, BuildInfo::CHAINED);
+ }
+ else if(const FileTarget *file = dynamic_cast<const FileTarget *>(kvp.second))
+ {
+ if(dynamic_cast<const CSourceFile *>(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);
+ }
+ }
+
+ if(!build_info.incpath.empty())
+ {
+ IO::print(out, "\t<PropertyGroup>\n");
+ string path_str;
+ for(const FS::Path &p: build_info.incpath)
+ append(path_str, ";", p.str());
+ IO::print(out, "\t\t<NMakeIncludeSearchPath>%s</NMakeIncludeSearchPath>\n", path_str);
+ IO::print(out, "\t</PropertyGroup>\n");
+ }
+
+ IO::print(out, "\t<ItemGroup>\n");
+ for(const FileTarget *s: sources)
+ IO::print(out, "\t\t<ClCompile Include=\"%s\" />\n", s->get_path());
+ IO::print(out, "\t</ItemGroup>\n");
+
+ IO::print(out, "\t<ItemGroup>\n");
+ for(const FileTarget *i: includes)
+ IO::print(out, "\t\t<ClInclude Include=\"%s\" />\n", i->get_path());
+ IO::print(out, "\t</ItemGroup>\n");
+
+ IO::print(out, "\t<ItemGroup>\n");
+ for(const FileTarget *t: others)
+ IO::print(out, "\t\t<None Include=\"%s\" />\n", t->get_path());
+ IO::print(out, "\t</ItemGroup>\n");
+
+ IO::print(out, "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n");
+ IO::print(out, "</Project>\n");
+
+ return true;
+}
--- /dev/null
+#ifndef VCXPROJECTGENERATOR_H_
+#define VCXPROJECTGENERATOR_H_
+
+#include <msp/builder/tool.h>
+
+class VcxProjectFile;
+
+class VcxProjectGenerator: public Tool
+{
+public:
+ VcxProjectGenerator(Builder &);
+
+ Target *create_target(const std::vector<Target *> &, const std::string &) override;
+
+private:
+ static bool _run(const VcxProjectFile &);
+};
+
+#endif
--- /dev/null
+#include <msp/builder/builder.h>
+#include <msp/builder/sourcepackage.h>
+#include <msp/core/algorithm.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()
+{
+ find_dependencies(*package);
+}
+
+void VsSolutionFile::find_dependencies(const SourcePackage &spkg)
+{
+ if(FileTarget *project = builder.get_vfs().get_target(spkg.get_source_directory()/(spkg.get_name()+".vcxproj")))
+ if(!any_equals(depends, static_cast<Target *>(project)))
+ {
+ add_dependency(*project);
+
+ for(const Package *r: spkg.get_required_packages())
+ if(const SourcePackage *s = dynamic_cast<const SourcePackage *>(r))
+ find_dependencies(*s);
+ }
+}
--- /dev/null
+#ifndef VSSOLUTIONFILE_H_
+#define VSSOLUTIONFILE_H_
+
+#include <msp/builder/filetarget.h>
+
+class VsSolutionFile: public FileTarget
+{
+public:
+ VsSolutionFile(Builder &, const SourcePackage &);
+
+ const char *get_type() const override { return "VsSolutionFile"; }
+protected:
+ void find_dependencies() override;
+ void find_dependencies(const SourcePackage &);
+};
+
+#endif
--- /dev/null
+#include <cstring>
+#include <msp/builder/builder.h>
+#include <msp/builder/sourcepackage.h>
+#include <msp/io/file.h>
+#include <msp/io/print.h>
+#include "vcxprojectfile.h"
+#include "vssolutionfile.h"
+#include "vssolutiongenerator.h"
+
+using namespace std;
+using namespace Msp;
+
+VsSolutionGenerator::VsSolutionGenerator(Builder &b):
+ Tool(b, "VSSG")
+{
+ set_run_internal(_run);
+}
+
+Target *VsSolutionGenerator::create_target(const vector<Target *> &, const string &)
+{
+ throw logic_error("Not implemented");
+}
+
+bool VsSolutionGenerator::_run(const VsSolutionFile &solution)
+{
+ const SourcePackage &spkg = *solution.get_package();
+ Builder &builder = spkg.get_builder();
+
+ IO::BufferedFile out(solution.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");
+
+ vector<const VcxProjectFile *> projects;
+ for(const Target *t: solution.get_dependencies())
+ if(const VcxProjectFile *project = dynamic_cast<const VcxProjectFile *>(t))
+ projects.push_back(project);
+
+ for(const VcxProjectFile *p: projects)
+ {
+ const SourcePackage *pkg = p->get_package();
+ IO::print(out, "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"%s\", \"%s\", \"{%s}\"\nEndProject\n",
+ pkg->get_name(), p->get_path(), p->get_guid());
+ }
+
+ vector<string> build_types = builder.get_build_types();
+ const char *platforms[] = { "x86", "x64" };
+
+ IO::print(out, "Global\n");
+ IO::print(out, "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n");
+ for(const string &t: build_types)
+ for(const char *p: platforms)
+ IO::print(out, "\t\t%s|%s = %s|%s\n", t, p, t, p);
+ IO::print(out, "\tEndGlobalSection\n");
+ IO::print(out, "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n");
+ for(const VcxProjectFile *p: projects)
+ for(const string &t: build_types)
+ for(const char *f: platforms)
+ {
+ const char *project_platform = (!strcmp(f, "x86") ? "Win32" : f);
+ IO::print(out, "\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n", p->get_guid(), t, f, t, project_platform);
+ if(p->get_package()==&spkg)
+ IO::print(out, "\t\t{%s}.%s|%s.Build.0 = %s|%s\n", p->get_guid(), t, f, t, project_platform);
+ }
+ IO::print(out, "\tEndGlobalSection\n");
+ IO::print(out, "EndGlobal\n");
+
+ return true;
+}
--- /dev/null
+#ifndef VSSOLUTIONGENERATOR_H_
+#define VSSOLUTIONGENERATOR_H_
+
+#include <msp/builder/tool.h>
+
+class VsSolutionFile;
+
+class VsSolutionGenerator: public Tool
+{
+public:
+ VsSolutionGenerator(Builder &);
+
+ Target *create_target(const std::vector<Target *> &, const std::string &) override;
+
+private:
+ static bool _run(const VsSolutionFile &);
+};
+
+#endif