Exemplo n.º 1
0
def run_in_windows_bash(conanfile, command, cwd=None, env=None):
    """ Will run a unix command inside a bash terminal It requires to have MSYS2, CYGWIN, or WSL"""
    if env:
        # Passing env invalidates the conanfile.environment_scripts
        env_win = [env] if not isinstance(env, list) else env
        env_shell = []
    else:
        env_shell = ["conanbuild.sh"]
        env_win = ["conanbuild.bat"]

    subsystem = conanfile.conf["tools.microsoft.bash:subsystem"]
    shell_path = conanfile.conf["tools.microsoft.bash:path"]

    if not platform.system() == "Windows":
        raise ConanException("Command only for Windows operating system")

    if not subsystem or not shell_path:
        raise ConanException("The config 'tools.microsoft.bash:subsystem' and 'tools.microsoft.bash:path' are "
                             "needed to run commands in a Windows subsystem")
    if subsystem == MSYS2:
        # Configure MSYS2 to inherith the PATH
        msys2_mode_env = Environment(conanfile)
        _msystem = {"x86": "MINGW32"}.get(conanfile.settings.get_safe("arch"), "MINGW64")
        msys2_mode_env.define("MSYSTEM", _msystem)
        msys2_mode_env.define("MSYS2_PATH_TYPE", "inherit")
        path = os.path.join(conanfile.generators_folder, "msys2_mode.bat")
        msys2_mode_env.save_bat(path)
        env_win.append(path)

    # Needed to change to that dir inside the bash shell
    wrapped_shell = '"%s"' % shell_path if " " in shell_path else shell_path
    if env_win:
        wrapped_shell = environment_wrap_command(conanfile, env_win, shell_path,
                                                 cwd=conanfile.generators_folder)

    cwd = cwd or os.getcwd()
    if not os.path.isabs(cwd):
        cwd = os.path.join(os.getcwd(), cwd)
    cwd_inside = unix_path(conanfile, cwd)
    wrapped_user_cmd = command
    if env_shell:
        # Wrapping the inside_command enable to prioritize our environment, otherwise /usr/bin go
        # first and there could be commands that we want to skip
        wrapped_user_cmd = environment_wrap_command(conanfile, env_shell, command,
                                                    cwd=conanfile.generators_folder)
    inside_command = 'cd "{cwd_inside}" && ' \
                     '{wrapped_user_cmd}'.format(cwd_inside=cwd_inside,
                                                 wrapped_user_cmd=wrapped_user_cmd)

    inside_command = escape_windows_cmd(inside_command)

    final_command = 'cd "{cwd}" && {wrapped_shell} --login -c {inside_command}'.format(
        cwd=cwd,
        wrapped_shell=wrapped_shell,
        inside_command=inside_command)
    conanfile.output.info('Running in windows bash: %s' % final_command)
    return conanfile._conan_runner(final_command, output=conanfile.output, subprocess=True)
Exemplo n.º 2
0
 def run_pkg(msg):
     # FIXME: This only works with ``--install-folder``, layout() will break this
     cmd_release = environment_wrap_command("conanrunenv-release-x86_64",
                                            "dep_app", cwd=c.current_folder)
     c.run_command(cmd_release)
     assert "{}: Release!".format(msg) in c.out
     cmd_release = environment_wrap_command("conanrunenv-debug-x86_64",
                                            "dep_app", cwd=c.current_folder)
     c.run_command(cmd_release)
     assert "{}: Debug!".format(msg) in c.out
Exemplo n.º 3
0
def test_shared_cmake_toolchain():
    client = TestClient(default_server_user=True)

    client.save(pkg_cmake("hello", "0.1"))
    client.run("create . -o hello:shared=True")
    client.save(pkg_cmake("chat", "0.1", requires=["hello/0.1"]),
                clean_first=True)
    client.run("create . -o chat:shared=True -o hello:shared=True")
    client.save(pkg_cmake_app("app", "0.1", requires=["chat/0.1"]),
                clean_first=True)
    client.run("create . -o chat:shared=True -o hello:shared=True")
    client.run("upload * --all -c")
    client.run("remove * -f")

    client = TestClient(servers=client.servers, users=client.users)
    client.run(
        "install app/0.1@ -o chat:shared=True -o hello:shared=True -g VirtualRunEnv"
    )
    conanfile = ConanFileMock()
    command = environment_wrap_command(conanfile,
                                       "conanrun",
                                       "app",
                                       cwd=client.current_folder)

    client.run_command(command)
    assert "main: Release!" in client.out
    assert "chat: Release!" in client.out
    assert "hello: Release!" in client.out
Exemplo n.º 4
0
    def run(self, command, output=True, cwd=None, win_bash=False, subsystem=None, msys_mingw=True,
            ignore_errors=False, run_environment=False, with_login=True, env="conanbuildenv"):

        command = environment_wrap_command(env, command, cwd=self.generators_folder)

        def _run():
            if not win_bash:
                return self._conan_runner(command, output, os.path.abspath(RUN_LOG_NAME), cwd)
            # FIXME: run in windows bash is not using output
            return tools.run_in_windows_bash(self, bashcmd=command, cwd=cwd, subsystem=subsystem,
                                             msys_mingw=msys_mingw, with_login=with_login)
        if run_environment:
            # When using_build_profile the required environment is already applied through
            # 'conanfile.env' in the contextmanager 'get_env_context_manager'
            with tools.run_environment(self) if not self._conan_using_build_profile else no_op():
                if OSInfo().is_macos and isinstance(command, string_types):
                    # Security policy on macOS clears this variable when executing /bin/sh. To
                    # keep its value, set it again inside the shell when running the command.
                    command = 'DYLD_LIBRARY_PATH="%s" DYLD_FRAMEWORK_PATH="%s" %s' % \
                              (os.environ.get('DYLD_LIBRARY_PATH', ''),
                               os.environ.get("DYLD_FRAMEWORK_PATH", ''),
                               command)
                retcode = _run()
        else:
            retcode = _run()

        if not ignore_errors and retcode != 0:
            raise ConanException("Error %d while executing %s" % (retcode, command))

        return retcode
Exemplo n.º 5
0
def test_complete(client):
    conanfile = textwrap.dedent("""
        import platform
        from conans import ConanFile

        class Pkg(ConanFile):
            requires = "openssl/1.0"
            build_requires = "mycmake/1.0"
            apply_env = False

            def build_requirements(self):
                self.build_requires("mygtest/1.0", force_host_context=True)

            def build(self):
                mybuild_cmd = "mycmake.bat" if platform.system() == "Windows" else "mycmake.sh"
                self.run(mybuild_cmd, env="conanbuildenv")
                mytest_cmd = "mygtest.bat" if platform.system() == "Windows" else "mygtest.sh"
                self.run(mytest_cmd, env="conanrunenv")
       """)

    client.save({"conanfile.py": conanfile})
    client.run("install . -s:b os=Windows -s:h os=Linux --build=missing")
    # Run the BUILD environment
    ext = "bat" if platform.system(
    ) == "Windows" else "sh"  # TODO: Decide on logic .bat vs .sh
    cmd = environment_wrap_command(ConanFileMock(),
                                   "conanbuildenv",
                                   "mycmake.{}".format(ext),
                                   cwd=client.current_folder)
    client.run_command(cmd)
    assert "MYCMAKE=Windows!!" in client.out
    assert "MYOPENSSL=Windows!!" in client.out

    # Run the RUN environment
    cmd = environment_wrap_command(
        ConanFileMock(),
        "conanrunenv",
        "mygtest.{ext} && .{sep}myrunner.{ext}".format(ext=ext, sep=os.sep),
        cwd=client.current_folder)
    client.run_command(cmd)
    assert "MYGTEST=Linux!!" in client.out
    assert "MYGTESTVAR=MyGTestValueLinux!!" in client.out

    client.run("build .")
    assert "MYCMAKE=Windows!!" in client.out
    assert "MYOPENSSL=Windows!!" in client.out
    assert "MYGTEST=Linux!!" in client.out
Exemplo n.º 6
0
def test_profile_buildenv():
    client = TestClient()
    save(client.cache.new_config_path, "tools.env.virtualenv:auto_use=True")
    conanfile = textwrap.dedent("""\
        import os, platform
        from conans import ConanFile
        class Pkg(ConanFile):
            def generate(self):
                if platform.system() == "Windows":
                    self.buildenv.save_bat("pkgenv.bat")
                else:
                    self.buildenv.save_sh("pkgenv.sh")
                    os.chmod("pkgenv.sh", 0o777)

        """)
    # Some scripts in a random system folders, path adding to the profile [env]

    compiler_bat = "@echo off\necho MYCOMPILER!!\necho MYPATH=%PATH%"
    compiler_sh = "echo MYCOMPILER!!\necho MYPATH=$PATH"
    compiler2_bat = "@echo off\necho MYCOMPILER2!!\necho MYPATH2=%PATH%"
    compiler2_sh = "echo MYCOMPILER2!!\necho MYPATH2=$PATH"

    myprofile = textwrap.dedent("""
           [buildenv]
           PATH+=(path){}
           mypkg*:PATH=!
           mypkg*:PATH+=(path){}
           """.format(os.path.join(client.current_folder, "compiler"),
                      os.path.join(client.current_folder, "compiler2")))
    client.save({
        "conanfile.py": conanfile,
        "myprofile": myprofile,
        "compiler/mycompiler.bat": compiler_bat,
        "compiler/mycompiler.sh": compiler_sh,
        "compiler2/mycompiler.bat": compiler2_bat,
        "compiler2/mycompiler.sh": compiler2_sh
    })

    os.chmod(os.path.join(client.current_folder, "compiler", "mycompiler.sh"),
             0o777)
    os.chmod(os.path.join(client.current_folder, "compiler2", "mycompiler.sh"),
             0o777)

    client.run("install . -pr=myprofile")
    # Run the BUILD environment
    ext = "bat" if platform.system(
    ) == "Windows" else "sh"  # TODO: Decide on logic .bat vs .sh
    cmd = environment_wrap_command("conanbuildenv",
                                   "mycompiler.{}".format(ext),
                                   cwd=client.current_folder)
    client.run_command(cmd)
    assert "MYCOMPILER!!" in client.out
    assert "MYPATH=" in client.out

    # Now with pkg-specific env-var
    client.run("install . mypkg/1.0@  -pr=myprofile")
    client.run_command(cmd)
    assert "MYCOMPILER2!!" in client.out
    assert "MYPATH2=" in client.out
Exemplo n.º 7
0
def command_env_wrapper(conanfile, command, envfiles, envfiles_folder):
    from conan.tools.env.environment import environment_wrap_command
    if platform.system() == "Windows" and conanfile.win_bash:  # New, Conan 2.0
        wrapped_cmd = _windows_bash_wrapper(conanfile, command, envfiles,
                                            envfiles_folder)
    else:
        wrapped_cmd = environment_wrap_command(envfiles, envfiles_folder,
                                               command)
    return wrapped_cmd
Exemplo n.º 8
0
def build_windows_subsystem(profile, make_program):
    """ The AutotoolsDeps can be used also in pure Makefiles, if the makefiles follow
    the Autotools conventions
    """
    # FIXME: cygwin in CI (my local machine works) seems broken for path with spaces
    client = TestClient(path_with_spaces=False)
    client.run("new hello/0.1 --template=cmake_lib")
    # TODO: Test Windows subsystems in CMake, at least msys is broken
    os.rename(os.path.join(client.current_folder, "test_package"),
              os.path.join(client.current_folder, "test_package2"))
    client.save({"profile": profile})
    client.run("create . --profile=profile")

    main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])
    makefile = gen_makefile(apps=["app"])

    conanfile = textwrap.dedent("""
        from conans import ConanFile
        from conan.tools.gnu import AutotoolsToolchain, Autotools, AutotoolsDeps

        class TestConan(ConanFile):
            requires = "hello/0.1"
            settings = "os", "compiler", "arch", "build_type"
            exports_sources = "Makefile"
            generators = "AutotoolsDeps", "AutotoolsToolchain"

            def build(self):
                autotools = Autotools(self)
                autotools.make()
        """)
    client.save({"app.cpp": main,
                 "Makefile": makefile,
                 "conanfile.py": conanfile,
                 "profile": profile}, clean_first=True)

    client.run("install . --profile=profile")
    cmd = environment_wrap_command(["conanbuildenv",
                                    "conanautotoolstoolchain",
                                    "conanautotoolsdeps"], client.current_folder, make_program)
    client.run_command(cmd)
    client.run_command("app")
    # TODO: fill compiler version when ready
    check_exe_run(client.out, "main", "gcc", None, "Release", "x86_64", None)
    assert "hello/0.1: Hello World Release!" in client.out

    client.save({"app.cpp": gen_function_cpp(name="main", msg="main2",
                                             includes=["hello"], calls=["hello"])})
    # Make sure it is newer
    t = time.time() + 1
    touch(os.path.join(client.current_folder, "app.cpp"), (t, t))

    client.run("build .")
    client.run_command("app")
    # TODO: fill compiler version when ready
    check_exe_run(client.out, "main2", "gcc", None, "Release", "x86_64", None, cxx11_abi=0)
    assert "hello/0.1: Hello World Release!" in client.out
    return client.out
Exemplo n.º 9
0
def test_complete(client):
    conanfile = textwrap.dedent("""
        import os
        from conans import ConanFile

        class Pkg(ConanFile):
            requires = "openssl/1.0"
            build_requires = "mycmake/1.0"
            apply_env = False

            def build_requirements(self):
                self.build_requires("mygtest/1.0", force_host_context=True)

            def build(self):
                self.run("mycmake.bat", env="conanbuildenv")
                assert os.path.exists(os.path.join(self.generators_folder, "conanrunenv.sh"))
       """)

    client.save({"conanfile.py": conanfile})
    client.run("install . -s:b os=Windows -s:h os=Linux --build=missing")
    # Run the BUILD environment
    if platform.system() == "Windows":
        cmd = environment_wrap_command("conanbuildenv",
                                       "mycmake.bat",
                                       cwd=client.current_folder)
        client.run_command(cmd)
        assert "MYCMAKE=Windows!!" in client.out
        assert "MYOPENSSL=Windows!!" in client.out

    # Run the RUN environment
    if platform.system() != "Windows":
        cmd = environment_wrap_command("conanrunenv",
                                       "mygtest.sh && .{}myrunner.sh".format(
                                           os.sep),
                                       cwd=client.current_folder)
        client.run_command(cmd)
        assert "MYGTEST=Linux!!" in client.out
        assert "MYGTESTVAR=MyGTestValueLinux!!" in client.out

    if platform.system() == "Windows":
        client.run("build .")
        assert "MYCMAKE=Windows!!" in client.out
        assert "MYOPENSSL=Windows!!" in client.out
Exemplo n.º 10
0
def _windows_bash_wrapper(conanfile, command, env, envfiles_folder):
    from conan.tools.env import Environment
    from conan.tools.env.environment import environment_wrap_command
    """ Will wrap a unix command inside a bash terminal It requires to have MSYS2, CYGWIN, or WSL"""

    subsystem = conanfile.conf.get("tools.microsoft.bash:subsystem")
    shell_path = conanfile.conf.get("tools.microsoft.bash:path")
    if not subsystem or not shell_path:
        raise ConanException("The config 'tools.microsoft.bash:subsystem' and "
                             "'tools.microsoft.bash:path' are "
                             "needed to run commands in a Windows subsystem")
    env = env or []
    if subsystem == MSYS2:
        # Configure MSYS2 to inherith the PATH
        msys2_mode_env = Environment()
        _msystem = {
            "x86": "MINGW32"
        }.get(conanfile.settings.get_safe("arch"), "MINGW64")
        msys2_mode_env.define("MSYSTEM", _msystem)
        msys2_mode_env.define("MSYS2_PATH_TYPE", "inherit")
        path = os.path.join(conanfile.generators_folder, "msys2_mode.bat")
        msys2_mode_env.vars(conanfile, "build").save_bat(path)
        env.append(path)

    wrapped_shell = '"%s"' % shell_path if " " in shell_path else shell_path
    wrapped_shell = environment_wrap_command(env,
                                             envfiles_folder,
                                             wrapped_shell,
                                             accepted_extensions=("bat",
                                                                  "ps1"))

    # Wrapping the inside_command enable to prioritize our environment, otherwise /usr/bin go
    # first and there could be commands that we want to skip
    wrapped_user_cmd = environment_wrap_command(env,
                                                envfiles_folder,
                                                command,
                                                accepted_extensions=("sh", ))
    wrapped_user_cmd = _escape_windows_cmd(wrapped_user_cmd)

    final_command = '{} -c {}'.format(wrapped_shell, wrapped_user_cmd)
    return final_command
