summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2022-06-29 13:32:01 +0200
committerBjörn Gustavsson <bjorn@erlang.org>2022-06-29 13:32:01 +0200
commit63abc6807d9998e8c44bc86cc673912b539ac397 (patch)
tree0bcb0efa91edb9408bb502714aad37aa9627b67f /lib
parentab0ea053e2053eb77c37480cdf82994ac972ebde (diff)
parent7f51a71aa483d9fa7781043a855040e45286c1ab (diff)
downloaderlang-63abc6807d9998e8c44bc86cc673912b539ac397.tar.gz
Merge branch 'maint'
* maint: make: Allow OTP to be built deterministically compiler: Make test_lib robust to +deterministic compiler: Make compiler forward +determinsitic flag to epp compiler: Make yecc respect +deterministic compiler: Make leex respect +deterministic compiler: Make asn1ct_gen respect +deterministic compiler: Make EPP respect +deterministic
Diffstat (limited to 'lib')
-rw-r--r--lib/asn1/doc/src/asn1ct.xml7
-rw-r--r--lib/asn1/src/Makefile12
-rw-r--r--lib/asn1/src/asn1ct_gen.erl18
-rw-r--r--lib/asn1/test/Makefile1
-rw-r--r--lib/asn1/test/asn1_SUITE.erl3
-rw-r--r--lib/asn1/test/test_compile_options.erl48
-rw-r--r--lib/common_test/test/Makefile1
-rw-r--r--lib/compiler/src/Makefile6
-rw-r--r--lib/compiler/src/compile.erl1
-rw-r--r--lib/compiler/test/Makefile1
-rw-r--r--lib/compiler/test/test_lib.erl3
-rw-r--r--lib/debugger/test/Makefile1
-rw-r--r--lib/diameter/src/Makefile12
-rw-r--r--lib/diameter/test/Makefile1
-rw-r--r--lib/edoc/test/Makefile1
-rw-r--r--lib/eldap/test/Makefile1
-rw-r--r--lib/erl_docgen/test/Makefile1
-rw-r--r--lib/eunit/test/Makefile1
-rw-r--r--lib/ftp/test/Makefile1
-rw-r--r--lib/inets/test/Makefile1
-rw-r--r--lib/kernel/test/Makefile1
-rw-r--r--lib/megaco/Makefile10
-rw-r--r--lib/megaco/src/app/megaco.mk6
-rw-r--r--lib/megaco/src/binary/depend.mk4
-rw-r--r--lib/megaco/test/Makefile2
-rw-r--r--lib/mnesia/test/Makefile1
-rw-r--r--lib/observer/test/Makefile1
-rw-r--r--lib/odbc/test/Makefile2
-rw-r--r--lib/os_mon/test/Makefile1
-rw-r--r--lib/parsetools/doc/src/leex.xml5
-rw-r--r--lib/parsetools/doc/src/yecc.xml5
-rw-r--r--lib/parsetools/src/leex.erl58
-rw-r--r--lib/parsetools/src/yecc.erl17
-rw-r--r--lib/parsetools/test/Makefile1
-rw-r--r--lib/parsetools/test/leex_SUITE.erl51
-rw-r--r--lib/parsetools/test/yecc_SUITE.erl52
-rw-r--r--lib/public_key/asn1/Makefile4
-rw-r--r--lib/public_key/test/Makefile1
-rw-r--r--lib/reltool/test/Makefile1
-rw-r--r--lib/runtime_tools/test/Makefile1
-rw-r--r--lib/sasl/test/Makefile1
-rw-r--r--lib/snmp/src/compile/Makefile4
-rw-r--r--lib/snmp/test/Makefile1
-rw-r--r--lib/ssh/test/Makefile1
-rw-r--r--lib/ssl/test/Makefile1
-rw-r--r--lib/stdlib/doc/src/epp.xml4
-rw-r--r--lib/stdlib/src/Makefile13
-rw-r--r--lib/stdlib/src/epp.erl43
-rw-r--r--lib/stdlib/test/Makefile1
-rw-r--r--lib/stdlib/test/epp_SUITE.erl65
-rw-r--r--lib/stdlib/test/epp_SUITE_data/deterministic_include.erl6
-rw-r--r--lib/stdlib/test/epp_SUITE_data/include/baz.hrl1
-rw-r--r--lib/syntax_tools/test/Makefile1
-rw-r--r--lib/tftp/test/Makefile1
-rw-r--r--lib/tools/test/Makefile1
-rw-r--r--lib/xmerl/src/Makefile9
-rw-r--r--lib/xmerl/test/Makefile1
57 files changed, 436 insertions, 63 deletions
diff --git a/lib/asn1/doc/src/asn1ct.xml b/lib/asn1/doc/src/asn1ct.xml
index e4c5a2a3ee..a9a71db629 100644
--- a/lib/asn1/doc/src/asn1ct.xml
+++ b/lib/asn1/doc/src/asn1ct.xml
@@ -83,7 +83,7 @@
legacy_bit_string | legacy_erlang_types |
noobj | {n2n, EnumTypeName} |{outdir, Dir} | {i, IncludeDir} |
asn1config | undec_rest | no_ok_wrapper |
- {macro_name_prefix, Prefix} | {record_name_prefix, Prefix} | verbose | warnings_as_errors</v>
+ {macro_name_prefix, Prefix} | {record_name_prefix, Prefix} | verbose | warnings_as_errors | deterministic</v>
<v>OldOption = ber | per</v>
<v>Reason = term()</v>
<v>Prefix = string()</v>
@@ -346,6 +346,11 @@ File3.asn</pre>
<item>
<p>Causes warnings to be treated as errors.</p>
</item>
+ <tag><c>deterministic</c></tag>
+ <item>
+ <p>Causes all non-deterministic options to be stripped from the
+ -asn1_info() attribute.</p>
+ </item>
</taglist>
<p>Any more option that is applied is passed to
the final step when the generated <c>.erl</c> file is compiled.
diff --git a/lib/asn1/src/Makefile b/lib/asn1/src/Makefile
index 6d02075576..9e13d02c8a 100644
--- a/lib/asn1/src/Makefile
+++ b/lib/asn1/src/Makefile
@@ -102,7 +102,13 @@ ERL_COMPILE_FLAGS += \
-I$(ERL_TOP)/lib/stdlib \
-Werror
-YRL_FLAGS =
+ifeq ($(ERL_DETERMINISTIC),yes)
+ YRL_FLAGS = +deterministic
+ DETERMINISM_FLAG = +deterministic
+else
+ YRL_FLAGS =
+ DETERMINISM_FLAG =
+endif
# ----------------------------------------------------
# Targets
@@ -182,10 +188,10 @@ asn1ct_rtt.erl: prepare_templates.$(EMULATOR) $(RT_TEMPLATES_TARGET)
$(RT_TEMPLATES_TARGET)
prepare_templates.$(EMULATOR): prepare_templates.erl
- $(V_ERLC) prepare_templates.erl
+ $(V_ERLC) $(DETERMINISM_FLAG) prepare_templates.erl
asn1rtt_%.$(EMULATOR): asn1rtt_%.erl
- $(V_ERLC) +debug_info $<
+ $(V_ERLC) +debug_info $(DETERMINISM_FLAG) $<
$(EVAL_CT_MODULES:%=%.erl): prepare_templates.$(EMULATOR) \
$(EBIN)/asn1ct_rtt.$(EMULATOR) \
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index 7f83ae63fd..88dc88487d 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -1327,9 +1327,25 @@ gen_head(#gen{options=Options}=Gen, Mod, Hrl) ->
0 -> ok;
_ -> emit(["-include(\"",Mod,".hrl\").",nl])
end,
+ Deterministic = proplists:get_bool(deterministic, Options),
+ Options1 =
+ case Deterministic of
+ true ->
+ %% compile:keep_compile_option will filter some of these
+ %% out of generated .beam files, but this will keep
+ %% them out of the generated .erl files
+ lists:filter(
+ fun({cwd, _}) -> false;
+ ({outdir, _}) -> false;
+ ({i, _}) -> false;
+ (_) -> true end,
+ Options);
+ false ->
+ Options
+ end,
emit(["-asn1_info([{vsn,'",asn1ct:vsn(),"'},",nl,
" {module,'",Mod,"'},",nl,
- " {options,",io_lib:format("~p",[Options]),"}]).",nl,nl]),
+ " {options,",io_lib:format("~p",[Options1]),"}]).",nl,nl]),
JerDefines = case Gen of
#gen{erule=jer} ->
true;
diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile
index 58f7b294f3..de2a38e752 100644
--- a/lib/asn1/test/Makefile
+++ b/lib/asn1/test/Makefile
@@ -138,6 +138,7 @@ RELSYSDIR = $(RELEASE_PATH)/asn1_test
# FLAGS
# ----------------------------------------------------
ERL_COMPILE_FLAGS += +warnings_as_errors +nowarn_export_all
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
# ----------------------------------------------------
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
index eeb5253c32..2a02f08a95 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -1062,7 +1062,8 @@ test_compile_options(Config) ->
ok = test_compile_options:noobj(Config),
ok = test_compile_options:record_name_prefix(Config),
ok = test_compile_options:verbose(Config),
- ok = test_compile_options:maps(Config).
+ ok = test_compile_options:maps(Config),
+ ok = test_compile_options:determinism(Config).
testDoubleEllipses(Config) -> test(Config, fun testDoubleEllipses/3).
testDoubleEllipses(Config, Rule, Opts) ->
diff --git a/lib/asn1/test/test_compile_options.erl b/lib/asn1/test/test_compile_options.erl
index f9997d37d0..45e8f39d39 100644
--- a/lib/asn1/test/test_compile_options.erl
+++ b/lib/asn1/test/test_compile_options.erl
@@ -22,10 +22,11 @@
-module(test_compile_options).
-include_lib("common_test/include/ct.hrl").
+-include_lib("stdlib/include/assert.hrl").
-export([wrong_path/1,comp/2,path/1,noobj/1,
- record_name_prefix/1,verbose/1,maps/1]).
+ record_name_prefix/1,verbose/1,maps/1,determinism/1]).
%% OTP-5689
wrong_path(Config) ->
@@ -150,6 +151,51 @@ do_maps(Erule, InFile, OutDir) ->
ok.
+determinism(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir,Config),
+ OutDir = proplists:get_value(priv_dir,Config),
+ Asn1File = filename:join([DataDir,"Comment.asn"]),
+ ErlFile = filename:join([OutDir,"Comment.erl"]),
+
+ ContainsNonDeterministicOptions =
+ fun
+ ({attribute,_Anno,asn1_info,Elems}) ->
+ lists:any(
+ fun
+ ({options, Opts}) ->
+ lists:any(fun ({i, _}) -> true; (_) -> false end, Opts)
+ andalso
+ lists:any(fun ({outdir, _}) -> true; (_) -> false end, Opts)
+ andalso
+ lists:any(fun ({cwd, _}) -> true; (_) -> false end, Opts);
+ (_) ->
+ false
+ end,
+ Elems);
+ (_) ->
+ false
+ end,
+
+ BaseOptions = [{i,DataDir},{outdir,OutDir},{cwd,DataDir},noobj],
+
+ %% Test deterministic compile
+ ok = asn1ct:compile(Asn1File, BaseOptions ++ [deterministic]),
+ {ok, List1} = epp:parse_file(ErlFile, [{includes, [DataDir]},
+ {source_name, "Comment.erl"}]),
+ ?assertNot(lists:any(ContainsNonDeterministicOptions, List1),
+ "Expected no debugging option values (i, outdir, cwd) in asn1_info attribute " ++
+ "in deterministic mode"),
+
+ %% Test non-deterministic compile
+ ok = asn1ct:compile(Asn1File, BaseOptions),
+ {ok, List2} = epp:parse_file(ErlFile, [{includes, [DataDir]},
+ {source_name, "Comment.erl"}]),
+ ?assert(lists:any(ContainsNonDeterministicOptions, List2),
+ "Expected debugging option values (i, outdir, cwd) in asn1_info attribute " ++
+ "in non-deterministic mode"),
+ ok.
+
+
outfiles_check(OutDir) ->
outfiles_check(OutDir,outfiles1()).
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile
index 4cc10cbdcc..1af9990bb7 100644
--- a/lib/common_test/test/Makefile
+++ b/lib/common_test/test/Makefile
@@ -99,6 +99,7 @@ RELSYSDIR = $(RELEASE_PATH)/common_test_test
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index 57c099601d..8b124d138b 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -138,6 +138,12 @@ ERL_COMPILE_FLAGS += -Werror
ERL_COMPILE_FLAGS += +inline +warn_unused_import \
-I../../stdlib/include -I$(EGEN) -W +warn_missing_spec
+ifeq ($(ERL_DETERMINISTIC),yes)
+ DETERMINISM_FLAG = +deterministic
+else
+ DETERMINISM_FLAG =
+endif
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index da388e4bce..771be26765 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1023,6 +1023,7 @@ do_parse_module(DefEncoding, #compile{ifile=File,options=Opts,dir=Dir}=St) ->
R = epp:parse_file(File,
[{includes,[".",Dir|inc_paths(Opts)]},
{source_name, SourceName},
+ {deterministic, member(deterministic, Opts)},
{macros,pre_defs(Opts)},
{default_encoding,DefEncoding},
{location,StartLocation},
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index 37fb570154..8e145ae136 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -168,6 +168,7 @@ RELSYSDIR = $(RELEASE_PATH)/compiler_test
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS += +clint +clint0 +ssalint
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl
index 4f24310d15..7182dd6555 100644
--- a/lib/compiler/test/test_lib.erl
+++ b/lib/compiler/test/test_lib.erl
@@ -82,7 +82,8 @@ uniq() ->
opt_opts(Mod) ->
Comp = Mod:module_info(compile),
- {options,Opts} = lists:keyfind(options, 1, Comp),
+ %% `options` may not be set at all if +deterministic is enabled.
+ Opts = proplists:get_value(options, Comp, []),
lists:filter(fun
(debug_info) -> true;
(dialyzer) -> true;
diff --git a/lib/debugger/test/Makefile b/lib/debugger/test/Makefile
index 14186798f0..015b5f9c29 100644
--- a/lib/debugger/test/Makefile
+++ b/lib/debugger/test/Makefile
@@ -71,6 +71,7 @@ RELSYSDIR = $(RELEASE_PATH)/debugger_test
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/diameter/src/Makefile b/lib/diameter/src/Makefile
index 6dd3667a46..75e23d4191 100644
--- a/lib/diameter/src/Makefile
+++ b/lib/diameter/src/Makefile
@@ -122,6 +122,12 @@ ERL_COMPILE_FLAGS += \
# -pa is to be able to include_lib from the include directory: the
# path must contain the application name.
+ifeq ($(ERL_DETERMINISTIC),yes)
+ DETERMINISM_FLAG = +deterministic
+else
+ DETERMINISM_FLAG =
+endif
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
@@ -152,7 +158,7 @@ $(filter-out opt, $(TYPES)):
# The dictionary parser.
gen/$(DICT_YRL).erl: compiler/$(DICT_YRL).yrl
$(yecc_verbose) \
- $(ERLC) -Werror -o $(@D) $<
+ $(ERLC) -Werror $(DETERMINISM_FLAG) -o $(@D) $<
# Generate the app file.
$(APP_TARGET): $(APP_SRC) ../vsn.mk modules.mk
@@ -256,8 +262,8 @@ release_spec: opt
$(INSTALL_DATA) $(EXTERNAL_HRLS:%=../include/%) $(DICT_HRLS) \
"$(RELSYSDIR)/include"
$(INSTALL_DATA) $(DICTS:%=dict/%.dia) "$(RELSYSDIR)/src/dict"
- $(MAKE) $(TARGET_DIRS:%/=release_src_%)
- $(MAKE) $(EXAMPLE_DIRS:%/=release_examples_%)
+ $(MAKE) ERL_DETERMINISTIC=$(ERL_DETERMINISTIC) $(TARGET_DIRS:%/=release_src_%)
+ $(MAKE) ERL_DETERMINISTIC=$(ERL_DETERMINISTIC) $(EXAMPLE_DIRS:%/=release_examples_%)
$(TARGET_DIRS:%/=release_src_%): release_src_%:
$(INSTALL_DIR) "$(RELSYSDIR)/src/$*"
diff --git a/lib/diameter/test/Makefile b/lib/diameter/test/Makefile
index 53b5fd4618..98fb9ff652 100644
--- a/lib/diameter/test/Makefile
+++ b/lib/diameter/test/Makefile
@@ -59,6 +59,7 @@ ERL_COMPILE_FLAGS += +warn_export_vars \
-I ../include \
-I ../src/gen \
$(STRICT_FLAGS)
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
# ----------------------------------------------------
# Targets
diff --git a/lib/edoc/test/Makefile b/lib/edoc/test/Makefile
index 80906a9456..139ba8b8bd 100644
--- a/lib/edoc/test/Makefile
+++ b/lib/edoc/test/Makefile
@@ -27,6 +27,7 @@ RELSYSDIR = $(RELEASE_PATH)/edoc_test
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/eldap/test/Makefile b/lib/eldap/test/Makefile
index ba8fe0dfa9..61cad55c64 100644
--- a/lib/eldap/test/Makefile
+++ b/lib/eldap/test/Makefile
@@ -54,6 +54,7 @@ RELSYSDIR = $(RELEASE_PATH)/eldap_test
# FLAGS
# ----------------------------------------------------
ERL_COMPILE_FLAGS += $(INCLUDES) -pa $(ERL_TOP)/lib/eldap/ebin
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/erl_docgen/test/Makefile b/lib/erl_docgen/test/Makefile
index fe45b2a684..9af7824553 100644
--- a/lib/erl_docgen/test/Makefile
+++ b/lib/erl_docgen/test/Makefile
@@ -26,6 +26,7 @@ RELSYSDIR = $(RELEASE_PATH)/erl_docgen_test
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/eunit/test/Makefile b/lib/eunit/test/Makefile
index e2fbdf7241..1bd9c0a07c 100644
--- a/lib/eunit/test/Makefile
+++ b/lib/eunit/test/Makefile
@@ -45,6 +45,7 @@ RELSYSDIR = $(RELEASE_PATH)/eunit_test
# ----------------------------------------------------
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/ftp/test/Makefile b/lib/ftp/test/Makefile
index 71ddb3bc7c..4686d8f1bd 100644
--- a/lib/ftp/test/Makefile
+++ b/lib/ftp/test/Makefile
@@ -152,6 +152,7 @@ RELTESTSYSBINDIR = $(RELTESTSYSALLDATADIR)/bin
ERL_COMPILE_FLAGS += \
$(INCLUDES) \
$(FTP_FLAGS)
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
# ----------------------------------------------------
# Targets
diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile
index 16a1abaee7..414884a535 100644
--- a/lib/inets/test/Makefile
+++ b/lib/inets/test/Makefile
@@ -200,6 +200,7 @@ RELTESTSYSBINDIR = $(RELTESTSYSALLDATADIR)/bin
ERL_COMPILE_FLAGS += \
$(INCLUDES) \
$(INETS_FLAGS)
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
# ----------------------------------------------------
# Targets
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index 12e6c42f7c..130e626b56 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -159,6 +159,7 @@ RELSYSDIR = $(RELEASE_PATH)/kernel_test
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/megaco/Makefile b/lib/megaco/Makefile
index 5dc2955dd8..a1b7adc924 100644
--- a/lib/megaco/Makefile
+++ b/lib/megaco/Makefile
@@ -98,7 +98,13 @@ else
FLEX_SCANNER_REENTRANT_ENABLER = --enable-megaco-reentrant-flex-scanner
endif
-CONFIGURE_OPTS = $(FLEX_SCANNER_LINENO_ENABLER) $(FLEX_SCANNER_REENTRANT_ENABLER)
+ifeq ($(ERL_DETERMINISTIC),yes)
+ ERL_DETERMINISTIC_ENABLER = --enable-deterministic-build
+else
+ ERL_DETERMINISTIC_ENABLER = --disable-deterministic-build
+endif
+
+CONFIGURE_OPTS = $(FLEX_SCANNER_LINENO_ENABLER) $(FLEX_SCANNER_REENTRANT_ENABLER) $(ERL_DETERMINISTIC_ENABLER)
DIA_PLT = ./priv/plt/$(APPLICATION).plt
@@ -115,7 +121,7 @@ include $(ERL_TOP)/make/otp_subdir.mk
reconf:
(cd $(ERL_TOP) && \
- ./otp_build configure && \
+ ./otp_build configure $(ERL_DETERMINISTIC_ENABLER) && \
cd $(ERL_TOP)/../libraries/megaco)
conf: do_configure
diff --git a/lib/megaco/src/app/megaco.mk b/lib/megaco/src/app/megaco.mk
index a887dd42bc..d42fd0d7ed 100644
--- a/lib/megaco/src/app/megaco.mk
+++ b/lib/megaco/src/app/megaco.mk
@@ -42,6 +42,12 @@ ifeq ($(WARN_UNUSED_WARS), true)
ERL_COMPILE_FLAGS += +warn_unused_vars
endif
+ifeq ($(ERL_DETERMINISTIC),yes)
+ERL_COMPILE_FLAGS += +deterministic
+YRL_FLAGS += +deterministic
+XRL_FLAGS += +deterministic
+endif
+
MEGACO_APP_VSN_COMPILE_FLAGS = \
+'{parse_transform,sys_pre_attributes}' \
+'{attribute,insert,app_vsn,$(APP_VSN)}'
diff --git a/lib/megaco/src/binary/depend.mk b/lib/megaco/src/binary/depend.mk
index ca2872975c..d430d157c0 100644
--- a/lib/megaco/src/binary/depend.mk
+++ b/lib/megaco/src/binary/depend.mk
@@ -35,6 +35,10 @@ ifeq ($(MEGACO_INLINE_ASN1_RT),true)
ASN1_CT_OPTS += +inline
endif
+ifeq ($(ERL_DETERMINISTIC),yes)
+ASN1_CT_OPTS += +deterministic
+endif
+
BER_V1_FLAGS = $(ASN1_CT_OPTS) +asn1config
BER_V2_FLAGS = $(ASN1_CT_OPTS) +asn1config
BER_V3_FLAGS = $(ASN1_CT_OPTS) +asn1config
diff --git a/lib/megaco/test/Makefile b/lib/megaco/test/Makefile
index 57437e50a6..eced232a47 100644
--- a/lib/megaco/test/Makefile
+++ b/lib/megaco/test/Makefile
@@ -90,6 +90,8 @@ ERL_COMPILE_FLAGS += $(MEGACO_ERL_COMPILE_FLAGS)
# We have a behaviour in the test catalog (megaco_test_generator)
ERL_COMPILE_FLAGS += -pa ../../megaco/test
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
+
ERL_PATH = -pa ../../megaco/examples/simple \
-pa ../../megaco/ebin \
-pa ../../et/ebin
diff --git a/lib/mnesia/test/Makefile b/lib/mnesia/test/Makefile
index 378bcc44d0..c3fbad88ca 100644
--- a/lib/mnesia/test/Makefile
+++ b/lib/mnesia/test/Makefile
@@ -91,6 +91,7 @@ RELSYSDIR = $(RELEASE_PATH)/mnesia_test
# FLAGS
# ----------------------------------------------------
#ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/observer/test/Makefile b/lib/observer/test/Makefile
index 8c7ca2fcfc..114f77400f 100644
--- a/lib/observer/test/Makefile
+++ b/lib/observer/test/Makefile
@@ -52,6 +52,7 @@ RELSYSDIR = $(RELEASE_PATH)/observer_test
# ----------------------------------------------------
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS += +warnings_as_errors +nowarn_export_all
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/odbc/test/Makefile b/lib/odbc/test/Makefile
index 87caa54c61..ab184ac06b 100644
--- a/lib/odbc/test/Makefile
+++ b/lib/odbc/test/Makefile
@@ -72,6 +72,8 @@ RELSYSDIR = $(RELEASE_PATH)/odbc_test
ERL_COMPILE_FLAGS += $(INCLUDES) \
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
diff --git a/lib/os_mon/test/Makefile b/lib/os_mon/test/Makefile
index d8dc4e57c7..df7b606c06 100644
--- a/lib/os_mon/test/Makefile
+++ b/lib/os_mon/test/Makefile
@@ -55,6 +55,7 @@ RELSYSDIR = $(RELEASE_PATH)/os_mon_test
# ----------------------------------------------------
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/snmp/include
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
# ----------------------------------------------------
# Targets
diff --git a/lib/parsetools/doc/src/leex.xml b/lib/parsetools/doc/src/leex.xml
index 357ed86f44..d802e46b59 100644
--- a/lib/parsetools/doc/src/leex.xml
+++ b/lib/parsetools/doc/src/leex.xml
@@ -110,6 +110,11 @@
<item>
<p>Causes warnings to be treated as errors.</p>
</item>
+ <tag><c>{deterministic, boolean()}</c></tag>
+ <item>
+ <p>Causes generated -file() attributes to only include
+ the basename of the file path.</p>
+ </item>
</taglist>
<p>Any of the Boolean options can be set to <c>true</c> by
stating the name of the option. For example, <c>verbose</c>
diff --git a/lib/parsetools/doc/src/yecc.xml b/lib/parsetools/doc/src/yecc.xml
index 218cec5330..4d639d1f21 100644
--- a/lib/parsetools/doc/src/yecc.xml
+++ b/lib/parsetools/doc/src/yecc.xml
@@ -134,6 +134,11 @@
is <c>column</c>, the location includes a line number and
a column number. Default is <c>column</c>.
</item>
+ <tag><c>{deterministic, boolean()}</c></tag>
+ <item>
+ <p>Causes generated -file() attributes to only include the
+ basename of the file path.</p>
+ </item>
</taglist>
<p>Any of the Boolean options can be set to <c>true</c> by
stating the name of the option. For example, <c>verbose</c>
diff --git a/lib/parsetools/src/leex.erl b/lib/parsetools/src/leex.erl
index 15803b3b82..b764678516 100644
--- a/lib/parsetools/src/leex.erl
+++ b/lib/parsetools/src/leex.erl
@@ -78,9 +78,10 @@ compile(Input0, Output0,
Output = assure_extension(shorten_filename(Output0), ".erl"),
Includefile = lists:sublist(Includes, 1),
Werror = proplists:get_bool(warnings_as_errors, Specific),
+ Deterministic = proplists:get_bool(deterministic, Specific),
Opts = [{scannerfile,Output},{includefile,Includefile},{verbose,Verbose},
{report_errors,true},{report_warnings,WarnLevel > 0},
- {warnings_as_errors, Werror}],
+ {warnings_as_errors, Werror}, {deterministic, Deterministic}],
case file(Input, Opts) of
{ok, _} ->
ok;
@@ -117,6 +118,7 @@ file(File) -> file(File, []).
| {'scannerfile', Scannerfile :: file:filename()}
| {'verbose', boolean()}
| {'warnings_as_errors', boolean()}
+ | {'deterministic', boolean()}
| 'dfa_graph'
| 'report_errors' | 'report_warnings' | 'report'
| 'return_errors' | 'return_warnings' | 'return'
@@ -287,7 +289,7 @@ check_options(_Options, _, _L) ->
all_options() ->
[dfa_graph,includefile,report_errors,report_warnings,
return_errors,return_warnings,scannerfile,verbose,
- warnings_as_errors].
+ warnings_as_errors, deterministic].
default_option(dfa_graph) -> false;
default_option(includefile) -> [];
@@ -297,7 +299,8 @@ default_option(return_errors) -> false;
default_option(return_warnings) -> false;
default_option(scannerfile) -> [];
default_option(verbose) -> false;
-default_option(warnings_as_errors) -> false.
+default_option(warnings_as_errors) -> false;
+default_option(deterministic) -> false.
atom_option(dfa_graph) -> {dfa_graph,true};
atom_option(report_errors) -> {report_errors,true};
@@ -306,6 +309,7 @@ atom_option(warnings_as_errors) -> {warnings_as_errors,true};
atom_option(return_errors) -> {return_errors,true};
atom_option(verbose) -> {verbose,true};
atom_option(return_warnings) -> {return_warnings,true};
+atom_option(deterministic) -> {deterministic,true};
atom_option(Key) -> Key.
is_filename(T) ->
@@ -1362,7 +1366,8 @@ out_file(St0, DFA, DF, Actions, Code) ->
set_encoding(St0, Ofile),
try
output_encoding_comment(Ofile, St0),
- output_file_directive(Ofile, St0#leex.ifile, 0),
+ Deterministic = proplists:get_bool(deterministic, St0#leex.opts),
+ output_file_directive(Ofile, St0#leex.ifile, Deterministic, 0),
out_file(Ifile, Ofile, St0, DFA, DF, Actions,
Code, 1),
verbose_print(St0, "ok~n", []),
@@ -1400,15 +1405,18 @@ inc_file_name(Filename) ->
%% characters.
out_file(Ifile, Ofile, St, DFA, DF, Actions, Code, L) ->
+ Deterministic = proplists:get_bool(deterministic, St#leex.opts),
case io:get_line(Ifile, leex) of
- eof -> output_file_directive(Ofile, St#leex.ifile, L);
- {error, _} -> add_error(St#leex.ifile, {L, leex, cannot_parse}, St);
+ eof ->
+ output_file_directive(Ofile, St#leex.ifile, Deterministic, L);
+ {error, _} ->
+ add_error(St#leex.ifile, {L, leex, cannot_parse}, St);
Line ->
case string:slice(Line, 0, 5) of
"##mod" -> out_module(Ofile, St);
"##cod" -> out_erlang_code(Ofile, St, Code, L);
"##dfa" -> out_dfa(Ofile, St, DFA, Code, DF, L);
- "##act" -> out_actions(Ofile, St#leex.xfile, Actions);
+ "##act" -> out_actions(Ofile, St#leex.xfile, Deterministic, Actions);
_ -> io:put_chars(Ofile, Line)
end,
out_file(Ifile, Ofile, St, DFA, DF, Actions, Code, L+1)
@@ -1419,7 +1427,8 @@ out_module(File, St) ->
out_erlang_code(File, St, Code, L) ->
{CodeL,CodePos,_NCodeLines} = Code,
- output_file_directive(File, St#leex.xfile, CodeL),
+ Deterministic = proplists:get_bool(deterministic, St#leex.opts),
+ output_file_directive(File, St#leex.xfile, Deterministic, CodeL),
{ok,Xfile} = file:open(St#leex.xfile, [read]),
try
set_encoding(St, Xfile),
@@ -1429,7 +1438,7 @@ out_erlang_code(File, St, Code, L) ->
ok = file:close(Xfile)
end,
io:nl(File),
- output_file_directive(File, St#leex.ifile, L).
+ output_file_directive(File, St#leex.ifile, Deterministic, L).
file_copy(From, To) ->
case io:get_line(From, leex) of
@@ -1441,8 +1450,9 @@ file_copy(From, To) ->
out_dfa(File, St, DFA, Code, DF, L) ->
{_CodeL,_CodePos,NCodeLines} = Code,
+ Deterministic = proplists:get_bool(deterministic, St#leex.opts),
%% Three file attributes before this one...
- output_file_directive(File, St#leex.efile, L+(NCodeLines-1)+3),
+ output_file_directive(File, St#leex.efile, Deterministic, L+(NCodeLines-1)+3),
io:fwrite(File, "yystate() -> ~w.~n~n", [DF]),
foreach(fun (S) -> out_trans(File, S) end, DFA),
io:fwrite(File, "yystate(S, Ics, Line, Tlen, Action, Alen) ->~n", []),
@@ -1565,14 +1575,14 @@ pack_trans([Tr|Trs], Pt) -> % The default uninteresting case
pack_trans(Trs, Pt ++ [Tr]);
pack_trans([], Pt) -> Pt.
-%% out_actions(File, XrlFile, ActionList) -> ok.
+%% out_actions(File, XrlFile, Deterministic, ActionList) -> ok.
%% Write out the action table.
-out_actions(File, XrlFile, As) ->
+out_actions(File, XrlFile, Deterministic, As) ->
As1 = prep_out_actions(As),
foreach(fun (A) -> out_action(File, A) end, As1),
io:fwrite(File, "yyaction(_, _, _, _) -> error.~n", []),
- foreach(fun (A) -> out_action_code(File, XrlFile, A) end, As1).
+ foreach(fun (A) -> out_action_code(File, XrlFile, Deterministic, A) end, As1).
prep_out_actions(As) ->
map(fun ({A,empty_action}) ->
@@ -1603,14 +1613,14 @@ out_action(File, {A,_Code,Vars,Name,_Args,ArgsChars}) ->
end,
io:fwrite(File, " ~s(~s);~n", [Name, ArgsChars]).
-out_action_code(_File, _XrlFile, {_A,empty_action}) ->
+out_action_code(_File, _XrlFile, _Deterministic, {_A,empty_action}) ->
ok;
-out_action_code(File, XrlFile, {_A,Code,_Vars,Name,Args,ArgsChars}) ->
+out_action_code(File, XrlFile, Deterministic, {_A,Code,_Vars,Name,Args,ArgsChars}) ->
%% Should set the file to the .erl file, but instead assumes that
%% ?LEEXINC is syntactically correct.
io:fwrite(File, "\n-compile({inline,~w/~w}).\n", [Name, length(Args)]),
L = erl_scan:line(hd(Code)),
- output_file_directive(File, XrlFile, L-2),
+ output_file_directive(File, XrlFile, Deterministic, L-2),
io:fwrite(File, "~s(~s) ->~n", [Name, ArgsChars]),
io:fwrite(File, " ~ts\n", [pp_tokens(Code, L, File)]).
@@ -1710,12 +1720,18 @@ output_encoding_comment(_File, #leex{encoding = none}) ->
output_encoding_comment(File, #leex{encoding = Encoding}) ->
io:fwrite(File, <<"%% ~s\n">>, [epp:encoding_to_string(Encoding)]).
-output_file_directive(File, Filename, Line) ->
+output_file_directive(File, Filename, Deterministic, Line) ->
io:fwrite(File, <<"-file(~ts, ~w).\n">>,
- [format_filename(Filename, File), Line]).
-
-format_filename(Filename0, File) ->
- Filename = filename:flatten(Filename0),
+ [format_filename(Filename, File, Deterministic), Line]).
+
+format_filename(Filename0, File, Deterministic) ->
+ Filename =
+ case Deterministic of
+ true ->
+ filename:basename(filename:flatten(Filename0));
+ false ->
+ filename:flatten(Filename0)
+ end,
case enc(File) of
unicode -> io_lib:write_string(Filename);
latin1 -> io_lib:write_string_as_latin1(Filename)
diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl
index 5b2a9efe4d..7833c6a120 100644
--- a/lib/parsetools/src/yecc.erl
+++ b/lib/parsetools/src/yecc.erl
@@ -141,9 +141,10 @@ compile(Input0, Output0,
Output = shorten_filename(Output0),
Includefile = lists:sublist(Includes, 1),
Werror = proplists:get_bool(warnings_as_errors, Specific),
+ Deterministic = proplists:get_bool(deterministic, Specific),
Opts = [{parserfile,Output}, {includefile,Includefile}, {verbose,Verbose},
{report_errors, true}, {report_warnings, WarnLevel > 0},
- {warnings_as_errors, Werror}],
+ {warnings_as_errors, Werror}, {deterministic, Deterministic}],
case file(Input, Opts) of
{ok, _OutFile} ->
ok;
@@ -265,6 +266,7 @@ file(GrammarFile) ->
| {'parserfile', Parserfile :: file:filename()}
| {'verbose', boolean()}
| {'warnings_as_errors', boolean()}
+ | {'deterministic', boolean()}
| 'report_errors' | 'report_warnings' | 'report'
| 'return_errors' | 'return_warnings' | 'return'
| 'verbose' | 'warnings_as_errors'.
@@ -407,7 +409,7 @@ check_options(_Options, _, _L) ->
all_options() ->
[error_location, file_attributes, includefile, parserfile,
report_errors, report_warnings, return_errors, return_warnings,
- time, verbose, warnings_as_errors].
+ time, verbose, warnings_as_errors, deterministic].
default_option(error_location) -> column;
default_option(file_attributes) -> true;
@@ -419,7 +421,8 @@ default_option(return_errors) -> false;
default_option(return_warnings) -> false;
default_option(time) -> false;
default_option(verbose) -> false;
-default_option(warnings_as_errors) -> false.
+default_option(warnings_as_errors) -> false;
+default_option(deterministic) -> false.
atom_option(file_attributes) -> {file_attributes, true};
atom_option(report_errors) -> {report_errors, true};
@@ -429,6 +432,7 @@ atom_option(return_warnings) -> {return_warnings, true};
atom_option(time) -> {time, true};
atom_option(verbose) -> {verbose, true};
atom_option(warnings_as_errors) -> {warnings_as_errors, true};
+atom_option(deterministic) -> {deterministic, true};
atom_option(Key) -> Key.
is_filename(T) ->
@@ -2695,7 +2699,12 @@ nl(#yecc{outport = Outport, line = Line}=St) ->
St#yecc{line = Line + 1}.
format_filename(Filename0, St) ->
- Filename = filename:flatten(Filename0),
+ Deterministic = proplists:get_bool(deterministic, St#yecc.options),
+ Filename =
+ case Deterministic of
+ true -> filename:basename(filename:flatten(Filename0));
+ false -> filename:flatten(Filename0)
+ end,
case lists:keyfind(encoding, 1, io:getopts(St#yecc.outport)) of
{encoding, unicode} -> io_lib:write_string(Filename);
_ -> io_lib:write_string_as_latin1(Filename)
diff --git a/lib/parsetools/test/Makefile b/lib/parsetools/test/Makefile
index d494953f1e..23cb9709e1 100644
--- a/lib/parsetools/test/Makefile
+++ b/lib/parsetools/test/Makefile
@@ -42,6 +42,7 @@ RELSYSDIR = $(RELEASE_PATH)/parsetools_test
# ----------------------------------------------------
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl
index 09a6e026bd..bef048dc82 100644
--- a/lib/parsetools/test/leex_SUITE.erl
+++ b/lib/parsetools/test/leex_SUITE.erl
@@ -22,6 +22,7 @@
%-define(debug, true).
-include_lib("stdlib/include/erl_compile.hrl").
+-include_lib("stdlib/include/assert.hrl").
-include_lib("kernel/include/file.hrl").
-ifdef(debug).
@@ -39,7 +40,7 @@
init_per_testcase/2, end_per_testcase/2]).
-export([
- file/1, compile/1, syntax/1,
+ file/1, compile/1, syntax/1, deterministic/1,
pt/1, man/1, ex/1, ex2/1, not_yet/1,
line_wrap/1,
@@ -64,7 +65,7 @@ all() ->
[{group, checks}, {group, examples}, {group, tickets}, {group, bugs}].
groups() ->
- [{checks, [], [file, compile, syntax]},
+ [{checks, [], [file, compile, syntax, deterministic]},
{examples, [], [pt, man, ex, ex2, not_yet, unicode]},
{tickets, [], [otp_10302, otp_11286, otp_13916, otp_14285, otp_17023,
compiler_warnings]},
@@ -368,6 +369,42 @@ syntax(Config) when is_list(Config) ->
leex:file(Filename, Ret),
ok.
+deterministic(doc) ->
+ "Check leex respects the +deterministic flag.";
+deterministic(suite) -> [];
+deterministic(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.xrl"),
+ Scannerfile = filename:join(Dir, "file.erl"),
+ Mini = <<"Definitions.\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : {token,{word,TokenLine,TokenChars}}.\n"
+ "Erlang code.\n">>,
+ ok = file:write_file(Filename, Mini),
+
+ %% Generated leex scanners include the leexinc.hrl header file by default,
+ %% so we'll get a -file attribute corresponding to that include. In
+ %% deterministic mode, that include should only use the basename,
+ %% "leexinc.hrl", but otherwise, it should contain the full path.
+
+ %% Matches when OTP is not installed (e.g. /lib/parsetools/include/leexinc.hrl)
+ %% and when it is (e.g. /lib/parsetools-2.3.2/include/leexinc.hrl)
+ AbsolutePathSuffix = ".*/lib/parsetools.*/include/leexinc\.hrl",
+
+ ok = leex:compile(Filename, Scannerfile, #options{specific=[deterministic]}),
+ {ok, FormsDet} = epp:parse_file(Scannerfile,[]),
+ ?assertMatch(false, search_for_file_attr(AbsolutePathSuffix, FormsDet)),
+ ?assertMatch({value, _}, search_for_file_attr("leexinc\.hrl", FormsDet)),
+ file:delete(Scannerfile),
+
+ ok = leex:compile(Filename, Scannerfile, #options{}),
+ {ok, Forms} = epp:parse_file(Scannerfile,[]),
+ ?assertMatch({value, _}, search_for_file_attr(AbsolutePathSuffix, Forms)),
+ file:delete(Scannerfile),
+
+ file:delete(Filename),
+ ok.
pt(doc) ->
"Pushing back characters.";
@@ -1272,3 +1309,13 @@ extract(File, {error, Es, Ws}) ->
{errors, extract(File, Es), extract(File, Ws)};
extract(File, Ts) ->
lists:append([T || {F, T} <- Ts, F =:= File]).
+
+search_for_file_attr(PartialFilePathRegex, Forms) ->
+ lists:search(fun
+ ({attribute, _, file, {FileAttr, _}}) ->
+ case re:run(FileAttr, PartialFilePathRegex) of
+ nomatch -> false;
+ _ -> true
+ end;
+ (_) -> false end,
+ Forms).
diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl
index c0f03edd9e..e76b98f0f5 100644
--- a/lib/parsetools/test/yecc_SUITE.erl
+++ b/lib/parsetools/test/yecc_SUITE.erl
@@ -22,6 +22,7 @@
%-define(debug, true).
-include_lib("stdlib/include/erl_compile.hrl").
+-include_lib("stdlib/include/assert.hrl").
-ifdef(debug).
-define(config(X,Y), foo).
@@ -40,7 +41,7 @@
-export([app_test/1,
file/1, syntax/1, compile/1, rules/1, expect/1,
- conflicts/1,
+ conflicts/1, deterministic/1,
empty/1, prec/1, yeccpre/1, lalr/1, old_yecc/1,
other_examples/1,
@@ -70,7 +71,7 @@ all() ->
groups() ->
[{checks, [],
- [file, syntax, compile, rules, expect, conflicts]},
+ [file, syntax, compile, rules, expect, conflicts, deterministic]},
{examples, [],
[empty, prec, yeccpre, lalr, old_yecc, other_examples]},
{bugs, [],
@@ -926,6 +927,43 @@ conflicts(Config) when is_list(Config) ->
file:delete(Filename),
ok.
+deterministic(doc) ->
+ "Check yecc respects the +deterministic flag.";
+deterministic(suite) -> [];
+deterministic(Config) when is_list(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.yrl"),
+ Parserfile = filename:join(Dir, "file.erl"),
+ ok = file:write_file(Filename,
+ <<"Nonterminals nt.
+ Terminals t.
+ Rootsymbol nt.
+ nt -> t.">>),
+
+ %% Generated yecc parsers need to include the yeccpre.hrl
+ %% header file, so we'll get a -file attribute corresponding
+ %% to that include. In deterministic mode, that include should
+ %% only use the basename, "yeccpre.hrl", but otherwise, it should
+ %% contain the full path.
+
+ %% Matches when OTP is not installed (e.g. /lib/parsetools/include/yeccpre.hrl)
+ %% and when it is (e.g. /lib/parsetools-2.3.2/include/yeccpre.hrl)
+ AbsolutePathSuffix = "/lib/parsetools.*/include/yeccpre\.hrl",
+
+ ok = yecc:compile(Filename, Parserfile, #options{specific=[deterministic]}),
+ {ok, FormsDet} = epp:parse_file(Parserfile,[]),
+ ?assertMatch(false, search_for_file_attr(AbsolutePathSuffix, FormsDet)),
+ ?assertMatch({value, _}, search_for_file_attr("yeccpre\.hrl", FormsDet)),
+ file:delete(Parserfile),
+
+ ok = yecc:compile(Filename, Parserfile, #options{}),
+ {ok, Forms} = epp:parse_file(Parserfile,[]),
+ ?assertMatch({value, _}, search_for_file_attr(AbsolutePathSuffix, Forms)),
+ file:delete(Parserfile),
+
+ file:delete(Filename),
+ ok.
+
empty(doc) ->
"'$empty'.";
empty(suite) -> [];
@@ -2284,3 +2322,13 @@ process_list() ->
safe_second_element({_,Info}) -> Info;
safe_second_element(Other) -> Other.
+
+search_for_file_attr(PartialFilePathRegex, Forms) ->
+ lists:search(fun
+ ({attribute, _, file, {FileAttr, _}}) ->
+ case re:run(FileAttr, PartialFilePathRegex) of
+ nomatch -> false;
+ _ -> true
+ end;
+ (_) -> false end,
+ Forms).
diff --git a/lib/public_key/asn1/Makefile b/lib/public_key/asn1/Makefile
index d33e13fb14..c1adf58ed4 100644
--- a/lib/public_key/asn1/Makefile
+++ b/lib/public_key/asn1/Makefile
@@ -70,6 +70,10 @@ ERL_COMPILE_FLAGS += $(EXTRA_ERLC_FLAGS)
ASN_FLAGS = -bber +der +noobj +asn1config
+ifeq ($(ERL_DETERMINISTIC),yes)
+ ASN_FLAGS += +deterministic
+endif
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
diff --git a/lib/public_key/test/Makefile b/lib/public_key/test/Makefile
index 6c39c534d2..aa42cf281f 100644
--- a/lib/public_key/test/Makefile
+++ b/lib/public_key/test/Makefile
@@ -55,6 +55,7 @@ RELSYSDIR = $(RELEASE_PATH)/public_key_test
# FLAGS
# ----------------------------------------------------
ERL_COMPILE_FLAGS += $(INCLUDES)
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/reltool/test/Makefile b/lib/reltool/test/Makefile
index 789019cf7d..245c9c9f00 100644
--- a/lib/reltool/test/Makefile
+++ b/lib/reltool/test/Makefile
@@ -51,6 +51,7 @@ RELSYSDIR = $(RELEASE_PATH)/reltool_test
# FLAGS
# ----------------------------------------------------
ERL_COMPILE_FLAGS += -pa $(ERL_TOP)/lib/reltool/ebin/
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/runtime_tools/test/Makefile b/lib/runtime_tools/test/Makefile
index f899d53f7f..c9578d376e 100644
--- a/lib/runtime_tools/test/Makefile
+++ b/lib/runtime_tools/test/Makefile
@@ -31,6 +31,7 @@ RELSYSDIR = $(RELEASE_PATH)/runtime_tools_test
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS += -Werror
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/sasl/test/Makefile b/lib/sasl/test/Makefile
index 11c2a9e69f..adc5a927ac 100644
--- a/lib/sasl/test/Makefile
+++ b/lib/sasl/test/Makefile
@@ -58,6 +58,7 @@ RELSYSDIR = $(RELEASE_PATH)/sasl_test
# ----------------------------------------------------
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/sasl/src
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/snmp/src/compile/Makefile b/lib/snmp/src/compile/Makefile
index d37eaf9636..f255237a04 100644
--- a/lib/snmp/src/compile/Makefile
+++ b/lib/snmp/src/compile/Makefile
@@ -85,6 +85,10 @@ ERL_COMPILE_FLAGS += -I../../include \
YRL_FLAGS = -o .
+ifeq ($(ERL_DETERMINISTIC),yes)
+ YRL_FLAGS += +deterministic
+endif
+
# ----------------------------------------------------
# Targets
diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile
index ac25a0d0b3..8de1b1e80d 100644
--- a/lib/snmp/test/Makefile
+++ b/lib/snmp/test/Makefile
@@ -161,6 +161,7 @@ ERL_COMPILE_FLAGS += -I../../snmp/src/app \
+'{parse_transform,sys_pre_attributes}' \
+'{attribute,insert,app_vsn,$(APP_VSN)}' \
$(SNMP_FLAGS)
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
ERL_SNMP_FLAGS = $(SNMP_MIB_FLAGS) \
-I../priv/mibs
diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile
index e07806f488..908312f8de 100644
--- a/lib/ssh/test/Makefile
+++ b/lib/ssh/test/Makefile
@@ -98,6 +98,7 @@ RELSYSDIR = $(RELEASE_PATH)/ssh_test
INCLUDES = -I$(ERL_TOP)/lib/ssh/src
ERL_COMPILE_FLAGS += $(INCLUDES) -pa ../ebin
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
index 5a69aeb674..ac1318bd14 100644
--- a/lib/ssl/test/Makefile
+++ b/lib/ssl/test/Makefile
@@ -144,6 +144,7 @@ RELSYSDIR = $(RELEASE_PATH)/ssl_test
# running the target "targets".
# ----------------------------------------------------
ERL_COMPILE_FLAGS += $(INCLUDES)
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
# ----------------------------------------------------
# Targets
diff --git a/lib/stdlib/doc/src/epp.xml b/lib/stdlib/doc/src/epp.xml
index 6cd715c55c..c2c24ee34d 100644
--- a/lib/stdlib/doc/src/epp.xml
+++ b/lib/stdlib/doc/src/epp.xml
@@ -131,6 +131,10 @@
attributes inserted during preprocessing, you can do with
<c>{source_name, <anno>SourceName</anno>}</c>. If unset it will
default to the name of the opened file.</p>
+ <p>Setting <c>{deterministic, <anno>Enabled</anno>}</c> will
+ additionally reduce the file name of the implicit -file()
+ attributes inserted during preprocessing to only the basename
+ of the path.</p>
<p>If <c>extra</c> is specified in
<c><anno>Options</anno></c>, the return value is
<c>{ok, <anno>Epp</anno>, <anno>Extra</anno>}</c> instead
diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile
index 369a448fe5..761d6c4c28 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -166,6 +166,12 @@ endif
ERL_COMPILE_FLAGS += -Werror
ERL_COMPILE_FLAGS += -I../include -I../../kernel/include
+ifeq ($(ERL_DETERMINISTIC),yes)
+ DETERMINISM_FLAG = +deterministic
+else
+ DETERMINISM_FLAG =
+endif
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
@@ -192,16 +198,17 @@ primary_bootstrap_compiler: \
$(BOOTSTRAP_COMPILER)/ebin/io.beam \
$(BOOTSTRAP_COMPILER)/ebin/otp_internal.beam
+
$(BOOTSTRAP_COMPILER)/ebin/erl_parse.beam: erl_parse.yrl
$(gen_verbose)
- $(V_at)$(ERLC) -o $(BOOTSTRAP_COMPILER)/egen erl_parse.yrl
- $(V_at)$(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $(BOOTSTRAP_COMPILER)/egen/erl_parse.erl
+ $(V_at)$(ERLC) -o $(BOOTSTRAP_COMPILER)/egen $(DETERMINISM_FLAG) erl_parse.yrl
+ $(V_at)$(ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $(DETERMINISM_FLAG) $(BOOTSTRAP_COMPILER)/egen/erl_parse.erl
$(BOOTSTRAP_TOP)/lib/stdlib/egen/erl_parse.erl: erl_parse.yrl
$(yecc_verbose)$(ERLC) $(YRL_FLAGS) -o$(BOOTSTRAP_TOP)/lib/stdlib/egen erl_parse.yrl
$(BOOTSTRAP_COMPILER)/ebin/%.beam: %.erl
- $(V_ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $<
+ $(V_ERLC) -o $(BOOTSTRAP_COMPILER)/ebin $(DETERMINISM_FLAG) $<
# ----------------------------------------------------
# Special Build Targets
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index 4d0dde0f52..bdb0bc64a2 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -77,7 +77,8 @@
erl_scan_opts = [] :: [_],
features = [] :: [atom()],
else_reserved = false :: boolean(),
- fname = [] :: function_name_type()
+ fname = [] :: function_name_type(),
+ deterministic = false :: boolean()
}).
%% open(Options)
@@ -119,6 +120,7 @@ open(Name, Path, Pdm) ->
Options :: [{'default_encoding', DefEncoding :: source_encoding()} |
{'includes', IncludePath :: [DirectoryName :: file:name()]} |
{'source_name', SourceName :: file:name()} |
+ {'deterministic', Enabled :: boolean()} |
{'macros', PredefMacros :: macros()} |
{'name',FileName :: file:name()} |
{'location',StartLocation :: erl_anno:location()} |
@@ -623,6 +625,7 @@ init_server(Pid, FileName, Options, St0) ->
%% the default location is 1 for backwards compatibility, not {1,1}
AtLocation = proplists:get_value(location, Options, 1),
+ Deterministic = proplists:get_value(deterministic, Options, false),
St = St0#epp{delta=0, name=SourceName, name2=SourceName,
path=Path, location=AtLocation, macs=Ms1,
default_encoding=DefEncoding,
@@ -630,11 +633,12 @@ init_server(Pid, FileName, Options, St0) ->
[{text_fun, keep_ftr_keywords()},
{reserved_word_fun, ResWordFun}],
features = Features,
- else_reserved = ResWordFun('else')},
+ else_reserved = ResWordFun('else'),
+ deterministic = Deterministic},
From = wait_request(St),
Anno = erl_anno:new(AtLocation),
enter_file_reply(From, file_name(SourceName), Anno,
- AtLocation, code),
+ AtLocation, code, Deterministic),
wait_req_scan(St);
{error,E} ->
epp_reply(Pid, {error,E})
@@ -798,14 +802,15 @@ enter_file(NewName, Inc, From, St) ->
enter_file2(NewF, Pname, From, St0, AtLocation) ->
Anno = erl_anno:new(AtLocation),
- enter_file_reply(From, Pname, Anno, AtLocation, code),
+ enter_file_reply(From, Pname, Anno, AtLocation, code, St0#epp.deterministic),
#epp{macs = Ms0,
default_encoding = DefEncoding,
in_prefix = InPrefix,
erl_scan_opts = ScanOpts,
else_reserved = ElseReserved,
- features = Ftrs} = St0,
- Ms = Ms0#{'FILE':={none,[{string,Anno,Pname}]}},
+ features = Ftrs,
+ deterministic = Deterministic} = St0,
+ Ms = Ms0#{'FILE':={none,[{string,Anno,source_name(St0,Pname)}]}},
%% update the head of the include path to be the directory of the new
%% source file, so that an included file can always include other files
%% relative to its current location (this is also how C does it); note
@@ -820,16 +825,17 @@ enter_file2(NewF, Pname, From, St0, AtLocation) ->
features = Ftrs,
erl_scan_opts = ScanOpts,
else_reserved = ElseReserved,
- default_encoding=DefEncoding}.
+ default_encoding=DefEncoding,
+ deterministic=Deterministic}.
-enter_file_reply(From, Name, LocationAnno, AtLocation, Where) ->
+enter_file_reply(From, Name, LocationAnno, AtLocation, Where, Deterministic) ->
Anno0 = erl_anno:new(AtLocation),
Anno = case Where of
code -> Anno0;
generated -> erl_anno:set_generated(true, Anno0)
end,
Rep = {ok, [{'-',Anno},{atom,Anno,file},{'(',Anno},
- {string,Anno,Name},{',',Anno},
+ {string,Anno,source_name(Deterministic,Name)},{',',Anno},
{integer,Anno,get_line(LocationAnno)},{')',LocationAnno},
{dot,Anno}]},
epp_reply(From, Rep).
@@ -865,13 +871,13 @@ leave_file(From, St) ->
Ftrs = St#epp.features,
ElseReserved = St#epp.else_reserved,
ScanOpts = St#epp.erl_scan_opts,
- Ms = Ms0#{'FILE':={none,[{string,Anno,OldName2}]}},
+ Ms = Ms0#{'FILE':={none,[{string,Anno,source_name(St,OldName2)}]}},
NextSt = OldSt#epp{sstk=Sts,macs=Ms,uses=St#epp.uses,
in_prefix = InPrefix,
features = Ftrs,
else_reserved = ElseReserved,
erl_scan_opts = ScanOpts},
- enter_file_reply(From, OldName, Anno, CurrLoc, code),
+ enter_file_reply(From, OldName, Anno, CurrLoc, code, St#epp.deterministic),
case OldName2 =:= OldName of
true ->
ok;
@@ -879,7 +885,7 @@ leave_file(From, St) ->
NFrom = wait_request(NextSt),
OldAnno = erl_anno:new(OldLoc),
enter_file_reply(NFrom, OldName2, OldAnno,
- CurrLoc, generated)
+ CurrLoc, generated, St#epp.deterministic)
end,
wait_req_scan(NextSt);
[] ->
@@ -1463,9 +1469,9 @@ scan_file(Tokens0, Tf, From, St) ->
scan_file1([{'(',_Alp},{string,_As,Name},{',',_Ac},{integer,_Ai,Ln},{')',_Arp},
{dot,_Ad}], Tf, From, St) ->
Anno = erl_anno:new(Ln),
- enter_file_reply(From, Name, Anno, loc(Tf), generated),
+ enter_file_reply(From, Name, Anno, loc(Tf), generated, St#epp.deterministic),
Ms0 = St#epp.macs,
- Ms = Ms0#{'FILE':={none,[{string,line1(),Name}]}},
+ Ms = Ms0#{'FILE':={none,[{string,line1(),source_name(St,Name)}]}},
Locf = loc(Tf),
NewLoc = new_location(Ln, St#epp.location, Locf),
Delta = get_line(element(2, Tf))-Ln + St#epp.delta,
@@ -2084,3 +2090,12 @@ interpret_file_attr([Form0 | Forms], Delta, Fs) ->
[Form | interpret_file_attr(Forms, Delta, Fs)];
interpret_file_attr([], _Delta, _Fs) ->
[].
+
+-spec source_name(#epp{} | boolean(), file:filename_all()) -> file:filename_all().
+source_name(Deterministic, Name) when is_boolean(Deterministic) ->
+ case Deterministic of
+ true -> filename:basename(Name);
+ false -> Name
+ end;
+source_name(St, Name) ->
+ source_name(St#epp.deterministic, Name).
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index f030235046..b8e4d89996 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -122,6 +122,7 @@ RELSYSDIR = $(RELEASE_PATH)/stdlib_test
ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/kernel/include \
-I$(ERL_TOP)/lib/stdlib/include
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index 5d7e362c50..c62f6fa3c1 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -29,7 +29,8 @@
otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1, otp_10820/1,
otp_11728/1, encoding/1, extends/1, function_macro/1,
test_error/1, test_warning/1, otp_14285/1,
- test_if/1,source_name/1,otp_16978/1,otp_16824/1,scan_file/1,file_macro/1]).
+ test_if/1,source_name/1,otp_16978/1,otp_16824/1,scan_file/1,file_macro/1,
+ deterministic_include/1, nondeterministic_include/1]).
-export([epp_parse_erl_form/2]).
@@ -50,6 +51,7 @@ config(data_dir, _) ->
filename:absname("./epp_SUITE_data").
-else.
-include_lib("common_test/include/ct.hrl").
+-include_lib("stdlib/include/assert.hrl").
-export([init_per_testcase/2, end_per_testcase/2]).
init_per_testcase(_, Config) ->
@@ -70,7 +72,8 @@ all() ->
overload_mac, otp_8388, otp_8470, otp_8562,
otp_8665, otp_8911, otp_10302, otp_10820, otp_11728,
encoding, extends, function_macro, test_error, test_warning,
- otp_14285, test_if, source_name, otp_16978, otp_16824, scan_file, file_macro].
+ otp_14285, test_if, source_name, otp_16978, otp_16824, scan_file, file_macro,
+ deterministic_include, nondeterministic_include].
groups() ->
[{upcase_mac, [], [upcase_mac_1, upcase_mac_2]},
@@ -124,6 +127,64 @@ file_macro(Config) when is_list(Config) ->
"Other source" = FileA = FileB,
ok.
+deterministic_include(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ File = filename:join(DataDir, "deterministic_include.erl"),
+ {ok, List} = epp:parse_file(File, [{includes, [DataDir]},
+ {deterministic, true},
+ {source_name, "deterministic_include.erl"}]),
+
+ %% In deterministic mode, only basenames, rather than full paths, should
+ %% be written to the -file() attributes resulting from -include and -include_lib
+ ?assert(lists:any(fun
+ ({attribute,_Anno,file,{"baz.hrl",_Line}}) -> true;
+ (_) -> false
+ end,
+ List),
+ "Expected a basename in the -file attribute resulting from " ++
+ "including baz.hrl in deterministic mode."),
+ ?assert(lists:any(fun
+ ({attribute,_Anno,file,{"file.hrl",_Line}}) -> true;
+ (_) -> false
+ end,
+ List),
+ "Expected a basename in the -file attribute resulting from " ++
+ "including file.hrl in deterministic mode."),
+ ok.
+
+nondeterministic_include(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ File = filename:join(DataDir, "deterministic_include.erl"),
+ {ok, List} = epp:parse_file(File, [{includes, [DataDir]},
+ {source_name, "deterministic_include.erl"}]),
+
+ %% Outside of deterministic mode, full paths, should be written to
+ %% the -file() attributes resulting from -include and -include_lib
+ %% to make debugging easier.
+ %% We don't try to assume what the full absolute path will be in the
+ %% unit test, since that can depend on the environment and how the
+ %% test is executed. Instead, we just look for whether there is
+ %% the parent directory along with the basename at least.
+ IncludeAbsolutePathSuffix = filename:join("include","baz.hrl"),
+ ?assert(lists:any(fun
+ ({attribute,_Anno,file,{IncludePath,_Line}}) ->
+ lists:suffix(IncludeAbsolutePathSuffix,IncludePath);
+ (_) -> false
+ end,
+ List),
+ "Expected an absolute in the -file attribute resulting from " ++
+ "including baz.hrl outside of deterministic mode."),
+ IncludeLibAbsolutePathSuffix = filename:join("include","file.hrl"),
+ ?assert(lists:any(fun
+ ({attribute,_Anno,file,{IncludePath,_line}}) ->
+ lists:suffix(IncludeLibAbsolutePathSuffix,IncludePath);
+ (_) -> false
+ end,
+ List),
+ "Expected an absolute in the -file attribute resulting from " ++
+ "including file.hrl outside of deterministic mode."),
+ ok.
+
%%% Here is a little reimplementation of epp:parse_file, which times out
%%% after 4 seconds if the epp server doesn't respond. If we use the
%%% regular epp:parse_file, the test case will time out, and then epp
diff --git a/lib/stdlib/test/epp_SUITE_data/deterministic_include.erl b/lib/stdlib/test/epp_SUITE_data/deterministic_include.erl
new file mode 100644
index 0000000000..67763b29a0
--- /dev/null
+++ b/lib/stdlib/test/epp_SUITE_data/deterministic_include.erl
@@ -0,0 +1,6 @@
+-module(deterministic_include).
+
+-export([]).
+
+-include("include/baz.hrl").
+-include_lib("kernel/include/file.hrl").
diff --git a/lib/stdlib/test/epp_SUITE_data/include/baz.hrl b/lib/stdlib/test/epp_SUITE_data/include/baz.hrl
new file mode 100644
index 0000000000..c0ef7a6e51
--- /dev/null
+++ b/lib/stdlib/test/epp_SUITE_data/include/baz.hrl
@@ -0,0 +1 @@
+-define(BAZ, true).
diff --git a/lib/syntax_tools/test/Makefile b/lib/syntax_tools/test/Makefile
index 51fe2417b1..deee5ab814 100644
--- a/lib/syntax_tools/test/Makefile
+++ b/lib/syntax_tools/test/Makefile
@@ -27,6 +27,7 @@ RELSYSDIR = $(RELEASE_PATH)/syntax_tools_test
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/tftp/test/Makefile b/lib/tftp/test/Makefile
index 3eb0886f66..a3caf45321 100644
--- a/lib/tftp/test/Makefile
+++ b/lib/tftp/test/Makefile
@@ -152,6 +152,7 @@ RELTESTSYSBINDIR = $(RELTESTSYSALLDATADIR)/bin
ERL_COMPILE_FLAGS += \
$(INCLUDES) \
$(TFTP_FLAGS)
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
# ----------------------------------------------------
# Targets
diff --git a/lib/tools/test/Makefile b/lib/tools/test/Makefile
index 571fdd07e9..984568e4c5 100644
--- a/lib/tools/test/Makefile
+++ b/lib/tools/test/Makefile
@@ -54,6 +54,7 @@ RELSYSDIR = $(RELEASE_PATH)/tools_test
# ----------------------------------------------------
ERL_MAKE_FLAGS +=
ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
EBIN = .
diff --git a/lib/xmerl/src/Makefile b/lib/xmerl/src/Makefile
index 0a9f8391c7..e7e7c8e978 100644
--- a/lib/xmerl/src/Makefile
+++ b/lib/xmerl/src/Makefile
@@ -127,6 +127,11 @@ ERL_COMPILE_FLAGS += \
# +bin_opt_info
+ifeq ($(ERL_DETERMINISTIC),yes)
+ DETERMINISM_FLAG = +deterministic
+else
+ DETERMINISM_FLAG =
+endif
# ----------------------------------------------------
# Targets
@@ -173,10 +178,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
$(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
xmerl_xpath_parse.erl: xmerl_xpath_parse.yrl
- $(yecc_verbose)$(ERLC) -o $(ESRC) $<
+ $(yecc_verbose)$(ERLC) -o $(ESRC) $(DETERMINISM_FLAG) $<
xmerl_b64Bin.erl: xmerl_b64Bin.yrl
- $(yecc_verbose)$(ERLC) -o $(ESRC) $<
+ $(yecc_verbose)$(ERLC) -o $(ESRC) $(DETERMINISM_FLAG) $<
xmerl_sax_parser_list.erl: xmerl_sax_parser_list.erlsrc xmerl_sax_parser_base.erlsrc
$(gen_verbose)cat xmerl_sax_parser_list.erlsrc xmerl_sax_parser_base.erlsrc >$@
diff --git a/lib/xmerl/test/Makefile b/lib/xmerl/test/Makefile
index 49091a9a54..97180d8051 100644
--- a/lib/xmerl/test/Makefile
+++ b/lib/xmerl/test/Makefile
@@ -86,6 +86,7 @@ RELSYSDIR = $(RELEASE_PATH)/xmerl_test
# ----------------------------------------------------
ERL_COMPILE_FLAGS +=
+ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
# ----------------------------------------------------