On Tue, May 2, 2017 at 9:20 AM, Maxim Uvarov <[email protected]>
wrote:

> On 05/02/17 14:43, Savolainen, Petri (Nokia - FI/Espoo) wrote:
> >
> >
> >> -----Original Message-----
> >> From: lng-odp [mailto:[email protected]] On Behalf Of
> maxim
> >> Sent: Tuesday, May 02, 2017 1:06 PM
> >> To: [email protected]
> >> Subject: Re: [lng-odp] [API-NEXT PATCH v2 0/4] Deprecated macros
> >>
> >> On ????., ??????. 12, 2017 at 10:33:24 -0500, Bill Fischofer wrote:
> >>> On Wed, Apr 12, 2017 at 10:05 AM, Dmitry Eremin-Solenikov
> >>> <[email protected]> wrote:
> >>>> On 12.04.2017 17:24, Bill Fischofer wrote:
> >>>>> On Wed, Apr 12, 2017 at 8:22 AM, Dmitry Eremin-Solenikov
> >>>>> <[email protected]> wrote:
> >>>>>> On 12.04.2017 15:21, Bill Fischofer wrote:
> >>>>>>> On Wed, Apr 12, 2017 at 7:11 AM, Dmitry Eremin-Solenikov
> >>>>>>> <[email protected]> wrote:
> >>>>>>>> On 12.04.2017 14:50, Savolainen, Petri (Nokia - FI/Espoo) wrote:
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>> -----Original Message-----
> >>>>>>>>>> From: Dmitry Eremin-Solenikov
> >> [mailto:[email protected]]
> >>>>>>>>>> Sent: Wednesday, April 12, 2017 2:32 PM
> >>>>>>>>>> To: Petri Savolainen <[email protected]>; lng-
> >>>>>>>>>> [email protected]
> >>>>>>>>>> Subject: Re: [lng-odp] [API-NEXT PATCH v2 0/4] Deprecated macros
> >>>>>>>>>>
> >>>>>>>>>> On 30.03.2017 16:58, Petri Savolainen wrote:
> >>>>>>>>>>> Replaced ODP_DEPRECATED macro (which was based on GCC
> >> __attribute__)
> >>>>>>>>>> with
> >>>>>>>>>>> compiler independent mechanism to control if deprecated API
> >> definitions
> >>>>>>>>>> are
> >>>>>>>>>>> visible to the application. ODP_DEPRECATED_API can be used both
> >> in
> >>>>>>>>>> application
> >>>>>>>>>>> and implementation to check if deprecated APIs are enabled. By
> >> default
> >>>>>>>>>> those are
> >>>>>>>>>>> disabled. Implementation may optimize the normal (new API) code
> >> path.
> >>>>>>>>>>>
> >>>>>>>>>>> ODP_DEPRECATE() macro is used to rename definitions, so that
> >> data
> >>>>>>>>>> structure
> >>>>>>>>>>> sizes are equal on both options. This enables implementation to
> >> serve
> >>>>>>>>>> both
> >>>>>>>>>>> options with a single library (if it wishes to do so).
> >>>>>>>>>>
> >>>>>>>>>> My main question remains as it was before: is it possible for
> >> the
> >>>>>>>>>> distribution to supply (unoptimized) ODP binary and headers and
> >> then for
> >>>>>>>>>> the application to select if it builds with or without
> >> deprecated API
> >>>>>>>>>> using that binary/headers?
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Yes. This patch set keeps the same struct fields/etc for both
> >> modes - only the names are scrambled (with __deprecated_ prefix) when
> >> deprecated APIs are not supported (the default).
> >>>>>>>>
> >>>>>>>> If so. Consider I have built and installed ODP headers & binary
> >> built
> >>>>>>>> with --enable-deprecated-api.
> >>>>>>>>
> >>>>>>>> How do I build:
> >>>>>>>>
> >>>>>>>> - application that uses deprecated API?
> >>>>>>>>   [I assume that the answer to this question is trivial: just
> >> build as is].
> >>>>>>>>
> >>>>>>>> - application that wants to be sure that it does not use
> >> deprecated API?
> >>>>>>>
> >>>>>>> As a practical matter, the support of deprecated APIs is similar to
> >>>>>>> the current provision for debug builds (--enable-debug and
> >>>>>>> --enable-debug-print in the current ./configure script). These
> >> really
> >>>>>>> are only of significance in the embedded space.
> >>>>>>
> >>>>>> Or for application developers.
> >>>>>>
> >>>>>>> In the cloud profile,
> >>>>>>> applications use whatever ODP release(s) are installed on the
> >> system
> >>>>>>> and the normal library-matchings are used to ensure that
> >> applications
> >>>>>>> built for Release X are paired with library .so files compatible
> >> with
> >>>>>>> that release. In this case, there are no deprecated APIs since
> >>>>>>> applications only move to newer ODP release levels when they are
> >>>>>>> ready. A cloud host system may specify the minimum ODP release
> >> level
> >>>>>>> available on it, and that determines when laggards need to upgrade.
> >>>>>>
> >>>>>> Yep. That is the deployed ODP release. It is optimized for speed, it
> >> is
> >>>>>> optimized for that exact platform, etc. I'm more thinking about app
> >>>>>> developers.
> >>>>>>
> >>>>>>>
> >>>>>>> So ODP will never ship a distribution that was configured with
> >>>>>>> --enable-deprecated-api. The only users of this feature will be
> >>>>>>> embedded applications that are customizing ODP to their own needs.
> >>>>>>
> >>>>>> I'm thinking about SuSe, Canonical, RedHat or anybody else shipping
> >> ODP
> >>>>>> to enable application  development on that platform. They would
> >> surely
> >>>>>> want to enable deprecated API (because otherwise old applications
> >>>>>> developed on that platform can stop building). But I'd expect that
> >> it is
> >>>>>> possible for the application developer to build an application
> >> checking
> >>>>>> that he does not use deprecated API anymore.
> >>>>>
> >>>>> This is really no different than supporting multiple levels of, say,
> >>>>> the GCC compiler. Or any other package. At some point the old
> >> releases
> >>>>> are no longer supported, but for some time you can have multiple
> >>>>> levels available at the same time and you just use the one that you
> >>>>> need.
> >>>>
> >>>> We might want to consult maintainers. But from my previous experience,
> >>>> supporting several 'levels' is a significant headache, that most of
> >>>> maintainers would like to stand away from. Moreover, even if several
> >>>> versions are provided by distro, app developers still would like to
> >> have
> >>>> 'migration' path. Consider the way deprecated API are implemented e.g.
> >>>> in Gtk, Qt or other app frameworks.
> >>>
> >>> The migration path is very straightforward: Don't move until you're
> >>> ready to move. When you are ready to move you change your application
> >>> to use the new preferred APIs.
> >>>
> >>> Will some wait until they are forced to move because the older
> >>> releases are no longer distributed? Sure. But that's just business as
> >>> usual. The point is that distributions can choose to distribute
> >>> whatever level(s) of ODP they wish. Our biggest problem is more likely
> >>> to be not that they won't distribute older releases but the lag in
> >>> getting them to distribute newer releases.
> >>>
> >>> It also points out that we really shouldn't be deprecating APIs in the
> >>> first place. These should be very rare instances, not something so
> >>> commonplace that we need a general framework to make it convenient to
> >>> deprecate a bunch of stuff each release. An API is "forever" and we
> >>> need to be mindful of that when we pour the concrete.
> >>>
> >>> As a practical matter, the main reason for deprecating an API is
> >>> because it is superseded by a better way to do something. But keeping
> >>> the older API around just means that applications don't get the
> >>> advantage of using the newer way until such time as we get tired of
> >>> carrying around the old baggage and the old forms get removed. So
> >>> deprecation is more a documentation than a code issue, which is all
> >>> that the original ODP_DEPRECATED() macros were intended to do.
> >>>
> >>> A likely more controversial issue is that we've stated that ODP makes
> >>> no ABI compatibility claims from one release to the next. It's assumed
> >>> that applications will recompile to move from ODP Release N to ODP
> >>> Release N+1. In ODP, ABI compatibility is a statement of compatibility
> >>> across different ODP implementations of a given API release, not
> >>> across multiple API releases.
> >>>
> >>
> >> I have some more thoughts on deprecating api / documentation.
> >>
> >> First lets clearly define what deprecation as:
> >> Feature of making api functions of struct element for limited support
> >> by ODP implementer in future.
> >
> >
> > No. Deprecation is part of API specification. For example,
> >
> > API spec v1.20 could define:
> >
> > typedef struct odp_foo_bar_t {
> >       /** This is foo*/
> >       uint8_t foo;
> > } odp_foo_bar_t;
> >
> >
> > API spec v1.30 could define:
> >
> > typedef struct odp_foo_bar_t {
> >       /** @deprecated Foo is deprecated, use bar instead. */
> >       uint8_t ODP_DEPRECATE(foo);
> >
> >       /** This is bar */
> >       uint8_t bar;
> > } odp_foo_bar_t;
> >
> >
> > By default, ODP_DEPRECATE() macro makes 'foo' unusable for the
> application. Each implementation may choose to support only the default
> (foo unusable), or also support all deprecated stuff (foo usable). API spec
> has only two modes: with or without deprecated stuff. If you compile with
> deprecated, the above example looks like this to the application:
> >
> > typedef struct odp_foo_bar_t {
> >       /** @deprecated Foo is deprecated, use bar instead. */
> >       uint8_t foo;
> >
> >       /** This is bar */
> >       uint8_t bar;
> > } odp_foo_bar_t;
> >
> >
> > ... and without deprecation (the default) it looks like this
> >
> > typedef struct odp_foo_bar_t {
> >       /** @deprecated Foo is deprecated, use bar instead. */
> >       uint8_t ____dont_use_this_since_its_deprecated_foo;
> >
> >       /** This is bar */
> >       uint8_t bar;
> > } odp_foo_bar_t;
> >
> >
> > Note: struct size does not change between the two modes.
> >
> >
> >
> >>
> >> In that case:
> >> - Upstream (Linaro/odp) has to provide common best practice way to do
> >>   that.
> >> - All api headers have to remain the same as main repo has, only some
> >>   function can be marked as deprecated.
> >> - Each ODP implementer can choose which functions he marks as deprecated
> >>   and for how long. The same for data structures.
> >
> >
> > Deprecated APIs are part of API spec. So, implementation cannot add or
> remove the number of deprecated APIs. It can just choose to support all of
> those, or none.
> >
> >
> >>
> >> What is delivery? How odp is shipped?
> >> - library + headers (more common for enterprise software).
> >> - git sources (more common for embedded).
> >
> > API spec is the primary deliverable of ODP project. Deprecation spec
> does not include how SW is delivered, it just defines those things in API
> that are invisible/visible to the application, when deprecation support is
> off/on. It's a business choice for an implementation / class of
> implementations to support deprecated APIs.
> >
> >
> >>
> >> In my understanding current approach with #idefs in api does not work
> >> due to it's impossible to quickly compare headers with main line code
> >> if everybody will start to mark unmark fields as deprecated
> >> (implementers and main line at the same time.)
> >
> > The spec does not contain #ifdef. It marks deprecated stuff with
> ODP_DEPRECATE(). An implementation must not add / remove those. The spec
> files are the same for everybody.
> >
> >
> >>
> >> I see a way how we can get more clear definition here:
> >> - ODP mainline provides documentation and ways how to mark deprecated
> >>   function or types.
> >
> > This is the ODP_DEPRECATE() macro.
> >
> >
> >> - ./configure has to have --enable-deprecated symbol
> >
> > It depends on implementation which build system is used, but obviously
> it needs a way to enable deprecated APIs if it supports those.
> >
> >
> >> - ./include/api headers have to be generated on ./configure stage
> >>   regarding if deprecated symbols are supported or not. That include
> >>   headers have to be shipped with library binary to package.
> >
> > This is no different from selecting if ABI compat is used. Both need to
> be selected at build time (at latest). Obviously, for distros we always
> build with ABI compat, we need to decide our position on deprecated APIs.
> Maybe those are always off (as the default mode suggests).
> >
> >
> >> - all deprecated api have to be in separate folder to be easy to remove
> >>   something like ./include/api-deprecated/
> >> - Doxygen note has to have all deprecated symbols documented.
> >
> >
> > Separate folders are not needed. API spec files mark deprecated
> definitions with both ODP_DEPRECATE() and @deprecated tag. Implementations
> re-use the spec files as-is, or otherwise make sure that the same
> definitions are visible/not-visible to the application through ODP API.
> >
> >
> > -Petri
> >
>
> So use case is only one - if you have source code for application based
> on api X and you want to jump to api level X+Y and if old api is
> supported as deprecated then app should compile and run without
> modifications. Right?
>
> In that case ABI compatibility more like will be broken but old API has
> to be supported.
>

Inter-release ABI compatibility is something ODP has explicitly said is not
a design goal. If we want to change that we need to discuss that as a
separate topic. The goal of ABI compatibility in ODP is for binary
application portability across different ODP implementations of the same
API level.


>
> Maxim.
>
>
> >>
> >>
> >> Now when we talk about real delivery we talk only about Long Term
> >> Support releases. When we do this release we can discuss which api
> >> people still want to support as deprecated. In that case we enable
> >> this apis in the build. But apps developers will know that these apis
> >> will no be valid on next release.
> >>
> >> In my understanding it has to solve patch original api headers with
> >> deprecated macro and makes maintains more easy.
> >>
> >> Best regards,
> >> Maxim.
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
>
>

Reply via email to