def test_complete(): client = TestClient() client.run("new myopenssl/1.0 -m=v2_cmake") client.run("create . -o myopenssl:shared=True") client.run("create . -o myopenssl:shared=True -s build_type=Debug") mycmake_main = gen_function_cpp(name="main", msg="mycmake", includes=["myopenssl"], calls=["myopenssl"]) mycmake_conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "myopenssl/1.0" default_options = {"myopenssl:shared": True} generators = "CMakeDeps", "CMakeToolchain", "VirtualEnv" exports = "*" apply_env = False def build(self): cmake = CMake(self) cmake.configure() cmake.build() def package(self): src = str(self.settings.build_type) if self.settings.os == "Windows" else "" self.copy("mycmake*", src=src, dst="bin") def package_info(self): self.cpp_info.bindirs = ["bin"] """) mycmake_cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.15) project(MyCmake CXX) find_package(myopenssl REQUIRED) add_executable(mycmake main.cpp) target_link_libraries(mycmake PRIVATE myopenssl::myopenssl) """) client.save( { "conanfile.py": mycmake_conanfile, "CMakeLists.txt": mycmake_cmakelists, "main.cpp": mycmake_main }, clean_first=True) client.run("create . mycmake/1.0@") mylib = textwrap.dedent(r""" from conans import ConanFile import os from conan.tools.cmake import CMake class Pkg(ConanFile): settings = "os", "compiler", "build_type", "arch" build_requires = "mycmake/1.0" requires = "myopenssl/1.0" default_options = {"myopenssl:shared": True} exports_sources = "CMakeLists.txt", "main.cpp" generators = "CMakeDeps", "CMakeToolchain", "VirtualEnv" def build(self): cmake = CMake(self) cmake.configure() cmake.build() self.run("mycmake") self.output.info("RUNNING MYAPP") if self.settings.os == "Windows": self.run(os.sep.join([".", str(self.settings.build_type), "myapp"]), env="conanrunenv") else: self.run(os.sep.join([".", "myapp"]), env="conanrunenv") """) cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.15) project(MyApp CXX) find_package(myopenssl) add_executable(myapp main.cpp) target_link_libraries(myapp myopenssl::myopenssl) """) client.save( { "conanfile.py": mylib, "main.cpp": gen_function_cpp(name="main", msg="myapp", includes=["myopenssl"], calls=["myopenssl"]), "CMakeLists.txt": cmakelists }, clean_first=True) client.run( "create . myapp/0.1@ -s:b build_type=Release -s:h build_type=Debug") first, last = str(client.out).split("RUNNING MYAPP") assert "mycmake: Release!" in first assert "myopenssl/1.0: Hello World Release!" in first assert "myapp: Debug!" in last assert "myopenssl/1.0: Hello World Debug!" in last
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=v2_cmake") # 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 = "AutotoolsGen" 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", make_program, cwd=client.current_folder) 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
class WinTest(unittest.TestCase): conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.microsoft import MSBuildToolchain, MSBuild, MSBuildDeps class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" options = {"shared": [True, False]} default_options = {"shared": False} def generate(self): tc = MSBuildToolchain(self) gen = MSBuildDeps(self) if self.options["hello"].shared and self.settings.build_type == "Release": tc.configuration = "ReleaseShared" gen.configuration = "ReleaseShared" tc.preprocessor_definitions["DEFINITIONS_BOTH"] = "True" if self.settings.build_type == "Debug": tc.preprocessor_definitions["DEFINITIONS_CONFIG"] = "Debug" else: tc.preprocessor_definitions["DEFINITIONS_CONFIG"] = "Release" tc.generate() gen.generate() def imports(self): if self.options["hello"].shared and self.settings.build_type == "Release": configuration = "ReleaseShared" else: configuration = self.settings.build_type self.copy("*.dll", src="bin", dst="%s/%s" % (self.settings.arch, configuration), keep_path=False) def build(self): msbuild = MSBuild(self) msbuild.build("MyProject.sln") """) app = gen_function_cpp( name="main", includes=["hello"], calls=["hello"], preprocessor=["DEFINITIONS_BOTH", "DEFINITIONS_CONFIG"]) @staticmethod def _run_app(client, arch, build_type, shared=None): if build_type == "Release" and shared: configuration = "ReleaseShared" else: configuration = build_type if arch == "x86": command_str = "%s\\MyApp.exe" % configuration else: command_str = "x64\\%s\\MyApp.exe" % configuration # To run the app without VS IDE, we need to copy the .exe to the DLLs folder new_cmd = "conan\\%s\\%s\\MyApp.exe" % (arch, configuration) with chdir(client.current_folder): mkdir(os.path.dirname(new_cmd)) shutil.copy(command_str, new_cmd) client.run_command(new_cmd) @pytest.mark.tool_cmake @parameterized.expand([("Visual Studio", "15", "MT"), ("msvc", "19.1", "static")]) def test_toolchain_win(self, compiler, version, runtime): client = TestClient(path_with_spaces=False) settings = { "compiler": compiler, "compiler.version": version, "compiler.cppstd": "17", "compiler.runtime": runtime, "build_type": "Release", "arch": "x86" } # Build the profile according to the settings provided settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) client.run("new hello/0.1 -m=v2_cmake") client.run("create . hello/0.1@ %s" % (settings, )) # Prepare the actual consumer package client.save( { "conanfile.py": self.conanfile, "MyProject.sln": sln_file, "MyApp/MyApp.vcxproj": myapp_vcxproj, "MyApp/MyApp.cpp": self.app }, clean_first=True) # Run the configure corresponding to this test case client.run("install . %s -if=conan" % (settings, )) self.assertIn( "conanfile.py: MSBuildToolchain created conantoolchain_release_win32.props", client.out) client.run("build . -if=conan") self.assertIn("Visual Studio 2017", client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x86'", client.out) self._run_app(client, "x86", "Release") self.assertIn("Hello World Release", client.out) check_exe_run(client.out, "main", "msvc", "19.1", "Release", "x86", "17", { "DEFINITIONS_BOTH": "True", "DEFINITIONS_CONFIG": "Release" }) check_vs_runtime("Release/MyApp.exe", client, "15", static=True, build_type="Release") @pytest.mark.tool_cmake def test_toolchain_win_debug(self): client = TestClient(path_with_spaces=False) settings = { "compiler": "Visual Studio", "compiler.version": "15", "compiler.toolset": "v140", "compiler.runtime": "MDd", "build_type": "Debug", "arch": "x86_64" } # Build the profile according to the settings provided settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) client.run("new hello/0.1 -s") client.run("create . hello/0.1@ %s" % (settings, )) # Prepare the actual consumer package client.save( { "conanfile.py": self.conanfile, "MyProject.sln": sln_file, "MyApp/MyApp.vcxproj": myapp_vcxproj, "MyApp/MyApp.cpp": self.app }, clean_first=True) # Run the configure corresponding to this test case client.run("install . %s -if=conan" % (settings, )) self.assertIn( "conanfile.py: MSBuildToolchain created conantoolchain_debug_x64.props", client.out) client.run("build . -if=conan") self.assertIn("Visual Studio 2017", client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) self._run_app(client, "x64", "Debug") self.assertIn("Hello World Debug", client.out) check_exe_run(client.out, "main", "msvc", "19.0", "Debug", "x86_64", "14", { "DEFINITIONS_BOTH": "True", "DEFINITIONS_CONFIG": "Debug" }) check_vs_runtime("x64/Debug/MyApp.exe", client, "15", static=False, build_type="Debug") @pytest.mark.tool_cmake def test_toolchain_win_multi(self): client = TestClient(path_with_spaces=False) settings = { "compiler": "Visual Studio", "compiler.version": "15", "compiler.cppstd": "17" } settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) client.run("new hello/0.1 -s") configs = [("Release", "x86", True), ("Release", "x86_64", True), ("Debug", "x86", False), ("Debug", "x86_64", False)] for build_type, arch, shared in configs: # Build the profile according to the settings provided runtime = "MT" if build_type == "Release" else "MTd" client.run( "create . hello/0.1@ %s -s build_type=%s -s arch=%s -s compiler.runtime=%s " " -o hello:shared=%s" % (settings, build_type, arch, runtime, shared)) # Prepare the actual consumer package client.save( { "conanfile.py": self.conanfile, "MyProject.sln": sln_file, "MyApp/MyApp.vcxproj": myapp_vcxproj, "MyApp/MyApp.cpp": self.app }, clean_first=True) # Run the configure corresponding to this test case for build_type, arch, shared in configs: runtime = "MT" if build_type == "Release" else "MTd" client.run( "install . %s -s build_type=%s -s arch=%s -s compiler.runtime=%s -if=conan" " -o hello:shared=%s" % (settings, build_type, arch, runtime, shared)) vs_path = vs_installation_path("15") vcvars_path = os.path.join(vs_path, "VC/Auxiliary/Build/vcvarsall.bat") for build_type, arch, shared in configs: platform_arch = "x86" if arch == "x86" else "x64" if build_type == "Release" and shared: configuration = "ReleaseShared" else: configuration = build_type # The "conan build" command is not good enough, cannot do the switch between configs cmd = ('set "VSCMD_START_DIR=%%CD%%" && ' '"%s" x64 && msbuild "MyProject.sln" /p:Configuration=%s ' '/p:Platform=%s ' % (vcvars_path, configuration, platform_arch)) client.run_command(cmd) self.assertIn("Visual Studio 2017", client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) self._run_app(client, arch, build_type, shared) check_exe_run(client.out, "main", "msvc", "19.1", build_type, arch, "17", { "DEFINITIONS_BOTH": "True", "DEFINITIONS_CONFIG": build_type }) new_cmd = "conan\\%s\\%s\\MyApp.exe" % (arch, configuration) vcvars = vcvars_command(version="15", architecture="amd64") cmd = ('%s && dumpbin /dependents "%s"' % (vcvars, new_cmd)) client.run_command(cmd) if shared: self.assertIn("hello.dll", client.out) else: self.assertNotIn("hello.dll", client.out) self.assertIn("KERNEL32.dll", client.out)
class CustomSettingsTest(unittest.TestCase): conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMakeDeps class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" def generate(self): cmake = CMakeDeps(self) #cmake.configurations.append("MyRelease") # NOT NECESSARY!!! cmake.generate() """) app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) cmakelist = textwrap.dedent(""" set(CMAKE_CONFIGURATION_TYPES Debug Release MyRelease CACHE STRING "Available build-types: Debug, Release and MyRelease") cmake_minimum_required(VERSION 2.8) project(App C CXX) set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR} ${CMAKE_PREFIX_PATH}) set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR} ${CMAKE_MODULE_PATH}) set(CMAKE_CXX_FLAGS_MYRELEASE ${CMAKE_CXX_FLAGS_RELEASE}) set(CMAKE_C_FLAGS_MYRELEASE ${CMAKE_C_FLAGS_RELEASE}) set(CMAKE_EXE_LINKER_FLAGS_MYRELEASE ${CMAKE_EXE_LINKER_FLAGS_RELEASE}) find_package(hello REQUIRED) add_executable(app app.cpp) target_link_libraries(app PRIVATE hello::hello) """) def setUp(self): self.client = TestClient(path_with_spaces=False) settings = load(self.client.cache.settings_path) settings = settings.replace("Release", "MyRelease") save(self.client.cache.settings_path, settings) self.client.run("new hello/0.1 -s") cmake = self.client.load("src/CMakeLists.txt") cmake = cmake.replace( "cmake_minimum_required", """ set(CMAKE_CONFIGURATION_TYPES Debug MyRelease Release CACHE STRING "Types") cmake_minimum_required""") cmake = cmake.replace( "conan_basic_setup()", """ conan_basic_setup() set(CMAKE_CXX_FLAGS_MYRELEASE ${CMAKE_CXX_FLAGS_RELEASE}) set(CMAKE_C_FLAGS_MYRELEASE ${CMAKE_C_FLAGS_RELEASE}) set(CMAKE_EXE_LINKER_FLAGS_MYRELEASE ${CMAKE_EXE_LINKER_FLAGS_RELEASE}) """) self.client.save({"src/CMakeLists.txt": cmake}) self.client.run( "create . hello/0.1@ -s compiler.version=15 -s build_type=MyRelease" ) # Prepare the actual consumer package self.client.save({ "conanfile.py": self.conanfile, "CMakeLists.txt": self.cmakelist, "app.cpp": self.app }) def test_generator_multi(self): settings = { "compiler": "Visual Studio", "compiler.version": "15", "arch": "x86_64", "build_type": "MyRelease", } settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) # Run the configure corresponding to this test case build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") with self.client.chdir(build_directory): self.client.run("install .. %s" % settings) self.assertTrue( os.path.isfile( os.path.join(self.client.current_folder, "helloTarget-myrelease.cmake"))) self.client.run_command('cmake .. -G "Visual Studio 15 Win64"') self.client.run_command('cmake --build . --config MyRelease') self.client.run_command(r"MyRelease\\app.exe") self.assertIn("hello/0.1: Hello World Release!", self.client.out) self.assertIn("main: Release!", self.client.out)
class Base(unittest.TestCase): conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake, CMakeToolchain class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" generators = "cmake_find_package_multi" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} def generate(self): tc = CMakeToolchain(self) tc.variables["MYVAR"] = "MYVAR_VALUE" tc.variables["MYVAR2"] = "MYVAR_VALUE2" tc.variables.debug["MYVAR_CONFIG"] = "MYVAR_DEBUG" tc.variables.release["MYVAR_CONFIG"] = "MYVAR_RELEASE" tc.variables.debug["MYVAR2_CONFIG"] = "MYVAR2_DEBUG" tc.variables.release["MYVAR2_CONFIG"] = "MYVAR2_RELEASE" tc.preprocessor_definitions["MYDEFINE"] = "MYDEF_VALUE" tc.preprocessor_definitions["MYDEFINEINT"] = 42 tc.preprocessor_definitions.debug["MYDEFINE_CONFIG"] = "MYDEF_DEBUG" tc.preprocessor_definitions.release["MYDEFINE_CONFIG"] = "MYDEF_RELEASE" tc.preprocessor_definitions.debug["MYDEFINEINT_CONFIG"] = 421 tc.preprocessor_definitions.release["MYDEFINEINT_CONFIG"] = 422 tc.generate() def build(self): cmake = CMake(self) cmake.configure() cmake.build() """) lib_h = gen_function_h(name="app") lib_cpp = gen_function_cpp(name="app", msg="App", includes=["hello"], calls=["hello"], preprocessor=["MYVAR", "MYVAR_CONFIG", "MYDEFINE", "MYDEFINE_CONFIG", "MYDEFINEINT", "MYDEFINEINT_CONFIG"]) main = gen_function_cpp(name="main", includes=["app"], calls=["app"]) cmakelist = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(App C CXX) if(NOT CMAKE_TOOLCHAIN_FILE) message(FATAL ">> Not using toolchain") endif() message(">> CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}") message(">> CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message(">> CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") message(">> CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") message(">> CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") message(">> CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") message(">> CMAKE_C_FLAGS_DEBUG: ${CMAKE_C_FLAGS_DEBUG}") message(">> CMAKE_C_FLAGS_RELEASE: ${CMAKE_C_FLAGS_RELEASE}") message(">> CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}") message(">> CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") message(">> CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") message(">> CMAKE_CXX_EXTENSIONS: ${CMAKE_CXX_EXTENSIONS}") message(">> CMAKE_POSITION_INDEPENDENT_CODE: ${CMAKE_POSITION_INDEPENDENT_CODE}") message(">> CMAKE_SKIP_RPATH: ${CMAKE_SKIP_RPATH}") message(">> CMAKE_INSTALL_NAME_DIR: ${CMAKE_INSTALL_NAME_DIR}") message(">> CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}") message(">> CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}") message(">> BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") get_directory_property(_COMPILE_DEFS DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS) message(">> COMPILE_DEFINITIONS: ${_COMPILE_DEFS}") find_package(hello REQUIRED) add_library(app_lib app_lib.cpp) target_link_libraries(app_lib PRIVATE hello::hello) target_compile_definitions(app_lib PRIVATE MYVAR="${MYVAR}") target_compile_definitions(app_lib PRIVATE MYVAR_CONFIG="${MYVAR_CONFIG}") add_executable(app app.cpp) target_link_libraries(app PRIVATE app_lib) """) def setUp(self): self.client = TestClient(path_with_spaces=True) conanfile = textwrap.dedent(""" from conans import ConanFile from conans.tools import save import os class Pkg(ConanFile): settings = "build_type" def package(self): save(os.path.join(self.package_folder, "include/hello.h"), '''#include <iostream> void hello(){std::cout<< "Hello: %s" <<std::endl;}''' % self.settings.build_type) """) self.client.save({"conanfile.py": conanfile}) self.client.run("create . hello/0.1@ -s build_type=Debug") self.client.run("create . hello/0.1@ -s build_type=Release") # Prepare the actual consumer package self.client.save({"conanfile.py": self.conanfile, "CMakeLists.txt": self.cmakelist, "app.cpp": self.main, "app_lib.cpp": self.lib_cpp, "app.h": self.lib_h}) def _run_build(self, settings=None, options=None): # Build the profile according to the settings provided settings = settings or {} settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) options = " ".join("-o %s=%s" % (k, v) for k, v in options.items()) if options else "" # Run the configure corresponding to this test case build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") with self.client.chdir(build_directory): self.client.run("install .. %s %s" % (settings, options)) install_out = self.client.out self.client.run("build ..") return install_out def _modify_code(self): lib_cpp = gen_function_cpp(name="app", msg="AppImproved", includes=["hello"], calls=["hello"], preprocessor=["MYVAR", "MYVAR_CONFIG", "MYDEFINE", "MYDEFINE_CONFIG", "MYDEFINEINT", "MYDEFINEINT_CONFIG"]) self.client.save({"app_lib.cpp": lib_cpp}) content = self.client.load("CMakeLists.txt") content = content.replace(">>", "++>>") self.client.save({"CMakeLists.txt": content}) def _incremental_build(self, build_type=None): build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") with self.client.chdir(build_directory): config = "--config %s" % build_type if build_type else "" self.client.run_command("cmake --build . %s" % config) def _run_app(self, build_type, bin_folder=False, msg="App", dyld_path=None): if dyld_path: build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") command_str = 'DYLD_LIBRARY_PATH="%s" build/app' % build_directory else: command_str = "build/%s/app.exe" % build_type if bin_folder else "build/app" if platform.system() == "Windows": command_str = command_str.replace("/", "\\") self.client.run_command(command_str) self.assertIn("Hello: %s" % build_type, self.client.out) self.assertIn("%s: %s!" % (msg, build_type), self.client.out) self.assertIn("MYVAR: MYVAR_VALUE", self.client.out) self.assertIn("MYVAR_CONFIG: MYVAR_%s" % build_type.upper(), self.client.out) self.assertIn("MYDEFINE: MYDEF_VALUE", self.client.out) self.assertIn("MYDEFINE_CONFIG: MYDEF_%s" % build_type.upper(), self.client.out) self.assertIn("MYDEFINEINT: 42", self.client.out) self.assertIn("MYDEFINEINT_CONFIG: {}".format(421 if build_type == "Debug" else 422), self.client.out)
def create_chat(client, components, package_info, cmake_find, test_cmake_find): conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake class Chat(ConanFile): name = "chat" version = "0.0.1" settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" exports_sources = "src/*" requires = "greetings/0.0.1" default_options = {{"greetings:components": "{}"}} def build(self): cmake = CMake(self) cmake.configure(build_script_folder="src") cmake.build() def package(self): self.copy("*.h", dst="include", src="src") self.copy("*.lib", dst="lib", keep_path=False) self.copy("*.a", dst="lib", keep_path=False) def package_info(self): {} """).format(components, "\n ".join(package_info.splitlines())) sayhello_h = gen_function_h(name="sayhello") sayhello_cpp = gen_function_cpp(name="sayhello", includes=["hello"], calls=["hello"]) sayhellobye_h = gen_function_h(name="sayhellobye") sayhellobye_cpp = gen_function_cpp(name="sayhellobye", includes=["sayhello", "bye"], calls=["sayhello", "bye"]) cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.0) project(world CXX) %s """ % cmake_find) test_conanfile = textwrap.dedent(""" import os from conans import ConanFile from conan.tools.cmake import CMake class WorldTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" requires = "chat/0.0.1" def build(self): cmake = CMake(self) cmake.configure() cmake.build() def test(self): path = "{}".format(self.settings.build_type) if self.settings.os == "Windows" else "." self.run("{}{}example".format(path, os.sep)) self.run("{}{}example2".format(path, os.sep)) """) test_example_cpp = gen_function_cpp(name="main", includes=["sayhellobye"], calls=["sayhellobye"]) test_cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.0) project(PackageTest CXX) %s """ % test_cmake_find) client.save( { "conanfile.py": conanfile, "src/CMakeLists.txt": cmakelists, "src/sayhello.h": sayhello_h, "src/sayhello.cpp": sayhello_cpp, "src/sayhellobye.h": sayhellobye_h, "src/sayhellobye.cpp": sayhellobye_cpp, "test_package/conanfile.py": test_conanfile, "test_package/CMakeLists.txt": test_cmakelists, "test_package/example.cpp": test_example_cpp }, clean_first=True) client.run("create . -s build_type=Release") assert "sayhellobye: Release!" in client.out assert "sayhello: Release!" in client.out assert "hello: Release!" in client.out assert "bye: Release!" in client.out client.run("create . -s build_type=Debug") assert "sayhellobye: Debug!" in client.out assert "sayhello: Debug!" in client.out assert "hello: Debug!" in client.out assert "bye: Debug!" in client.out
def test_same_name_global_target_collision(self): # https://github.com/conan-io/conan/issues/7889 conanfile_tpl = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake class Conan(ConanFile): name = "{name}" version = "1.0" settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" exports_sources = "src/*" def build(self): cmake = CMake(self) cmake.configure(build_script_folder="src") cmake.build() def package(self): self.copy("*.h", dst="include", src="src") self.copy("*.lib", dst="lib", keep_path=False) self.copy("*.a", dst="lib", keep_path=False) def package_info(self): self.cpp_info.set_property("cmake_target_name", "nonstd::nonstd" ) self.cpp_info.set_property("cmake_file_name", "{name}") self.cpp_info.components["1"].set_property("cmake_target_name", "nonstd::{name}") self.cpp_info.components["1"].libs = ["{name}"] """) basic_cmake = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) project(middle CXX) cmake_minimum_required(VERSION 3.1) add_library({name} {name}.cpp) """) client = TestClient() for name in ["expected", "variant"]: client.run("new {name}/1.0 -s".format(name=name)) client.save({ "conanfile.py": conanfile_tpl.format(name=name), "src/CMakeLists.txt": basic_cmake.format(name=name) }) client.run("create . {name}/1.0@".format(name=name)) middle_cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) project(middle CXX) cmake_minimum_required(VERSION 3.1) find_package(expected) find_package(variant) add_library(middle middle.cpp) target_link_libraries(middle nonstd::nonstd) """) middle_h = gen_function_h(name="middle") middle_cpp = gen_function_cpp( name="middle", includes=["middle", "expected", "variant"], calls=["expected", "variant"]) middle_conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake class Conan(ConanFile): name = "middle" version = "1.0" settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" exports_sources = "src/*" requires = "expected/1.0", "variant/1.0" def build(self): cmake = CMake(self) cmake.configure(build_script_folder="src") cmake.build() def package(self): self.copy("*.h", dst="include", src="src") self.copy("*.lib", dst="lib", keep_path=False) self.copy("*.a", dst="lib", keep_path=False) def package_info(self): self.cpp_info.libs = ["middle"] """) client.save( { "conanfile.py": middle_conanfile, "src/CMakeLists.txt": middle_cmakelists, "src/middle.h": middle_h, "src/middle.cpp": middle_cpp }, clean_first=True) client.run("create . middle/1.0@") conanfile = textwrap.dedent(""" import os from conans import ConanFile from conan.tools.cmake import CMake, cmake_layout class Conan(ConanFile): name = "consumer" version = "1.0" generators = "CMakeDeps", "CMakeToolchain" settings = "os", "compiler", "build_type", "arch" exports_sources = "src/*" requires = "middle/1.0" def layout(self): cmake_layout(self) def build(self): cmake = CMake(self) cmake.configure(build_script_folder="src") cmake.build() cmd = os.path.join(self.cpp.build.bindirs[0], "main") self.run(cmd, env="conanrun") """) cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) project(consumer CXX) cmake_minimum_required(VERSION 3.1) find_package(middle) get_target_property(tmp middle::middle INTERFACE_LINK_LIBRARIES) message("Middle link libraries: ${tmp}") add_executable(main main.cpp) target_link_libraries(main middle::middle) """) main_cpp = gen_function_cpp(name="main", includes=["middle"], calls=["middle"]) client.save( { "conanfile.py": conanfile, "src/CMakeLists.txt": cmakelists, "src/main.cpp": main_cpp }, clean_first=True) client.run("create . consumer/1.0@") assert 'main: Release!' in client.out assert 'middle: Release!' in client.out assert 'expected/1.0: Hello World Release!' in client.out assert 'variant/1.0: Hello World Release!' in client.out
def test_file_api(): """ simple library providing 3 targets: - decoder - encoder - transcoder (requires decoder and encoder) generates the following targets: - triunfo::decoder - triunfo::encoder - triunfo::transcoder (depends on triunfo::decoder and triunfo::encoder) consumer uses find_package(triunfo COMPONENTS <component>) """ client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake, CMakeFileAPI from conan.tools.files import CppPackage class Triunfo(ConanFile): name = "triunfo" version = "1.0" settings = "os", "compiler", "arch", "build_type" exports_sources = "*CMakeLists.txt", "*.cpp", "*.h" generators = "CMakeToolchain" def build(self): file_api = CMakeFileAPI(self) file_api.query(CMakeFileAPI.CODEMODELV2) cmake = CMake(self) cmake.configure() reply = file_api.reply(CMakeFileAPI.CODEMODELV2) package = reply.to_conan_package() package.save() cmake.build() def package(self): cmake = CMake(self) cmake.install() self.copy(CppPackage.DEFAULT_FILENAME) def package_info(self): cpp_package = CppPackage.load(CppPackage.DEFAULT_FILENAME) cpp_package.package_info(self) """) decoder_cpp = gen_function_cpp(name="decoder", includes=["decoder"]) encoder_cpp = gen_function_cpp(name="encoder", includes=["encoder"]) transcoder_cpp = gen_function_cpp( name="transcoder", calls=["decoder", "encoder"], includes=["transcoder", "../decoder/decoder", "../encoder/encoder"]) decoder_h = gen_function_h(name="decoder") encoder_h = gen_function_h(name="encoder") transcoder_h = gen_function_h(name="transcoder") decoder_cmake = gen_cmakelists(libname="decoder", libsources=["decoder.cpp"], install=True, public_header="decoder.h") encoder_cmake = gen_cmakelists(libname="encoder", libsources=["encoder.cpp"], install=True, public_header="encoder.h") transcoder_cmake = gen_cmakelists(libname="transcoder", libsources=["transcoder.cpp"], install=True, public_header="transcoder.h", deps=["decoder", "encoder"]) common_cmake = textwrap.dedent(""" cmake_minimum_required(VERSION 2.8) project(triunfo) add_subdirectory(decoder) add_subdirectory(encoder) add_subdirectory(transcoder) """) client.save({ "conanfile.py": conanfile, os.path.join("decoder", "decoder.cpp"): decoder_cpp, os.path.join("encoder", "encoder.cpp"): encoder_cpp, os.path.join("transcoder", "transcoder.cpp"): transcoder_cpp, os.path.join("decoder", "decoder.h"): decoder_h, os.path.join("encoder", "encoder.h"): encoder_h, os.path.join("transcoder", "transcoder.h"): transcoder_h, os.path.join("decoder", "CMakeLists.txt"): decoder_cmake, os.path.join("encoder", "CMakeLists.txt"): encoder_cmake, os.path.join("transcoder", "CMakeLists.txt"): transcoder_cmake, "CMakeLists.txt": common_cmake, }) client.run("create .") conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake, CMakeFileAPI from conan.tools.files import CppPackage class Elogio(ConanFile): name = "elogio" version = "1.0" requires = "triunfo/1.0" settings = "os", "compiler", "arch", "build_type" exports_sources = "*CMakeLists.txt", "*.cpp", "*.h" generators = "CMakeDeps", "CMakeToolchain" def build(self): file_api = CMakeFileAPI(self) file_api.query(CMakeFileAPI.CODEMODELV2) cmake = CMake(self) cmake.configure() reply = file_api.reply(CMakeFileAPI.CODEMODELV2) package = reply.to_conan_package() package.save() cmake.build() """) use_decoder_cpp = gen_function_cpp(name="main", includes=["decoder"], calls=["decoder"]) use_encoder_cpp = gen_function_cpp(name="main", includes=["encoder"], calls=["encoder"]) use_transcoder_cpp = gen_function_cpp(name="main", includes=["transcoder"], calls=["transcoder"]) use_decoder_cmake = gen_cmakelists(appname="use_decoder", appsources=["use_decoder.cpp"], find_package={"triunfo": "decoder"}) use_encoder_cmake = gen_cmakelists(appname="use_encoder", appsources=["use_encoder.cpp"], find_package={"triunfo": "encoder"}) use_transcoder_cmake = gen_cmakelists( appname="use_transcoder", appsources=["use_transcoder.cpp"], find_package={"triunfo": "transcoder"}) common_cmake = textwrap.dedent(""" cmake_minimum_required(VERSION 2.8) project(elogio) add_subdirectory(use_decoder) add_subdirectory(use_encoder) add_subdirectory(use_transcoder) """) client.save( { "conanfile.py": conanfile, os.path.join("use_decoder", "use_decoder.cpp"): use_decoder_cpp, os.path.join("use_encoder", "use_encoder.cpp"): use_encoder_cpp, os.path.join("use_transcoder", "use_transcoder.cpp"): use_transcoder_cpp, os.path.join("use_decoder", "CMakeLists.txt"): use_decoder_cmake, os.path.join("use_encoder", "CMakeLists.txt"): use_encoder_cmake, os.path.join("use_transcoder", "CMakeLists.txt"): use_transcoder_cmake, "CMakeLists.txt": common_cmake, }, clean_first=True) client.run("install .") client.run("build .")
class WinTest(unittest.TestCase): conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.microsoft import MSBuildToolchain, MSBuild, MSBuildDeps class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" options = {"shared": [True, False]} default_options = {"shared": False} def layout(self): self.folders.generators = "conan" self.folders.build = "." def generate(self): tc = MSBuildToolchain(self) gen = MSBuildDeps(self) if self.options["hello"].shared and self.settings.build_type == "Release": tc.configuration = "ReleaseShared" gen.configuration = "ReleaseShared" tc.preprocessor_definitions["DEFINITIONS_BOTH"] = '"True"' tc.preprocessor_definitions["DEFINITIONS_BOTH2"] = 'DEFINITIONS_BOTH' tc.preprocessor_definitions["DEFINITIONS_BOTH_INT"] = 123 if self.settings.build_type == "Debug": tc.preprocessor_definitions["DEFINITIONS_CONFIG"] = '"Debug"' tc.preprocessor_definitions["DEFINITIONS_CONFIG_INT"] = 234 else: tc.preprocessor_definitions["DEFINITIONS_CONFIG"] = '"Release"' tc.preprocessor_definitions["DEFINITIONS_CONFIG_INT"] = 456 tc.preprocessor_definitions["DEFINITIONS_CONFIG2"] = 'DEFINITIONS_CONFIG' tc.generate() gen.generate() def imports(self): if self.options["hello"].shared and self.settings.build_type == "Release": configuration = "ReleaseShared" if self.settings.arch == "x86_64": dst = "x64/%s" % configuration else: dst = configuration else: configuration = self.settings.build_type dst = "%s/%s" % (self.settings.arch, configuration) self.copy("*.dll", src="bin", dst=dst, keep_path=False) def build(self): msbuild = MSBuild(self) msbuild.build("MyProject.sln") """) app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"], preprocessor=["DEFINITIONS_BOTH", "DEFINITIONS_BOTH2", "DEFINITIONS_BOTH_INT", "DEFINITIONS_CONFIG", "DEFINITIONS_CONFIG2", "DEFINITIONS_CONFIG_INT"]) @staticmethod def _run_app(client, arch, build_type, shared=None): if build_type == "Release" and shared: configuration = "ReleaseShared" else: configuration = build_type if arch == "x86": command_str = "%s\\MyApp.exe" % configuration else: command_str = "x64\\%s\\MyApp.exe" % configuration client.run_command(command_str) @parameterized.expand([("Visual Studio", "15", "MT", "17"), ("msvc", "191", "static", "17"), ("msvc", "190", "static", "14")] ) @pytest.mark.tool_cmake def test_toolchain_win_vs2017(self, compiler, version, runtime, cppstd): if self.vs_version != "15": pytest.skip("test for Visual Studio 2017") else: self.check_toolchain_win(compiler, version, runtime, cppstd) @parameterized.expand([("Visual Studio", "17", "MT", "17"), ("msvc", "193", "static", "17")] ) def test_toolchain_win_vs2022(self, compiler, version, runtime, cppstd): if self.vs_version != "17": pytest.skip("test for Visual Studio 2022") else: self.check_toolchain_win(compiler, version, runtime, cppstd) def check_toolchain_win(self, compiler, version, runtime, cppstd): client = TestClient(path_with_spaces=False) settings = [("compiler", compiler), ("compiler.version", version), ("compiler.cppstd", cppstd), ("compiler.runtime", runtime), ("build_type", "Release"), ("arch", "x86")] profile = textwrap.dedent(""" [settings] os=Windows [conf] tools.microsoft.msbuild:vs_version={vs_version} """.format(vs_version=self.vs_version)) client.save({"myprofile": profile}) # Build the profile according to the settings provided settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings if v) client.run("new hello/0.1 -m=cmake_lib") client.run("create . hello/0.1@ %s" % (settings, )) # Prepare the actual consumer package client.save({"conanfile.py": self.conanfile, "MyProject.sln": sln_file, "MyApp/MyApp.vcxproj": myapp_vcxproj, "MyApp/MyApp.cpp": self.app, "myprofile": profile}, clean_first=True) # Run the configure corresponding to this test case client.run("install . %s -if=conan -pr=myprofile" % (settings, )) self.assertIn("conanfile.py: MSBuildToolchain created conantoolchain_release_win32.props", client.out) client.run("build . -if=conan") self.assertIn("Visual Studio {ide_year}".format(ide_year=self.ide_year), client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x86'", client.out) self._run_app(client, "x86", "Release") self.assertIn("Hello World Release", client.out) compiler_version = version if compiler == "msvc" else self.msvc_version check_exe_run(client.out, "main", "msvc", compiler_version, "Release", "x86", cppstd, {"DEFINITIONS_BOTH": 'True', "DEFINITIONS_BOTH2": "True", "DEFINITIONS_BOTH_INT": "123", "DEFINITIONS_CONFIG": 'Release', "DEFINITIONS_CONFIG2": 'Release', "DEFINITIONS_CONFIG_INT": "456"}) static_runtime = True if runtime == "static" or "MT" in runtime else False check_vs_runtime("Release/MyApp.exe", client, self.vs_version, build_type="Release", static_runtime=static_runtime) @pytest.mark.tool_cmake def test_toolchain_win_debug(self): client = TestClient(path_with_spaces=False) settings = [("compiler", "Visual Studio"), ("compiler.version", self.vs_version), ("compiler.toolset", "v140"), ("compiler.runtime", "MDd"), ("build_type", "Debug"), ("arch", "x86_64")] # Build the profile according to the settings provided settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings if v) client.run("new hello/0.1 -s") client.run("create . hello/0.1@ %s" % (settings,)) # Prepare the actual consumer package client.save({"conanfile.py": self.conanfile, "MyProject.sln": sln_file, "MyApp/MyApp.vcxproj": myapp_vcxproj, "MyApp/MyApp.cpp": self.app}, clean_first=True) # Run the configure corresponding to this test case client.run("install . %s -if=conan" % (settings, )) self.assertIn("conanfile.py: MSBuildToolchain created conantoolchain_debug_x64.props", client.out) client.run("build . -if=conan") self.assertIn("Visual Studio {ide_year}".format(ide_year=self.ide_year), client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) self._run_app(client, "x64", "Debug") self.assertIn("Hello World Debug", client.out) check_exe_run(client.out, "main", "msvc", "190", "Debug", "x86_64", "14", {"DEFINITIONS_BOTH": 'True', "DEFINITIONS_BOTH2": "True", "DEFINITIONS_BOTH_INT": "123", "DEFINITIONS_CONFIG": 'Debug', "DEFINITIONS_CONFIG2": 'Debug', "DEFINITIONS_CONFIG_INT": "234"}) check_vs_runtime("x64/Debug/MyApp.exe", client, self.vs_version, build_type="Debug") @pytest.mark.tool_cmake def test_toolchain_win_multi(self): client = TestClient(path_with_spaces=False) settings = [("compiler", "Visual Studio"), ("compiler.version", self.vs_version), ("compiler.cppstd", "17")] settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings if v) client.run("new hello/0.1 -m=cmake_lib") configs = [("Release", "x86", True), ("Release", "x86_64", True), ("Debug", "x86", False), ("Debug", "x86_64", False)] for build_type, arch, shared in configs: # Build the profile according to the settings provided # TODO: It is a bit ugly to remove manually build_test_folder = os.path.join(client.current_folder, "test_package", "build") rmdir(build_test_folder) runtime = "MT" if build_type == "Release" else "MTd" client.run("create . hello/0.1@ %s -s build_type=%s -s arch=%s -s compiler.runtime=%s " " -o hello:shared=%s" % (settings, build_type, arch, runtime, shared)) # Prepare the actual consumer package client.save({"conanfile.py": self.conanfile, "MyProject.sln": sln_file, "MyApp/MyApp.vcxproj": myapp_vcxproj, "MyApp/MyApp.cpp": self.app}, clean_first=True) # Run the configure corresponding to this test case for build_type, arch, shared in configs: runtime = "MT" if build_type == "Release" else "MTd" client.run("install . %s -s build_type=%s -s arch=%s -s compiler.runtime=%s -if=conan" " -o hello:shared=%s" % (settings, build_type, arch, runtime, shared)) vs_path = vs_installation_path(self.vs_version) vcvars_path = os.path.join(vs_path, "VC/Auxiliary/Build/vcvarsall.bat") for build_type, arch, shared in configs: platform_arch = "x86" if arch == "x86" else "x64" if build_type == "Release" and shared: configuration = "ReleaseShared" else: configuration = build_type # The "conan build" command is not good enough, cannot do the switch between configs cmd = ('set "VSCMD_START_DIR=%%CD%%" && ' '"%s" x64 && msbuild "MyProject.sln" /p:Configuration=%s ' '/p:Platform=%s ' % (vcvars_path, configuration, platform_arch)) client.run_command(cmd) self.assertIn("Visual Studio {ide_year}".format(ide_year=self.ide_year), client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) self._run_app(client, arch, build_type, shared) check_exe_run(client.out, "main", "msvc", self.msvc_version, build_type, arch, "17", {"DEFINITIONS_BOTH": "True", "DEFINITIONS_CONFIG": build_type}) if arch == "x86": command_str = "%s\\MyApp.exe" % configuration else: command_str = "x64\\%s\\MyApp.exe" % configuration vcvars = vcvars_command(version=self.vs_version, architecture="amd64") cmd = ('%s && dumpbin /dependents "%s"' % (vcvars, command_str)) client.run_command(cmd) if shared: self.assertIn("hello.dll", client.out) else: self.assertNotIn("hello.dll", client.out) self.assertIn("KERNEL32.dll", client.out)
def test_autotools_real_install_dirs(self): body = gen_function_cpp(name="hello", msg="Hola Mundo!") header = gen_function_h(name="hello") main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) conanfile = """ from conans import ConanFile, AutoToolsBuildEnvironment, tools class TestConan(ConanFile): name = "test" version = "1.0" settings = "os", "compiler", "arch", "build_type" exports_sources = "*" def build(self): makefile_am = ''' bin_PROGRAMS = main lib_LIBRARIES = libhello.a libhello_a_SOURCES = hello.cpp main_SOURCES = main.cpp main_LDADD = libhello.a ''' configure_ac = ''' AC_INIT([main], [1.0], [[email protected]]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CXX AC_PROG_RANLIB AM_PROG_AR AC_CONFIG_FILES([Makefile]) AC_OUTPUT ''' tools.save("Makefile.am", makefile_am) tools.save("configure.ac", configure_ac) self.run("aclocal") self.run("autoconf") self.run("automake --add-missing --foreign") autotools = AutoToolsBuildEnvironment(self) autotools.configure() autotools.make() autotools.install() def package_id(self): # easier to have same package_id for the test self.info.header_only() """ client = TestClient() client.save({"conanfile.py": conanfile, "main.cpp": main, "hello.h": header, "hello.cpp": body}) client.run("create . danimtb/testing") pref = PackageReference.loads("test/1.0@danimtb/testing:%s" % NO_SETTINGS_PACKAGE_ID) pkg_path = client.cache.package_layout(pref.ref).package(pref) [self.assertIn(folder, os.listdir(pkg_path)) for folder in ["lib", "bin"]] new_conanfile = conanfile.replace("autotools.configure()", "autotools.configure(args=['--bindir=${prefix}/superbindir', '--libdir=${prefix}/superlibdir'])") client.save({"conanfile.py": new_conanfile}) client.run("create . danimtb/testing") [self.assertIn(folder, os.listdir(pkg_path)) for folder in ["superlibdir", "superbindir"]] [self.assertNotIn(folder, os.listdir(pkg_path)) for folder in ["lib", "bin"]]
def pkg_cmake(name, version, requires=None, exe=False): refs = [ConanFileReference.loads(r) for r in requires or []] pkg_name = name name = name.replace(".", "_") conanfile = textwrap.dedent("""\ import os from conans import ConanFile from conan.tools.cmake import CMake, cmake_layout class Pkg(ConanFile): name = "{pkg_name}" version = "{version}" exports_sources = "CMakeLists.txt", "src/*" {deps} settings = "os", "compiler", "arch", "build_type" options = {{"shared": [True, False]}} default_options = {{"shared": False}} generators = "CMakeToolchain", "CMakeDeps" def layout(self): cmake_layout(self) def build(self): cmake = CMake(self) cmake.configure() cmake.build() def package(self): self.copy("*.h", dst="include", src="src") self.copy("*.lib", dst="lib", keep_path=False) self.copy("*.dll", dst="bin", keep_path=False) self.copy("*.dylib*", dst="lib", keep_path=False) self.copy("*.so", dst="lib", keep_path=False) self.copy("*.a", dst="lib", keep_path=False) self.copy("*app.exe", dst="bin", keep_path=False) self.copy("*app", dst="bin", keep_path=False) def package_info(self): self.cpp_info.libs = ["{name}"] """) deps = "requires = " + ", ".join('"{}"'.format(r) for r in requires) if requires else "" conanfile = conanfile.format(pkg_name=pkg_name, name=name, version=version, deps=deps) hdr = gen_function_h(name=name) deps = [r.name.replace(".", "_") for r in refs] src = gen_function_cpp(name=name, includes=deps, calls=deps) deps = [r.name for r in refs] files = { "src/{}.h".format(name): hdr, "src/{}.cpp".format(name): src, "conanfile.py": conanfile } if exe: src_app = gen_function_cpp(name="main", includes=[name], calls=[name]) files["src/{}_app.cpp".format(name)] = src_app cmake = gen_cmakelists(appname="{}_app".format(name), appsources=["src/{}_app.cpp".format(name)], libname=name, libsources=["src/{}.cpp".format(name)], find_package=deps) else: cmake = gen_cmakelists(libname=name, libsources=["src/{}.cpp".format(name)], find_package=deps) files["CMakeLists.txt"] = cmake return files
def _build(self, client): main_cpp = gen_function_cpp(name="main") client.save({"Makefile": self.makefile, "main.cpp": main_cpp}) client.run_command("make") client.run_command("app")
def test_autotools_real_install_dirs(self): body = gen_function_cpp(name="hello", msg="Hola Mundo!") header = gen_function_h(name="hello") main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) makefile_am = gen_makefile_am(main="main", main_srcs="main.cpp", lib="libhello.a", lib_srcs="hello.cpp") configure_ac = gen_configure_ac() conanfile = textwrap.dedent(""" from conans import ConanFile, AutoToolsBuildEnvironment class TestConan(ConanFile): name = "test" version = "1.0" settings = "os", "compiler", "arch", "build_type" exports_sources = "*" def build(self): self.run("aclocal") self.run("autoconf") self.run("automake --add-missing --foreign") autotools = AutoToolsBuildEnvironment(self) autotools.configure() autotools.make() autotools.install() def package_id(self): # easier to have same package_id for the test self.info.header_only() """) client = TestClient() client.save({ "conanfile.py": conanfile, "configure.ac": configure_ac, "Makefile.am": makefile_am, "main.cpp": main, "hello.h": header, "hello.cpp": body }) client.run("create . danimtb/testing") pref = PackageReference.loads("test/1.0@danimtb/testing:%s" % NO_SETTINGS_PACKAGE_ID) pkg_path = client.cache.package_layout(pref.ref).package(pref) [ self.assertIn(folder, os.listdir(pkg_path)) for folder in ["lib", "bin"] ] new_conanfile = conanfile.replace( "autotools.configure()", "autotools.configure(args=['--bindir=${prefix}/superbindir', '--libdir=${prefix}/superlibdir'])" ) client.save({"conanfile.py": new_conanfile}) client.run("create . danimtb/testing") [ self.assertIn(folder, os.listdir(pkg_path)) for folder in ["superlibdir", "superbindir"] ] [ self.assertNotIn(folder, os.listdir(pkg_path)) for folder in ["lib", "bin"] ]
def test_ios(): xcrun = XCRun(None, sdk='iphoneos') cflags = "" cflags += " -isysroot " + xcrun.sdk_path cflags += " -arch " + to_apple_arch('armv8') cxxflags = cflags ldflags = cflags profile = textwrap.dedent(""" include(default) [settings] os=iOS os.sdk=iphoneos os.version=12.0 arch=armv8 [env] CC={cc} CXX={cxx} CFLAGS={cflags} CXXFLAGS={cxxflags} LDFLAGS={ldflags} """).format(cc=xcrun.cc, cxx=xcrun.cxx, cflags=cflags, cxxflags=cxxflags, ldflags=ldflags) client = TestClient(path_with_spaces=False) client.save({"m1": profile}, clean_first=True) client.run("new hello/0.1 --template=cmake_lib") client.run("create . --profile:build=default --profile:host=m1 -tf None") main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) makefile_am = gen_makefile_am(main="main", main_srcs="main.cpp") configure_ac = gen_configure_ac() conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.gnu import Autotools class TestConan(ConanFile): requires = "hello/0.1" settings = "os", "compiler", "arch", "build_type" exports_sources = "configure.ac", "Makefile.am", "main.cpp" generators = "AutotoolsToolchain", "AutotoolsDeps" def build(self): autotools = Autotools(self) autotools.autoreconf() autotools.configure() autotools.make() """) client.save( { "conanfile.py": conanfile, "configure.ac": configure_ac, "Makefile.am": makefile_am, "main.cpp": main, "m1": profile }, clean_first=True) client.run("install . --profile:build=default --profile:host=m1") client.run("build .") client.run_command("./main", assert_error=True) assert "Bad CPU type in executable" in client.out client.run_command("lipo -info main") assert "Non-fat file: main is architecture: arm64" in client.out conanbuild = load_toolchain_args(client.current_folder) configure_args = conanbuild["configure_args"] make_args = conanbuild["make_args"] autoreconf_args = conanbuild["autoreconf_args"] assert configure_args == "'--prefix=/' '--bindir=${prefix}/bin' '--sbindir=${prefix}/bin' " \ "'--libdir=${prefix}/lib' '--includedir=${prefix}/include' " \ "'--oldincludedir=${prefix}/include' '--datarootdir=${prefix}/res' " \ "'--host=aarch64-apple-ios' '--build=x86_64-apple-darwin'" assert make_args == "" assert autoreconf_args == "'--force' '--install'"
def check_build_vs_project_with_a(vs_version): client = TestClient() client.save({"conanfile.py": GenConanfile()}) client.run("create . updep.pkg.team/0.1@") conanfile = textwrap.dedent(""" from conans import ConanFile, CMake class HelloConan(ConanFile): settings = "os", "build_type", "compiler", "arch" exports = '*' requires = "updep.pkg.team/0.1@" def build(self): cmake = CMake(self) cmake.configure() cmake.build() def package(self): self.copy("*.h", dst="include") self.copy("*.a", dst="lib", keep_path=False) def package_info(self): self.cpp_info.libs = ["hello.a"] """) hello_cpp = gen_function_cpp(name="hello") hello_h = gen_function_h(name="hello") cmake = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.15) project(MyLib CXX) set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") add_library(hello hello.cpp) """) client.save({ "conanfile.py": conanfile, "CMakeLists.txt": cmake, "hello.cpp": hello_cpp, "hello.h": hello_h }) client.run( 'create . mydep.pkg.team/0.1@ -s compiler="Visual Studio"' ' -s compiler.version={vs_version}'.format(vs_version=vs_version)) consumer = textwrap.dedent(""" from conans import ConanFile from conan.tools.microsoft import MSBuild class HelloConan(ConanFile): settings = "os", "build_type", "compiler", "arch" requires = "mydep.pkg.team/0.1@" generators = "MSBuildDeps", "MSBuildToolchain" def build(self): msbuild = MSBuild(self) msbuild.build("MyProject.sln") """) files = get_vs_project_files() main_cpp = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) files["MyProject/main.cpp"] = main_cpp files["conanfile.py"] = consumer props = os.path.join(client.current_folder, "conandeps.props") old = r'<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) client.run( 'install . -s compiler="Visual Studio"' ' -s compiler.version={vs_version}'.format(vs_version=vs_version)) client.run("build .") client.run_command(r"x64\Release\MyProject.exe") assert "hello: Release!" in client.out
def _modify_code(self): lib_cpp = gen_function_cpp(name="hello", msg="HelloImproved", includes=["hello"]) self.client.save({"app/hello.cpp": lib_cpp})
def setup_client_with_greetings(): """ creates a multi-component package with 2 components "hello" and "bye """ hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello", includes=["hello"]) bye_h = gen_function_h(name="bye") bye_cpp = gen_function_cpp(name="bye", includes=["bye"]) conanfile_greetings = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake class GreetingsConan(ConanFile): name = "greetings" version = "0.0.1" settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" exports_sources = "src/*" options = {"components": ["standard", "custom", "none"]} default_options = {"components": "standard"} def build(self): cmake = CMake(self) cmake.configure(build_script_folder="src") cmake.build() def package(self): self.copy("*.h", dst="include", src="src") self.copy("*.lib", dst="lib", keep_path=False) self.copy("*.a", dst="lib", keep_path=False) def package_info(self): if self.options.components == "standard": self.cpp_info.components["hello"].libs = ["hello"] self.cpp_info.components["bye"].libs = ["bye"] elif self.options.components == "custom": self.cpp_info.set_property("cmake_file_name", "MYG") self.cpp_info.set_property("cmake_target_name", "MyGreetings::MyGreetings") self.cpp_info.components["hello"].set_property("cmake_target_name", "MyGreetings::MyHello") self.cpp_info.components["bye"].set_property("cmake_target_name", "MyGreetings::MyBye") self.cpp_info.components["hello"].libs = ["hello"] self.cpp_info.components["bye"].libs = ["bye"] else: self.cpp_info.libs = ["hello", "bye"] def package_id(self): del self.info.options.components """) cmakelists_greetings = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.0) project(greetings CXX) add_library(hello hello.cpp) add_library(bye bye.cpp) """) test_package_greetings_conanfile = textwrap.dedent(""" import os from conans import ConanFile from conan.tools.cmake import CMake class GreetingsTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" requires = "greetings/0.0.1" def build(self): cmake = CMake(self) cmake.configure() cmake.build() def test(self): path = "{}".format(self.settings.build_type) if self.settings.os == "Windows" else "." self.run("{}{}example".format(path, os.sep)) """) test_package_greetings_cpp = gen_function_cpp(name="main", includes=["hello", "bye"], calls=["hello", "bye"]) test_package_greetings_cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.0) project(PackageTest CXX) find_package(greetings) add_executable(example example.cpp) target_link_libraries(example greetings::greetings) """) client = TestClient() client.save({ "conanfile.py": conanfile_greetings, "src/CMakeLists.txt": cmakelists_greetings, "src/hello.h": hello_h, "src/hello.cpp": hello_cpp, "src/bye.h": bye_h, "src/bye.cpp": bye_cpp, "test_package/conanfile.py": test_package_greetings_conanfile, "test_package/example.cpp": test_package_greetings_cpp, "test_package/CMakeLists.txt": test_package_greetings_cmakelists }) client.run("create . -s build_type=Release") assert "hello: Release!" in client.out assert "bye: Release!" in client.out client.run("create . -s build_type=Debug") assert "hello: Debug!" in client.out assert "bye: Debug!" in client.out return client
class Base(unittest.TestCase): conanfile = textwrap.dedent(""" from conan.tools.google import Bazel from conans import ConanFile class App(ConanFile): name="test_bazel_app" version="0.0" settings = "os", "compiler", "build_type", "arch" generators = "BazelDeps", "BazelToolchain" exports_sources = "WORKSPACE", "app/*" def build(self): bazel = Bazel(self) bazel.configure() bazel.build(label="//app:main") def package(self): self.copy('*', src='bazel-bin') """) buildfile = textwrap.dedent(""" load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") cc_library( name = "hello", srcs = ["hello.cpp"], hdrs = ["hello.h",], ) cc_binary( name = "main", srcs = ["main.cpp"], deps = [":hello"], ) """) lib_h = gen_function_h(name="hello") lib_cpp = gen_function_cpp(name="hello", msg="Hello", includes=["hello"]) main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) workspace_file = textwrap.dedent(""" load("@//bazel-build/conandeps:dependencies.bzl", "load_conan_dependencies") load_conan_dependencies() """) def setUp(self): self.client = TestClient(path_with_spaces=False ) # bazel doesn't work with paths with spaces conanfile = textwrap.dedent(""" from conans import ConanFile from conans.tools import save import os class Pkg(ConanFile): settings = "build_type" def package(self): save(os.path.join(self.package_folder, "include/hello.h"), '''#include <iostream> void hello(){std::cout<< "Hello: %s" <<std::endl;}''' % self.settings.build_type) """) self.client.save({"conanfile.py": conanfile}) self.client.run("create . hello/0.1@ -s build_type=Debug") self.client.run("create . hello/0.1@ -s build_type=Release") # Prepare the actual consumer package self.client.save({ "conanfile.py": self.conanfile, "WORKSPACE": self.workspace_file, "app/BUILD": self.buildfile, "app/main.cpp": self.main, "app/hello.cpp": self.lib_cpp, "app/hello.h": self.lib_h }) def _run_build(self): build_directory = os.path.join(self.client.current_folder, "bazel-build").replace("\\", "/") with self.client.chdir(build_directory): self.client.run("install .. ") install_out = self.client.out self.client.run("build ..") return install_out def _modify_code(self): lib_cpp = gen_function_cpp(name="hello", msg="HelloImproved", includes=["hello"]) self.client.save({"app/hello.cpp": lib_cpp}) def _incremental_build(self): with self.client.chdir(self.client.current_folder): self.client.run_command( "bazel build --explain=output.txt //app:main") def _run_app(self, bin_folder=False): command_str = "bazel-bin/app/main.exe" if bin_folder else "bazel-bin/app/main" if platform.system() == "Windows": command_str = command_str.replace("/", "\\") self.client.run_command(command_str)
def test_same_names(): client = TestClient() conanfile_greetings = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake class HelloConan(ConanFile): name = "hello" version = "0.0.1" settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" exports_sources = "src/*" def build(self): cmake = CMake(self) cmake.configure(build_script_folder="src") cmake.build() def package(self): self.copy("*.h", dst="include", src="src") self.copy("*.lib", dst="lib", keep_path=False) self.copy("*.a", dst="lib", keep_path=False) def package_info(self): self.cpp_info.components["global"].name = "hello" self.cpp_info.components["global"].libs = ["hello"] """) hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello", includes=["hello"]) cmakelists_greetings = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.0) project(greetings CXX) add_library(hello hello.cpp) """) test_package_greetings_conanfile = textwrap.dedent(""" import os from conans import ConanFile from conan.tools.cmake import CMake class HelloTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" def build(self): cmake = CMake(self) cmake.configure() cmake.build() def test(self): path = "{}".format(self.settings.build_type) if self.settings.os == "Windows" else "." self.run("{}{}example".format(path, os.sep)) """) test_package_greetings_cpp = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) test_package_greetings_cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.0) project(PackageTest CXX) find_package(hello) add_executable(example example.cpp) target_link_libraries(example hello::hello) """) client.save({ "conanfile.py": conanfile_greetings, "src/CMakeLists.txt": cmakelists_greetings, "src/hello.h": hello_h, "src/hello.cpp": hello_cpp, "test_package/conanfile.py": test_package_greetings_conanfile, "test_package/example.cpp": test_package_greetings_cpp, "test_package/CMakeLists.txt": test_package_greetings_cmakelists }) client.run("create .") assert "hello: Release!" in client.out
def test_no_soname_flag(): """ This test case is testing this graph structure: * 'LibNoSoname' -> 'OtherLib' -> 'Executable' Where: * LibNoSoname: is a package built as shared and without the SONAME flag. * OtherLib: is a package which requires LibNoSoname. * Executable: is the final consumer building an application and depending on OtherLib. """ client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile, CMake, tools class {name}Conan(ConanFile): name = "{name}" version = "1.0" # Binary configuration settings = "os", "compiler", "build_type", "arch" options = {{"shared": [True, False], "fPIC": [True, False]}} default_options = {{"shared": True, "fPIC": True}} # Sources are located in the same place as this recipe, copy them to the recipe exports_sources = "CMakeLists.txt", "src/*" generators = "cmake_find_package_multi" {requires} def config_options(self): if self.settings.os == "Windows": del self.options.fPIC def build(self): cmake = CMake(self) cmake.configure() cmake.build() def package(self): self.copy("*.h", dst="include", src="src") self.copy("*.lib", dst="lib", keep_path=False) self.copy("*.dll", dst="bin", keep_path=False) self.copy("*.so", dst="lib", keep_path=False) self.copy("*.dylib", dst="lib", keep_path=False) self.copy("*.a", dst="lib", keep_path=False) def package_info(self): self.cpp_info.libs = ["{name}"] self.cpp_info.names["cmake_find_package_multi"] = "{name}" """) cmakelists_nosoname = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(nosoname CXX) add_library(nosoname SHARED src/nosoname.cpp) # Adding NO_SONAME flag to main library set_target_properties(nosoname PROPERTIES PUBLIC_HEADER "src/nosoname.h" NO_SONAME 1) install(TARGETS nosoname DESTINATION "." PUBLIC_HEADER DESTINATION include RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) """) cpp = gen_function_cpp(name="nosoname") h = gen_function_h(name="nosoname") client.save({ "CMakeLists.txt": cmakelists_nosoname, "src/nosoname.cpp": cpp, "src/nosoname.h": h, "conanfile.py": conanfile.format(name="nosoname", requires="") }) # Now, let's create both libraries client.run("create .") cmakelists_libB = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(libB CXX) find_package(nosoname CONFIG REQUIRED) add_library(libB SHARED src/libB.cpp) target_link_libraries(libB nosoname::nosoname) set_target_properties(libB PROPERTIES PUBLIC_HEADER "src/libB.h") install(TARGETS libB DESTINATION "." PUBLIC_HEADER DESTINATION include RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) """) cpp = gen_function_cpp(name="libB", includes=["nosoname"], calls=["nosoname"]) h = gen_function_h(name="libB") client.save( { "CMakeLists.txt": cmakelists_libB, "src/libB.cpp": cpp, "src/libB.h": h, "conanfile.py": conanfile.format(name="libB", requires='requires = "nosoname/1.0"') }, clean_first=True) # Now, let's create both libraries client.run("create .") # Now, let's create the application consuming libB cmakelists = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(PackageTest CXX) include(${{CMAKE_BINARY_DIR}}/conanbuildinfo.cmake) conan_basic_setup() set(CMAKE_MODULE_PATH ${{CMAKE_BINARY_DIR}}) set(CMAKE_PREFIX_PATH ${{CMAKE_BINARY_DIR}}) find_package(libB CONFIG REQUIRED) add_executable(example src/example.cpp) target_link_libraries(example libB) """) conanfile = textwrap.dedent(""" [requires] libB/1.0 [generators] cmake cmake_find_package_multi """) cpp = gen_function_cpp(name="main", includes=["libB"], calls=["libB"]) client.save( { "CMakeLists.txt": cmakelists.format(current_folder=client.current_folder), "src/example.cpp": cpp, "conanfile.txt": conanfile }, clean_first=True) client.run('install . ') client.run_command( 'cmake -G "Unix Makefiles" . && cmake --build . && ./bin/example')
def test_autotools_bash_complete(): client = TestClient(path_with_spaces=False) bash_path = tools_locations["msys2"]["system"]["path"][ "Windows"] + "/bash.exe" save( client.cache.new_config_path, textwrap.dedent(""" tools.microsoft.bash:subsystem=msys2 tools.microsoft.bash:path={} """.format(bash_path))) main = gen_function_cpp(name="main") # The autotools support for "cl" compiler (VS) is very limited, linking with deps doesn't # work but building a simple app do makefile_am = gen_makefile_am(main="main", main_srcs="main.cpp") configure_ac = gen_configure_ac() conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.gnu import Autotools from conan.tools.microsoft import VCVars from conan.tools.env import Environment class TestConan(ConanFile): settings = "os", "compiler", "arch", "build_type" exports_sources = "configure.ac", "Makefile.am", "main.cpp" generators = "AutotoolsToolchain" win_bash = True def generate(self): # Add vcvars launcher VCVars(self).generate() # Force autotools to use "cl" compiler # FIXME: Should this be added to AutotoolsToolchain when visual? env = Environment() env.define("CXX", "cl") env.define("CC", "cl") env.vars(self).save_script("conan_compiler") def build(self): # These commands will run in bash activating first the vcvars and # then inside the bash activating the self.run("aclocal") self.run("autoconf") self.run("automake --add-missing --foreign") autotools = Autotools(self) autotools.configure() autotools.make() """) client.save({ "conanfile.py": conanfile, "configure.ac": configure_ac, "Makefile.am": makefile_am, "main.cpp": main }) client.run("install . -s:b os=Windows -s:h os=Windows") client.run("build .") client.run_command("main.exe") check_exe_run(client.out, "main", "msvc", None, "Release", "x86_64", None) bat_contents = client.load("conanbuild.bat") sh_contents = client.load("conanbuild.sh") assert "conanvcvars.bat" in bat_contents assert "conan_compiler.sh" in sh_contents and "conanautotoolstoolchain.sh" in sh_contents
def test_native_export_multi(self): """ bye depends on hello. Both use find_package in their CMakeLists.txt The consumer depends on bye, using the cmake_find_package_multi generator """ c = TestClient() project_folder_name = "project_targets" c.copy_assets("cmake_find_package_multi", ["bye", "hello", project_folder_name]) # Create packages for hello and bye for p in ("hello", "bye"): for bt in ("Debug", "Release"): c.run("create {} user/channel -s build_type={}".format(p, bt)) with c.chdir(project_folder_name): # Save conanfile and example conanfile = textwrap.dedent(""" [requires] bye/1.0@user/channel [generators] cmake_find_package_multi """) example_cpp = gen_function_cpp(name="main", includes=["bye"], calls=["bye"]) c.save({"conanfile.txt": conanfile, "example.cpp": example_cpp}) with c.chdir("build"): for bt in ("Debug", "Release"): c.run( "install .. user/channel -s build_type={}".format(bt)) # Test that we are using find_dependency with the NO_MODULE option # to skip finding first possible FindBye somewhere self.assertIn( "find_dependency(hello REQUIRED NO_MODULE)", load(os.path.join(c.current_folder, "bye-config.cmake"))) if platform.system() == "Windows": c.run_command('cmake .. -G "Visual Studio 15 Win64"') c.run_command('cmake --build . --config Debug') c.run_command('cmake --build . --config Release') c.run_command('Debug\\example.exe') self.assertIn("Hello World Debug!", c.out) self.assertIn("bye World Debug!", c.out) c.run_command('Release\\example.exe') self.assertIn("Hello World Release!", c.out) self.assertIn("bye World Release!", c.out) else: for bt in ("Debug", "Release"): c.run_command( 'cmake .. -DCMAKE_BUILD_TYPE={}'.format(bt)) c.run_command('cmake --build .') c.run_command('./example') self.assertIn("Hello World {}!".format(bt), c.out) self.assertIn("bye World {}!".format(bt), c.out) os.remove(os.path.join(c.current_folder, "example"))
class CustomConfigurationTest(unittest.TestCase): conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMakeDeps class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" def generate(self): cmake = CMakeDeps(self) cmake.configurations.append("ReleaseShared") if self.options["hello"].shared: cmake.configuration = "ReleaseShared" cmake.generate() def imports(self): config = str(self.settings.build_type) if self.options["hello"].shared: config = "ReleaseShared" self.copy("*.dll", src="bin", dst=config, keep_path=False) """) app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) cmakelist = textwrap.dedent(""" set(CMAKE_CONFIGURATION_TYPES Debug Release ReleaseShared CACHE STRING "Available build-types: Debug, Release and ReleaseShared") cmake_minimum_required(VERSION 2.8) project(App C CXX) set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR} ${CMAKE_PREFIX_PATH}) set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR} ${CMAKE_MODULE_PATH}) set(CMAKE_CXX_FLAGS_RELEASESHARED ${CMAKE_CXX_FLAGS_RELEASE}) set(CMAKE_C_FLAGS_RELEASESHARED ${CMAKE_C_FLAGS_RELEASE}) set(CMAKE_EXE_LINKER_FLAGS_RELEASESHARED ${CMAKE_EXE_LINKER_FLAGS_RELEASE}) find_package(hello REQUIRED) add_executable(app app.cpp) target_link_libraries(app PRIVATE hello::hello) """) def setUp(self): self.client = TestClient(path_with_spaces=False) self.client.run("new hello/0.1 -s") self.client.run("create . hello/0.1@ -s compiler.version=15 " "-s build_type=Release -o hello:shared=True") self.client.run("create . hello/0.1@ -s compiler.version=15 " "-s build_type=Release") # Prepare the actual consumer package self.client.save({ "conanfile.py": self.conanfile, "CMakeLists.txt": self.cmakelist, "app.cpp": self.app }) def test_generator_multi(self): settings = { "compiler": "Visual Studio", "compiler.version": "15", "arch": "x86_64", "build_type": "Release", } settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) # Run the configure corresponding to this test case with self.client.chdir('build'): self.client.run("install .. %s -o hello:shared=True" % settings) self.client.run("install .. %s -o hello:shared=False" % settings) self.assertTrue( os.path.isfile( os.path.join(self.client.current_folder, "helloTarget-releaseshared.cmake"))) self.assertTrue( os.path.isfile( os.path.join(self.client.current_folder, "helloTarget-release.cmake"))) self.client.run_command('cmake .. -G "Visual Studio 15 Win64"') self.client.run_command('cmake --build . --config Release') self.client.run_command(r"Release\\app.exe") self.assertIn("hello/0.1: Hello World Release!", self.client.out) self.assertIn("main: Release!", self.client.out) self.client.run_command('cmake --build . --config ReleaseShared') self.client.run_command(r"ReleaseShared\\app.exe") self.assertIn("hello/0.1: Hello World Release!", self.client.out) self.assertIn("main: Release!", self.client.out)
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)
class WinTest(unittest.TestCase): conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.microsoft import MSBuildToolchain, MSBuild class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" generators = "msbuild" options = {"shared": [True, False]} default_options = {"shared": False} def generate(self): tc = MSBuildToolchain(self) tc.preprocessor_definitions["DEFINITIONS_BOTH"] = "True" if self.settings.build_type == "Debug": tc.preprocessor_definitions["DEFINITIONS_CONFIG"] = "Debug" else: tc.preprocessor_definitions["DEFINITIONS_CONFIG"] = "Release" tc.generate() def build(self): msbuild = MSBuild(self) msbuild.build("MyProject.sln") """) app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"], preprocessor=["DEFINITIONS_BOTH", "DEFINITIONS_CONFIG"]) def _run_app(self, client, arch, build_type, msg="main"): if arch == "x86": command_str = "%s\\MyApp.exe" % build_type else: command_str = "x64\\%s\\MyApp.exe" % build_type client.run_command(command_str) if arch == "x86": self.assertIn("main _M_IX86 defined", client.out) else: self.assertIn("main _M_X64 defined", client.out) self.assertIn("Hello World %s" % build_type, client.out) self.assertIn("%s: %s!" % (msg, build_type), client.out) self.assertIn("DEFINITIONS_BOTH: True", client.out) self.assertIn("DEFINITIONS_CONFIG: %s" % build_type, client.out) @pytest.mark.tool_cmake def test_toolchain_win(self): client = TestClient(path_with_spaces=False) settings = {"compiler": "Visual Studio", "compiler.version": "15", "compiler.cppstd": "17", "compiler.runtime": "MT", "build_type": "Release", "arch": "x86"} # Build the profile according to the settings provided settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) client.run("new hello/0.1 -s") client.run("create . hello/0.1@ %s" % (settings, )) # Prepare the actual consumer package client.save({"conanfile.py": self.conanfile, "MyProject.sln": sln_file, "MyApp/MyApp.vcxproj": myapp_vcxproj, "MyApp/MyApp.cpp": self.app}, clean_first=True) # Run the configure corresponding to this test case client.run("install . %s -if=conan" % (settings, )) self.assertIn("conanfile.py: MSBuildToolchain created conantoolchain_release_win32.props", client.out) client.run("build . -if=conan") self.assertIn("Visual Studio 2017", client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x86'", client.out) self._run_app(client, "x86", "Release") version = re.search("main _MSC_VER19([0-9]*)", str(client.out)).group(1) version = int(version) self.assertTrue(10 <= version < 20) self.assertIn("main _MSVC_LANG2017", client.out) vcvars = vcvars_command(version="15", architecture="x86") cmd = ('%s && dumpbin /dependents "Release\\MyApp.exe"' % vcvars) client.run_command(cmd) # No other DLLs dependencies rather than kernel, it was MT, statically linked self.assertIn("KERNEL32.dll", client.out) self.assertEqual(1, str(client.out).count(".dll")) @pytest.mark.tool_cmake def test_toolchain_win_debug(self): client = TestClient(path_with_spaces=False) settings = {"compiler": "Visual Studio", "compiler.version": "15", "compiler.toolset": "v140", "compiler.runtime": "MDd", "build_type": "Debug", "arch": "x86_64"} # Build the profile according to the settings provided settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) client.run("new hello/0.1 -s") client.run("create . hello/0.1@ %s" % (settings,)) # Prepare the actual consumer package client.save({"conanfile.py": self.conanfile, "MyProject.sln": sln_file, "MyApp/MyApp.vcxproj": myapp_vcxproj, "MyApp/MyApp.cpp": self.app}, clean_first=True) # Run the configure corresponding to this test case client.run("install . %s -if=conan" % (settings, )) self.assertIn("conanfile.py: MSBuildToolchain created conantoolchain_debug_x64.props", client.out) client.run("build . -if=conan") self.assertIn("Visual Studio 2017", client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) self._run_app(client, "x64", "Debug") self.assertIn("main _MSC_VER1900", client.out) self.assertIn("main _MSVC_LANG2014", client.out) vcvars = vcvars_command(version="15", architecture="amd64") cmd = ('%s && dumpbin /dependents "x64\\Debug\\MyApp.exe"' % vcvars) client.run_command(cmd) self.assertIn("MSVCP140D.dll", client.out) self.assertIn("VCRUNTIME140D.dll", client.out) @pytest.mark.tool_cmake def test_toolchain_win_multi(self): client = TestClient(path_with_spaces=False) settings = {"compiler": "Visual Studio", "compiler.version": "15", "compiler.cppstd": "17"} settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) client.run("new hello/0.1 -s") configs = [("Release", "x86"), ("Release", "x86_64"), ("Debug", "x86"), ("Debug", "x86_64")] for build_type, arch in configs: # Build the profile according to the settings provided runtime = "MT" if build_type == "Release" else "MTd" client.run("create . hello/0.1@ %s -s build_type=%s -s arch=%s -s compiler.runtime=%s" % (settings, build_type, arch, runtime)) # Prepare the actual consumer package client.save({"conanfile.py": self.conanfile, "MyProject.sln": sln_file, "MyApp/MyApp.vcxproj": myapp_vcxproj, "MyApp/MyApp.cpp": self.app}, clean_first=True) # Run the configure corresponding to this test case for build_type, arch in configs: runtime = "MT" if build_type == "Release" else "MTd" client.run("install . %s -s build_type=%s -s arch=%s -s compiler.runtime=%s -if=conan" % (settings, build_type, arch, runtime)) vs_path = vs_installation_path("15") vcvars_path = os.path.join(vs_path, "VC/Auxiliary/Build/vcvarsall.bat") for build_type, arch in configs: platform_arch = "x86" if arch == "x86" else "x64" cmd = ('set "VSCMD_START_DIR=%%CD%%" && ' '"%s" x64 && msbuild "MyProject.sln" /p:Configuration=%s ' '/p:Platform=%s ' % (vcvars_path, build_type, platform_arch)) client.run_command(cmd) self.assertIn("Visual Studio 2017", client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) self._run_app(client, arch, build_type) version = re.search("main _MSC_VER19([0-9]*)", str(client.out)).group(1) version = int(version) self.assertTrue(10 <= version < 20) self.assertIn("main _MSVC_LANG2017", client.out)
def setup_client_with_greetings(): """ creates a multi-component package with 2 components "hello" and "bye """ hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello", includes=["hello"]) bye_h = gen_function_h(name="bye") bye_cpp = gen_function_cpp(name="bye", includes=["bye"]) conanfile_greetings = textwrap.dedent(""" import os from conans import ConanFile, CMake, tools class GreetingsConan(ConanFile): name = "greetings" version = "0.0.1" settings = "os", "compiler", "build_type", "arch" generators = "cmake" exports_sources = "src/*" options = {"components": ["standard", "custom", "none"]} default_options = {"components": "standard"} def build(self): cmake = CMake(self) cmake.configure(source_folder="src") cmake.build() def package(self): self.copy("*.h", dst="include", src="src") self.copy("*.lib", dst="lib", keep_path=False) self.copy("*.a", dst="lib", keep_path=False) tools.save(os.path.join(self.package_folder, "my_cmake_functions.cmake"), "set(MY_CMAKE_VAR 99)") def package_info(self): if self.options.components == "standard": self.cpp_info.components["hello"].libs = ["hello"] self.cpp_info.components["bye"].libs = ["bye"] self.cpp_info.components["hello"].build_modules = ["my_cmake_functions.cmake"] elif self.options.components == "custom": self.cpp_info.filenames["cmake_find_package_multi"] = "MYG" self.cpp_info.filenames["cmake_find_package"] = "MYG" self.cpp_info.set_property("cmake_file_name", "MYG") self.cpp_info.names["cmake_find_package_multi"] = "MyGreetings" self.cpp_info.names["cmake_find_package"] = "MyGreetings" self.cpp_info.set_property("cmake_target_name", "MyGreetings") self.cpp_info.components["hello"].names["cmake_find_package_multi"] = "MyHello" self.cpp_info.components["bye"].names["cmake_find_package_multi"] = "MyBye" self.cpp_info.components["hello"].names["cmake_find_package"] = "MyHello" self.cpp_info.components["bye"].names["cmake_find_package"] = "MyBye" self.cpp_info.components["hello"].set_property("cmake_target_name", "MyHello") self.cpp_info.components["bye"].set_property("cmake_target_name", "MyBye") self.cpp_info.components["hello"].libs = ["hello"] self.cpp_info.components["bye"].libs = ["bye"] # Duplicated on purpose to check that it doesn't break self.cpp_info.components["bye"].build_modules = ["my_cmake_functions.cmake"] self.cpp_info.components["hello"].build_modules = ["my_cmake_functions.cmake"] else: self.cpp_info.libs = ["hello", "bye"] def package_id(self): del self.info.options.components """) cmakelists_greetings = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.0) project(greetings CXX) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_output_dirs_setup() add_library(hello hello.cpp) add_library(bye bye.cpp) """) test_package_greetings_conanfile = textwrap.dedent(""" import os from conans import ConanFile, CMake class GreetingsTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "cmake", "cmake_find_package_multi" requires = "greetings/0.0.1" def build(self): cmake = CMake(self) cmake.configure() cmake.build() def test(self): os.chdir("bin") self.run(".%sexample" % os.sep) """) test_package_greetings_cpp = gen_function_cpp(name="main", includes=["hello", "bye"], calls=["hello", "bye"]) test_package_greetings_cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.0) project(PackageTest CXX) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_output_dirs_setup() find_package(greetings) add_executable(example example.cpp) target_link_libraries(example greetings::greetings) """) client = TestClient() client.save({ "conanfile.py": conanfile_greetings, "src/CMakeLists.txt": cmakelists_greetings, "src/hello.h": hello_h, "src/hello.cpp": hello_cpp, "src/bye.h": bye_h, "src/bye.cpp": bye_cpp, "test_package/conanfile.py": test_package_greetings_conanfile, "test_package/example.cpp": test_package_greetings_cpp, "test_package/CMakeLists.txt": test_package_greetings_cmakelists }) client.run("create . -s build_type=Release") assert "hello: Release!" in client.out assert "bye: Release!" in client.out client.run("create . -s build_type=Debug") assert "hello: Debug!" in client.out assert "bye: Debug!" in client.out return client
def test_ios(): xcrun = XCRun(None, sdk='iphoneos') cflags = "" cflags += " -isysroot " + xcrun.sdk_path cflags += " -arch " + to_apple_arch('armv8') cxxflags = cflags ldflags = cflags profile = textwrap.dedent(""" include(default) [settings] os=iOS os.version=12.0 arch=armv8 [env] CC={cc} CXX={cxx} CFLAGS={cflags} CXXFLAGS={cxxflags} LDFLAGS={ldflags} """).format(cc=xcrun.cc, cxx=xcrun.cxx, cflags=cflags, cxxflags=cxxflags, ldflags=ldflags) client = TestClient(path_with_spaces=False) client.save({"m1": profile}, clean_first=True) client.run("new hello/0.1 --template=v2_cmake") client.run("create . --profile:build=default --profile:host=m1 -tf None") main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) makefile_am = gen_makefile_am(main="main", main_srcs="main.cpp") configure_ac = gen_configure_ac() conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.gnu import Autotools class TestConan(ConanFile): requires = "hello/0.1" settings = "os", "compiler", "arch", "build_type" exports_sources = "configure.ac", "Makefile.am", "main.cpp" generators = "AutotoolsGen" def build(self): self.run("aclocal") self.run("autoconf") self.run("automake --add-missing --foreign") autotools = Autotools(self) autotools.configure() autotools.make() """) client.save({"conanfile.py": conanfile, "configure.ac": configure_ac, "Makefile.am": makefile_am, "main.cpp": main, "m1": profile}, clean_first=True) client.run("install . --profile:build=default --profile:host=m1") client.run("build .") client.run_command("./main", assert_error=True) assert "Bad CPU type in executable" in client.out client.run_command("lipo -info main") assert "Non-fat file: main is architecture: arm64" in client.out js = client.load("conanbuild.json") assert '"build": "x86_64-apple-darwin"' in js assert '"host": "aarch64-apple-ios"' in js
def create_chat(client, generator, components, package_info, cmake_find, test_cmake_find): conanfile = textwrap.dedent(""" from conans import ConanFile, CMake class Chat(ConanFile): name = "chat" version = "0.0.1" settings = "os", "compiler", "build_type", "arch" generators = "{}", "cmake" exports_sources = "src/*" requires = "greetings/0.0.1" default_options = {{"greetings:components": "{}"}} def build(self): cmake = CMake(self) cmake.configure(source_folder="src") cmake.build() def package(self): self.copy("*.h", dst="include", src="src") self.copy("*.lib", dst="lib", keep_path=False) self.copy("*.a", dst="lib", keep_path=False) def package_info(self): {} """).format(generator, components, "\n ".join(package_info.splitlines())) sayhello_h = gen_function_h(name="sayhello") sayhello_cpp = gen_function_cpp(name="sayhello", includes=["hello"], calls=["hello"]) sayhellobye_h = gen_function_h(name="sayhellobye") sayhellobye_cpp = gen_function_cpp(name="sayhellobye", includes=["sayhello", "bye"], calls=["sayhello", "bye"]) cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.0) project(world CXX) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_output_dirs_setup() %s """ % cmake_find) test_conanfile = textwrap.dedent(""" import os from conans import ConanFile, CMake class WorldTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "cmake", "{}" requires = "chat/0.0.1" def build(self): cmake = CMake(self) cmake.configure() cmake.build() def test(self): os.chdir("bin") self.run(".%sexample" % os.sep) self.run(".%sexample2" % os.sep) """.format(generator)) test_example_cpp = gen_function_cpp(name="main", includes=["sayhellobye"], calls=["sayhellobye"]) test_cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) cmake_minimum_required(VERSION 3.0) project(PackageTest CXX) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_output_dirs_setup() # necessary for the local set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR} ${CMAKE_MODULE_PATH}) set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR} ${CMAKE_PREFIX_PATH}) %s """ % test_cmake_find) client.save( { "conanfile.py": conanfile, "src/CMakeLists.txt": cmakelists, "src/sayhello.h": sayhello_h, "src/sayhello.cpp": sayhello_cpp, "src/sayhellobye.h": sayhellobye_h, "src/sayhellobye.cpp": sayhellobye_cpp, "test_package/conanfile.py": test_conanfile, "test_package/CMakeLists.txt": test_cmakelists, "test_package/example.cpp": test_example_cpp }, clean_first=True) client.run("create . -s build_type=Release") assert "sayhellobye: Release!" in client.out assert "sayhello: Release!" in client.out assert "hello: Release!" in client.out assert "bye: Release!" in client.out client.run("create . -s build_type=Debug") assert "sayhellobye: Debug!" in client.out assert "sayhello: Debug!" in client.out assert "hello: Debug!" in client.out assert "bye: Debug!" in client.out
def test_cpp_info_link_objects(): client = TestClient() obj_ext = "obj" if platform.system() == "Windows" else "o" cpp_info = { "objects": [os.path.join("lib", "myobject.{}".format(obj_ext))] } object_cpp = gen_function_cpp(name="myobject") object_h = gen_function_h(name="myobject") cmakelists = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(MyObject) file(GLOB HEADERS *.h) add_library(myobject OBJECT myobject.cpp) if( WIN32 ) set(OBJ_PATH "myobject.dir/Release/myobject${CMAKE_C_OUTPUT_EXTENSION}") else() set(OBJ_PATH "CMakeFiles/myobject.dir/myobject.cpp${CMAKE_C_OUTPUT_EXTENSION}") endif() install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${OBJ_PATH} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib RENAME myobject${CMAKE_C_OUTPUT_EXTENSION}) install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include) """) test_package_cpp = gen_function_cpp(name="main", includes=["myobject"], calls=["myobject"]) test_package_cmakelists = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(example) find_package(myobject REQUIRED) add_executable(example example.cpp) target_link_libraries(example myobject::myobject) """) client.save({ "CMakeLists.txt": cmakelists, "conanfile.py": GenConanfile("myobject", "1.0").with_package_info( cpp_info=cpp_info, env_info={}).with_exports_sources( "*").with_cmake_build().with_package("cmake = CMake(self)", "cmake.install()"), "myobject.cpp": object_cpp, "myobject.h": object_h, "test_package/conanfile.py": GenConanfile().with_cmake_build().with_import("import os").with_test( 'path = "{}".format(self.settings.build_type) ' 'if self.settings.os == "Windows" else "."').with_test( 'self.run("{}{}example".format(path, os.sep))'), "test_package/example.cpp": test_package_cpp, "test_package/CMakeLists.txt": test_package_cmakelists }) client.run("create . -s build_type=Release") assert "myobject: Release!" in client.out
def test_cmake_virtualenv(): client = TestClient() client.run("new hello/0.1 -s") client.run("create .") cmakewrapper = textwrap.dedent(r""" from conans import ConanFile import os from conans.tools import save, chdir class Pkg(ConanFile): def package(self): with chdir(self.package_folder): save("cmake.bat", "@echo off\necho MYCMAKE WRAPPER!!\ncmake.exe %*") save("cmake.sh", 'echo MYCMAKE WRAPPER!!\ncmake "$@"') os.chmod("cmake.sh", 0o777) def package_info(self): # Custom buildenv not defined by cpp_info self.buildenv_info.prepend_path("PATH", self.package_folder) """) consumer = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake class App(ConanFile): settings = "os", "arch", "compiler", "build_type" exports_sources = "CMakeLists.txt", "main.cpp" requires = "hello/0.1" build_requires = "cmakewrapper/0.1" generators = "CMakeDeps", "CMakeToolchain", "VirtualEnv" apply_env = False def build(self): cmake = CMake(self) if self.settings.os != "Windows": cmake._cmake_program = "cmake.sh" # VERY DIRTY HACK cmake.configure() cmake.build() """) cmakelists = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(MyApp CXX) find_package(hello) add_executable(app main.cpp) target_link_libraries(app hello::hello) """) client.save( { "cmakewrapper/conanfile.py": cmakewrapper, "consumer/conanfile.py": consumer, "consumer/main.cpp": gen_function_cpp(name="main", includes=["hello"], calls=["hello"]), "consumer/CMakeLists.txt": cmakelists }, clean_first=True) client.run("create cmakewrapper cmakewrapper/0.1@") client.run("create consumer consumer/0.1@") assert "MYCMAKE WRAPPER!!" in client.out assert "consumer/0.1: Created package" in client.out