Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"flexlink -install" to compile its own runtime objects #46

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 22 additions & 35 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ version.ml: Makefile
echo "let version = \"$(VERSION)\"" > version.ml
echo "let mingw_prefix = \"$(MINGW_PREFIX)\"" >> version.ml
echo "let mingw64_prefix = \"$(MINGW64_PREFIX)\"" >> version.ml
echo "let cygwin_prefix = \"$(CYGWIN_PREFIX)\"" >> version.ml
echo "let cygwin64_prefix = \"$(CYGWIN64_PREFIX)\"" >> version.ml

# Supported tool-chains

Expand All @@ -51,6 +53,8 @@ MSVC_PREFIX=
MSVC64_PREFIX=
MSVCC=cl.exe $(MSVC_FLAGS)
MSVCC64=cl.exe $(MSVC_FLAGS)
MSVC_CCPREFIX=
MSVC64_CCPREFIX=
else
ifeq ($(SDK),)
# Otherwise, assume the 32-bit version of VS 2008 or Win7 SDK is in the path.
Expand All @@ -67,13 +71,17 @@ MSVC64_PREFIX=LIB="$(MSVC64_LIB)" INCLUDE="$(MSVC_INCLUDE)"

MSVCC = $(MSVCC_ROOT)/cl.exe $(MSVC_FLAGS)
MSVCC64 = $(MSVCC_ROOT)/amd64/cl.exe $(MSVC_FLAGS)
MSVC_CCPREFIX=-cc-prefix $(MSVCC_ROOT)/
MSVC64_CCPREFIX=-cc-prefix $(MSVCC_ROOT)/amd64/
else
MSVCC_ROOT:=
MSVC_PREFIX=PATH="$(SDK):$(PATH)" LIB="$(SDK_LIB);$(LIB)" INCLUDE="$(SDK_INC);$(INCLUDE)"
MSVC64_PREFIX=PATH="$(SDK64):$(PATH)" LIB="$(SDK64_LIB);$(LIB)" INCLUDE="$(SDK64_INC);$(INCLUDE)"

MSVCC = cl.exe $(MSVC_FLAGS)
MSVCC64 = cl.exe $(MSVC_FLAGS)
MSVC_CCPREFIX=
MSVC64_CCPREFIX=
endif
endif

Expand Down Expand Up @@ -145,47 +153,26 @@ version.res: version.rc
version_res.o: version.rc
$(TOOLPREF)windres version.rc version_res.o

flexdll_msvc.obj: flexdll.h flexdll.c
$(MSVC_PREFIX) $(MSVCC) /DMSVC -c /Fo"flexdll_msvc.obj" flexdll.c
flexdll_initer_msvc.obj flexdll_msvc.obj: flexdll.h flexdll.c flexdll_initer.c flexlink.exe
$(MSVC_PREFIX) ./flexlink -v -install -o . -chain msvc $(MSVC_CCPREFIX)

flexdll_msvc64.obj: flexdll.h flexdll.c
$(MSVC64_PREFIX) $(MSVCC64) /DMSVC /DMSVC64 -c /Fo"flexdll_msvc64.obj" flexdll.c
flexdll_initer_msvc64.obj flexdll_msvc64.obj: flexdll.h flexdll.c flexdll_initer.c flexlink.exe
$(MSVC64_PREFIX) ./flexlink -v -install -o . -chain msvc64 $(MSVC64_CCPREFIX)

flexdll_cygwin.o: flexdll.h flexdll.c
$(CYGCC) -c -DCYGWIN -o flexdll_cygwin.o flexdll.c
flexdll_initer_cygwin.o flexdll_cygwin.o: flexdll.h flexdll.c flexdll_initer.c flexlink.exe
./flexlink -v -install -o . -chain cygwin

flexdll_cygwin64.o: flexdll.h flexdll.c
$(CYG64CC) -c -DCYGWIN -o flexdll_cygwin64.o flexdll.c
flexdll_initer_cygwin64.o flexdll_cygwin64.o: flexdll.h flexdll.c flexdll_initer.c flexlink.exe
./flexlink -v -install -o . -chain cygwin64

flexdll_mingw.o: flexdll.h flexdll.c
$(MINCC) -c -DMINGW -o flexdll_mingw.o flexdll.c
flexdll_initer_mingw.o flexdll_mingw.o: flexdll.h flexdll.c flexdll_initer.c flexlink.exe
./flexlink -v -install -o . -chain mingw

flexdll_gnat.o: flexdll.h flexdll.c
gcc -c -o flexdll_gnat.o flexdll.c
flexdll_initer_mingw64.o flexdll_mingw64.o: flexdll.h flexdll.c flexdll_initer.c flexlink.exe
./flexlink -v -install -o . -chain mingw64

flexdll_mingw64.o: flexdll.h flexdll.c
$(MIN64CC) -c -DMINGW -o flexdll_mingw64.o flexdll.c

flexdll_initer_msvc.obj: flexdll_initer.c
$(MSVC_PREFIX) $(MSVCC) -c /Fo"flexdll_initer_msvc.obj" flexdll_initer.c

flexdll_initer_msvc64.obj: flexdll_initer.c
$(MSVC64_PREFIX) $(MSVCC64) -c /Fo"flexdll_initer_msvc64.obj" flexdll_initer.c

flexdll_initer_cygwin.o: flexdll_initer.c
$(CYGCC) -c -o flexdll_initer_cygwin.o flexdll_initer.c

flexdll_initer_cygwin64.o: flexdll_initer.c
$(CYG64CC) -c -o flexdll_initer_cygwin64.o flexdll_initer.c

flexdll_initer_mingw.o: flexdll_initer.c
$(MINCC) -c -o flexdll_initer_mingw.o flexdll_initer.c

flexdll_initer_gnat.o: flexdll_initer.c
gcc -c -o flexdll_initer_gnat.o flexdll_initer.c

flexdll_initer_mingw64.o: flexdll_initer.c
$(MIN64CC) -c -o flexdll_initer_mingw64.o flexdll_initer.c
flexdll_initer_gnat.o flexdll_gnat.o: flexdll.h flexdll.c flexdll_initer.c flexlink.exe
./flexlink -v -install -o . -chain gnat


demo_msvc: flexlink.exe flexdll_msvc.obj flexdll_initer_msvc.obj
Expand Down
13 changes: 12 additions & 1 deletion cmdline.ml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ let underscore = ref true

let machine : [ `x86 | `x64 ] ref = ref `x86

let runtime_objects_dir = ref ""
let cc_prefix = ref ""
let noexport = ref false
let custom_crt = ref false
let reexport_from_implibs = ref true
Expand All @@ -36,7 +38,7 @@ let exts = ref []
let output_file = ref ""
let exe_mode : [`DLL | `EXE | `MAINDLL] ref = ref `DLL
let extra_args = ref []
let mode : [`NORMAL | `DUMP | `PATCH] ref = ref `NORMAL
let mode : [`NORMAL | `DUMP | `PATCH | `INSTALL] ref = ref `NORMAL
let defexports = ref []
let noentry = ref false
let use_cygpath = ref true
Expand Down Expand Up @@ -210,6 +212,15 @@ let specs = [
"-U", Arg.String (fun _ -> ()),
"<symbol> (Ignored)";

"-install", Arg.Unit (fun () -> mode := `INSTALL),
" Compile runtime support file for the selected toolchain";

"-cc-prefix", Arg.Set_string cc_prefix,
"<file> Add an explicit directory or a prefix in front of the C compiler (cl / gcc) and other tools";

"-runtime-objects", Arg.Set_string runtime_objects_dir,
"<dir> Specify in which directory the flexdll runtime objects are found";

"--", Arg.Rest (fun s -> extra_args := s :: !extra_args),
" Following arguments are passed verbatim to the linker";
]
Expand Down
143 changes: 102 additions & 41 deletions reloc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ let search_path = ref []
let default_libs = ref []

let gcc = ref "gcc"
let cl = ref "cl"
let objdump = ref "objdump"
let link = ref "link"

let is_crt_lib = function
| "LIBCMT"
Expand All @@ -31,6 +33,10 @@ let flexdir =
with Not_found ->
Filename.dirname Sys.executable_name

let runtime_objects_dir =
if !runtime_objects_dir = "" then flexdir
else !runtime_objects_dir

let ext_obj () =
if !toolchain = `MSVC || !toolchain = `MSVC64 then ".obj" else ".o"

Expand Down Expand Up @@ -1018,7 +1024,8 @@ let build_dll link_exe output_file files exts extra_args =
with the Windows 7 SDK in 64-bit mode. *)

Printf.sprintf
"link /nologo %s%s%s%s%s /implib:%s /out:%s /subsystem:%s %s %s %s"
"%s /nologo %s%s%s%s%s /implib:%s /out:%s /subsystem:%s %s %s %s"
!link
(if !verbose >= 2 then "/verbose " else "")
(if link_exe = `EXE then "" else "/dll ")
(if main_pgm then "" else "/export:symtbl /export:reloctbl ")
Expand Down Expand Up @@ -1198,6 +1205,7 @@ let remove_duplicate_paths paths =

let setup_toolchain () =
let mingw_libs pre =
let pre = if !cc_prefix = "" then pre else !cc_prefix in
gcc := pre ^ "gcc";
objdump := pre ^ "objdump";
let rec get_lib_search_dirs input =
Expand Down Expand Up @@ -1229,24 +1237,39 @@ let setup_toolchain () =
if !exe_mode = `EXE then default_libs := "crt2.o" :: !default_libs
else default_libs := "dllcrt2.o" :: !default_libs
in
let cygwin pre =
let pre = if !cc_prefix = "" then pre else !cc_prefix in
gcc := pre ^ "gcc";
objdump := pre ^ "objdump";
let lib_search_dirs =
[
"/lib";
"/lib/w32api";
Filename.dirname (get_output1 ~use_bash:true (!gcc ^ " -print-libgcc-file-name"));
]
in
search_path := !dirs @ lib_search_dirs;
if !verbose >= 1 then begin
print_endline "lib search dirs:";
List.iter (Printf.printf " %s\n%!") lib_search_dirs;
end;
default_libs := ["-lkernel32"; "-luser32"; "-ladvapi32";
"-lshell32"; "-lcygwin"; "-lgcc"]
in
match !toolchain with
| _ when !builtin_linker ->
search_path := !dirs;
add_flexdll_obj := false;
noentry := true
| `CYGWIN | `CYGWIN64 ->
gcc := "gcc";
objdump := "objdump";
search_path :=
!dirs @
[
"/lib";
"/lib/w32api";
Filename.dirname (get_output1 ~use_bash:true "gcc -print-libgcc-file-name");
];
default_libs := ["-lkernel32"; "-luser32"; "-ladvapi32";
"-lshell32"; "-lcygwin"; "-lgcc"]
| `CYGWIN ->
cygwin Version.cygwin_prefix
| `CYGWIN64 ->
cygwin Version.cygwin64_prefix
| `MSVC | `MSVC64 ->
if !cc_prefix <> "" then begin
cl := !cc_prefix ^ "cl";
link := !cc_prefix ^ "link";
end;
search_path := !dirs @
parse_libpath (try Sys.getenv "LIB" with Not_found -> "");
if not !custom_crt then
Expand All @@ -1258,17 +1281,19 @@ let setup_toolchain () =
| `GNAT ->
(* This is a plain copy of the mingw version, but we do not change the
prefix and use "gnatls" to compute the include dir. *)
search_path :=
!dirs @
[
Filename.dirname (get_output1 (!gcc ^ " -print-libgcc-file-name"));
read_gnatls ();
];
default_libs :=
["-lmingw32"; "-lgcc"; "-lmoldname"; "-lmingwex"; "-lmsvcrt";
"-luser32"; "-lkernel32"; "-ladvapi32"; "-lshell32" ];
if !exe_mode = `EXE then default_libs := "crt2.o" :: !default_libs
else default_libs := "dllcrt2.o" :: !default_libs
gcc := !cc_prefix ^ "gcc";
objdump := !cc_prefix ^ "objdump";
search_path :=
!dirs @
[
Filename.dirname (get_output1 (!gcc ^ " -print-libgcc-file-name"));
read_gnatls ();
];
default_libs :=
["-lmingw32"; "-lgcc"; "-lmoldname"; "-lmingwex"; "-lmsvcrt";
"-luser32"; "-lkernel32"; "-ladvapi32"; "-lshell32" ];
if !exe_mode = `EXE then default_libs := "crt2.o" :: !default_libs
else default_libs := "dllcrt2.o" :: !default_libs
| `LIGHTLD ->
search_path := !dirs

Expand Down Expand Up @@ -1300,18 +1325,13 @@ let compile_if_needed file =
let cmd = match !toolchain with
| `MSVC | `MSVC64 ->
Printf.sprintf
"cl /c /MD /nologo /Fo%s %s %s%s"
"%s /c /MD /nologo /Fo%s %s %s%s"
!cl
(Filename.quote tmp_obj)
(mk_dirs_opt "/I")
file
pipe
| `CYGWIN | `CYGWIN64 ->
Printf.sprintf
"gcc -c -o %s %s %s"
(Filename.quote tmp_obj)
(mk_dirs_opt "-I")
file
| `MINGW | `MINGW64 | `GNAT ->
| `CYGWIN | `CYGWIN64 | `MINGW | `MINGW64 | `GNAT ->
Printf.sprintf
"%s -c -o %s %s %s"
!gcc
Expand All @@ -1329,6 +1349,16 @@ let compile_if_needed file =
end else
file

let toolchain_suffix () =
match !toolchain with
| `MSVC -> "msvc.obj"
| `MSVC64 -> "msvc64.obj"
| `CYGWIN -> "cygwin.o"
| `CYGWIN64 -> "cygwin64.o"
| `MINGW64 -> "mingw64.o"
| `GNAT -> "gnat.o"
| `MINGW | `LIGHTLD -> "mingw.o"

let dump fn =
let fn = find_file fn in
Printf.printf "*** %s:\n" fn;
Expand All @@ -1349,27 +1379,55 @@ let dump fn =
let all_files () =
let files = List.rev (List.map compile_if_needed !files) in
let f obj =
let fn = Filename.concat flexdir obj in
let fn = Filename.concat runtime_objects_dir obj in
(* Allow the obj files to be stored in a different location *)
if file_exists fn <> None then
fn
else
obj in
let tc = match !toolchain with
| `MSVC -> "msvc.obj"
| `MSVC64 -> "msvc64.obj"
| `CYGWIN -> "cygwin.o"
| `CYGWIN64 -> "cygwin64.o"
| `MINGW64 -> "mingw64.o"
| `GNAT -> "gnat.o"
| `MINGW | `LIGHTLD -> "mingw.o" in
let tc = toolchain_suffix () in
if !exe_mode <> `DLL then
if !add_flexdll_obj then f ("flexdll_" ^ tc) :: files
else files
else
if !noentry then files
else f ("flexdll_initer_" ^ tc) :: files

let install file =
let target = Filename.concat !output_file file ^ "_" ^ toolchain_suffix () in
let target = Filename.quote (if !use_cygpath then cygpath1 target else target) in
let src = Filename.quote (Filename.concat flexdir file ^ ".c") in
let call_gcc extra =
Printf.sprintf
"%s -c %s -o %s %s"
!gcc
extra
target
src
in
let call_cl extra =
Printf.sprintf
"%s /DMSVC %s /c /MD /nologo -D_CRT_SECURE_NO_DEPRECATE /GS- /Fo%s %s"
!cl
extra
target
src
in
let cmd =
match !toolchain with
| `MSVC -> call_cl ""
| `MSVC64 -> call_cl "/DMSVC64"
| `CYGWIN | `CYGWIN64 -> call_gcc "-DCYGWIN"
| `MINGW | `MINGW64 -> call_gcc "-DMINGW"
| `GNAT -> call_gcc ""
| `LIGHTLD -> failwith "Compilation of C code is not supported for this toolchain"
in
if !verbose >= 1 || !dry_mode then Printf.printf "+ %s\n%!" cmd;
if not !dry_mode && Sys.command cmd <> 0
then
failwith (Printf.sprintf "Error while compiling %s.c" file)


let main () =
parse_cmdline ();
setup_toolchain ();
Expand Down Expand Up @@ -1408,6 +1466,9 @@ let main () =
(String.concat " " (List.map Filename.quote (List.rev !extra_args)))
| `PATCH ->
patch_output !output_file
| `INSTALL ->
install "flexdll";
install "flexdll_initer"

let () =
try main ()
Expand Down