1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1997-2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21%%% Purpose : Autoconf for Windows. 22 23-module(ts_autoconf_win32). 24-export([configure/0]). 25 26-include("ts.hrl"). 27 28configure() -> 29 case variables() of 30 {ok, Vars} -> 31 ts_lib:subst_file("conf_vars.in", "conf_vars", Vars); 32 Error -> 33 Error 34 end. 35 36variables() -> 37 run_tests(tests(), []). 38 39run_tests([{Prompt, Tester}|Rest], Vars) -> 40 io:format("checking ~s... ", [Prompt]), 41 case catch Tester(Vars) of 42 {'EXIT', Reason} -> 43 io:format("FAILED~nExit status: ~p~n", [Reason]), 44 {error, auto_conf_failed}; 45 {Result, NewVars} -> 46 io:format("~s~n", [lists:concat([Result])]), 47 run_tests(Rest, NewVars) 48 end; 49run_tests([], Vars) -> 50 {ok, Vars}. 51 52%%% The tests. 53 54tests() -> 55 [{"host system type", fun system_type/1}, 56 {"CPU type", fun cpu/1}, 57 {"for C compiler", fun c_compiler/1}, 58 {"for make program", fun make/1}, 59 {"for location of SSL libraries", fun ssl/1}, 60 {"for location of Java compiler", fun javac/1}, 61 {"if wsl is to used as shell", fun wsl/1} 62 ]. 63 64system_type(Vars) -> 65 Os = case os:type() of 66 {win32, nt} -> 67 case os:version() of 68 {4,_,_} -> "Windows NT"; 69 {5,0,_} -> "Windows 2000"; 70 {5,1,_} -> "Windows XP"; 71 {5,2,_} -> "Windows 2003"; 72 {6,0,_} -> "Windows Vista"; 73 {6,1,_} -> "Windows 7"; 74 {_,_,_} -> "Windows NCC-1701-D" 75 end; 76 {win32, windows} -> 77 case os:version() of 78 {4,0,_} -> "Windows 95"; 79 {4,10,_} -> "Windows 98" 80 end; 81 {win32, _} -> "Windows" 82 end, 83 {Os, [{host_os, Os}, {host, "win32"}|Vars]}. 84 85cpu(Vars) -> 86 Arch = os:getenv("PROCESSOR_ARCHITECTURE"), 87 Level0 = os:getenv("PROCESSOR_Level"), 88 Cpu = case {Arch, Level0} of 89 {"x86", Level} when is_list(Level) -> 90 "i" ++ Level ++ "86"; 91 {Other, _Level} when is_list(Other) -> 92 Other; 93 {false, _} -> 94 "i386" 95 end, 96 {Cpu, [{host_cpu, Cpu}|Vars]}. 97 98c_compiler(Vars) -> 99 try 100 CompTests = [{msc, fun visual_cxx/1}, 101 {gnuc, fun mingw32/1}], 102 %% First try to find the same compiler that the system 103 %% was built with... 104 UsedCompiler = case erlang:system_info(c_compiler_used) of 105 {UsedCmplr, _} -> 106 case lists:keysearch(UsedCmplr, 1, CompTests) of 107 {value, {UsedCmplr, CompTest}} -> 108 CompTest(Vars); 109 _ -> 110 ok 111 end, 112 UsedCmplr; 113 undefined -> 114 undefined 115 end, 116 %% ... then try to find a compiler... 117 lists:foreach(fun ({Cmplr, _CmplrTst}) when Cmplr =:= UsedCompiler -> 118 ok; % Have already checked for this one 119 ({_Cmplr, CmplrTst}) -> 120 CmplrTst(Vars) 121 end, 122 CompTests), 123 {no, Vars} 124 catch 125 throw:{_Path, _NewVars} = Res -> Res 126 end. 127 128visual_cxx(Vars) -> 129 case os:find_executable("cl") of 130 false -> 131 {no, Vars}; 132 Path when is_list(Path) -> 133 {DEFAULT_THR_LIB, 134 ERTS_THR_LIB, 135 DLL, 136 DBG_LINK, 137 DBG_COMP, 138 OPT} = 139 case is_debug_build() of 140 true -> 141 {"-MTd ", 142 "-MDd ", 143 "-LDd ", 144 "-link -debug -pdb:none ", 145 "-Z7 -DDEBUG", 146 " "}; 147 false -> 148 {"-MT ", 149 "-MD ", 150 "-LD ", 151 "-Zi -link ", 152 "-Zi ", 153 "-Ox "} 154 end, 155 WIN32 = "-D__WIN32__ ", 156 ERTS_CFLAGS = ERTS_THR_LIB ++ WIN32 ++ OPT ++ DBG_COMP, 157 LIBS = "ws2_32.lib", 158 CC = "cl -nologo", 159 throw({Path, [{'CC', CC}, 160 {'LD', CC}, 161 {'SHLIB_LD', CC}, 162 {'SHLIB_LDFLAGS', ERTS_THR_LIB ++ DLL}, 163 {'SHLIB_LDLIBS', DBG_LINK ++ "kernel32.lib"}, 164 {'SHLIB_EXTRACT_ALL', ""}, 165 {'CFLAGS', DEFAULT_THR_LIB ++ WIN32 ++ DBG_COMP}, 166 {'EI_CFLAGS', DEFAULT_THR_LIB ++ WIN32 ++ DBG_COMP}, 167 {'ERTS_CFLAGS', ERTS_CFLAGS}, 168 {'SHLIB_CFLAGS', ERTS_CFLAGS++DLL}, 169 {'CROSSLDFLAGS', ""}, 170 {'DEFS', common_c_defs()}, 171 {'SHLIB_SUFFIX', ".dll"}, 172 {'ERTS_LIBS', ERTS_THR_LIB ++ LIBS}, 173 {'LIBS', DBG_LINK ++ LIBS}, 174 {obj,".obj"}, 175 {exe, ".exe"}, 176 {test_c_compiler, "{msc, undefined}"} 177 | Vars]}) 178 end. 179 180mingw32(Vars) -> 181 Gcc = "mingw32-gcc", 182 case os:find_executable(Gcc) of 183 false -> 184 {no, Vars}; 185 Path when is_list(Path) -> 186 {DBG_COMP, 187 OPT} = 188 case is_debug_build() of 189 true -> 190 {"-DDEBUG", 191 " "}; 192 false -> 193 {" ", 194 "-O2 "} 195 end, 196 WIN32 = "-D__WIN32__ ", 197 ERTS_CFLAGS = WIN32 ++ "-g " ++ OPT ++ DBG_COMP, 198 LIBS = "-lws2_32", 199 CC = Gcc, 200 throw({Path, [{'CC', CC}, 201 {'LD', CC}, 202 {'SHLIB_LD', CC}, 203 {'SHLIB_LDFLAGS', "-shared "}, 204 {'SHLIB_LDLIBS', " -lkernel32"}, 205 {'SHLIB_EXTRACT_ALL', ""}, 206 {'CFLAGS', WIN32 ++ DBG_COMP}, 207 {'EI_CFLAGS', WIN32 ++ DBG_COMP}, 208 {'ERTS_CFLAGS', ERTS_CFLAGS}, 209 {'SHLIB_CFLAGS', ERTS_CFLAGS}, 210 {'CROSSLDFLAGS', ""}, 211 {'DEFS', common_c_defs()}, 212 {'SHLIB_SUFFIX', ".dll"}, 213 {'ERTS_LIBS', LIBS}, 214 {'LIBS', LIBS}, 215 {obj,".o"}, 216 {exe, ".exe"}, 217 {test_c_compiler, "{gnuc, undefined}"} 218 | Vars]}) 219 end. 220 221common_c_defs() -> 222 "-DHAVE_STRERROR=1". 223 224make(Vars) -> 225 try 226 find_make("nmake -nologo", Vars), 227 find_make("mingw32-make", Vars) 228 catch 229 throw:{_Path, _NewVars} = Res -> Res 230 end. 231 232find_make(MakeCmd, Vars) -> 233 [Make|_] = string:lexemes(MakeCmd, " \t"), 234 case os:find_executable(Make) of 235 false -> 236 {no, Vars}; 237 Path when is_list(Path) -> 238 throw({Path, [{make_command, MakeCmd} | Vars]}) 239 end. 240 241ssl(Vars) -> 242 {"win32",[{'SSLEAY_ROOT',"win32"}|Vars]}. 243 244javac(Vars) -> 245 case os:find_executable("javac") of 246 false -> 247 {no, Vars}; 248 Path when is_list(Path) -> 249 {Path, [{'JAVAC', "javac"} | Vars]} 250 end. 251 252wsl(Vars) -> 253 case os:getenv("WSLENV") of 254 false -> 255 {no, [{'wsl', ""} | Vars]}; 256 _ -> 257 {"wsl.exe", [{'wsl', "wsl.exe"} | Vars]} 258 end. 259 260is_debug_build() -> 261 case catch string:find(erlang:system_info(system_version), "debug") of 262 nomatch -> 263 false; 264 _Else -> 265 true 266 end. 267