Exemple #1
0
    def test_install(self):
        hello_cpp = gen_function_cpp(name="hello")
        hello_h = gen_function_h(name="hello")
        test_package_cpp = gen_function_cpp(name="main",
                                            includes=["hello"],
                                            calls=["hello"])

        self.t.save({
            "conanfile.py":
            self._conanfile_py,
            "meson.build":
            self._meson_build,
            "hello.cpp":
            hello_cpp,
            "hello.h":
            hello_h,
            os.path.join("test_package", "conanfile.py"):
            self._test_package_conanfile_py,
            os.path.join("test_package", "CMakeLists.txt"):
            self._test_package_cmake_lists,
            os.path.join("test_package", "test_package.cpp"):
            test_package_cpp
        })

        self.t.run("create . hello/0.1@ %s" % self._settings_str)

        self._check_binary()
    def test_build(self):
        hello_h = gen_function_h(name="hello")
        hello_cpp = gen_function_cpp(
            name="hello",
            preprocessor=["TEST_DEFINITION1", "TEST_DEFINITION2"])
        app = gen_function_cpp(name="main",
                               includes=["hello"],
                               calls=["hello"])

        self.t.save({
            "conanfile.py": self._conanfile_py,
            "meson.build": self._meson_build,
            "hello.h": hello_h,
            "hello.cpp": hello_cpp,
            "main.cpp": app
        })

        self.t.run("install . %s" % self._settings_str)

        content = self.t.load("conan_meson_native.ini")

        self.assertIn("[built-in options]", content)
        self.assertIn("buildtype = 'release'", content)

        self.t.run("build .")
        self.t.run_command(os.path.join("build", "demo"))

        self.assertIn("hello: Release!", self.t.out)
        self.assertIn("TEST_DEFINITION1: TestPpdValue1", self.t.out)
        self.assertIn("TEST_DEFINITION2: TestPpdValue2", self.t.out)

        self._check_binary()
Exemple #3
0
    def _build(self, settings):
        self.t = TestClient()

        settings_str = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v)

        hello_h = gen_function_h(name="hello")
        hello_cpp = gen_function_cpp(name="hello", preprocessor=["STRING_DEFINITION"])
        app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])

        self.t.save({"conanfile.py": self._conanfile_py,
                     "meson.build": self._meson_build,
                     "meson_options.txt": self._meson_options_txt,
                     "hello.h": hello_h,
                     "hello.cpp": hello_cpp,
                     "main.cpp": app})

        self.t.run("install . %s" % settings_str)

        content = self.t.load("conan_meson_native.ini")

        self.assertIn("[project options]", content)
        self.assertIn("STRING_DEFINITION = 'Text'", content)
        self.assertIn("TRUE_DEFINITION = true", content)
        self.assertIn("FALSE_DEFINITION = false", content)
        self.assertIn("INT_DEFINITION = 42", content)
        self.assertIn("ARRAY_DEFINITION = ['Text1', 'Text2']", content)

        self.assertIn("[built-in options]", content)
        self.assertIn("buildtype = 'release'", content)

        self.t.run("build .")
        self.t.run_command(os.path.join("build", "demo"))

        self.assertIn("hello: Release!", self.t.out)
        self.assertIn("STRING_DEFINITION: Text", self.t.out)
Exemple #4
0
def pkg_cmake(name, version, requires=None):
    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
        from conan.tools.layout import cmake_layout

        class Pkg(ConanFile):
            name = "{pkg_name}"
            version = "{version}"
            exports_sources = "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")
                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)

            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]
    cmake = gen_cmakelists(libname=name,
                           libsources=["{}.cpp".format(name)],
                           find_package=deps)

    return {
        "src/{}.h".format(name): hdr,
        "src/{}.cpp".format(name): src,
        "src/CMakeLists.txt": cmake,
        "conanfile.py": conanfile
    }
Exemple #5
0
    def test_catalyst(self, arch):
        profile = textwrap.dedent("""
            include(default)
            [settings]
            os = Macos
            os.version = 12.0
            os.sdk = macosx
            os.subsystem = catalyst
            os.subsystem.ios_version = 13.1
            arch = {arch}
            """).format(arch=arch)

        self.t = TestClient()
        hello_h = gen_function_h(name="hello")
        hello_cpp = gen_function_cpp(name="hello")
        main_cpp = textwrap.dedent("""
            #include "hello.h"
            #include <TargetConditionals.h>
            #include <iostream>

            int main()
            {
            #if TARGET_OS_MACCATALYST
                std::cout << "running catalyst " << __IPHONE_OS_VERSION_MIN_REQUIRED << std::endl;
            #else
                #error "not building for Apple Catalyst"
            #endif
            }
            """)

        self.t.save({
            "Makefile": self.makefile,
            "hello.h": hello_h,
            "hello.cpp": hello_cpp,
            "app.cpp": main_cpp,
            "conanfile.py": self.conanfile_py,
            "profile": profile
        })

        self.t.run("install . --profile:host=profile")
        self.t.run("build .")

        libhello = os.path.join(self.t.current_folder, "libhello.a")
        app = os.path.join(self.t.current_folder, "app")
        self.assertTrue(os.path.isfile(libhello))
        self.assertTrue(os.path.isfile(app))

        expected_arch = to_apple_arch(arch)

        self.t.run_command('lipo -info "%s"' % libhello)
        self.assertIn("architecture: %s" % expected_arch, self.t.out)

        self.t.run_command('lipo -info "%s"' % app)
        self.assertIn("architecture: %s" % expected_arch, self.t.out)

        if arch == "x86_64":
            self.t.run_command('"%s"' % app)
            self.assertIn("running catalyst 130100", self.t.out)
def test_apple_meson_toolchain_cross_compiling(arch, os_, os_version, sdk):
    profile = textwrap.dedent("""
    include(default)

    [settings]
    os = {os}
    os.version = {os_version}
    os.sdk = {os_sdk}
    arch = {arch}
    compiler = apple-clang
    compiler.version = 12.0
    compiler.libcxx = libc++

    [conf]
    tools.apple:sdk_path={sdk_path}
    """)

    xcrun = XCRun(None, sdk)
    sdk_path = xcrun.sdk_path

    hello_h = gen_function_h(name="hello")
    hello_cpp = gen_function_cpp(name="hello",
                                 preprocessor=["STRING_DEFINITION"])
    app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])
    profile = profile.format(os=os_,
                             os_version=os_version,
                             os_sdk=sdk,
                             arch=arch,
                             sdk_path=sdk_path)

    t = TestClient()
    t.save({
        "conanfile.py": _conanfile_py,
        "meson.build": _meson_build,
        "meson_options.txt": _meson_options_txt,
        "hello.h": hello_h,
        "hello.cpp": hello_cpp,
        "main.cpp": app,
        "profile_host": profile
    })

    t.run("install . --profile:build=default --profile:host=profile_host")
    t.run("build .")

    libhello = os.path.join(t.current_folder, "build", "libhello.a")
    assert os.path.isfile(libhello) is True
    demo = os.path.join(t.current_folder, "build", "demo")
    assert os.path.isfile(demo) is True

    lipo = xcrun.find('lipo')

    t.run_command('"%s" -info "%s"' % (lipo, libhello))
    assert "architecture: %s" % to_apple_arch(arch) in t.out

    t.run_command('"%s" -info "%s"' % (lipo, demo))
    assert "architecture: %s" % to_apple_arch(arch) in t.out
Exemple #7
0
def client():
    t = TestClient()
    cpp = gen_function_cpp(name="mydep")
    h = gen_function_h(name="mydep")
    cmake = gen_cmakelists(libname="mydep", libsources=["mydep.cpp"])
    conanfile = textwrap.dedent("""
        import os
        from conans import ConanFile
        from conan.tools.cmake import CMake

        class Conan(ConanFile):
            name = "mydep"
            version = "1.0"
            settings = "os", "arch", "compiler", "build_type"
            exports_sources = "*.cpp", "*.h", "CMakeLists.txt"
            generators = "CMakeToolchain"

            def build(self):
                cmake = CMake(self)
                cmake.configure()
                cmake.build()

            def package(self):
                self.copy("*.h", dst="include")
                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)

            def package_info(self):

                self.cpp_info.set_property("cmake_find_mode", "both")

                self.cpp_info.set_property("cmake_file_name", "MyDep")
                self.cpp_info.set_property("cmake_target_name", "MyDepTarget")

                self.cpp_info.set_property("cmake_module_file_name", "mi_dependencia")
                self.cpp_info.set_property("cmake_module_target_name", "mi_dependencia_target")
                self.cpp_info.set_property("cmake_module_target_namespace",
                                           "mi_dependencia_namespace")

                self.cpp_info.components["crispin"].libs = ["mydep"]
                self.cpp_info.components["crispin"].set_property("cmake_target_name",
                                                                 "MyCrispinTarget")
                self.cpp_info.components["crispin"].set_property("cmake_module_target_name",
                                                                 "mi_crispin_target")
        """)

    t.save({"conanfile.py": conanfile,
            "mydep.cpp": cpp,
            "mydep.h": h,
            "CMakeLists.txt": cmake})

    t.run("create .")
    return t
