def get_command(): def instance_remote_manager(client_cache): requester = requests.Session() requester.proxies = client_cache.conan_config.proxies # Verify client version against remotes version_checker_requester = VersionCheckerRequester( requester, Version(CLIENT_VERSION), Version(MIN_SERVER_COMPATIBLE_VERSION), out) # To handle remote connections rest_api_client = RestApiClient(out, requester=version_checker_requester) # To store user and token localdb = LocalDB(client_cache.localdb) # Wraps RestApiClient to add authentication support (same interface) auth_manager = ConanApiAuthManager(rest_api_client, user_io, localdb) # Handle remote connections remote_manager = RemoteManager(client_cache, auth_manager, out) return remote_manager use_color = get_env("CONAN_COLOR_DISPLAY", 1) if use_color and hasattr(sys.stdout, "isatty") and sys.stdout.isatty(): import colorama colorama.init() color = True else: color = False out = ConanOutput(sys.stdout, color) user_io = UserIO(out=out) user_folder = os.getenv("CONAN_USER_HOME", conan_expand_user("~")) try: # To capture exceptions in conan.conf parsing client_cache = ClientCache(user_folder, None, out) # obtain a temp ConanManager instance to execute the migrations remote_manager = instance_remote_manager(client_cache) # Get a DiskSearchManager search_adapter = DiskSearchAdapter() search_manager = DiskSearchManager(client_cache, search_adapter) manager = ConanManager(client_cache, user_io, ConanRunner(), remote_manager, search_manager) client_cache = migrate_and_get_client_cache(user_folder, out, manager) except Exception as e: out.error(str(e)) sys.exit(True) # Get the new command instance after migrations have been done remote_manager = instance_remote_manager(client_cache) # Get a search manager search_adapter = DiskSearchAdapter() search_manager = DiskSearchManager(client_cache, search_adapter) command = Command(client_cache, user_io, ConanRunner(), remote_manager, search_manager) return command
def get_conan_runner(): print_commands_to_output = get_env("CONAN_PRINT_RUN_COMMANDS", False) generate_run_log_file = get_env("CONAN_LOG_RUN_TO_FILE", False) log_run_to_output = get_env("CONAN_LOG_RUN_TO_OUTPUT", True) runner = ConanRunner(print_commands_to_output, generate_run_log_file, log_run_to_output) return runner
def __init__(self, runner=None, os_info=None, tool=None, recommends=False): os_info = os_info or OSInfo() self._is_up_to_date = False self._tool = tool or self._create_tool(os_info) self._tool._sudo_str = "sudo " if self._is_sudo_enabled() else "" self._tool._runner = runner or ConanRunner() self._tool._recommends = recommends
def run_command(self, command, cwd=None, assert_error=False): output = TestBufferConanOutput() self.out = output runner = ConanRunner(output=output) ret = runner(command, cwd=cwd or self.current_folder) self._handle_cli_result(command, assert_error=assert_error, error=ret) return ret
def __init__(self, runner=None, os_info=None, tool=None): env_sudo = os.environ.get("CONAN_SYSREQUIRES_SUDO", None) self._sudo = (env_sudo != "False" and env_sudo != "0") os_info = os_info or OSInfo() self._is_up_to_date = False self._tool = tool or self._create_tool(os_info) self._tool._sudo_str = "sudo " if self._sudo else "" self._tool._runner = runner or ConanRunner()
def __init__(self, runner=None, os_info=None, tool=None, recommends=False, output=None, conanfile=None): output = output if output else conanfile.output if conanfile else None self._output = default_output(output, 'conans.client.tools.system_pm.SystemPackageTool') os_info = os_info or OSInfo() self._is_up_to_date = False self._tool = tool or self._create_tool(os_info, output=self._output) self._tool._sudo_str = self._get_sudo_str() self._tool._runner = runner or ConanRunner(output=self._output) self._tool._recommends = recommends self._conanfile = conanfile
def test_write_to_stringio(self): runner = ConanRunner(print_commands_to_output=True, generate_run_log_file=True, log_run_to_output=True) out = six.StringIO() runner("python --version", output=out) self.assertIn("""---Running------ > python --version -----------------""", out.getvalue())
def test_vcvars_echo(self): settings = Settings.loads(get_default_settings_yml()) settings.os = "Windows" settings.compiler = "Visual Studio" settings.compiler.version = "14" cmd = tools.vcvars_command(settings, output=self.output) output = TestBufferConanOutput() runner = ConanRunner(print_commands_to_output=True, output=output) runner(cmd + " && set vs140comntools") self.assertIn("vcvarsall.bat", str(output)) self.assertIn("VS140COMNTOOLS=", str(output)) with tools.environment_append({"VisualStudioVersion": "14"}): output = TestBufferConanOutput() runner = ConanRunner(print_commands_to_output=True, output=output) cmd = tools.vcvars_command(settings, output=self.output) runner(cmd + " && set vs140comntools") self.assertNotIn("vcvarsall.bat", str(output)) self.assertIn("Conan:vcvars already set", str(output)) self.assertIn("VS140COMNTOOLS=", str(output))
def append_variables_test(self): output = TestBufferConanOutput() runner = ConanRunner() if platform.system() != "Windows": os.environ["LDFLAGS"] = "ldflag=23 otherldflag=33" os.environ["CPPFLAGS"] = "-cppflag -othercppflag" os.environ["CFLAGS"] = "-cflag" os.environ[ "C_INCLUDE_PATH"] = "/path/to/c_include_path:/anotherpath" os.environ[ "CPLUS_INCLUDE_PATH"] = "/path/to/cpp_include_path:/anotherpathpp" env = ConfigureEnvironment(BuildInfoMock(), MockLinuxSettings()) runner(env.command_line, output=output) self.assertIn( "LDFLAGS=-Lpath/to/lib1 -Lpath/to/lib2 -m32 -framework thing -framework thing2 ldflag=23 otherldflag=33\n", output) self.assertIn( "CPPFLAGS=-cppflag -othercppflag -m32 cppflag1 -s -DNDEBUG -Ipath/to/includes/lib1 -Ipath/to/includes/lib2 -DMYDEF1 -DMYDEF2\n", output) self.assertIn( "CFLAGS=-cflag -m32 cflag1 -s -DNDEBUG -Ipath/to/includes/lib1 -Ipath/to/includes/lib2 -DMYDEF1 -DMYDEF2\n", output) self.assertIn( "C_INCLUDE_PATH=/path/to/c_include_path:/anotherpath:path/to/includes/lib1:path/to/includes/lib2\n", output) self.assertIn( "CPLUS_INCLUDE_PATH=/path/to/cpp_include_path:/anotherpathpp:path/to/includes/lib1:path/to/includes/lib2\n", output) # Reset env vars to not mess with other tests os.environ["LDFLAGS"] = "" os.environ["CPPFLAGS"] = "" os.environ["CFLAGS"] = "" os.environ["C_INCLUDE_PATH"] = "" os.environ["CPLUS_INCLUDE_PATH"] = "" else: os.environ["LIB"] = '"/path/to/lib.a"' os.environ["CL"] = '/I"path/to/cl1" /I"path/to/cl2"' env = ConfigureEnvironment(BuildInfoMock(), MockWinSettings()) command = "%s && SET" % env.command_line runner(command, output=output) self.assertIn('LIB="path/to/lib1";"path/to/lib2";"/path/to/lib.a"', output) self.assertIn( 'CL=/I"path/to/includes/lib1" /I"path/to/includes/lib2"', output) os.environ["LIB"] = "" os.environ["CL"] = ""
def __init__(self, runner=None, os_info=None, tool=None, recommends=False): env_sudo = os.environ.get("CONAN_SYSREQUIRES_SUDO", None) self._sudo = (env_sudo != "False" and env_sudo != "0") if env_sudo is None and os.name == 'posix' and os.geteuid() == 0: self._sudo = False if env_sudo is None and os.name == 'nt': self._sudo = False os_info = os_info or OSInfo() self._is_up_to_date = False self._tool = tool or self._create_tool(os_info) self._tool._sudo_str = "sudo " if self._sudo else "" self._tool._runner = runner or ConanRunner() self._tool._recommends = recommends
def test_write_to_stringio(self): runner = ConanRunner(print_commands_to_output=True, generate_run_log_file=True, log_run_to_output=True) out = StringIO() if six.PY2: with self.assertRaisesRegexp(Exception, "Invalid output parameter"): runner("python --version", output=out) out = six.StringIO() runner("python --version", output=out) self.assertIn("""---Running------ > python --version -----------------""", out.getvalue())
def build_vs_project_test(self, generator, props): client = TestClient() files = {} files["conanfile.py"] = hello_conanfile_py files["hello.h"] = hello_h client.save(files) client.run("create . lasote/testing") files = get_vs_project_files() files["MyProject/main.cpp"] = main_cpp files["conanfile.txt"] = conanfile_txt.format(generator=generator) props = os.path.join(client.current_folder, props) old = '<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />' new = old + '<Import Project="{props}" />'.format(props=props) files["MyProject/MyProject.vcxproj"] = files[ "MyProject/MyProject.vcxproj"].replace(old, new) client.save(files, clean_first=True) for build_type in ["Debug", "Release"]: arch = "x86" runner = ConanRunner(print_commands_to_output=True, generate_run_log_file=False, log_run_to_output=True, output=TestBufferConanOutput()) settings = MockSettings({ "os": "Windows", "build_type": build_type, "arch": arch, "compiler": "Visual Studio", "compiler.version": "15", "compiler.toolset": "v141" }) conanfile = MockConanfile(settings, runner=runner) settings = " -s os=Windows " \ " -s build_type={build_type} " \ " -s arch={arch}" \ " -s compiler=\"Visual Studio\"" \ " -s compiler.toolset=v141" \ " -s compiler.version=15".format(build_type=build_type, arch=arch) client.run("install . %s" % settings) with tools.chdir(client.current_folder): msbuild = MSBuild(conanfile) msbuild.build(project_file="MyProject.sln", build_type=build_type, arch=arch) output = TestBufferConanOutput() runner("%s\MyProject.exe" % build_type, output) self.assertIn("Hello %s!!!" % build_type, output)
def generate_expanded_profile_from_in_file(profiles_path, f): nf = f.replace(".in", "") profile_path = os.path.join(profiles_path, f) print("Processing {0}...".format(profile_path)) with open(profile_path, "r") as pf: data = pf.readlines() newlines = [] # get CC binary cc = [i.split("CC=")[1] for i in data if i.startswith("CC=")][0].replace("ccache ", "").strip() cc_output = CBuffer() cc_cmd = "{0} -print-sysroot".format(cc) runner = ConanRunner() if not runner(cc_cmd, output=cc_output) is 0: print("Failed to run {0} for {1}!\n{2}".format(cc_cmd, f, cc_output.lines)) return False sysroot = os.path.abspath(cc_output.lines[0].strip()) if cc_output.lines else None cc_output.clear() triple = [i.split("_STATUS_GCC_TRIPLE_NAME=")[1] for i in data if i.startswith("_STATUS_GCC_TRIPLE_NAME=")] if triple: triple = triple[0].strip() ccpath = os.path.abspath(os.path.join(sysroot, os.pardir)) if not os.path.isdir(os.path.join(ccpath, triple)): ccpath = os.path.abspath(os.path.join(sysroot, os.pardir, os.pardir)) triple_sysrootpath = os.path.normpath(os.path.abspath(os.path.join(sysroot, "usr", triple))) flags = " --sysroot=" + sysroot if sysroot else "" for line in data: line = line.rstrip() if line.startswith("LDFLAGS="): newlines.append("LDFLAGS={0}{1}".format(line.strip().split("LDFLAGS=")[1], flags)) elif line.startswith("_STATUS_TRIPLE_PATH="): path=os.path.normpath(os.path.join(triple_sysrootpath, "../../..", line.strip().split("_STATUS_TRIPLE_PATH=")[1])) newlines.append("_STATUS_TRIPLE_PATH={0}".format(path)) elif line.startswith("_STATUS_TRIPLE_SYSROOTPATH="): newlines.append("_STATUS_TRIPLE_SYSROOTPATH={0}".format(triple_sysrootpath)) else: newlines.append(line) with open(os.path.join(profiles_path, nf), "w") as nfp: nfp.write("\n".join(newlines) + "\n") return True
def _install_a_package(print_commands_to_output, generate_run_log_file): output = TestBufferConanOutput() runner = ConanRunner(print_commands_to_output, generate_run_log_file, log_run_to_output=True, output=output) client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}, runner=runner) ref = ConanFileReference.loads("Hello0/0.1@lasote/stable") client.save({"conanfile.py": base}) client.run("create . lasote/stable") package_dir = client.cache.package_layout(ref).packages() package_dir = os.path.join(package_dir, os.listdir(package_dir)[0]) log_file_packaged_ = os.path.join(package_dir, RUN_LOG_NAME) output = "\n".join([str(output), str(client.out)]) return log_file_packaged_, output
def _check_build_generator(self, os_build, generator): output = TestBufferConanOutput() runner = ConanRunner(True, False, True, output=output) client = TestClient(runner=runner) client.save({"conanfile.py": CONAN_RECIPE, "CMakeLists.txt": CMAKE_RECIPE, "dummy.cpp": CPP_CONTENT, "my_profile": PROFILE.format(os_build=os_build) }) client.run("install . -pr my_profile") client.run("build .") if generator: self.assertIn('cmake -G "{}"'.format(generator), output) self.assertTrue(os.path.isfile(os.path.join(client.current_folder, "Makefile"))) else: self.assertNotIn("cmake -G", output) self.assertFalse(os.path.isfile(os.path.join(client.current_folder, "Makefile")))
def _install_a_package(print_commands_to_output, generate_run_log_file): runner = ConanRunner(print_commands_to_output, generate_run_log_file, log_run_to_output=True) client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}, runner=runner) conan_reference = ConanFileReference.loads("Hello0/0.1@lasote/stable") files = {} files[CONANFILE] = base client.save(files) client.run("user lasote -p mypass -r default") client.run("export . lasote/stable") client.run("install %s --build missing" % str(conan_reference)) package_dir = client.client_cache.packages(ConanFileReference.loads("Hello0/0.1@lasote/stable")) package_dir = os.path.join(package_dir, os.listdir(package_dir)[0]) log_file_packaged = os.path.join(package_dir, RUN_LOG_NAME) return log_file_packaged, client.user_io.out
def append_variables_test(self): output = TestBufferConanOutput() runner = ConanRunner() if platform.system() != "Windows": os.environ["LDFLAGS"] = "ldflag=23 otherldflag=33" os.environ["CPPFLAGS"] = "-cppflag -othercppflag" os.environ["CFLAGS"] = "-cflag" os.environ["C_INCLUDE_PATH"] = "/path/to/c_include_path:/anotherpath" os.environ["CPLUS_INCLUDE_PATH"] = "/path/to/cpp_include_path:/anotherpathpp" c11settings_release = MockSettings("Release", os="Linux", arch="x86", compiler_name="gcc", libcxx="libstdc++11", version="6.2") env = ConfigureEnvironment(MockConanfile(c11settings_release)) runner(env.command_line, output=output) self.assertIn("LDFLAGS=-Lpath/to/lib1 -Lpath/to/lib2 -m32 -framework thing -framework thing2 ldflag=23 otherldflag=33\n", output) self.assertIn("CPPFLAGS=-cppflag -othercppflag -m32 cppflag1 -D_GLIBCXX_USE_CXX11_ABI=1 -s -DNDEBUG -Ipath/to/includes/lib1 -Ipath/to/includes/lib2 -DMYDEF1 -DMYDEF2\n", output) self.assertIn("CFLAGS=-cflag -m32 cflag1 -s -DNDEBUG -Ipath/to/includes/lib1 -Ipath/to/includes/lib2 -DMYDEF1 -DMYDEF2\n", output) self.assertIn("C_INCLUDE_PATH=/path/to/c_include_path:/anotherpath:path/to/includes/lib1:path/to/includes/lib2\n", output) self.assertIn("CPLUS_INCLUDE_PATH=/path/to/cpp_include_path:/anotherpathpp:path/to/includes/lib1:path/to/includes/lib2\n", output) # Reset env vars to not mess with other tests os.environ["LDFLAGS"] = "" os.environ["CPPFLAGS"] = "" os.environ["CFLAGS"] = "" os.environ["C_INCLUDE_PATH"] = "" os.environ["CPLUS_INCLUDE_PATH"] = "" else: os.environ["LIB"] = '/path/to/lib.a' os.environ["CL"] = '/I"path/to/cl1" /I"path/to/cl2"' win_settings = MockSettings("Release", os="Windows", arch="x86", compiler_name="Visual Studio", libcxx=None, version="12") env = ConfigureEnvironment(MockConanfile(win_settings)) command = "%s && SET" % env.command_line runner(command, output=output) self.assertIn('/path/to/lib.a;path/to/lib1;path/to/lib2', output) self.assertIn('CL=/I"path/to/cl1" /I"path/to/cl2" ' '/I"path/to/includes/lib1" /I"path/to/includes/lib2"', output) os.environ["LIB"] = "" os.environ["CL"] = ""
def process_port(port, tmp_folder, visual_version, arch, build_type, is_link_dynamic): try: logger.info("Processing... %s:%s" % (port.source, port.version)) tmp_folder = os.path.join(tmp_folder, port.name) try: shutil.rmtree(tmp_folder) except Exception: pass new_template_to(port.name, port.version, tmp_folder) runner = ConanRunner() command = 'conan test_package -s compiler="Visual Studio" ' \ '-s compiler.version=%s -s arch=%s -s build_type=%s -o %s:shared=%s' \ % (visual_version, arch, build_type, port.name, str(is_link_dynamic)) logger.info(command) ret = runner(command, output=True, log_filepath=None, cwd=tmp_folder) return ret == 0 except Exception as exc: logger.error("Error in processing %s: Error '%s'" % (port.name, str(exc))) return False
def init_dynamic_vars(self, user_io=None): # Migration system output = TestBufferConanOutput() self.user_io = user_io or MockedUserIO(self.users, out=output) self.cache = ClientCache(self.base_folder, output) # Migration system migrator = ClientMigrator(self.cache, Version(__version__), output) migrator.migrate() http_requester = self._get_http_requester() config = self.cache.config if self.conan_runner: self.runner = self.conan_runner else: self.runner = ConanRunner(config.print_commands_to_output, config.generate_run_log_file, config.log_run_to_output, output=output) self.requester = ConanRequester(config, http_requester) self.hook_manager = HookManager(self.cache.hooks_path, config.hooks, self.user_io.out) put_headers = self.cache.read_put_headers() self.rest_api_client = RestApiClient( self.user_io.out, self.requester, revisions_enabled=config.revisions_enabled, put_headers=put_headers) # To store user and token self.localdb = LocalDB.create(self.cache.localdb) # Wraps RestApiClient to add authentication support (same interface) auth_manager = ConanApiAuthManager(self.rest_api_client, self.user_io, self.localdb) # Handle remote connections self.remote_manager = RemoteManager(self.cache, auth_manager, self.user_io.out, self.hook_manager) return output, self.requester
def __init__(self, output, runner=None): self._output = output self.runner = runner or ConanRunner(print_commands_to_output=True, generate_run_log_file=True, log_run_to_output=True)
def log_test(self): conanfile = ''' from conans import ConanFile from conans.client.runner import ConanRunner import platform class ConanFileToolsTest(ConanFile): def build(self): self.run("cmake --version") ''' # A runner logging everything runner = ConanRunner(print_commands_to_output=True, generate_run_log_file=True, log_run_to_output=True) client = self._install_and_build(conanfile, runner=runner) self.assertIn("--Running---", client.user_io.out) self.assertIn("> cmake --version", client.user_io.out) self.assertIn("cmake version", client.user_io.out) self.assertIn("Logging command output to file ", client.user_io.out) # A runner logging everything runner = ConanRunner(print_commands_to_output=True, generate_run_log_file=False, log_run_to_output=True) client = self._install_and_build(conanfile, runner=runner) self.assertIn("--Running---", client.user_io.out) self.assertIn("> cmake --version", client.user_io.out) self.assertIn("cmake version", client.user_io.out) self.assertNotIn("Logging command output to file ", client.user_io.out) runner = ConanRunner(print_commands_to_output=False, generate_run_log_file=True, log_run_to_output=True) client = self._install_and_build(conanfile, runner=runner) self.assertNotIn("--Running---", client.user_io.out) self.assertNotIn("> cmake --version", client.user_io.out) self.assertIn("cmake version", client.user_io.out) self.assertIn("Logging command output to file ", client.user_io.out) runner = ConanRunner(print_commands_to_output=False, generate_run_log_file=False, log_run_to_output=True) client = self._install_and_build(conanfile, runner=runner) self.assertNotIn("--Running---", client.user_io.out) self.assertNotIn("> cmake --version", client.user_io.out) self.assertIn("cmake version", client.user_io.out) self.assertNotIn("Logging command output to file ", client.user_io.out) runner = ConanRunner(print_commands_to_output=False, generate_run_log_file=False, log_run_to_output=False) client = self._install_and_build(conanfile, runner=runner) self.assertNotIn("--Running---", client.user_io.out) self.assertNotIn("> cmake --version", client.user_io.out) self.assertNotIn("cmake version", client.user_io.out) self.assertNotIn("Logging command output to file ", client.user_io.out) runner = ConanRunner(print_commands_to_output=False, generate_run_log_file=True, log_run_to_output=False) client = self._install_and_build(conanfile, runner=runner) self.assertNotIn("--Running---", client.user_io.out) self.assertNotIn("> cmake --version", client.user_io.out) self.assertNotIn("cmake version", client.user_io.out) self.assertIn("Logging command output to file ", client.user_io.out)
def __init__(self, runner=None): self._runner = runner or ConanRunner() env_sudo = os.environ.get("CONAN_SYSREQUIRES_SUDO", None) self._sudo = (env_sudo != "False" and env_sudo != "0") self._os_info = OSInfo()
def __init__(self, output): self._output = output self.runner = ConanRunner()
def test_log(self): conanfile = ''' from conans import ConanFile class ConanFileToolsTest(ConanFile): def build(self): self.run("cmake --version") ''' # A runner logging everything output = TestBufferConanOutput() runner = ConanRunner(print_commands_to_output=True, generate_run_log_file=True, log_run_to_output=True, output=output) self._install_and_build(conanfile, runner=runner) self.assertIn("--Running---", output) self.assertIn("> cmake --version", output) self.assertIn("cmake version", output) self.assertIn("Logging command output to file ", output) # A runner logging everything output = TestBufferConanOutput() runner = ConanRunner(print_commands_to_output=True, generate_run_log_file=False, log_run_to_output=True, output=output) self._install_and_build(conanfile, runner=runner) self.assertIn("--Running---", output) self.assertIn("> cmake --version", output) self.assertIn("cmake version", output) self.assertNotIn("Logging command output to file ", output) output = TestBufferConanOutput() runner = ConanRunner(print_commands_to_output=False, generate_run_log_file=True, log_run_to_output=True, output=output) self._install_and_build(conanfile, runner=runner) self.assertNotIn("--Running---", output) self.assertNotIn("> cmake --version", output) self.assertIn("cmake version", output) self.assertIn("Logging command output to file ", output) output = TestBufferConanOutput() runner = ConanRunner(print_commands_to_output=False, generate_run_log_file=False, log_run_to_output=True, output=output) self._install_and_build(conanfile, runner=runner) self.assertNotIn("--Running---", output) self.assertNotIn("> cmake --version", output) self.assertIn("cmake version", output) self.assertNotIn("Logging command output to file ", output) output = TestBufferConanOutput() runner = ConanRunner(print_commands_to_output=False, generate_run_log_file=False, log_run_to_output=False, output=output) self._install_and_build(conanfile, runner=runner) self.assertNotIn("--Running---", output) self.assertNotIn("> cmake --version", output) self.assertNotIn("cmake version", output) self.assertNotIn("Logging command output to file ", output) output = TestBufferConanOutput() runner = ConanRunner(print_commands_to_output=False, generate_run_log_file=True, log_run_to_output=False, output=output) self._install_and_build(conanfile, runner=runner) self.assertNotIn("--Running---", output) self.assertNotIn("> cmake --version", output) self.assertNotIn("cmake version", output) self.assertIn("Logging command output to file ", output)
def run_command(self, command, cwd=None): output = TestBufferConanOutput() self.out = output runner = ConanRunner(output=output) return runner(command, cwd=cwd or self.current_folder)
def detect_compiler_id(executable, runner=None): runner = runner or ConanRunner() # use a temporary file, as /dev/null might not be available on all platforms tmpdir = tempfile.mkdtemp() tmpname = os.path.join(tmpdir, "temp.c") with open(tmpname, "wb") as f: f.write(b"\n") cmd = os.path.join(tmpdir, "file.cmd") with open(cmd, "wb") as f: f.write(b"echo off\nset MSC_CMD_FLAGS\n") detectors = [ # "-dM" generate list of #define directives # "-E" run only preprocessor # "-x c" compiler as C code # the output is of lines in form of "#define name value" "-dM -E -x c", "--driver-mode=g++ -dM -E -x c", # clang-cl "-c -xdumpmacros", # SunCC, # cl (Visual Studio, MSVC) # "/nologo" Suppress Startup Banner # "/E" Preprocess to stdout # "/B1" C front-end # "/c" Compile Without Linking # "/TC" Specify Source File Type '/nologo /E /B1 "%s" /c /TC' % cmd, "/QdM /E /TC" # icc (Intel) on Windows, "-Wp,-dM -E -x c" # QNX QCC ] try: for detector in detectors: command = '%s %s "%s"' % (executable, detector, tmpname) result = StringIO() if 0 == runner(command, output=result): output = result.getvalue() defines = dict() for line in output.splitlines(): tokens = line.split(' ', 3) if len(tokens) == 3 and tokens[0] == '#define': defines[tokens[1]] = tokens[2] # MSVC dumps macro definitions in single line: # "MSC_CMD_FLAGS=-D_MSC_VER=1921 -Ze" elif line.startswith("MSC_CMD_FLAGS="): line = line[len("MSC_CMD_FLAGS="):].rstrip() defines = dict() tokens = line.split() for token in tokens: if token.startswith("-D") or token.startswith( "/D"): token = token[2:] if '=' in token: name, value = token.split('=', 2) else: name, value = token, '1' defines[name] = value break compiler = _parse_compiler_version(defines) if compiler == UNKNOWN_COMPILER: continue return compiler return UNKNOWN_COMPILER finally: try: rmdir(tmpdir) except OSError: pass