Skip to content

Commit

Permalink
[cpp] on windows, whenever you invoke a linker/archiver, it will firs…
Browse files Browse the repository at this point in the history
…t attempt to find and call vcvars64.bat. this should fail silently if you dont have visual studio iinstalled (although will instead fail to find link.exe). in this case, you should explicitly specify the linker you want via -l. this means that you can now use visual studio stuff with psyc and it will automatically call vcvarsxyz.bat instead of you having to do it in a vc terminal
  • Loading branch information
harrand committed Apr 18, 2024
1 parent c8e78f3 commit 42b8308
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions cpp/src/link.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "link.hpp"
#include "diag.hpp"
#include <array>

namespace link
{
Expand Down Expand Up @@ -85,6 +86,56 @@ namespace link
}
}

std::string exec_windows(std::string_view cmd)
{
#ifdef _WIN32
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&_pclose)> pipe(_popen(cmd.data(), "r"), _pclose);
if (!pipe) {
return "";
}
while (fgets(buffer.data(), static_cast<int>(buffer.size()), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;

#else

return "";
#endif
}

std::string replace_all(std::string str, const std::string& from, const std::string& to) {
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
}
return str;
}

std::string get_linker_prefix()
{
// if we're on win32, we will need to invoke vcvars64.bat first.
// let's get that.
#ifdef _WIN32

std::string root_path = exec_windows("\"\"C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe\" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 | findstr \"installationPath\"");
if(root_path.empty())
{
return "";
}

root_path.erase(0, sizeof("installationPath:"));
std::string vcvarsall_path = replace_all(root_path + "\\VC\\Auxiliary\\Build\\vcvars64.bat", "\n", "");
vcvarsall_path = "\"\"" + vcvarsall_path + "\" && ";
return vcvarsall_path;
#else
return "";
#endif
}

void executable(std::vector<std::filesystem::path> object_files, std::filesystem::path output_path, std::string output_name, std::string linker)
{
if(linker.empty())
Expand All @@ -109,6 +160,7 @@ namespace link
break;
case linker_type::msvc:
cmd += std::format( " /OUT:\"{}\"", full_output);
cmd = get_linker_prefix() + cmd;
break;
}

Expand All @@ -135,6 +187,7 @@ namespace link
break;
case linker_type::msvc:
cmd += std::format( " /OUT:\"{}\"", full_output);
cmd = get_linker_prefix() + cmd;
break;
}

Expand Down

0 comments on commit 42b8308

Please sign in to comment.