Exemple #8
0
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
Exemple #9
0
    def setUp(self):
        self.servers = {"default": TestServer()}
        client = TestClient(servers=self.servers,
                            users={"default": [("lasote", "mypass")]})
        cmake = gen_cmakelists(libname="hello",
                               libsources=["hello.cpp"],
                               libtype="SHARED",
                               appname="say_hello",
                               appsources=["main.cpp"])
        hello_h = gen_function_h(name="hello")
        hello_cpp = gen_function_cpp(name="hello",
                                     msg="Hello Tool!",
                                     includes=["hello"])
        main = gen_function_cpp(name="main",
                                includes=["hello"],
                                calls=["hello"])

        conanfile = textwrap.dedent("""
            from conans import ConanFile, CMake
            class Pkg(ConanFile):
                settings = "os", "compiler", "build_type", "arch"
                exports_sources = "*"

                def build(self):
                    cmake = CMake(self)
                    cmake.configure()
                    cmake.build()

                def package(self):
                    self.copy("*say_hello.exe", dst="bin", keep_path=False)
                    self.copy("*say_hello", dst="bin", keep_path=False)
                    self.copy(pattern="*.dll", dst="bin", keep_path=False)
                    self.copy(pattern="*.dylib", dst="lib", keep_path=False)
                    self.copy(pattern="*.so", dst="lib", keep_path=False)
        """)

        client.save({
            "conanfile.py": conanfile,
            "CMakeLists.txt": cmake,
            "main.cpp": main,
            "hello.cpp": hello_cpp,
            "hello.h": hello_h
        })
        client.run("create . Pkg/0.1@lasote/testing")
        client.run("upload Pkg* --all --confirm")
        client.run('remove "*" -f')
        client.run("search")
        self.assertIn("There are no packages", client.out)
    def test_android_meson_toolchain_cross_compiling(self, arch, expected_arch,
                                                     expected_class,
                                                     expected_machine):
        self.arch = arch

        hello_h = gen_function_h(name="hello")
        hello_cpp = gen_function_cpp(name="hello",
                                     preprocessor=["STRING_DEFINITION"])
        app = gen_function_cpp(name="main",
                               includes=["hello"],
                               calls=["hello"])

        self.t = TestClient()

        self.t.save({
            "conanfile.py": _conanfile_py,
            "meson.build": _meson_build,
            "meson_options.txt": _meson_options_txt,
            "hello.h": hello_h,
            "hello.cpp": hello_cpp,
            "main.cpp": app,
            "profile_host": self.profile()
        })

        self.t.run(
            "install . --profile:build=default --profile:host=profile_host")

        self.t.run("build .")

        libhello = os.path.join(self.t.current_folder, "build", "libhello.a")
        self.assertTrue(os.path.isfile(libhello))
        demo = os.path.join(self.t.current_folder, "build", "demo")
        self.assertTrue(os.path.isfile(demo))

        readelf = self._tool('readelf')
        objdump = self._tool('objdump')

        self.t.run_command('"%s" -f "%s"' % (objdump, libhello))
        self.assertIn("architecture: %s" % expected_arch, self.t.out)

        self.t.run_command('"%s" -h "%s"' % (readelf, demo))
        self.assertIn("Class:                             %s" % expected_class,
                      self.t.out)
        self.assertIn("OS/ABI:                            UNIX - System V",
                      self.t.out)
        self.assertIn(
            "Machine:                           %s" % expected_machine,
            self.t.out)
Exemple #11
0
def test_android_meson_toolchain_cross_compiling(arch, expected_arch):
    profile_host = textwrap.dedent("""
    include(default)

    [settings]
    os = Android
    os.api_level = 21
    arch = {arch}

    [conf]
    tools.android:ndk_path={ndk_path}
    """)
    hello_h = gen_function_h(name="hello")
    hello_cpp = gen_function_cpp(name="hello",
                                 preprocessor=["STRING_DEFINITION"])
    app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])
    profile_host = profile_host.format(
        arch=arch, ndk_path=os.getenv("TEST_CONAN_ANDROID_NDK"))

    client = TestClient()
    client.save({
        "conanfile.py": _conanfile_py,
        "meson.build": _meson_build,
        "meson_options.txt": _meson_options_txt,
        "hello.h": hello_h,
        "hello.cpp": hello_cpp,
        "main.cpp": app,
        "profile_host": profile_host
    })

    client.run("install . --profile:build=default --profile:host=profile_host")
    client.run("build .")
    content = client.load(os.path.join("conan_meson_cross.ini"))
    assert "needs_exe_wrapper = true" in content
    assert "Target machine cpu family: {}".format(
        expected_arch if expected_arch != "i386" else "x86") in client.out
    assert "Target machine cpu: {}".format(arch) in client.out
    libhello_name = "libhello.a" if platform.system(
    ) != "Windows" else "libhello.lib"
    libhello = os.path.join(client.current_folder, "build", libhello_name)
    demo = os.path.join(client.current_folder, "build", "demo")
    assert os.path.isfile(libhello)
    assert os.path.isfile(demo)

    # Check binaries architecture
    if platform.system() == "Darwin":
        client.run_command('objdump -f "%s"' % libhello)
        assert "architecture: %s" % expected_arch in client.out
def client_weird_lib_name():
    c = TestClient()
    conanfile = textwrap.dedent("""
        import os, platform
        from conans import ConanFile
        from conan.tools.cmake import CMake
        from conan.tools.layout import cmake_layout

        class Pkg(ConanFile):
            exports_sources = "CMakeLists.txt", "src/*"
            settings = "os", "compiler", "arch", "build_type"
            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("*.a", dst="lib", keep_path=False)
                ext = "a" if platform.system() != "Windows" else "lib"
                prefix = "lib" if platform.system() != "Windows" else ""
                os.chdir(os.path.join(self.package_folder, "lib"))
                os.rename("{}hello_0.1.{}".format(prefix, ext),
                          "{}[email protected].{}".format(prefix, ext))

            def package_info(self):
                self.cpp_info.libs = ["[email protected]"]
            """)

    hdr = gen_function_h(name="hello")
    src = gen_function_cpp(name="hello")
    cmake = gen_cmakelists(libname="hello_0.1", libsources=["src/hello.cpp"])

    c.save({
        "src/hello.h": hdr,
        "src/hello.cpp": src,
        "CMakeLists.txt": cmake,
        "conanfile.py": conanfile
    })
    c.run("create . hello/0.1@")
    return c
Exemple #13
0
def client():
    conanfile = textwrap.dedent("""
        import os
        from conans import ConanFile
        from conan.tools.cmake import CMake, CMakeToolchain

        class Library(ConanFile):
            name = "hello"
            version = "1.0"
            settings = 'os', 'arch', 'compiler', 'build_type'
            exports_sources = 'hello.h', '*.cpp', 'CMakeLists.txt'
            options = {'shared': [True, False]}
            default_options = {'shared': False}

            def generate(self):
                tc = CMakeToolchain(self, generator="Ninja")
                tc.generate()

            def build(self):
                cmake = CMake(self)
                cmake.configure()
                cmake.build()
                self.run(os.sep.join([".", "myapp"]))

            def package(self):
                cmake = CMake(self)
                cmake.install()
        """)

    test_client = TestClient(path_with_spaces=False)
    test_client.save({
        'conanfile.py':
        conanfile,
        "CMakeLists.txt":
        gen_cmakelists(libsources=["hello.cpp"],
                       appsources=["main.cpp"],
                       install=True),
        "hello.h":
        gen_function_h(name="hello"),
        "hello.cpp":
        gen_function_cpp(name="hello", includes=["hello"]),
        "main.cpp":
        gen_function_cpp(name="main", includes=["hello"], calls=["hello"])
    })
    return test_client
Exemple #14
0
    def test_meson_toolchain(self, arch, os_, os_version, sdk):
        self.xcrun = XCRun(None, sdk)
        self.arch = arch
        self.os = os_
        self.os_version = os_version

        hello_h = gen_function_h(name="hello")
        hello_cpp = gen_function_cpp(name="hello",
                                     preprocessor=["STRING_DEFINITION"])
        app = gen_function_cpp(name="main",
                               includes=["hello"],
                               calls=["hello"])

        self.t = TestClient()

        self.t.save({
            "conanfile.py": self._conanfile_py,
            "meson.build": self._meson_build,
            "meson_options.txt": self._meson_options_txt,
            "hello.h": hello_h,
            "hello.cpp": hello_cpp,
            "main.cpp": app,
            "profile_host": self.profile()
        })

        self.t.run(
            "install . --profile:build=default --profile:host=profile_host")

        self.t.run("build .")

        libhello = os.path.join(self.t.current_folder, "build", "libhello.a")
        self.assertTrue(os.path.isfile(libhello))
        demo = os.path.join(self.t.current_folder, "build", "demo")
        self.assertTrue(os.path.isfile(demo))

        lipo = self.xcrun.find('lipo')

        self.t.run_command('"%s" -info "%s"' % (lipo, libhello))
        self.assertIn("architecture: %s" % to_apple_arch(self.arch),
                      self.t.out)

        self.t.run_command('"%s" -info "%s"' % (lipo, demo))
        self.assertIn("architecture: %s" % to_apple_arch(self.arch),
                      self.t.out)
Exemple #15
0
    def test_makefile_arch(self, arch, os_, os_version):
        self.arch = arch
        self.os = os_
        self.os_version = os_version

        profile = textwrap.dedent("""
            include(default)
            [settings]
            os = {os}
            os.version = {os_version}
            arch = {arch}
            """).format(os=self.os, arch=self.arch, os_version=self.os_version)

        self.t = TestClient()
        hello_h = gen_function_h(name="hello")
        hello_cpp = gen_function_cpp(name="hello")
        main_cpp = gen_function_cpp(name="main",
                                    includes=["hello"],
                                    calls=["hello"])

        self.t.save({
            "Makefile": self.makefile,
            "hello.h": hello_h,
            "hello.cpp": hello_cpp,
            "main.cpp": main_cpp,
            "conanfile.py": self.conanfile_py,
            "profile": profile
        })

        self.t.run("install . --profile:host=profile")
        self.t.run("build .")

        libhello = os.path.join(self.t.current_folder, "libhello.a")
        app = os.path.join(self.t.current_folder, "app")
        self.assertTrue(os.path.isfile(libhello))
        self.assertTrue(os.path.isfile(app))

        expected_arch = to_apple_arch(self.arch)

        self.t.run_command('lipo -info "%s"' % libhello)
        self.assertIn("architecture: %s" % expected_arch, self.t.out)

        self.t.run_command('lipo -info "%s"' % app)
        self.assertIn("architecture: %s" % expected_arch, self.t.out)
Exemple #16
0
    def test_build(self):
        hello_h = gen_function_h(name="hello")
        hello_cpp = gen_function_cpp(name="hello",
                                     preprocessor=["STRING_DEFINITION"])
        app = gen_function_cpp(name="main",
                               includes=["hello"],
                               calls=["hello"])

        self.t.save({
            "conanfile.py": self._conanfile_py,
            "meson.build": self._meson_build,
            "meson_options.txt": self._meson_options_txt,
            "hello.h": hello_h,
            "hello.cpp": hello_cpp,
            "main.cpp": app
        })

        self.t.run("install . %s" % self._settings_str)

        content = self.t.load(
            os.path.join("build", "gen_folder", "conan_meson_native.ini"))

        self.assertIn("[project options]", content)
        self.assertIn("STRING_DEFINITION = 'Text'", content)
        self.assertIn("TRUE_DEFINITION = true", content)
        self.assertIn("FALSE_DEFINITION = false", content)
        self.assertIn("INT_DEFINITION = 42", content)
        self.assertIn("ARRAY_DEFINITION = ['Text1', 'Text2']", content)

        self.assertIn("[built-in options]", content)
        self.assertIn("buildtype = 'release'", content)

        self.t.run("build .")
        self.t.run_command(os.path.join("build", "demo"))

        self.assertIn("hello: Release!", self.t.out)
        self.assertIn("STRING_DEFINITION: Text", self.t.out)

        self.assertIn("[properties]", content)
        self.assertNotIn("needs_exe_wrapper", content)

        self._check_binary()
