Понадобилось тут собрать С++ Qmake приложение под Windows используя cl компилятор из под C# приложения. При этом хотелось не запускать это C# приложение из под VisualStudio comand prompt, а разрулить всё прямо в коде.
Обычно, для сборки приложения в консоли студийным компилятором, необходимо открыть VisualStudio command prompt и делать сборку там, либо вручную вызвать vcvars64.bat или vcvarsall.bat для настройки окружения, но тут есть 2 проблемы: 1. Как найти этот bat файл, 2. Как его запустить внутри C# приложения так, что бы он правильно настроил environment variables.
Решение:
1. Найти все VisualStudio >= 2017 можно при помощи приложения vswhere, которое ставится с VisualStudio installer
2. Находим VisualStudio при помощи vswhere, находим vcvars64.bat, выполняем bat файл, забирая себе его environment в текстовом виде, парсим и применяем в своё приложение.
В коде вообще нет ни каких проверок, потестил просто как proof of concept. SystemProcess - мой мини враппер над System.Diagnostics.Process, запускает процесс и возвращает массив строк stdout, stderr и exit code.
По хорошему надо делать не совсем так, необходимо применить лишь diff переменных окружения, но в моей задаче это было не нужно.
А дальше просто собираем своё Qmake приложение:
Обычно, для сборки приложения в консоли студийным компилятором, необходимо открыть VisualStudio command prompt и делать сборку там, либо вручную вызвать vcvars64.bat или vcvarsall.bat для настройки окружения, но тут есть 2 проблемы: 1. Как найти этот bat файл, 2. Как его запустить внутри C# приложения так, что бы он правильно настроил environment variables.
Решение:
1. Найти все VisualStudio >= 2017 можно при помощи приложения vswhere, которое ставится с VisualStudio installer
2. Находим VisualStudio при помощи vswhere, находим vcvars64.bat, выполняем bat файл, забирая себе его environment в текстовом виде, парсим и применяем в своё приложение.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //Find vswhere path var programFilesDir = Environment.GetEnvironmentVariable( "ProgramFiles(x86)" ); var vsInstallationDir = Path.Combine(programFilesDir, @"Microsoft Visual Studio" , "Installer" ); var vsWherePath = Path.Combine(vsInstallationDir, "vswhere.exe" ); //Find latest VisualStudio installation directory var vsWhereResult = SystemProcess.Execute(vsWherePath, "-latest -property installationPath" ); var vsInstallPath = vsWhereResult.outBuffer[0]; //Import VisualStudio environment var vsEnvBatchFile = Path.Combine(vsInstallPath, @"VC\Auxiliary\Build\vcvars64.bat" ); var vsEnvResult = SystemProcess.Execute( "cmd" , $ "/C \"{vsEnvBatchFile}\" > nul 2>&1 && set" ); Regex envVariableRegex = new Regex( "^([^=]+)=(.*)" ); foreach (var str in vsEnvResult.outBuffer) { var match = envVariableRegex.Match(str); if (match.Success) { System.Environment.SetEnvironmentVariable(match.Groups[1].Value, match.Groups[2].Value); } } |
1 2 3 4 | //run qmake SystemProcess.Execute(@ "C:\Qt\5.13.0\msvc2019_64_custom\bin\qmake.exe" , proFileDir + " -spec win32-msvc \"CONFIG += release\"" ); //run nmake SystemProcess.Execute( "nmake" ); |