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

Sankel feedback on BCM #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

camio
Copy link

@camio camio commented Jun 13, 2017

Overall, I have two big concerns about this approach:

  • It is too tied to how Boost builds things and/or has incompatible
    Boost-specific workarounds.
  • BCM provides an alternative to the typical CMake conventions. I'd much rather
    see standard CMake commands being used when possible, even if this means
    there'll be more code and repetition. I've seen similar shorthands made in
    several different projects and it has always resulted in harder-to-approach
    code and leaky abstractions. For maintainability, conventional CMake combined
    with a good coding standard seems to work the best.

@pfultz2
Copy link
Member

pfultz2 commented Jun 13, 2017

It is too tied to how Boost builds things and/or has incompatible
Boost-specific workarounds.

The bcm_boost_package is very boost-specific, however, the rest of the functions can work with any project. I should provide an overview on how to use these modules in non-boost projects.

I've seen similar shorthands made in several different projects and it has always resulted in harder-to-approach code and leaky abstractions.

I've seen similar things as well(for example trilinos), but do you think these modules suffer the same issues?

I would like for boost libraries to be written in high-level way as it allows for us to generate a lot of things directly from that. For other libraries that are not boost-specific, they can use bcm_package or bcm_install_targets or bcm_auto_export where it makes sense, and use built-in cmake for everything else.

Of course, any abstraction can have the problems you mentioned, I want to make sure this is not the case here. Thanks for the feedback.

what the standard find_package does. Can't the targets exported by
'find_package' carry all the "package config" information needed for '.pg'
file generation?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to track the dependency, it works exactly as find_package does except it stores this in a variable, so when 'foo-config.cmake' is generated, it will generate a call find_dependency for each bcm_find_package that is called. This only happens with bcm_boost_package or bcm_package. When using bcm_auto_export the user will still need to explicitly define each dependency.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the PACKAGE_FOUND property could be used for this, however, this is a global property, so it will break superproject builds, I believe. Let me test this.

It could possible be named differently as well, since its only to be used for non-build dependencies.

@@ -18,10 +23,17 @@ bcm_package

This setups a non-boost package in cmake. This is similar to ``bcm_boost_package`` but with extra flexibility as it does not have boost specific conventions. This function creates a library target that will be installed and exported. In addition, the target will be setup to auto-link for the tests.

.. "setup to auto-link for the tests". This is a bit unclear. Maybe say
"Subsequent uses of 'bcm_test' will automatically include this target as a
dependency" or something along these lines.
Copy link
Member

@pfultz2 pfultz2 Jun 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think that sounds better. Although "subsequent uses" is not needed. If you write:

bcm_test(...)
bcm_package(...)

It will still use the package. This is because bcm_test links against the libraries or package at generation time.

.. option:: <package-name>

The name of the package. This is both the name of the library target and the cmake package config that can be used with ``find_package(<package-name>)``.

.. This is inconsistent with 'bcm_boost_package' below. Why does Boost have to
be special?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bcm_boost_package does it differently to enforce that a boost library's name starts with boost_, the find_package name starts with boost_, and the imported target starts with boost::. Alternatively, we could check that the name starts with boost_, if we want to enforce the naming. This could makes things more consistent and clearer.

@@ -30,6 +42,10 @@ Sets the version of the package.

This will parse the version from a header file. It will parse the macros defined in the header as ``<prefix>_<package-name>_VERSION_MAJOR``, ``<prefix>_<package-name>_VERSION_MINOR``, and ``<prefix>_<package-name>_VERSION_PATCH``. The ``prefix`` by default is the package name in all caps, but can be set using the ``VERSION_PREFIX`` option.

.. I'm a bit unsure about the above and following option. I think many codebases
use their own "version header" format and hardcoding this one is a but
unflexible.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but if a project uses a different version header format, then they can parse the header themselves and set the header:

# Parse custom version header
parse_header_version_header(MYVERSION)
bcm_setup_version(VERSION ${MYVERSION})

This format is what is used by some boost projects and kde projects as well(they provided similar functionality in their cmake modules: ecm_setup_version).

@@ -74,3 +90,5 @@ The source files to build the library.

This specifies internal boost dependencies, that is, dependencies on other boost libraries. The libraries should not be prefixed with ``boost_`` nor ``boost::``.

.. Why not use 'boost::' here? This special casing will be unobvious for casual
readers of code which uses this library.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good point. I didn't because it always needs boost dependencies, so it might be a good idea to always require it to make it explicit that its a boost dependency:

bcm_boost_package(boost_core
    VERSION 1.61.0
    DEPENDS
        boost::assert
        boost::config
)

I don't know if it always helps clarity as the package is declared with boost_ and the dependency that is used starts with boost::. Maybe it might be better to say boost_assert instead of boost::assert. I am not sure.

@@ -10,6 +10,9 @@ CXX_EXCEPTIONS

This property can be used to enable or disable C++ exceptions. This can be applied at global, directory or target scope. At global scope this defaults to On.

.. Why these particular C++ options? If we go down this route, won't someone
always be dissappointed because their particular option won't be here?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used by many tests in boosts, and there may need to be more added to support other options as well.

@@ -44,6 +52,10 @@ The BCM modules provide some high-level cmake functions to take care of all the

bcm_auto_pkgconfig()

.. The above snippet is mysterious for folks not accustomed to this library.
Where are the '.cpp' files being added? Where are the include files? What
do these functions do?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I need to explain this better. This relies on boost's directory structure to find the includes. Of course, Boost.Core does not have any source files, so that is why it is not mentioned here.

choice to go in such a different direction from the standard CMake way of
doing things. It strikes me as a possibly leaky abstraction where folks will
have a mix of code which uses both the CMake way and the BCM way; maintainers
will have to be familiar with both.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bcm_boost_package is setup this way so it can handle both superproject builds and modular builds. Ideally, we could remove DEPENDS and have it work like bcm_package, like this:

bcm_find_package(boost_assert)
bcm_find_package(boost_config)

bcm_boost_package(boost_core
    VERSION 1.61.0
)

target_link_libraries(boost_core boost::assert boost::config)

We will just need to hijack find_package for superproject builds.

Of course, I like the terse version more. I don't think its a problem mixing bcm functions with cmake functions. Its designed to do that. Also, I think it helps authors who are not familiar with cmake.

Finally, there is no tool to ensure the correctness of the above snippet. An author may do:

bcm_find_package(boost_assert)
bcm_find_package(boost_config)

bcm_boost_package(boost_core
    VERSION 1.61.0
)

target_link_libraries(boost_core boost::config)

Which is a mistake, but there is no way to detect this mistake.

Of course, for external dependencies, it needs to be done like above:

bcm_find_package(ZLib)

bcm_boost_package(boost_core
    VERSION 1.61.0
    DEPENDS
        assert
        config
)

target_link_libraries(boost_core Zlib::ZLib)

However, boost has very little external dependencies.

@pfultz2
Copy link
Member

pfultz2 commented Jul 24, 2017 via email

nemothenoone referenced this pull request in BoostCMake/cmake_modules Jun 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants