Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] Is there a way to reference specific targets with the CMake find_package_multi generator? #7116

Closed
1 task done
akosik-anyvision opened this issue May 28, 2020 · 8 comments · Fixed by #7108
Closed
1 task done

Comments

@akosik-anyvision
Copy link

Hi,

I'm working on a project with optional conan support. I want fellow devs to be able decide whether or not to use conan, but still have all the cmake logic the same.

I've hit a problem with GTest because the conan find_package_multi generator only creates a GTest::GTest target, but GTest's own config doesn't usually export this target; it exports GTest::gtest, GTest::gmock, etc...

This forces me to use some conditional logic in the cmake file to try linking with both GTest::GTest and GTest::gtest, depending on the package manager.

Is there a way to reference specific library targets like GTest::gtest from conan?

I know you can do it with other cmake generators, but I see no mention of it for the find_package_multi generator.

@memsharded
Copy link
Member

This will be the "components" feature. It is on its way, we already added recipe support in past release, and this release will release support for cmake_find_package generators: #7108

Once this is out, the first step would be to contribute the components model to the gtest recipe in conan-center-index, and then, the same targets will be available.

I am considering that #7108 will close this issue (at least on the Conan CLI side, pending the gtest recipe update)

@memsharded
Copy link
Member

For info: it is possible to address specific targets today, but they have undocumented names like CONAN_LIB::gtest and CONAN_LIB::gmock. If you need a solution today, you can use them, otherwise I would recommend for the components feature.

@akosik-anyvision
Copy link
Author

There's an issue that a component cannot be named the same as a package. So you can't create GTest::gtest without changing the name of the package to GTest.

@memsharded
Copy link
Member

Not necessary to change the name of the package. The package_info() has a cpp_info.names["cmake_find_package"] = "GTest" that can define the GTest target even if the package is called gtest in lowercase. This is already implemented in the gtest/1.10.0 package (without user/channel) from ConanCenter.

@akosik-anyvision
Copy link
Author

Yep, I kept that line and it still complains. It seems to check the package name directly.

ERROR: 
	ConanException: gtest/1.10.0@ak/testing package_info(): Component name cannot be the same as the package name: 'gtest'

Here is my new version of package_info(). everything else should be the same as the gtest recipe in the conan center index.

    def package_info(self):
        self.cpp_info.names["cmake_find_package"] = "GTest"
        self.cpp_info.names["cmake_find_package_multi"] = "GTest"
        if self.options.build_gmock:
            self.cpp_info.components['gmock'].libs = ["{}{}".format('gmock', self._postfix)]
        if not self.options.no_main:
            self.cpp_info.components['gtest_main'].libs = ["{}{}".format('gtest_main', self._postfix)]
        self.cpp_info.components['gtest'].libs = ["{}{}".format('gtest', self._postfix)]

        if self.settings.os == "Linux":
            for component in self.cpp_info.components.values():
                component.system_libs.append("pthread")

        if self.options.shared:
            for component in self.cpp_info.components.values():
                component.defines.append("GTEST_LINKED_AS_SHARED_LIBRARY=1")

        if self.settings.compiler == "Visual Studio":
            if Version(self.settings.compiler.version.value) >= "15":
                for component in self.cpp_info.components.values():
                    component.defines.append("GTEST_LANG_CXX11=1")
                    component.defines.append("GTEST_HAS_TR1_TUPLE=0")

I can open a separate issue if this is unexpected behavior.

@memsharded memsharded modified the milestones: 1.26, 1.27 Jun 5, 2020
@memsharded
Copy link
Member

Sorry, this is not closed by #7108, because that only applies to cmake_find_package. Reopening for 1.27.

@memsharded memsharded reopened this Jun 5, 2020
@danimtb
Copy link
Member

danimtb commented Jun 30, 2020

@akosik-anyvision with #7259 merged, you will be able to use the components feature with the cmake_find_package_multi in the next 1.27 release.

In order to achieve the behavior you describe above, you will need to declare a "global" (or any other name) component with a different name that the package name. for example, something like this should work:

    def package_info(self):
        self.cpp_info.names["cmake_find_package"] = "GTest"
        self.cpp_info.names["cmake_find_package_multi"] = "GTest"
        ....
        self.cpp_info.components["global"].libs = ["{}{}".format('gtest', self._postfix)]  # gtest component
        self.cpp_info.components["global"].names["cmake_find_package_multi"] = "gtest"  # gtest component

The reason for this is that apart from components, we also provide a "global" target by default that depends on all the other component targets (gtest::gtest here or Gtest::Gtest).

With the approach above, you "override" the global target providing your own one.

@danimtb danimtb self-assigned this Jun 30, 2020
@danimtb danimtb removed this from the 1.27 milestone Jun 30, 2020
@jgsogo
Copy link
Contributor

jgsogo commented Aug 5, 2020

components are available to both generators 🎉

@jgsogo jgsogo closed this as completed Aug 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants