vccvswhere.nim 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. ## VCC compiler discovery using vswhere (https://github.com/Microsoft/vswhere)
  2. import os, osproc, strformat, strutils
  3. const
  4. vswhereRelativePath = joinPath("Microsoft Visual Studio", "Installer", "vswhere.exe")
  5. vswhereArgs = "-latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath"
  6. vcvarsRelativePath = joinPath("VC", "Auxiliary", "Build", "vcvarsall.bat")
  7. proc vccVswhereExtractVcVarsAllPath(vswherePath: string): string =
  8. ## Returns the path to `vcvarsall.bat` if Visual Studio location was obtained by executing `vswhere.exe`.
  9. ##
  10. ## `vcvarsall.bat` is supposed to exist under {vsPath}\VC\Auxiliary\Build directory.
  11. ##
  12. ## Returns "" if no appropriate `vcvarsall.bat` file was found.
  13. # For more detail on vswhere arguments, refer to https://github.com/microsoft/vswhere/wiki/Find-VC
  14. let vsPath = execProcess(&"\"{vswherePath}\" {vswhereArgs}").strip()
  15. if vsPath.len > 0:
  16. let vcvarsallPath = joinPath(vsPath, vcvarsRelativePath)
  17. if fileExists(vcvarsallPath):
  18. return vcvarsallPath
  19. proc vccVswhereGeneratePath(envName: string): string =
  20. ## Generate a path to vswhere.exe under "Program Files" or "Program Files (x86)" depending on envName.
  21. ##
  22. ## Returns "" if an environment variable specified by envName was not available.
  23. let val = getEnv(envName)
  24. if val.len > 0:
  25. result = try: expandFilename(joinPath(val, vswhereRelativePath)) except OSError: ""
  26. proc vccVswhereVcVarsAllPath*(): string =
  27. ## Returns the path to `vcvarsall.bat` for the latest Visual Studio (2017 and later).
  28. ##
  29. ## Returns "" if no recognizable Visual Studio installation was found.
  30. ##
  31. ## Note: Beginning with Visual Studio 2017, the installers no longer set environment variables to allow for
  32. ## multiple side-by-side installations of Visual Studio. Therefore, `vccEnvVcVarsAllPath` cannot be used
  33. ## to detect the VCC Developer Command Prompt executable path for Visual Studio 2017 and later.
  34. for tryEnv in ["ProgramFiles(x86)", "ProgramFiles"]:
  35. let vswherePath = vccVswhereGeneratePath(tryEnv)
  36. if vswherePath.len > 0 and fileExists(vswherePath):
  37. let vcVarsAllPath = vccVswhereExtractVcVarsAllPath(vswherePath)
  38. if vcVarsAllPath.len > 0:
  39. return vcVarsAllPath