Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

creating conanvcvars file for toolchains #8719

Merged
merged 3 commits into from Mar 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 11 additions & 12 deletions conan/tools/meson/meson.py
@@ -1,7 +1,6 @@
import os

from conan.tools.meson import MesonToolchain
from conan.tools.microsoft.visual import vcvars_command, vcvars_arch
from conans.client.tools.oss import cross_building


Expand All @@ -17,13 +16,6 @@ def __init__(self, conanfile, build_folder='build'):
self._conanfile = conanfile
self._build_folder = build_folder

def _run(self, cmd):
if self._conanfile.settings.get_safe("compiler") == "Visual Studio":
vcvars = vcvars_command(self._conanfile.settings.get_safe("compiler.version"),
vcvars_arch(self._conanfile))
cmd = '%s && %s' % (vcvars, cmd)
self._conanfile.run(cmd)

@property
def _build_dir(self):
build = self._conanfile.build_folder
Expand All @@ -44,7 +36,8 @@ def configure(self, source_folder=None):
cmd += ' "{}" "{}"'.format(self._build_dir, source)
if self._conanfile.package_folder:
cmd += ' -Dprefix="{}"'.format(self._conanfile.package_folder)
self._run(cmd)
vcvars = os.path.join(self._conanfile.install_folder, "conanvcvars")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code is repeating 3 times, maybe move it inside self._run instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self._run might use different locations of environment scripts, depending if they are from Conan or from user ones.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and how do we know this locations?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is a generated file, it will be by definition in the install_folder.
If it is a user file, the user will specify its location.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but right now it uses self._conanfile.install_folder always, so these 2 lines are repeated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but if we put it inside self._run, it will try to apply it to all the environment scripts, which is incorrect

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean doing:

    def _run(self, cmd):
       vcvars = os.path.join(self._conanfile.install_folder, "conanvcvars")
        self._conanfile.run(cmd, env=["conanbuildenv", vcvars])

are there other environment scripts in meson toolchain? I can't spot any right now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see what you mean, I was confusing it with self._conanfile.run(). I put some TODOs and some comments there regarding the install or test that I didn't know if they really need the vcvars environment at all. If they need it, then I guess it is ok, if not, each method should define its own environment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure, probably best add vcvars everywhere, just in case install needs tools from vcvars (e.g. dumpbin or whatever)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case, it is a small detail, can be refactored later, I am merging this, I prefer to have this in the next release.

self._conanfile.run(cmd, env=["conanbuildenv", vcvars])

def build(self, target=None):
cmd = 'meson compile -C "{}"'.format(self._build_dir)
Expand All @@ -53,12 +46,18 @@ def build(self, target=None):
cmd += " {}".format(njobs)
if target:
cmd += " {}".format(target)
self._run(cmd)
vcvars = os.path.join(self._conanfile.install_folder, "conanvcvars")
self._conanfile.run(cmd, env=["conanbuildenv", vcvars])

def install(self):
cmd = 'meson install -C "{}"'.format(self._build_dir)
self._run(cmd)
# TODO: Do we need vcvars for install?
vcvars = os.path.join(self._conanfile.install_folder, "conanvcvars")
self._conanfile.run(cmd, env=["conanbuildenv", vcvars])

def test(self):
cmd = 'meson test -v -C "{}"'.format(self._build_dir)
self._run(cmd)
# TODO: Do we need vcvars for test?
vcvars = os.path.join(self._conanfile.install_folder, "conanvcvars")
# TODO: This should use conanrunenv, but what if meson itself is a build-require?
self._conanfile.run(cmd, env=["conanbuildenv", "conanrunenv", vcvars])
2 changes: 2 additions & 0 deletions conan/tools/meson/toolchain.py
@@ -1,5 +1,6 @@
import os

from conan.tools.microsoft.toolchain import write_conanvcvars
from conans.client.build.cppstd_flags import cppstd_from_settings
from conans.client.tools.oss import cross_building, get_cross_building_settings
from conans.util.files import save
Expand Down Expand Up @@ -270,3 +271,4 @@ def generate(self):
self._write_cross_file()
else:
self._write_native_file()
write_conanvcvars(self._conanfile)
10 changes: 6 additions & 4 deletions conan/tools/microsoft/msbuild.py
@@ -1,3 +1,5 @@
import os

from conans.errors import ConanException


Expand Down Expand Up @@ -33,9 +35,8 @@ def __init__(self, conanfile):
self.platform = msvc_arch

