-
Notifications
You must be signed in to change notification settings - Fork 12
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
base: master
Are you sure you want to change the base?
Conversation
The
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 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? | ||
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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? |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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? |
There was a problem hiding this comment.
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? |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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.
On Mon, 2017-07-24 at 05:22 +0000, Michael H. Cox wrote:
@mikehcox commented on this pull request.
In doc/src/Intro.rst:
> @@ -76,6 +90,12 @@ For dependencies on other boost libraries, they can be
listed with the ``DEPENDS
config
)
+.. This is interesting. I like the reduction in boilerplate, but I question
the
+ 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.
Definitely agree with camio on this. See this Youtube video by Daniel
Pfeiffer
https://www.youtube.com/watch?v=bsXLMQ6WgIk
Having a set of guidelines, templates, and conventions on how to use modern
CMake (3.0+) is a better way to go than reinventing CMake's conventions.
I have actually removed this function. I totally agree, I don't want to write
functions that wraps cmake's current functions. My original goal was to make
something easier for developers who do not want to learn cmake, but this does
lead to maintenance problems.
I am trying to follow the model the Daniel has outlined in his Effective CMake
talk. However, this does lead to repeating the dependencies 3 times.
Now I have refactored this, so the user creates the library using standard
cmake, and then call `bcm_deloy` which will do the install and package
configuration. This does reduce down the repetition without reinventing cmake
conventions. You can see a comparison here:
http://bcm.readthedocs.io/en/latest/src/Building.html
Please let me know if you still think this is too much. I really want to avoid
creating cmake functions like what is used in trillinos or llvm that seems to
make the build more complicated. The ultimate goal is to build something that
can be merged into cmake eventually. So that the function we provide are
standard cmake functionality.
|
Overall, I have two big concerns about this approach:
Boost-specific workarounds.
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.