[erlang-questions] Deprecation warnings: OTP20 and OTP21 compatible code

Loïc Hoguin essen@REDACTED
Wed Jun 6 13:12:25 CEST 2018


It's worth noting that you did not have an issue with Cowboy, Ranch and 
friends. That's because the default policy in Erlang.mk is to NOT use 
warnings_as_errors for dependencies (and as a result this option is not 
included in the generated rebar.config).

This saves a lot of headaches. erlang:get_stacktrace/0 is notable in how 
widely used it is but issues with warnings_as_error have always existed 
for as long as I've been doing Erlang. Tools should really have a saner 
default policy for this. The build shouldn't break for your users just 
because a new warning was introduced.

On 06/06/2018 01:01 PM, Jesper Louis Andersen wrote:
> For a larger project, I stumbled into the following while trying to 
> build it on OTP-21.0-rc2-69-g9ae2044073:
> 
> * `erlexec` sets `warnings_as_errors` which fails due to 
> `erlang:get_stacktrace/0`
> * `meck` sets `warnings_as_errors` which fails due to 
> `erlang:get_stacktrace/0`
> * `ranch_proxy_protocol` sets `warnings as errors which fails due to 
> `ssl:ssl_accept/3`
> * `jose` sets `warnings_as_errors` which fails due to 
> `erlang:get_stacktrace/0`
> * `cowboy_cors` sets `warnings_as_errors` which fails due to 
> `erlang:get_stacktrace/0`
> 
> In effect, the warnings_as_errors is now a useless option on any system 
> which wants an upgrade-path from 20 to 21. If you start using the new 
> syntax straight away, you lock out users so they can't use 20 anymore, 
> and in any software project, some system has to support multiple 
> versions in order to do code upgrade[0].
> 
> Current fix for the above is to use rebar3's overrides:
> 
> {overrides,
>      [{override, erlexec, [{erl_opts, [debug_info]}]},
>       {override, ranch_proxy_protocol, [{erl_opts, [debug_info]}]},
>       {override, cowboy_cors, [{erl_opts, [debug_info]}]},
>       {override, jose, [{erl_opts, [debug_info]}]},
>       {override, meck, [{erl_opts, [debug_info]}]}]
> }.
> 
> which plugs the hole for now. But I'm a bit hesitant to just write those 
> projects since I'm not sure I have a good, easily implemented transition 
> path here. I think one might be able to use a bit of macro-magic to 
> accept the particular deprecation warning on 21 (only!) as 
> not-an-error-and-intended-for-now, so one can postpone the 21 upgrade a 
> bit in the software.
> 
> NOTE: This isn't a problem in fully vendored software where you control 
> everything. You can simply define when you upgrade and handle all 
> dependencies directly. But in a setting where other people rely on your 
> libraries, it is usually a bit more flexibile to allow them the ability 
> to run on the current version as well as the version one level back.
> 
> [0] Note this is somewhat similar to a code_change/3: Some function 
> needs to understand how to transform old data to new data and thus work 
> with both versions for a while.
> 
> On Tue, Jun 5, 2018 at 2:22 PM Danil Zagoskin <z@REDACTED 
> <mailto:z@REDACTED>> wrote:
> 
>     Hi!
> 
>     This is a shout of pain we got while preparing our project for
>     upcoming OTP release.
> 
>     The problem:
>       * We compile our code for production using warnings_as_errors
>     option. This helps us to keep the code tidy.
>       * OTP21 deprecates some functions (erlang:get_stacktrace/0,
>     ssl:ssl_accept/0, may be more)
>       * OTP20 does not support new API (catch C:R:S, ssl:handshake/2)
> 
>     So, to be able to go with both OTP20 and OTP21, we need some hacks.
> 
>     First thought: let's pass {nowarn_deprecated_function, [...]} with
>     Emakefile, letting old code
>     compile smootly in newer OTP.
>     But that cannot be done — this option is only recognized when given
>     in files.
> 
>     Second thought: OK, let's just add this option to all affected files.
>     But "Warning: erlang:get_stacktrace/0 is not a deprecated function"
> 
>     So, we needed to implement some preprocessor logic which adds nowarn
>     only when compiling with OTP21.
>     Luckily, there is a OTP_RELEASE var defined in OTP21:
>     -ifdef(OTP_RELEASE).
>     -compile({nowarn_deprecated_function, [{erlang, get_stacktrace, 0}]}).
>     -endif.
> 
>     Adding that to tens of files (large project, lots of dependencies
>     in-tree) seemed too ugly,
>     so we implemented a parse_transform which can be added to Emakefile.
> 
>     Parse transform itself:
>     https://gist.github.com/stolen/6a55221ffb906bde712cd939a729718d
> 
>     -- 
>     Danil Zagoskin | z@REDACTED <mailto:z@REDACTED>
>     _______________________________________________
>     erlang-questions mailing list
>     erlang-questions@REDACTED <mailto:erlang-questions@REDACTED>
>     http://erlang.org/mailman/listinfo/erlang-questions
> 
> 
> 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
> 

-- 
Loïc Hoguin
https://ninenines.eu



More information about the erlang-questions mailing list