def command(self, sln):
install_folder = self._conanfile.install_folder
cmd = ('%s/conanvcvars.bat && msbuild "%s" /p:Configuration=%s /p:Platform=%s'
% (install_folder, sln, self.build_type, self.platform))
cmd = ('msbuild "%s" /p:Configuration=%s /p:Platform=%s'
% (sln, self.build_type, self.platform))

verbosity = msbuild_verbosity_cmd_line_arg(self._conanfile)
if verbosity:
Expand All @@ -49,7 +50,8 @@ def command(self, sln):

def build(self, sln):
cmd = self.command(sln)
self._conanfile.run(cmd)
vcvars = os.path.join(self._conanfile.install_folder, "conanvcvars")
self._conanfile.run(cmd, env=["conanbuildenv", vcvars])

@staticmethod
def get_version(_):
Expand Down
74 changes: 41 additions & 33 deletions conan/tools/microsoft/toolchain.py
Expand Up @@ -8,6 +8,46 @@
from conans.util.files import save, load


def write_conanvcvars(conanfile):
"""
write a conanvcvars.bat file with the good args from settings
"""
compiler = conanfile.settings.get_safe("compiler")
cvars = None
if compiler == "intel":
cvars = intel_compilervars_command(conanfile)
elif compiler == "Visual Studio" or compiler == "msvc":
vs_version = _vs_ide_version(conanfile)
vcvarsarch = vcvars_arch(conanfile)
cvars = vcvars_command(vs_version, architecture=vcvarsarch, platform_type=None,
winsdk_version=None, vcvars_ver=None)
if cvars:
content = textwrap.dedent("""\
@echo off
{}
""".format(cvars))
save("conanvcvars.bat", content)


def _vs_ide_version(conanfile):
compiler = conanfile.settings.get_safe("compiler")
compiler_version = (conanfile.settings.get_safe("compiler.base.version") or
conanfile.settings.get_safe("compiler.version"))
if compiler == "msvc":
toolset_override = conanfile.conf["tools.microsoft.msbuild"].vs_version
if toolset_override:
visual_version = toolset_override
else:
version = compiler_version[:4] # Remove the latest version number 19.1X if existing
_visuals = {'19.0': '14', # TODO: This is common to CMake, refactor
'19.1': '15',
'19.2': '16'}
visual_version = _visuals[version]
else:
visual_version = compiler_version
return visual_version


class MSBuildToolchain(object):

filename = "conantoolchain.props"
Expand All @@ -21,25 +61,6 @@ def __init__(self, conanfile):
self.cppstd = conanfile.settings.get_safe("compiler.cppstd")
self.toolset = self._msvs_toolset(conanfile.settings)

# For VCVARS stuff
self.compiler = conanfile.settings.get_safe("compiler")
# This is assuming this is the Visual Studio IDE version, used for the vcvars
compiler_version = (conanfile.settings.get_safe("compiler.base.version") or
conanfile.settings.get_safe("compiler.version"))
self.vcvars_arch = vcvars_arch(conanfile)
if self.compiler == "msvc":
toolset_override = self._conanfile.conf["tools.microsoft.msbuild"].vs_version
if toolset_override:
self.visual_version = toolset_override
else:
version = compiler_version[:4] # Remove the latest version number 19.1X if existing
_visuals = {'19.0': '14', # TODO: This is common to CMake, refactor
'19.1': '15',
'19.2': '16'}
self.visual_version = _visuals[version]
else:
self.visual_version = compiler_version

def _name_condition(self, settings):
props = [("Configuration", self.configuration),
# FIXME: This probably requires mapping ARM architectures
Expand All @@ -55,20 +76,7 @@ def generate(self):
config_filename = "conantoolchain{}.props".format(name)
self._write_config_toolchain(config_filename)
self._write_main_toolchain(config_filename, condition)
self._write_vcvars()

def _write_vcvars(self):
if self.compiler == "intel":
cvars = intel_compilervars_command(self._conanfile)
else:
cvars = vcvars_command(self.visual_version, architecture=self.vcvars_arch,
platform_type=None, winsdk_version=None,
vcvars_ver=None)
content = textwrap.dedent("""\
@echo off
{}
""".format(cvars))
save("conanvcvars.bat", content)
write_conanvcvars(self._conanfile)

@staticmethod
def _msvs_toolset(settings):
Expand Down
2 changes: 1 addition & 1 deletion conans/test/utils/mocks.py
Expand Up @@ -179,7 +179,7 @@ def __init__(self, shared=None, options=None, options_values=None):
self._conan_user = None
self._conan_channel = None

def run(self, command, win_bash=False, subsystem=None):
def run(self, command, win_bash=False, subsystem=None, env=None):
assert win_bash is False
assert subsystem is None
self.command = command
Expand Down