Skip to content

Instantly share code, notes, and snippets.

@milasudril
Created March 23, 2021 20:35
Show Gist options
  • Save milasudril/0033686e607c8c53c73ddf3896dd8100 to your computer and use it in GitHub Desktop.
Save milasudril/0033686e607c8c53c73ddf3896dd8100 to your computer and use it in GitHub Desktop.
Expose host environment variables to C++ compiler
#!/usr/bin/env python3
import os
import json
import string
import tempfile
import subprocess
import sys
cxx_template = string.Template('''#ifndef COMPILE_ENV_INCLUDED
#define COMPILE_ENV_INCLUDED
#include <array>
#include <algorithm>
#include <string_view>
#include <utility>
namespace CompileEnv
{
constexpr std::array<std::pair<std::string_view, char const*>, $NUMVARS> Variables{$VARIABLES};
consteval char const* get(std::string_view key)
{
return std::find_if(std::begin(Variables), std::end(Variables), [key](auto const item) {
return item.first == key;
})->second;
}
}
#endif
''')
def escape_string(str):
ret = '';
for ch in str:
if (ord(ch) >= 0 and ord(ch) < 32) or ch in('\\', '"'):
ret+='\\%03o' % ord(ch)
else:
ret+=ch
return ret;
subst = dict()
vars = []
for key, value in os.environ.items():
vars.append('std::pair{std::string_view{"%s"}, "%s"}'%(escape_string(key), escape_string(value)))
subst['VARIABLES'] = ', '.join(vars)
subst['NUMVARS'] = len(vars)
fd, path = tempfile.mkstemp()
try:
with os.fdopen(fd, 'w') as include:
include.write(cxx_template.substitute(subst))
cmdline = ['g++-10', '-std=c++20', '-include%s'%path]
cmdline.extend(sys.argv[1:])
exit(subprocess.run(cmdline).returncode)
finally:
os.remove(path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment