def with_pacman(self): if self.is_linux: return self.linux_distro == "arch" elif self.is_windows and which('uname.exe'): uname = subprocess.check_output(['uname.exe', '-s']).decode() return uname.startswith('MSYS_NT') and which('pacman.exe') return False
def with_pacman(self): if self.is_linux: return self.linux_distro == "arch" elif self.is_windows and which('uname.exe'): uname = subprocess.check_output(['uname.exe', '-s']).decode() return uname.startswith('MSYS_NT') and which('pacman.exe') return False
def _get_tool(name, version): # None: not cached yet # False = tool not available, legally skipped # True = tool not available, test error # (path, env) = tool available cached = _cached_tools.setdefault(name, {}).get(version) if cached is None: tool = tools_locations.get(name, {}) if tool.get("disabled"): _cached_tools[name][version] = False return False tool_platform = platform.system() if tool.get("platform", tool_platform) != tool_platform: _cached_tools[name][version] = None, None return None, None exe = tool.get("exe", name) version = version or tool.get("default") tool_version = tool.get(version) if tool_version is not None: assert isinstance(tool_version, dict) if tool_version.get("disabled"): _cached_tools[name][version] = False return False tool_path = tool_version.get("path", {}).get(tool_platform) else: if version is not None: # if the version is specified, it should be in the conf _cached_tools[name][version] = True return True tool_path = None try: tool_env = tools_environments[name][tool_platform] except KeyError: tool_env = None cached = tool_path, tool_env # Check this particular tool is installed if name == "visual_studio": if not vswhere(): # TODO: Missing version detection cached = True else: # which based detection old_environ = None if tool_path is not None: old_environ = dict(os.environ) os.environ[ "PATH"] = tool_path + os.pathsep + os.environ["PATH"] if not which( exe): # TODO: This which doesn't detect version either cached = True if old_environ is not None: os.environ.clear() os.environ.update(old_environ) _cached_tools[name][version] = cached return cached
def test_which_not_dir(self): tmp_dir = temp_folder() dev_dir = os.path.join(tmp_dir, "Dev") dev_git_dir = os.path.join(dev_dir, "Git") mkdir(dev_git_dir) with tools.environment_append({'PATH': dev_dir}): self.assertEqual(dev_dir, tools.get_env("PATH")) self.assertIsNone(tools.which('git'))
def test_which_positive(self): tmp_dir = temp_folder() ext = ".sh" if platform.system() != "Windows" else ".bat" fullname = os.path.join(tmp_dir, 'example%s' % ext) self._touch(fullname) self._add_executable_bit(fullname) with tools.environment_append({'PATH': tmp_dir}): self.assertEqual(tools.which('example').lower(), fullname.lower())
def test_which_non_executable(self): if platform.system() == "Windows": """on Windows we always have executable permissions by default""" return tmp_dir = temp_folder() fullname = os.path.join(tmp_dir, 'example.sh') self._touch(fullname) with tools.environment_append({'PATH': tmp_dir}): self.assertIsNone(tools.which('example.sh'))
def _get_make_program_definition(self): make_program = os.getenv("CONAN_MAKE_PROGRAM") or self._make_program if make_program: if not tools.which(make_program): self._output.warn("The specified make program '%s' cannot be found and will be " "ignored" % make_program) else: self._output.info("Using '%s' as CMAKE_MAKE_PROGRAM" % make_program) return {"CMAKE_MAKE_PROGRAM": make_program} return {}
import textwrap import unittest import pytest from nose.plugins.attrib import attr from conans.client.tools import which from conans.test.utils.tools import TestClient @attr("premake") @pytest.mark.tool_premake @unittest.skipIf(which("premake5") is None, "Needs premake5") class PremakeGeneratorTest(unittest.TestCase): def setUp(self): self.client = TestClient() conanfile = textwrap.dedent(""" [generators] premake """) premake = textwrap.dedent(""" include("conanbuildinfo.premake.lua") workspace("example") conan_basic_setup() project("example") kind "ConsoleApp" language "C++" targetdir = "bin/%{cfg.buildcfg}"
def setUpClass(cls): if not which("ninja"): raise unittest.SkipTest("Ninja expected in PATH")
def vswhere(all_=False, prerelease=False, products=None, requires=None, version="", latest=False, legacy=False, property_="", nologo=True): # 'version' option only works if Visual Studio 2017 is installed: # https://github.com/Microsoft/vswhere/issues/91 products = list() if products is None else products requires = list() if requires is None else requires if legacy and (products or requires): raise ConanException( "The 'legacy' parameter cannot be specified with either the " "'products' or 'requires' parameter") installer_path = None program_files = get_env("ProgramFiles(x86)") or get_env("ProgramFiles") if program_files: expected_path = os.path.join(program_files, "Microsoft Visual Studio", "Installer", "vswhere.exe") if os.path.isfile(expected_path): installer_path = expected_path vswhere_path = installer_path or which("vswhere") if not vswhere_path: raise ConanException( "Cannot locate vswhere in 'Program Files'/'Program Files (x86)' " "directory nor in PATH") arguments = list() arguments.append(vswhere_path) # Output json format arguments.append("-format") arguments.append("json") if all_: arguments.append("-all") if prerelease: arguments.append("-prerelease") if products: arguments.append("-products") arguments.extend(products) if requires: arguments.append("-requires") arguments.extend(requires) if len(version) != 0: arguments.append("-version") arguments.append(version) if latest: arguments.append("-latest") if legacy: arguments.append("-legacy") if len(property_) != 0: arguments.append("-property") arguments.append(property_) if nologo: arguments.append("-nologo") try: output = check_output_runner(arguments).strip() # Ignore the "description" field, that even decoded contains non valid charsets for json # (ignored ones) output = "\n".join([ line for line in output.splitlines() if not line.strip().startswith('"description"') ]) except (ValueError, subprocess.CalledProcessError, UnicodeDecodeError) as e: raise ConanException("vswhere error: %s" % str(e)) return json.loads(output)
def setUpClass(cls): if not which('cmake'): raise unittest.SkipTest("CMake expected in PATH") if not which('ndk-build'): raise unittest.SkipTest("ANDROID_NDK (ndk-build) expected in PATH")
import textwrap import unittest import pytest from conans.client.tools import which from conans.test.utils.tools import TestClient @pytest.mark.tool_premake @pytest.mark.skipif(which("premake5") is None, reason="Needs premake5") class PremakeGeneratorTest(unittest.TestCase): def setUp(self): self.client = TestClient() conanfile = textwrap.dedent(""" [generators] premake """) premake = textwrap.dedent(""" include("conanbuildinfo.premake.lua") workspace("example") conan_basic_setup() project("example") kind "ConsoleApp" language "C++" targetdir = "bin/%{cfg.buildcfg}" filter "configurations:Debug"
def bash_path(): if os.getenv("CONAN_BASH_PATH"): return os.getenv("CONAN_BASH_PATH") return which("bash")
def bash_path(): if os.getenv("CONAN_BASH_PATH"): return os.getenv("CONAN_BASH_PATH") return which("bash")
class MakeToolchainTest(unittest.TestCase): @pytest.mark.skipif(platform.system() != "Linux", reason="Requires linux") def test_toolchain_posix(self): client = TestClient(path_with_spaces=False) settings = { "arch": "x86_64", "build_type": "Release", "compiler": "gcc", "compiler.version": "9", "compiler.libcxx": "libstdc++11", } settings_str = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.gnu import MakeToolchain class App(ConanFile): settings = "os", "arch", "compiler", "build_type" def generate(self): tc = MakeToolchain(self) tc.variables["TEST_VAR"] = "TestVarValue" tc.preprocessor_definitions["TEST_DEFINITION"] = "TestPpdValue" tc.generate() def build(self): self.run("make -C ..") """) hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello", preprocessor=["TEST_DEFINITION"]) makefile = textwrap.dedent(""" include conan_toolchain.mak #------------------------------------------------- # Make variables for a sample App #------------------------------------------------- OUT_DIR ?= out SRC_DIR ?= src INCLUDE_DIR ?= include PROJECT_NAME = hello STATIC_LIB_FILENAME = lib$(PROJECT_NAME).a SRCS += $(wildcard $(SRC_DIR)/*.cpp) OBJS += $(patsubst $(SRC_DIR)/%.cpp,$(OUT_DIR)/%.o,$(SRCS)) CPPFLAGS += $(addprefix -I,$(INCLUDE_DIR)) #------------------------------------------------- # Append CONAN_ variables to standards #------------------------------------------------- CPPFLAGS += $(CONAN_TC_CPPFLAGS) #------------------------------------------------- # Print variables to be tested #------------------------------------------------- $(info >> CPPFLAGS: $(CPPFLAGS)) $(info >> TEST_VAR: $(TEST_VAR)) #------------------------------------------------- # Make Rules #------------------------------------------------- .PHONY : static static : $(OBJS) $(AR) $(ARFLAGS) $(OUT_DIR)/$(STATIC_LIB_FILENAME) $(OBJS) $(OUT_DIR)/%.o : $(SRC_DIR)/%.cpp $(OUT_DIR) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@ $(OUT_DIR): -mkdir $@ """) files_to_save = { "conanfile.py": conanfile, "Makefile": makefile, "src/hello.cpp": hello_cpp, "include/hello.h": hello_h } client.save(files_to_save, clean_first=True) client.run("install . hello/0.1@ %s" % settings_str) client.run_command("make static") client.run_command("nm -C out/libhello.a | grep 'hello()'") self.assertIn("hello()", client.out) @pytest.mark.skipif(platform.system() != "Windows", reason="Requires mingw32-make") @pytest.mark.skipif(which("mingw32-make") is None, reason="Needs mingw32-make") @pytest.mark.tool_mingw def test_toolchain_windows(self): client = TestClient(path_with_spaces=False) settings = { "arch": "x86_64", "build_type": "Release", "compiler": "gcc", "compiler.version": "9", "compiler.libcxx": "libstdc++11", } settings_str = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.gnu import MakeToolchain class App(ConanFile): settings = "os", "arch", "compiler", "build_type" def generate(self): tc = MakeToolchain(self) tc.variables["TEST_VAR"] = "TestVarValue" tc.preprocessor_definitions["TEST_DEFINITION"] = "TestPpdValue" tc.generate() def build(self): self.run("make -C ..") """) hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello", preprocessor=["TEST_DEFINITION"]) makefile = textwrap.dedent(""" include conan_toolchain.mak #------------------------------------------------- # Make variables for a sample App #------------------------------------------------- OUT_DIR ?= out SRC_DIR ?= src INCLUDE_DIR ?= include PROJECT_NAME = hello STATIC_LIB_FILENAME = lib$(PROJECT_NAME).a SRCS += $(wildcard $(SRC_DIR)/*.cpp) OBJS += $(patsubst $(SRC_DIR)/%.cpp,$(OUT_DIR)/%.o,$(SRCS)) CPPFLAGS += $(addprefix -I,$(INCLUDE_DIR)) #------------------------------------------------- # Append CONAN_ variables to standards #------------------------------------------------- CPPFLAGS += $(CONAN_TC_CPPFLAGS) #------------------------------------------------- # Print variables to be tested #------------------------------------------------- $(info >> CPPFLAGS: $(CPPFLAGS)) $(info >> TEST_VAR: $(TEST_VAR)) #------------------------------------------------- # Make Rules #------------------------------------------------- .PHONY : static static : $(OBJS) $(AR) $(ARFLAGS) $(OUT_DIR)/$(STATIC_LIB_FILENAME) $(OBJS) $(OUT_DIR)/%.o : $(SRC_DIR)/%.cpp $(OUT_DIR) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@ $(OUT_DIR): -mkdir $@ """) files_to_save = { "conanfile.py": conanfile, "Makefile": makefile, "src/hello.cpp": hello_cpp, "include/hello.h": hello_h } client.save(files_to_save, clean_first=True) client.run("install . hello/0.1@ %s" % settings_str) client.run_command("mingw32-make static") client.run_command("nm -C out/libhello.a | find \"hello()\"") self.assertIn("hello()", client.out)
def test_which_negative(self): tmp_dir = temp_folder() with tools.environment_append({'PATH': tmp_dir}): self.assertIsNone(tools.which('example.sh'))
class MakeToolchainTest(unittest.TestCase): @parameterized.expand([ ("exe", "Release"), ("exe", "Debug"), ("exe", "Release"), ("shared", "Release"), ("static", "Release"), ]) @unittest.skipUnless(platform.system() in ["Linux", "Macos"], "Requires make") def test_toolchain_posix(self, target, build_type): client = TestClient(path_with_spaces=False) settings = { "build_type": build_type, } options = { "fPIC": "True", } if target == "exe": conanfile_options = 'options = {"fPIC": [True, False]}' conanfile_default_options = 'default_options = {"fPIC": True}' else: conanfile_options = 'options = {"shared": [True, False], "fPIC": [True, False]}' conanfile_default_options = 'default_options = {"shared": False, "fPIC": True}' if target == "shared": options["shared"] = True settings_str = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) options_str = " ".join("-o %s=%s" % (k, v) for k, v in options.items()) if options else "" conanfile = textwrap.dedent(""" from conans import ConanFile, MakeToolchain class App(ConanFile): settings = "os", "arch", "compiler", "build_type" {options} {default_options} def toolchain(self): tc = MakeToolchain(self) tc.variables["TEST_VAR"] = "TestVarValue" tc.preprocessor_definitions["TEST_DEFINITION"] = "TestPpdValue" tc.write_toolchain_files() def build(self): self.run("make -C ..") """).format(options=conanfile_options, default_options=conanfile_default_options) hello_h = textwrap.dedent(""" #pragma once #define HELLO_MSG "{0}" #ifdef WIN32 #define APP_LIB_EXPORT __declspec(dllexport) #else #define APP_LIB_EXPORT #endif APP_LIB_EXPORT void hello(); """.format(build_type)) hello_cpp = textwrap.dedent(""" #include <iostream> #include "hello.h" void hello() { std::cout << "Hello World " << HELLO_MSG << "!" << std::endl; #ifdef NDEBUG std::cout << "App: Release!" << std::endl; #else std::cout << "App: Debug!" << std::endl; #endif std::cout << "TEST_DEFINITION: " << TEST_DEFINITION << "\\n"; } """) # only used for the executable test case main = textwrap.dedent(""" #include "hello.h" int main() { hello(); } """) makefile = textwrap.dedent(""" include conan_toolchain.mak #------------------------------------------------- # Make variables for a sample App #------------------------------------------------- OUT_DIR ?= out SRC_DIR ?= src INCLUDE_DIR ?= include PROJECT_NAME = hello EXE_FILENAME = $(PROJECT_NAME).bin STATIC_LIB_FILENAME = lib$(PROJECT_NAME).a SHARED_LIB_FILENAME = lib$(PROJECT_NAME).so SRCS += $(wildcard $(SRC_DIR)/*.cpp) OBJS += $(patsubst $(SRC_DIR)/%.cpp,$(OUT_DIR)/%.o,$(SRCS)) CPPFLAGS += $(addprefix -I,$(INCLUDE_DIR)) #------------------------------------------------- # Append CONAN_ variables to standards #------------------------------------------------- $(call CONAN_TC_SETUP) # The above function should append CONAN_TC flags to standard flags $(info >> CFLAGS: $(CFLAGS)) $(info >> CXXFLAGS: $(CXXFLAGS)) $(info >> CPPFLAGS: $(CPPFLAGS)) $(info >> LDFLAGS: $(LDFLAGS)) $(info >> LDLIBS: $(LDLIBS)) $(info >> TEST_VAR: $(TEST_VAR)) #------------------------------------------------- # Make Rules #------------------------------------------------- .PHONY : exe static shared exe : $(OBJS) $(CXX) $(OBJS) $(LDFLAGS) $(LDLIBS) -o $(OUT_DIR)/$(EXE_FILENAME) static : $(OBJS) $(AR) $(ARFLAGS) $(OUT_DIR)/$(STATIC_LIB_FILENAME) $(OBJS) shared : $(OBJS) $(CXX) -shared $(OBJS) $(LDFLAGS) $(LDLIBS) -o $(OUT_DIR)/$(SHARED_LIB_FILENAME) $(OUT_DIR)/%.o : $(SRC_DIR)/%.cpp $(OUT_DIR) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@ $(OUT_DIR): -mkdir $@ """) files_to_save = { "conanfile.py": conanfile, "Makefile": makefile, "src/hello.cpp": hello_cpp, "include/hello.h": hello_h } if target == "exe": files_to_save["src/main.cpp"] = main client.save(files_to_save, clean_first=True) client.run("install . hello/0.1@ %s %s" % (settings_str, options_str)) if target == "exe": client.run_command("make exe") client.run_command("./out/hello.bin") self.assertIn("Hello World {}!".format(build_type), client.out) elif target == "shared": client.run_command("make shared") client.run_command("nm -C out/libhello.so | grep 'hello()'") self.assertIn("hello()", client.out) elif target == "static": client.run_command("make static") client.run_command("nm -C out/libhello.a | grep 'hello()'") self.assertIn("hello()", client.out) @parameterized.expand([ ("exe", "Release"), ("exe", "Debug"), ("exe", "Release"), ("shared", "Release"), ("static", "Release"), ]) @unittest.skipUnless(platform.system() in ["Windows"], "Requires mingw32-make") @unittest.skipIf(which("mingw32-make") is None, "Needs mingw32-make") def test_toolchain_windows(self, target, build_type): client = TestClient(path_with_spaces=False) settings = { "arch": "x86_64", "build_type": build_type, "compiler": "gcc", "compiler.version": "9", "compiler.libcxx": "libstdc++11", } options = { "fPIC": "True", } if target == "exe": conanfile_options = 'options = {"fPIC": [True, False]}' conanfile_default_options = 'default_options = {"fPIC": True}' else: conanfile_options = 'options = {"shared": [True, False], "fPIC": [True, False]}' conanfile_default_options = 'default_options = {"shared": False, "fPIC": True}' if target == "shared": options["shared"] = True settings_str = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) options_str = " ".join("-o %s=%s" % (k, v) for k, v in options.items()) if options else "" conanfile = textwrap.dedent(""" from conans import ConanFile, MakeToolchain class App(ConanFile): settings = "os", "arch", "compiler", "build_type" {options} {default_options} def toolchain(self): tc = MakeToolchain(self) tc.variables["TEST_VAR"] = "TestVarValue" tc.preprocessor_definitions["TEST_DEFINITION"] = "TestPpdValue" tc.write_toolchain_files() def build(self): self.run("make -C ..") """).format(options=conanfile_options, default_options=conanfile_default_options) hello_h = textwrap.dedent(""" #pragma once #define HELLO_MSG "{0}" #ifdef WIN32 #define APP_LIB_EXPORT __declspec(dllexport) #else #define APP_LIB_EXPORT #endif APP_LIB_EXPORT void hello(); """.format(build_type)) hello_cpp = textwrap.dedent(""" #include <iostream> #include "hello.h" void hello() { std::cout << "Hello World " << HELLO_MSG << "!" << std::endl; #ifdef NDEBUG std::cout << "App: Release!" << std::endl; #else std::cout << "App: Debug!" << std::endl; #endif std::cout << "TEST_DEFINITION: " << TEST_DEFINITION << "\\n"; } """) # only used for the executable test case main = textwrap.dedent(""" #include "hello.h" int main() { hello(); } """) makefile = textwrap.dedent(""" include conan_toolchain.mak #------------------------------------------------- # Make variables for a sample App #------------------------------------------------- OUT_DIR ?= out SRC_DIR ?= src INCLUDE_DIR ?= include PROJECT_NAME = hello EXE_FILENAME = $(PROJECT_NAME).bin STATIC_LIB_FILENAME = lib$(PROJECT_NAME).a SHARED_LIB_FILENAME = lib$(PROJECT_NAME).so SRCS += $(wildcard $(SRC_DIR)/*.cpp) OBJS += $(patsubst $(SRC_DIR)/%.cpp,$(OUT_DIR)/%.o,$(SRCS)) CPPFLAGS += $(addprefix -I,$(INCLUDE_DIR)) #------------------------------------------------- # Append CONAN_ variables to standards #------------------------------------------------- $(call CONAN_TC_SETUP) # The above function should append CONAN_TC flags to standard flags $(info >> CFLAGS: $(CFLAGS)) $(info >> CXXFLAGS: $(CXXFLAGS)) $(info >> CPPFLAGS: $(CPPFLAGS)) $(info >> LDFLAGS: $(LDFLAGS)) $(info >> LDLIBS: $(LDLIBS)) $(info >> TEST_VAR: $(TEST_VAR)) #------------------------------------------------- # Make Rules #------------------------------------------------- .PHONY : exe static shared exe : $(OBJS) $(CXX) -v $(OBJS) $(LDFLAGS) $(LDLIBS) -o $(OUT_DIR)/$(EXE_FILENAME) static : $(OBJS) $(AR) $(ARFLAGS) $(OUT_DIR)/$(STATIC_LIB_FILENAME) $(OBJS) shared : $(OBJS) $(CXX) -shared $(OBJS) $(LDFLAGS) $(LDLIBS) -o $(OUT_DIR)/$(SHARED_LIB_FILENAME) $(OUT_DIR)/%.o : $(SRC_DIR)/%.cpp $(OUT_DIR) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@ $(OUT_DIR): -mkdir $@ """) files_to_save = { "conanfile.py": conanfile, "Makefile": makefile, "src/hello.cpp": hello_cpp, "include/hello.h": hello_h } if target == "exe": files_to_save["src/main.cpp"] = main client.save(files_to_save, clean_first=True) client.run("install . hello/0.1@ %s %s" % (settings_str, options_str)) mkdir(os.path.join(client.current_folder, "out")) if target == "exe": client.run_command("mingw32-make exe") client.run_command("out\\hello.bin") self.assertIn("Hello World {}!".format(build_type), client.out) elif target == "shared": client.run_command("mingw32-make shared") client.run_command("nm -C out/libhello.so | find \"hello()\"") self.assertIn("hello()", client.out) elif target == "static": client.run_command("mingw32-make static") client.run_command("nm -C out/libhello.a | find \"hello()\"") self.assertIn("hello()", client.out)
'msys2', 'cygwin', 'mingw32', 'mingw64', 'autotools', 'pkg_config', 'premake', 'meson', 'file', 'git', 'svn', 'compiler', 'conan', # Search the tool_conan test that needs conan itself ] if not which("cmake"): tools_available.remove("cmake") if not which("gcc"): tools_available.remove("gcc") if not which("clang"): tools_available.remove("clang") try: if not vswhere(): tools_available.remove("visual_studio") except ConanException: tools_available.remove("visual_studio") if not any( [x for x in ("gcc", "clang", "visual_studio") if x in tools_available]): tools_available.remove("compiler")