Exemple #17
0
def test_makefile_arch(config):
    arch, os_, os_version = config
    profile = textwrap.dedent("""
                include(default)
                [settings]
                os = {os}
                os.version = {os_version}
                arch = {arch}
                """).format(os=os_, arch=arch, os_version=os_version)

    t = TestClient()
    hello_h = gen_function_h(name="hello")
    hello_cpp = gen_function_cpp(name="hello")
    main_cpp = gen_function_cpp(name="main",
                                includes=["hello"],
                                calls=["hello"])

    t.save({
        "Makefile": makefile,
        "hello.h": hello_h,
        "hello.cpp": hello_cpp,
        "app.cpp": main_cpp,
        "conanfile.py": conanfile_py,
        "profile": profile
    })

    t.run("install . --profile:host=profile --profile:build=default")
    t.run("build .")

    libhello = os.path.join(t.current_folder, "libhello.a")
    app = os.path.join(t.current_folder, "app")
    assert os.path.isfile(libhello)
    assert os.path.isfile(app)

    expected_arch = to_apple_arch(arch)

    t.run_command('lipo -info "%s"' % libhello)
    assert "architecture: %s" % expected_arch in t.out

    t.run_command('lipo -info "%s"' % app)
    assert "architecture: %s" % expected_arch in t.out
Exemple #18
0
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
    from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout

    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}
        {requires}

        def config_options(self):
            if self.settings.os == "Windows":
                del self.options.fPIC

        def layout(self):
            cmake_layout(self)

        def generate(self):
            tc = CMakeToolchain(self)
            tc.generate()

        def build(self):
            cmake = CMake(self)
            cmake.configure()
            cmake.build()

        def package(self):
            cmake = CMake(self)
            cmake.install()

        def package_info(self):
            self.cpp_info.libs = ["{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="", generators="")
    })
    # 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"',
                             generators='generators = "CMakeDeps"')
        },
        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)

        find_package(libB CONFIG REQUIRED)

        add_executable(example src/example.cpp)
        target_link_libraries(example libB::libB)
    """)
    conanfile = textwrap.dedent("""
        [requires]
        libB/1.0

        [generators]
        CMakeDeps
        CMakeToolchain
    """)
    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" -DCMAKE_TOOLCHAIN_FILE="./conan_toolchain.cmake" .'
        ' -DCMAKE_BUILD_TYPE=Release && cmake --build . && ./example')
Exemple #19
0
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.debug["MYDEFINE_CONFIG"] = "MYDEF_DEBUG"
                tc.preprocessor_definitions.release["MYDEFINE_CONFIG"] = "MYDEF_RELEASE"
                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"])
    main = gen_function_cpp(name="main", includes=["app"], calls=["app"])

    cmakelist = textwrap.dedent("""
        cmake_minimum_required(VERSION 2.8)
        project(App C CXX)
        if(CONAN_TOOLCHAIN_INCLUDED AND CMAKE_VERSION VERSION_LESS "3.15")
            include("${CMAKE_BINARY_DIR}/conan_project_include.cmake")
        endif()
        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"
                                   ])
        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)
Exemple #20
0
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
Exemple #21
0
    def test_same_name_global_target_collision(self, generator):
        # https://github.com/conan-io/conan/issues/7889
        conanfile_tpl = textwrap.dedent("""
            from conans import ConanFile, CMake

            class Conan(ConanFile):
                name = "{name}"
                version = "1.0"
                settings = "os", "compiler", "build_type", "arch"
                generators = "cmake"
                exports_sources = "src/*"

                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):
                    self.cpp_info.names["{generator}"] = "nonstd"
                    self.cpp_info.filenames["{generator}"] = "{name}"
                    self.cpp_info.set_property("cmake_target_name", "nonstd", "{generator}")
                    self.cpp_info.set_property("cmake_file_name", "{name}", "{generator}")

                    self.cpp_info.components["1"].names["{generator}"] = "{name}"
                    self.cpp_info.components["1"].set_property("cmake_target_name",
                                                               "{name}", "{generator}")
                    self.cpp_info.components["1"].libs = ["{name}"]
            """)
        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, generator=generator)
            })
            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)

            include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
            conan_basic_setup()

            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, CMake

            class Conan(ConanFile):
                name = "middle"
                version = "1.0"
                settings = "os", "compiler", "build_type", "arch"
                generators = "cmake", "{}"
                exports_sources = "src/*"
                requires = "expected/1.0", "variant/1.0"

                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):
                    self.cpp_info.libs = ["middle"]
            """.format(generator))
        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, CMake

            class Conan(ConanFile):
                name = "consumer"
                version = "1.0"
                generators = "{}", "cmake"
                settings = "os", "compiler", "build_type", "arch"
                exports_sources = "src/*"
                requires = "middle/1.0"

                def build(self):
                    cmake = CMake(self)
                    cmake.configure(source_folder="src")
                    cmake.build()
                    self.run(os.path.join("bin", "main"))
            """.format(generator))
        cmakelists = textwrap.dedent("""
            set(CMAKE_CXX_COMPILER_WORKS 1)
            set(CMAKE_CXX_ABI_COMPILED 1)
            project(consumer CXX)
            cmake_minimum_required(VERSION 3.1)

            include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
            conan_basic_setup()

            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
Exemple #22
0
def test_same_names(generator):
    client = TestClient()
    conanfile_greetings = textwrap.dedent("""
        from conans import ConanFile, CMake

        class HelloConan(ConanFile):
            name = "hello"
            version = "0.0.1"
            settings = "os", "compiler", "build_type", "arch"
            generators = "cmake"
            exports_sources = "src/*"

            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):
                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)

        include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
        conan_basic_setup()

        add_library(hello hello.cpp)
        """)
    test_package_greetings_conanfile = textwrap.dedent("""
        import os
        from conans import ConanFile, CMake

        class HelloTestConan(ConanFile):
            settings = "os", "compiler", "build_type", "arch"
            generators = "cmake", "{}"

            def build(self):
                cmake = CMake(self)
                cmake.configure()
                cmake.build()

            def test(self):
                os.chdir("bin")
                self.run(".%sexample" % os.sep)
        """.format(generator))
    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)

        include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
        conan_basic_setup()

        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
Exemple #23
0
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
Exemple #24
0
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, CMake

        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)

            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.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"]
                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
Exemple #25
0
    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)
Exemple #26
0
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_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 .")
Exemple #28
0
    def test_makefile_arch(self, arch, os_, os_version):
        self.arch = arch
        self.os = os_
        self.os_version = os_version

        makefile = textwrap.dedent("""
            .PHONY: all
            all: libhello.a app

            app: main.o libhello.a
            	$(CXX) $(CFLAGS) -o app main.o -lhello -L.

            libhello.a: hello.o
            	$(AR) rcs libhello.a hello.o

            main.o: main.cpp
            	$(CXX) $(CFLAGS) -c -o main.o main.cpp

            hello.o: hello.cpp
            	$(CXX) $(CFLAGS) -c -o hello.o hello.cpp
            """)

        profile = textwrap.dedent("""
            include(default)
            [settings]
            os = {os}
            os.version = {os_version}
            arch = {arch}
            """).format(os=self.os, arch=self.arch, os_version=self.os_version)

        conanfile_py = textwrap.dedent("""
            from conans import ConanFile, tools, AutoToolsBuildEnvironment


            class App(ConanFile):
                settings = "os", "arch", "compiler", "build_type"
                options = {"shared": [True, False], "fPIC": [True, False]}
                default_options = {"shared": False, "fPIC": True}

                def config_options(self):
                    if self.settings.os == "Windows":
                        del self.options.fPIC

                def build(self):
                    env_build = AutoToolsBuildEnvironment(self)
                    env_build.make()
            """)

        self.t = TestClient()
        hello_h = gen_function_h(name="hello")
        hello_cpp = gen_function_cpp(name="hello")
        main_cpp = gen_function_cpp(name="main",
                                    includes=["hello"],
                                    calls=["hello"])

        self.t.save({
            "Makefile": makefile,
            "hello.h": hello_h,
            "hello.cpp": hello_cpp,
            "main.cpp": main_cpp,
            "conanfile.py": conanfile_py,
            "profile": profile
        })

        self.t.run("install . --profile:host=profile")
        self.t.run("build .")

        libhello = os.path.join(self.t.current_folder, "libhello.a")
        app = os.path.join(self.t.current_folder, "app")
        self.assertTrue(os.path.isfile(libhello))
        self.assertTrue(os.path.isfile(app))

        expected_arch = to_apple_arch(self.arch)

        self.t.run_command('lipo -info "%s"' % libhello)
        self.assertIn("architecture: %s" % expected_arch, self.t.out)

        self.t.run_command('lipo -info "%s"' % app)
        self.assertIn("architecture: %s" % expected_arch, self.t.out)
Exemple #29
0
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("""
            import os
            from conans import ConanFile, CMake

            class Conan(ConanFile):
                name = "{name}"
                version = "1.0"
                settings = "os", "compiler", "build_type", "arch"
                generators = "cmake"
                exports_sources = "src/*"

                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):
                    self.cpp_info.names["cmake_find_package_multi"] = "nonstd"
                    self.cpp_info.filenames["cmake_find_package_multi"] = "{name}"
                    self.cpp_info.components["1"].names["cmake_find_package_multi"] = "{name}"
                    self.cpp_info.components["1"].libs = ["{name}"]
            """)
        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)})
            client.run("create . {name}/1.0@".format(name=name))
        middle_cmakelists = textwrap.dedent("""
            project(middle)
            cmake_minimum_required(VERSION 3.1)

            include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
            conan_basic_setup()

            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 = textwrap.dedent("""
            #include "middle.h"
            #include "expected.h"
            #include "variant.h"

            int middle() {
                expected();
                variant();
                return 0;
            }
            """)
        middle_conanfile = textwrap.dedent("""
            import os
            from conans import ConanFile, CMake

            class Conan(ConanFile):
                name = "middle"
                version = "1.0"
                settings = "os", "compiler", "build_type", "arch"
                generators = "cmake", "cmake_find_package_multi"
                exports_sources = "src/*"
                requires = "expected/1.0", "variant/1.0"

                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):
                    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, CMake

            class Conan(ConanFile):
                name = "consumer"
                version = "1.0"
                generators = "cmake_find_package_multi", "cmake"
                settings = "os", "compiler", "build_type", "arch"
                exports_sources = "src/*"
                requires = "middle/1.0"

                def build(self):
                    cmake = CMake(self)
                    cmake.configure(source_folder="src")
                    cmake.build()
                    self.run(os.path.join("bin", "main"))
            """)
        cmakelists = textwrap.dedent("""
            project(consumer)
            cmake_minimum_required(VERSION 3.1)

            include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
            conan_basic_setup()

            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 = textwrap.dedent("""
            #include "middle.h"

            int main() {
                middle();
            }
            """)
        client.save({"conanfile.py": conanfile,
                     "src/CMakeLists.txt": cmakelists,
                     "src/main.cpp": main_cpp}, clean_first=True)
        client.run("create . consumer/1.0@")
        self.assertIn('Library middle found', client.out)
        self.assertIn('Library expected found', client.out)
        self.assertIn('Library variant found', client.out)
        self.assertIn("Middle link libraries: "
                      "$<$<CONFIG:Debug>:;>;$<$<CONFIG:MinSizeRel>:;>;$<$<CONFIG:RelWithDebInfo>:;>;"
                      "$<$<CONFIG:Release>:CONAN_LIB::middle_middle_RELEASE;nonstd::nonstd;$",
                      client.out)
        self.assertIn('expected/1.0: Hello World Release!', client.out)
        self.assertIn('variant/1.0: Hello World Release!', client.out)