]> git.tdb.fi Git - builder.git/blob - source/microsofttools.cpp
9d3f1da92ee8f47fc2b854c0c6d66da80f7a9eaf
[builder.git] / source / microsofttools.cpp
1 #include <msp/core/algorithm.h>
2 #include <msp/fs/dir.h>
3 #include <msp/strings/format.h>
4 #include <msp/strings/utils.h>
5 #include "builder.h"
6 #include "externaltask.h"
7 #include "logger.h"
8 #include "microsofttools.h"
9 #include "msvcarchiver.h"
10 #include "msvccompiler.h"
11 #include "msvclinker.h"
12 #include "sysutils.h"
13
14 using namespace std;
15 using namespace Msp;
16
17 MicrosoftTools::MicrosoftTools(Builder &builder, const Architecture &arch)
18 {
19         find_vc_bin_dir(builder, arch);
20         find_windows_sdk_dir(builder);
21
22         add_tool(new MsvcCompiler(builder, arch, "CC", *this));
23         add_tool(new MsvcCompiler(builder, arch, "CXX", *this));
24         add_tool(new MsvcLinker(builder, arch, *this));
25         add_tool(new MsvcArchiver(builder, arch, *this));
26 }
27
28 void MicrosoftTools::find_vc_bin_dir(Builder &builder, const Architecture &arch)
29 {
30         FS::Path program_files_x86 = get_program_files_x86_dir();
31
32         ExternalTask::Arguments argv;
33         argv.push_back((program_files_x86/"Microsoft Visual Studio"/"Installer"/"vswhere.exe").str());
34         argv.push_back("-latest");
35         argv.push_back("-property");
36         argv.push_back("installationPath");
37
38         builder.get_logger().log("auxcommands", format("Running %s", join(argv.begin(), argv.end())));
39
40         string output = ExternalTask::run_and_capture_output(argv, FS::Path(), true);
41         FS::Path vs_path = strip(output);
42
43         builder.get_logger().log("tools", format("Visual Studio found in %s", vs_path));
44
45         FS::Path vc_aux_build_dir = vs_path/"VC"/"Auxiliary"/"Build";
46         builder.get_logger().log("files", format("Traversing %s", vc_aux_build_dir));
47         vector<string> vc_version_files = FS::list_filtered(vc_aux_build_dir, "^Microsoft\\.VCToolsVersion\\.");
48         if(vc_version_files.empty())
49         {
50                 builder.get_logger().log("problems", "MSVC tools version not found");
51                 return;
52         }
53
54         sort(vc_version_files);
55         FS::Path vc_version_fn = vc_aux_build_dir/vc_version_files.back();
56         builder.get_logger().log("files", format("Reading %s", vc_version_fn));
57         char buffer[256];
58         unsigned len = IO::File(vc_version_fn.str()).read(buffer, sizeof(buffer));
59         string vc_version = strip(string(buffer, len));
60
61         builder.get_logger().log("tools", format("Detected MSVC version %s", vc_version));
62
63         const Architecture &native_arch = builder.get_native_arch();
64         string host = (native_arch.get_bits()==64 ? "Hostx64" : "Hostx86");
65         string target = (arch.get_bits()==64 ? "x64" : "x86");
66
67         vc_base_dir = vs_path/"VC"/"Tools"/"MSVC"/vc_version;
68         vc_bin_dir = vc_base_dir/"bin"/host/target;
69 }
70
71 void MicrosoftTools::find_windows_sdk_dir(Builder &builder)
72 {
73         win_sdk_dir = get_registry_value<string>("HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0\\InstallationFolder");
74         if(win_sdk_dir.empty())
75                 win_sdk_dir = get_program_files_x86_dir()/"Windows Kits"/"10";
76
77         builder.get_logger().log("files", format("Traversing %s", win_sdk_dir/"include"));
78         vector<string> sdk_versions = FS::list_filtered(win_sdk_dir/"include", "^10\\.");
79         if(sdk_versions.empty())
80         {
81                 builder.get_logger().log("problems", "No Windows SDK versions found");
82                 return;
83         }
84
85         sort(sdk_versions);
86         win_sdk_version = sdk_versions.back();
87
88         builder.get_logger().log("tools", format("Windows SDK version %s found in %s", win_sdk_version, win_sdk_dir));
89 }