|
Boost : |
Subject: Re: [boost] cmake target and binary name mangling
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-07-25 11:55:56
On 24/07/2017 21:27, Roger Leigh via Boost wrote:
> On 24/07/17 21:07, Niall Douglas via Boost wrote:
>>> Yea, I dont think we should mangle the logical target name at all.
>>> The user
>>> should be able to write `target_link_libraries(lib boost::foo)` and that
>>> should work for either static, shared, or header-only. Supporting
>>> multiple
>>> variants like shared and static in the same build tree are not
>>> supported with
>>> cmake, and creating workarounds to try and support them in the same
>>> build tree
>>> just creates problems. To build shared and static requires two build
>>> directories with cmake.
>>
>> This is provably untrue.
>
> It's entirely correct if you read what he was saying carefully.
If and only if you start from the cmake 2 design pattern of a build
directory per configuration. Which may be wise to choose for a long list
of *other* reasons given the wider picture, but the reason that it is
"natural", "correct", "modern" or any of the other things Paul is
claiming is provably untrue.
It for sure is not cmake 3 anyway. cmake 3's target based enhancements
are unnecessary extra work and complication if you can hard assume a
build directory per configuration. Just go ahead and set things based on
directory as you did in cmake 2 e.g. add_definitions(). Make life easier
on yourself. Skip all that cmake 3 target nonsense.
And then ask yourself why bother with cmake 3 altogether if you're not
using it? cmake 2.8.12 was perfectly fine. Let's use that, and lots of
custom macros. Plenty of large scale cmake build systems work perfectly
well with cmake 2.8.
> If you use a single target name "lib", this will be a shared library or
> a static library depending upon the build configuration (the
> BUILD_SHARED_LIBS option), or a header-only library.
>
> Supporting shared and static simultaneously isn't possible *with a
> single target name*. You would have to have e.g. "lib" and
> "lib-static". And on of the libraries e.g. the static library would
> need a mangled name since on Windows both the import library and the
> static library have a .lib extension and would clash with each other.
> Doing that is possible, but bad practice. The target names are mangled
> and not as usable downstream; downstream use has to commit to specific
> variants, and it's a lot less flexible. Choosing shared or static at
> configure time is the way cmake is designed to work, and it's the better
> choice here. (I have gone with the lib+list-static approach in the past
> and regretted it later.)
It is how cmake *was* designed to work in the 2000s. That was later
discovered to be suboptimal. cmake 3's improvements enable very
significant cmake scripting composability and reusability via a mostly
or purely declarative target based specification, including reuse by
unknown third party cmake.
But I get the feeling that nobody here is listening. You're all set in
your cmake ways and that's that. Before the SC made this decision,
myself and Peter did up a reasonable prototype use case example for
Boost cmake, I obviously think mine is better, but I still find his
acceptable as his design was sound. It used an impure declarative
design. It was okay. It was cmake 3 at least.
If Boost proceeds down a path of build directory per config, I will
fight it as hard as I can because I believe it to be seriously
suboptimal. But in the end, it comes down to whomever is willing to do
the work, and I am definitely not after my experience contributing to
the git migration. If those willing to do the work are incapable of
understanding cmake 3 design patterns, then Boost will have to adopt a
cmake 2 design instead. So long as they don't dress it up as being
"modern cmake", I'm fine with that.
As I said earlier right at the top of this email, it may well be judged
that whatever cmake a critical mass in the community can wrap their
heads around is considered better than what is optimal or modern. And
cmake 2.8 design patterns would have a critical mass far more than
modern cmake, not least in terms of documentation and tutorials.
So for all those *other reasons*, maybe a clean cmake 2.8 design is best
after all. Just stop calling it anything other than cmake 2, because
it's not. And don't pin the cmake version required to anything later
than cmake 2.8.12, because you don't need to.
Niall
-- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk