Skip to content

Commit

Permalink
win: refactor envfile generation
Browse files Browse the repository at this point in the history
  • Loading branch information
refack committed Feb 7, 2017
1 parent 305c7bf commit ecff6ea
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 98 deletions.
169 changes: 81 additions & 88 deletions lib/gyp/platform/win.js
Original file line number Diff line number Diff line change
Expand Up @@ -364,21 +364,6 @@ win.detectVersion = function detectVersion() {
throw new Error('No known Visual Studio version found, sorry!');
};

const IMPORTANT_VARS =
/^(include|lib|libpath|path|pathext|systemroot|temp|tmp)=(.*)$/i;

function formatEnvBlock(lines) {
let res = '';
lines.forEach((line) => {
const match = line.match(IMPORTANT_VARS);
if (match === null)
return;

res += match[1].toUpperCase() + '=' + match[2] + '\0';
});
return res;
}

win.getMSVSVersion = function getMSVSVersion(version) {
const env = process.env;

Expand Down Expand Up @@ -409,97 +394,105 @@ win.getOSBits = function getOSBits() {
return 32;
};

win.genEnvironment = function genEnvironment(outDir, version, arch) {
const env = process.env;
const bits = win.getOSBits();

function tryVS7() {
try {
const psFile = path.join(__dirname, '..', '..', '..', 'tools', 'Get-VSConfig.ps1');
const vsSetupRaw = gyp.bindings.execSync(`powershell ${psFile}`).toString();
if (!vsSetupRaw) return;
const vsSetup = vsSetupRaw.split(/[\r|\n]/g).reduce((s, l) => {
const lParts = l.split(': ');
if (lParts.length > 1) s[lParts[0]] = lParts[1];
return s;
}, {});
const VsDevCmd = path.join(vsSetup.InstallationPath, 'Common7', 'Tools', 'VsDevCmd.bat');
const argArch = arch === 'x64' ? 'amd64' : 'x86';
const argHost = bits === 64 ? 'amd64' : 'x86';
return `${VsDevCmd} -arch=${argArch} -host_arch=${argHost} -no_logo`;
} catch (e) {
gyp.bindings.log('Couldn\'t find VS7 :(');
}
function tryVS7(hostBits, target_arch) {
try {
const psFile = path.join(__dirname, '..', '..', '..', 'tools', 'Get-VSConfig.ps1');
const vsSetupRaw = gyp.bindings.execSync(`powershell ${psFile}`).toString();
if (!vsSetupRaw) return;
const vsSetup = vsSetupRaw.split(/[\r|\n]/g).reduce((s, l) => {
const lParts = l.split(': ');
if (lParts.length > 1) s[lParts[0]] = lParts[1];
return s;
}, {});
const VsDevCmd = path.join(vsSetup.InstallationPath, 'Common7', 'Tools', 'VsDevCmd.bat');
const argArch = target_arch === 'x64' ? 'amd64' : 'x86';
const argHost = hostBits === 64 ? 'amd64' : 'x86';
return `${VsDevCmd} -arch=${argArch} -host_arch=${argHost} -no_logo`;
} catch (e) {
gyp.bindings.log('Couldn\'t find VS7 :(');
}
}

function findVcVarsFile() {
// NOTE: Largely inspired by MSVSVersion.py

let tools;
// Try to find a MSVS installation
if (version === 'auto' && env['VS140COMNTOOLS'] || version === '2015') {
version = '2015';
tools = path.join(env.VS140COMNTOOLS, '..', '..');
}
if (version === 'auto' && env['VS120COMNTOOLS'] || version === '2013') {
version = '2013';
tools = path.join(env.VS120COMNTOOLS, '..', '..');
}
// TODO(indutny): more versions?
if (version === 'auto' && env['VS100COMNTOOLS'] || version === '2010') {
version = '2010';
tools = path.join(env.VS120COMNTOOLS, '..', '..');
}
// TODO(indutny): does it work with MSVS Express?
function findOldVcVarsFile(hostBits, target_arch) {
// NOTE: Largely inspired by MSVSVersion.py
const env = process.env;
let version = win.getMSVSVersion();

if (version === 'auto') {
gyp.bindings.error('No Visual Studio found. When building - please ' +
'run `ninja` from the MSVS console');
return;
}
let tools;
// Try to find a MSVS installation
if (version === 'auto' && env['VS140COMNTOOLS'] || version === '2015') {
version = '2015';
tools = path.join(env.VS140COMNTOOLS, '..', '..');
}
if (version === 'auto' && env['VS120COMNTOOLS'] || version === '2013') {
version = '2013';
tools = path.join(env.VS120COMNTOOLS, '..', '..');
}
// TODO(indutny): more versions?
if (version === 'auto' && env['VS100COMNTOOLS'] || version === '2010') {
version = '2010';
tools = path.join(env.VS120COMNTOOLS, '..', '..');
}
// TODO(indutny): does it work with MSVS Express?

let vcvars;
// TODO(indutny): proper escape for the .bat file
if (arch === 'ia32') {
if (bits === 64)
vcvars = '"' + path.join(tools, 'VC', 'vcvarsall.bat') + '" amd64_x86';
else
vcvars = '"' + path.join(tools, 'Common7', 'Tools', 'vsvars32.bat') + '"';
} else if (arch === 'x64') {
let arg;
if (bits === 64)
arg = 'amd64';
else
arg = 'x86_amd64';
vcvars = '"' + path.join(tools, 'VC', 'vcvarsall.bat') + '" ' + arg;
} else {
throw new Error(`Arch: '${arch}' is not supported on windows`);
}
return vcvars;
if (version === 'auto') {
throw new Error('No Visual Studio found. When building - please ' +
'run `ninja` from the MSVS console');
}

const vcvars = tryVS7() || findVcVarsFile();
if (!vcvars) {
return;
let vcEnvCmd;
// TODO(indutny): proper escape for the .bat file
if (target_arch === 'ia32') {
if (hostBits === 64)
vcEnvCmd = '"' + path.join(tools, 'VC', 'vcvarsall.bat') + '" amd64_x86';
else
vcEnvCmd = '"' + path.join(tools, 'Common7', 'Tools', 'vsvars32.bat') + '"';
} else if (target_arch === 'x64') {
let arg;
if (hostBits === 64)
arg = 'amd64';
else
arg = 'x86_amd64';
vcEnvCmd = '"' + path.join(tools, 'VC', 'vcvarsall.bat') + '" ' + arg;
} else {
throw new Error(`Arch: '${target_arch}' is not supported on windows`);
}
return vcEnvCmd;
}

let lines;
win.resolveDevEnvironment = function resolveDevEnvironment(target_arch) {
const hostBits = win.getOSBits();

const vcEnvCmd = tryVS7(hostBits, target_arch)
|| findOldVcVarsFile(hostBits, target_arch);
let lines = [];
try {
lines = gyp.bindings.execSync(`${vcvars} & set`, { env: {} }).toString()
lines = gyp.bindings.execSync(`${vcEnvCmd} & set`, {env: {}}).toString()
.trim().split(/\r\n/g);
} catch (e) {
gyp.bindings.error(e.message);
return;
}
const env = lines.reduce((s, l) => {
const kv = l.split('=');
s[kv[0]] = kv[1];
return s;
}, {});

return env;
};

if (!outDir) {
return lines;
}
const IMPORTANT_VARS =
/^include|lib|libpath|path|pathext|systemroot|temp|tmp$/i;

const envBlock = formatEnvBlock(lines);
win.genEnvironment = function genEnvironment(outDir, target_arch) {
const env = win.resolveDevEnvironment(target_arch);
const envBlock = Object.keys(env)
// .filter(key => key.match(IMPORTANT_VARS))
.map(key => `${key}=${env[key]}`)
.join('\0');

const envFile = win.getEnvFileName(target_arch);
fs.writeFileSync(path.join(outDir, envFile), envBlock);
return envFile;
};

27 changes: 17 additions & 10 deletions test/platform-win-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,20 +229,27 @@ describe('gyp.platform.win', () => {
describe('genEnvironment', function () {
this.timeout(20000);
it('resolve for x64', () => {
const env = win.genEnvironment(null, 'auto', 'x64');
const env = win.resolveDevEnvironment('x64');
assert(env, 'didn\'t get ENVIRONMENT :(');
assert.equal(env.find(l => l.includes('ARG_TGT_ARCH')), 'VSCMD_ARG_TGT_ARCH=x64');
assert.equal(env.pop().split('=')[0], '__VSCMD_PREINIT_PATH',
'Last env var should be __VSCMD_PREINIT_PATH'
);
const COMNTOOLS = Object.keys(env).find(k => k.includes('COMNTOOLS'));
assert(COMNTOOLS, 'didn\'t get COMNTOOLS :(');
if (COMNTOOLS === 'VS150COMNTOOLS'){
assert.equal(env['VSCMD_ARG_TGT_ARCH'], 'x64');
assert.equal(env['VisualStudioVersion'], '15.0');
assert(env['__VSCMD_PREINIT_PATH'], 'Last env var should be __VSCMD_PREINIT_PATH');
}
});

it('resolve for x86', () => {
const env = win.genEnvironment(null, 'auto', 'x86');
const env = win.resolveDevEnvironment('x86');
assert(env, 'didn\'t get ENVIRONMENT :(');
assert.equal(env.find(l => l.includes('ARG_TGT_ARCH')), 'VSCMD_ARG_TGT_ARCH=x86');
assert.equal(env.pop().split('=')[0], '__VSCMD_PREINIT_PATH',
'Last env var should be __VSCMD_PREINIT_PATH'
);
const COMNTOOLS = Object.keys(env).find(k => k.includes('COMNTOOLS'));
assert(COMNTOOLS, 'didn\'t get COMNTOOLS :(');
if (COMNTOOLS === 'VS150COMNTOOLS') {
assert.equal(env['VSCMD_ARG_TGT_ARCH'], 'x86');
assert.equal(env['VisualStudioVersion'], '15.0');
assert(env['__VSCMD_PREINIT_PATH'], 'Last env var should be __VSCMD_PREINIT_PATH');
}
});
});
}
Expand Down

0 comments on commit ecff6ea

Please sign in to comment.