You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
4.8 KiB

преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
  1. %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
  2. %% ex: ts=4 sw=4 ft=erlang et
  3. -module(erlc_rt).
  4. -export([files/0,
  5. run/1]).
  6. -include_lib("eunit/include/eunit.hrl").
  7. -define(MODULES,
  8. [first_xrl,
  9. first_yrl,
  10. first_erl,
  11. foo,
  12. foo_app,
  13. foo_sup,
  14. foo_test_worker,
  15. foo_worker,
  16. 'SIMPLE-ASN']).
  17. -define(BEAM_FILES,
  18. ["first_xrl.beam",
  19. "first_yrl.beam",
  20. "first_erl.beam",
  21. "foo.beam",
  22. "foo_app.beam",
  23. "foo_sup.beam",
  24. "foo_test_worker.beam",
  25. "foo_worker.beam",
  26. "SIMPLE-ASN.beam"]).
  27. files() ->
  28. [
  29. {copy, "../../rebar", "rebar"},
  30. {copy, "rebar.config", "rebar.config"},
  31. {copy, "rebar-no_debug_info.config", "rebar-no_debug_info.config"},
  32. {copy, "include", "include"},
  33. {copy, "extra-include", "extra-include"},
  34. {copy, "src", "src"},
  35. {copy, "extra-src", "extra-src"},
  36. {copy, "mibs", "mibs"},
  37. {copy, "asn1", "asn1"},
  38. {create, "ebin/foo.app", app(foo, ?MODULES)},
  39. %% deps
  40. {create, "deps/foobar/ebin/foobar.app", app(foobar, [foobar])},
  41. {copy, "foobar.erl", "deps/foobar/src/foobar.erl"}
  42. ].
  43. run(_Dir) ->
  44. ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])),
  45. ok = check_beams(true),
  46. ok = check_debug_info(true),
  47. MibResult = filename:join(["priv", "mibs", "SIMPLE-MIB.bin"]),
  48. ?assertMatch(true, filelib:is_regular(MibResult)),
  49. ?assertMatch({ok, _}, retest_sh:run("./rebar clean", [])),
  50. ok = check_beams(false),
  51. ?assertMatch(false, filelib:is_regular(MibResult)),
  52. ?assertMatch(
  53. {ok, _},
  54. retest_sh:run("./rebar -C rebar-no_debug_info.config compile", [])),
  55. ok = check_beams(true),
  56. ok = check_debug_info(false),
  57. ?assertMatch(true, filelib:is_regular(MibResult)),
  58. %% Regression test for https://github.com/rebar/rebar/issues/249
  59. %%
  60. %% Root cause: We didn't have per-project .rebar/erlcinfo but just one in
  61. %% <base_dir>/.rebar/erlcinfo.
  62. %%
  63. %% Solution: Ensure every project has its own .rebar/erlcinfo
  64. %%
  65. %% For the bug to happen, the following conditions must be met:
  66. %%
  67. %% 1. <base_dir>/rebar.config has erl_first_files
  68. %% 2. one of the 'first' files depends on another file (in this
  69. %% case via -include_lib())
  70. %% 3. a sub project's rebar.config, if any, has no erl_first_files entry
  71. %%
  72. %% Now because erl_first_files is retrieved via rebar_config:get_list/3,
  73. %% base_dir/rebar.config's erl_first_files is inherited, and because we had
  74. %% a shared <base_dir>/.rebar/erlcinfo instead of one per project, the
  75. %% cached entry was reused. Next, while compiling the sub project
  76. %% rebar_erlc_compiler:needs_compile/3 gets a last modification time of
  77. %% zero for the 'first' file which does not exist inside the sub project.
  78. %% This, and the fact that it has at least one dependency, makes
  79. %% needs_compile/3 return 'true'. The root cause is that we didn't have per
  80. %% project .rebar/erlcinfo. For <base_dir>/.rebar/erlcinfo to be populated,
  81. %% base_dir has to be compiled at least once. Therefore, after the first
  82. %% compile any compile processing the sub project will fail because
  83. %% needs_compile/3 will always return true for the non-existent 'first'
  84. %% file.
  85. ?assertMatch({ok, _}, retest_sh:run("./rebar clean", [])),
  86. ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])),
  87. ok = check_beams(true),
  88. ?assertMatch({ok, _}, retest_sh:run("./rebar compile", [])),
  89. ok = check_beams(true),
  90. ok.
  91. check_beams(Exist) ->
  92. check_files(Exist, fun filelib:is_regular/1).
  93. check_debug_info(HasDebugInfo) ->
  94. check_files(HasDebugInfo, fun has_debug_info/1).
  95. check_files(Expected, Check) ->
  96. lists:foreach(
  97. fun(F) ->
  98. File = filename:join("ebin", F),
  99. ?assertEqual(Expected, Check(File))
  100. end,
  101. ?BEAM_FILES).
  102. %% NOTE: Copied from dialyzer_utils:get_abstract_code_from_beam/1 and
  103. %% modified for local use. We could have called the function directly,
  104. %% but dialyzer_utils is not an official API to rely on.
  105. has_debug_info(File) ->
  106. case beam_lib:chunks(File, [abstract_code]) of
  107. {ok, {_Mod, List}} ->
  108. case lists:keyfind(abstract_code, 1, List) of
  109. {abstract_code, {raw_abstract_v1, _Abstr}} ->
  110. true;
  111. _ ->
  112. false
  113. end;
  114. _ ->
  115. false
  116. end.
  117. %%
  118. %% Generate the contents of a simple .app file
  119. %%
  120. app(Name, Modules) ->
  121. App = {application, Name,
  122. [{description, atom_to_list(Name)},
  123. {vsn, "1"},
  124. {modules, Modules},
  125. {registered, []},
  126. {applications, [kernel, stdlib]}]},
  127. io_lib:format("~p.\n", [App]).