summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTuncer Ayaz <tuncer.ayaz@gmail.com>2015-07-02 13:45:35 +0200
committerTuncer Ayaz <tuncer.ayaz@gmail.com>2015-07-02 19:50:16 +0200
commit9a64826172ade12997e8ee0ff32df52757c43025 (patch)
tree464aa2f93fd4ea611d7b6907704dbe2b9bf8140b
parent49fd99c7011191ae9fe499f03c8070faf0bb41ba (diff)
downloadrebar-9a64826172ade12997e8ee0ff32df52757c43025.tar.gz
cross-arch: fix up issues
* fix commit messages * fix whitespace issues * move internal helper functions to correct location * unexport internal cross arch helper functions * fix 18.0 time API compatibility * fix Windows temp dir detection * use correct helper function name * use sh/2 instead of os:cmd/1 * match file:delete/1 result * use logging macros * fix typo * fix Dialyzer warnings * add Tony Rogvall to THANKS * add missing termination clause * os type must be win32, not windows * match file:write_file/2 result * document cross-arch variables * simplify env_wordsize/1 (Thanks Fred Hebert)
-rw-r--r--THANKS1
-rw-r--r--rebar.config3
-rw-r--r--src/rebar_port_compiler.erl59
-rw-r--r--src/rebar_utils.erl265
4 files changed, 183 insertions, 145 deletions
diff --git a/THANKS b/THANKS
index 042bb30..2ba6abe 100644
--- a/THANKS
+++ b/THANKS
@@ -142,3 +142,4 @@ Derek Brown
Danil Onishchenko
Stavros Aronis
James Fish
+Tony Rogvall
diff --git a/rebar.config b/rebar.config
index a3849ec..bcd5368 100644
--- a/rebar.config
+++ b/rebar.config
@@ -29,7 +29,8 @@
- (\"gpb_compile\":\"format_error\"/\"1\")
- (\"diameter_codegen\":\"from_dict\"/\"4\")
- (\"diameter_dict_util\":\"format_error\"/\"1\")
- - (\"diameter_dict_util\":\"parse\"/\"2\"))",
+ - (\"diameter_dict_util\":\"parse\"/\"2\")
+ - (\"erlang\":\"timestamp\"/\"0\"))",
[]}]}.
{dialyzer,
diff --git a/src/rebar_port_compiler.erl b/src/rebar_port_compiler.erl
index 84cf49b..dcd8a20 100644
--- a/src/rebar_port_compiler.erl
+++ b/src/rebar_port_compiler.erl
@@ -165,7 +165,14 @@ info_help(Description) ->
"~n"
"Valid rebar.config options:~n"
" ~p~n"
- " ~p~n",
+ " ~p~n"
+ "Cross-arch environment variables:~n"
+ " REBAR_TARGET_ARCH to set the tool chain name to use~n"
+ " REBAR_TARGET_ARCH_WORDSIZE optional "
+ "(if CC fails to determine word size)~n"
+ " fallback word size is 32~n"
+ " REBAR_TARGET_ARCH_VSN optional "
+ "(if a special version of CC/CXX is requested)~n",
[
Description,
{port_env, [{"CFLAGS", "$CFLAGS -Ifoo"},
@@ -183,8 +190,10 @@ setup_env(Config, ExtraEnv) ->
%% Get any port-specific envs; use port_env first and then fallback
%% to port_envs for compatibility
- RawPortEnv = rebar_config:get_list(Config, port_env,
- rebar_config:get_list(Config, port_envs, [])),
+ RawPortEnv = rebar_config:get_list(
+ Config,
+ port_env,
+ rebar_config:get_list(Config, port_envs, [])),
PortEnv = filter_env(RawPortEnv, []),
Defines = get_defines(Config),
@@ -571,17 +580,17 @@ default_env() ->
Arch = os:getenv("REBAR_TARGET_ARCH"),
Vsn = os:getenv("REBAR_TARGET_ARCH_VSN"),
[
- {"CC" , get_tool(Arch,Vsn,"gcc","cc")},
- {"CXX", get_tool(Arch,Vsn,"g++","c++")},
- {"AR" , get_tool(Arch,"ar","ar")},
- {"AS" , get_tool(Arch,"as","as")},
- {"CPP" , get_tool(Arch,Vsn,"cpp","cpp")},
- {"LD" , get_tool(Arch,"ld","ld")},
- {"RANLIB" , get_tool(Arch,Vsn,"ranlib","ranlib")},
- {"STRIP" , get_tool(Arch,"strip","strip")},
- {"NM" , get_tool(Arch,"nm","nm")},
- {"OBJCOPY" , get_tool(Arch,"objcopy","objcopy")},
- {"OBJDUMP" , get_tool(Arch,"objdump","objdump")},
+ {"CC", get_tool(Arch, Vsn,"gcc", "cc")},
+ {"CXX", get_tool(Arch, Vsn,"g++", "c++")},
+ {"AR", get_tool(Arch, "ar", "ar")},
+ {"AS", get_tool(Arch, "as", "as")},
+ {"CPP", get_tool(Arch, Vsn, "cpp", "cpp")},
+ {"LD", get_tool(Arch, "ld", "ld")},
+ {"RANLIB", get_tool(Arch, Vsn, "ranlib", "ranlib")},
+ {"STRIP", get_tool(Arch, "strip", "strip")},
+ {"NM", get_tool(Arch, "nm", "nm")},
+ {"OBJCOPY", get_tool(Arch, "objcopy", "objcopy")},
+ {"OBJDUMP", get_tool(Arch, "objdump", "objdump")},
{"DRV_CXX_TEMPLATE",
"$CXX -c $CXXFLAGS $DRV_CFLAGS $PORT_IN_FILES -o $PORT_OUT_FILE"},
@@ -600,9 +609,12 @@ default_env() ->
{"EXE_CFLAGS" , "-g -Wall -fPIC -MMD $ERL_CFLAGS"},
{"EXE_LDFLAGS", "$ERL_LDFLAGS"},
- {"ERL_CFLAGS", lists:concat([" -I\"", erl_interface_dir(include),
- "\" -I\"", filename:join(erts_dir(), "include"),
- "\" "])},
+ {"ERL_CFLAGS", lists:concat(
+ [
+ " -I\"", erl_interface_dir(include),
+ "\" -I\"", filename:join(erts_dir(), "include"),
+ "\" "
+ ])},
{"ERL_EI_LIBDIR", lists:concat(["\"", erl_interface_dir(lib), "\""])},
{"ERL_LDFLAGS" , " -L$ERL_EI_LIBDIR -lerl_interface -lei"},
{"ERLANG_ARCH" , rebar_utils:wordsize()},
@@ -651,20 +663,17 @@ default_env() ->
{"win32", "EXE_LINK_TEMPLATE",
"$LINKER $PORT_IN_FILES $LDFLAGS $EXE_LDFLAGS /OUT:$PORT_OUT_FILE"},
%% ERL_CFLAGS are ok as -I even though strictly it should be /I
- {"win32", "ERL_LDFLAGS", " /LIBPATH:$ERL_EI_LIBDIR erl_interface.lib ei.lib"},
+ {"win32", "ERL_LDFLAGS",
+ " /LIBPATH:$ERL_EI_LIBDIR erl_interface.lib ei.lib"},
{"win32", "DRV_CFLAGS", "/Zi /Wall $ERL_CFLAGS"},
{"win32", "DRV_LDFLAGS", "/DLL $ERL_LDFLAGS"}
].
-get_tool(Arch,Tool,Default) ->
- get_tool(Arch,false,Tool,Default).
+get_tool(Arch, Tool, Default) ->
+ get_tool(Arch, false, Tool, Default).
get_tool(false, _, _, Default) -> Default;
-get_tool("",_,_, Default) -> Default;
+get_tool("", _, _, Default) -> Default;
get_tool(Arch, false, Tool, _Default) -> Arch++"-"++Tool;
get_tool(Arch, "", Tool, _Default) -> Arch++"-"++Tool;
get_tool(Arch, Vsn, Tool, _Default) -> Arch++"-"++Tool++"-"++Vsn.
-
-
-
-
diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl
index 31ccb3f..045e67b 100644
--- a/src/rebar_utils.erl
+++ b/src/rebar_utils.erl
@@ -67,12 +67,7 @@
processing_base_dir/1,
processing_base_dir/2,
patch_env/2,
- cleanup_code_path/1,
- cross_wordsize/1,
- native_wordsize/0,
- wordsize/1,
- cross_sizeof/2,
- env_wordsize/1
+ cleanup_code_path/1
]).
%% for internal use only
@@ -98,9 +93,9 @@ is_arch(ArchRegex) ->
false
end.
%%
-%% REBAR_TARGET_ARCH, if used, should be set to the "standard"
+%% REBAR_TARGET_ARCH, if used, should be set to the "standard"
%% target string. That is a prefix for binutils tools.
-%% "x86_64-linux-gnu" or "arm-linux-gnueabi" are good candiates
+%% "x86_64-linux-gnu" or "arm-linux-gnueabi" are good candidates
%% ${REBAR_TARGET_ARCH}-gcc, ${REBAR_TARGET_ARCH}-ld ...
%%
get_arch() ->
@@ -116,117 +111,6 @@ get_system_arch(Arch) ->
wordsize() ->
wordsize(os:getenv("REBAR_TARGET_ARCH")).
-wordsize(Arch) when Arch =:= false; Arch =:= "" ->
- native_wordsize();
-wordsize(Arch) ->
- case match_wordsize(Arch, [{"i686","32"}, {"i386","32"},
- {"arm","32"}, {"aarch64", "64"},
- {"x86_64","64"}]) of
- false ->
- case cross_wordsize(Arch) of
- "" ->
- env_wordsize(os:getenv("REBAR_TARGET_ARCH_WORDSIZE"));
- WordSize -> WordSize
- end;
- {_, Wordsize} ->
- Wordsize
- end.
-
-match_wordsize(Arch, [V={Match,_Bits}|Vs]) ->
- case re:run(Arch, Match, [{capture, none}]) of
- match -> V;
- _ ->
- match_wordsize(Arch, Vs)
- end.
-
-env_wordsize(Wordsize) when Wordsize =:= false;
- Wordsize =:= "" ->
- io:format("REBAR_TARGET_ARCH_WORDSIZE not set, assuming 32\n"),
- "32";
-env_wordsize(Wordsize) ->
- try list_to_integer(Wordsize) of
- 16 -> "16";
- 32 -> "32";
- 64 -> "64";
- _ ->
- io:format("REBAR_TARGET_ARCH_WORDSIZE bad value: ~p\n", [Wordsize]),
- "32"
- catch
- error:_ ->
- io:format("REBAR_TARGET_ARCH_WORDSIZE bad value: ~p\n", [Wordsize]),
- "32"
- end.
-
-%%
-%% Findout the word size of the target by using Arch-gcc
-%%
-
-cross_wordsize(Arch) ->
- cross_sizeof(Arch, "void*").
-
-%%
-%% Find the size of target Type using a specially crafted C file
-%% that will report an error on the line of the byte size of the type.
-%%
-
-cross_sizeof(Arch, Type) ->
- Compiler = if Arch =:= "" -> "cc";
- true -> Arch ++ "-gcc"
- end,
- TempFile = mktemp(".c"),
- file:write_file(TempFile,
- <<"int t01 [1 - 2*(((long) (sizeof (TYPE))) == 1)];\n"
- "int t02 [1 - 2*(((long) (sizeof (TYPE))) == 2)];\n"
- "int t03 [1 - 2*(((long) (sizeof (TYPE))) == 3)];\n"
- "int t04 [1 - 2*(((long) (sizeof (TYPE))) == 4)];\n"
- "int t05 [1 - 2*(((long) (sizeof (TYPE))) == 5)];\n"
- "int t06 [1 - 2*(((long) (sizeof (TYPE))) == 6)];\n"
- "int t07 [1 - 2*(((long) (sizeof (TYPE))) == 7)];\n"
- "int t08 [1 - 2*(((long) (sizeof (TYPE))) == 8)];\n"
- "int t09 [1 - 2*(((long) (sizeof (TYPE))) == 9)];\n"
- "int t10 [1 - 2*(((long) (sizeof (TYPE))) == 10)];\n"
- "int t11 [1 - 2*(((long) (sizeof (TYPE))) == 11)];\n"
- "int t12 [1 - 2*(((long) (sizeof (TYPE))) == 12)];\n"
- "int t13 [1 - 2*(((long) (sizeof (TYPE))) == 13)];\n"
- "int t14 [1 - 2*(((long) (sizeof (TYPE))) == 14)];\n"
- "int t15 [1 - 2*(((long) (sizeof (TYPE))) == 15)];\n"
- "int t16 [1 - 2*(((long) (sizeof (TYPE))) == 16)];\n"
- >>),
- Res = os:cmd(Compiler ++ " -DTYPE=\""++Type++"\" " ++ TempFile),
- file:delete(TempFile),
- case string:tokens(Res, ":") of
- [_,Ln | _] ->
- try list_to_integer(Ln) of
- NumBytes -> integer_to_list(NumBytes*8)
- catch
- error:_ ->
- ""
- end;
- _ ->
- ""
- end.
-
-mktemp(Suffix) ->
- {A,B,C} = erlang:now(),
- Dir = case os:type() of
- {windows,_} -> "C:/WINDOWS/TEMP";
- _ -> "/tmp"
- end,
- File = "rebar_"++os:getpid()++
- integer_to_list(A)++"_"++
- integer_to_list(B)++"_"++
- integer_to_list(C)++Suffix,
- filename:join(Dir,File).
-
-native_wordsize() ->
- try erlang:system_info({wordsize, external}) of
- Val ->
- integer_to_list(8 * Val)
- catch
- error:badarg ->
- integer_to_list(8 * erlang:system_info(wordsize))
- end.
-
sh_send(Command0, String, Options0) ->
?INFO("sh_send info:\n\tcwd: ~p\n\tcmd: ~s < ~s\n",
[get_cwd(), Command0, String]),
@@ -794,3 +678,146 @@ cleanup_code_path(OrigPath) ->
_ ->
code:set_path(OrigPath)
end.
+
+wordsize(Arch) when Arch =:= false; Arch =:= "" ->
+ native_wordsize();
+wordsize(Arch) ->
+ AllArchs = [
+ {"i686","32"},
+ {"i386","32"},
+ {"arm","32"},
+ {"aarch64", "64"},
+ {"x86_64","64"}
+ ],
+ case match_wordsize(Arch, AllArchs) of
+ false ->
+ case cross_wordsize(Arch) of
+ "" ->
+ env_wordsize(os:getenv("REBAR_TARGET_ARCH_WORDSIZE"));
+ WordSize ->
+ WordSize
+ end;
+ {_, Wordsize} ->
+ Wordsize
+ end.
+
+match_wordsize(Arch, [V={Match,_Bits}|Vs]) ->
+ case re:run(Arch, Match, [{capture, none}]) of
+ match ->
+ V;
+ nomatch ->
+ match_wordsize(Arch, Vs)
+ end;
+match_wordsize(_Arch, []) ->
+ false.
+
+env_wordsize(Wordsize) when Wordsize =:= false;
+ Wordsize =:= "" ->
+ ?WARN("REBAR_TARGET_ARCH_WORDSIZE not set, assuming 32\n", []),
+ "32";
+env_wordsize(Wordsize) ->
+ case Wordsize of
+ "16" -> Wordsize;
+ "32" -> Wordsize;
+ "64" -> Wordsize;
+ _ ->
+ ?WARN("REBAR_TARGET_ARCH_WORDSIZE bad value: ~p\n", [Wordsize]),
+ "32"
+ end.
+
+%%
+%% Find out the word size of the target by using Arch-gcc
+%%
+cross_wordsize(Arch) ->
+ cross_sizeof(Arch, "void*").
+
+%%
+%% Find the size of target Type using a specially crafted C file
+%% that will report an error on the line of the byte size of the type.
+%%
+cross_sizeof(Arch, Type) ->
+ Compiler = if Arch =:= "" -> "cc";
+ true -> Arch ++ "-gcc"
+ end,
+ TempFile = mktempfile(".c"),
+ ok = file:write_file(TempFile,
+ <<"int t01 [1 - 2*(((long) (sizeof (TYPE))) == 1)];\n"
+ "int t02 [1 - 2*(((long) (sizeof (TYPE))) == 2)];\n"
+ "int t03 [1 - 2*(((long) (sizeof (TYPE))) == 3)];\n"
+ "int t04 [1 - 2*(((long) (sizeof (TYPE))) == 4)];\n"
+ "int t05 [1 - 2*(((long) (sizeof (TYPE))) == 5)];\n"
+ "int t06 [1 - 2*(((long) (sizeof (TYPE))) == 6)];\n"
+ "int t07 [1 - 2*(((long) (sizeof (TYPE))) == 7)];\n"
+ "int t08 [1 - 2*(((long) (sizeof (TYPE))) == 8)];\n"
+ "int t09 [1 - 2*(((long) (sizeof (TYPE))) == 9)];\n"
+ "int t10 [1 - 2*(((long) (sizeof (TYPE))) == 10)];\n"
+ "int t11 [1 - 2*(((long) (sizeof (TYPE))) == 11)];\n"
+ "int t12 [1 - 2*(((long) (sizeof (TYPE))) == 12)];\n"
+ "int t13 [1 - 2*(((long) (sizeof (TYPE))) == 13)];\n"
+ "int t14 [1 - 2*(((long) (sizeof (TYPE))) == 14)];\n"
+ "int t15 [1 - 2*(((long) (sizeof (TYPE))) == 15)];\n"
+ "int t16 [1 - 2*(((long) (sizeof (TYPE))) == 16)];\n"
+ >>),
+ Cmd = Compiler ++ " -DTYPE=\""++Type++"\" " ++ TempFile,
+ ShOpts = [{use_stdout, false}, return_on_error],
+ {ok, Res} = sh(Cmd, ShOpts),
+ ok = file:delete(TempFile),
+ case string:tokens(Res, ":") of
+ [_, Ln | _] ->
+ try list_to_integer(Ln) of
+ NumBytes -> integer_to_list(NumBytes*8)
+ catch
+ error:_ ->
+ ""
+ end;
+ _ ->
+ ""
+ end.
+
+mktempfile(Suffix) ->
+ {A,B,C} = rebar_now(),
+ Dir = temp_dir(),
+ File = "rebar_"++os:getpid()++
+ integer_to_list(A)++"_"++
+ integer_to_list(B)++"_"++
+ integer_to_list(C)++Suffix,
+ filename:join(Dir, File).
+
+temp_dir() ->
+ case os:type() of
+ {win32, _} -> windows_temp_dir();
+ _ -> "/tmp"
+ end.
+
+windows_temp_dir() ->
+ case os:getenv("TEMP") of
+ false ->
+ case os:getenv("TMP") of
+ false -> "C:/WINDOWS/TEMP";
+ TMP -> TMP
+ end;
+ TEMP -> TEMP
+ end.
+
+rebar_now() ->
+ case erlang:function_exported(erlang, timestamp, 0) of
+ true ->
+ erlang:timestamp();
+ false ->
+ %% erlang:now/0 was deprecated in 18.0, and as the escript has to
+ %% pass erl_lint:module/1 (even without -mode(compile)), we would
+ %% see a deprecation warning for erlang:now/0. One solution is to
+ %% use -compile({nowarn_deprecated_function, [{erlang, now, 0}]}),
+ %% but that would raise a warning in versions older than 18.0.
+ %% Calling erlang:now/0 via apply/3 avoids that.
+ apply(erlang, now, [])
+ end.
+
+native_wordsize() ->
+ try erlang:system_info({wordsize, external}) of
+ Val ->
+ integer_to_list(8 * Val)
+ catch
+ error:badarg ->
+ integer_to_list(8 * erlang:system_info(wordsize))
+ end.