Exemplo n.º 11
0
 def _run(cmd, _env):
     # FIXME: run in windows bash is not using output
     if platform.system() == "Windows":
         if win_bash:
             return tools.run_in_windows_bash(self, bashcmd=cmd, cwd=cwd, subsystem=subsystem,
                                              msys_mingw=msys_mingw, with_login=with_login)
         elif self.win_bash:  # New, Conan 2.0
             from conan.tools.microsoft.subsystems import run_in_windows_bash
             return run_in_windows_bash(self, command=cmd, cwd=cwd, env=_env)
     if _env is None:
         _env = "conanbuild"
     from conan.tools.env.environment import environment_wrap_command
     wrapped_cmd = environment_wrap_command(_env, cmd, cwd=self.generators_folder)
     return self._conan_runner(wrapped_cmd, output, os.path.abspath(RUN_LOG_NAME), cwd)
Exemplo n.º 12
0
def test_massive_paths(num_deps):
    """ This test proves that having too many dependencies that will result in a very long PATH
    env-var in the consumer by one VirtualXXXEnv environment, will overflow.
    https://github.com/conan-io/conan/issues/9565
    This seems an unsolvable limitation, the only alternatives are:
    - shorten the paths in general (shorter cache paths)
    - add exclusively the paths of needed things (better visibility)
    Seems that Conan 2.0 will improve over these things, allowing larger dependencies graphs without
    failing. Besides that, it might use the deployers to workaround shared-libs running scenarios.

    The test is parameterized for being fast an passing, but if we add a num_deps >= 80 approx,
    it will start to enter the failing scenarios. Not adding the >=80 scenario, because that tests
    takes 1 minute by itself, not worth the value.
    """
    client = TestClient(path_with_spaces=False)
    compiler_bat = "@echo off\necho MYTOOL {}!!\n"
    conanfile = textwrap.dedent("""\
        from conans import ConanFile
        class Pkg(ConanFile):
            exports = "*"
            def package(self):
                self.copy("*", dst="bin")
        """)

    for i in range(num_deps):
        client.save({
            "conanfile.py": conanfile,
            "mycompiler{}.bat".format(i): compiler_bat.format(i)
        })
        client.run("create . pkg{}/0.1@".format(i))

    conanfile = textwrap.dedent("""\
        from conans import ConanFile
        class Pkg(ConanFile):
            settings = "os"
            requires = {}
            generators = "VirtualRunEnv"
        """)
    requires = ", ".join('"pkg{}/0.1"'.format(i) for i in range(num_deps))
    conanfile = conanfile.format(requires)
    client.save({"conanfile.py": conanfile}, clean_first=True)
    client.run("install . -c tools.env.virtualenv:powershell=True")
    assert os.path.isfile(
        os.path.join(client.current_folder, "conanrunenv.ps1"))
    assert not os.path.isfile(
        os.path.join(client.current_folder, "conanrunenv.bat"))
    for i in range(num_deps):
        cmd = environment_wrap_command("conanrunenv", client.current_folder,
                                       "mycompiler{}.bat".format(i))
        if num_deps > 50:  # to be safe if we change the "num_deps" number
            client.run_command(cmd, assert_error=True)
            assert "is not recognized as an internal" in client.out
        else:
            client.run_command(cmd)
            assert "MYTOOL {}!!".format(i) in client.out

    # Test .bats now
    client.save({"conanfile.py": conanfile}, clean_first=True)
    client.run("install .")
    assert not os.path.isfile(
        os.path.join(client.current_folder, "conanrunenv.ps1"))
    assert os.path.isfile(
        os.path.join(client.current_folder, "conanrunenv.bat"))
    for i in range(num_deps):
        cmd = environment_wrap_command("conanrunenv", client.current_folder,
                                       "mycompiler{}.bat".format(i))
        if num_deps > 50:  # to be safe if we change the "num_deps" number
            client.run_command(cmd, assert_error=True)
            # This also fails, but without an error message (in my terminal, it kills the terminal!)
        else:
            client.run_command(cmd)
            assert "MYTOOL {}!!".format(i) in client.out