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

win32 bug (long command line) OCaml 3.06 #7975

Closed
vicuna opened this issue Dec 19, 2002 · 2 comments
Closed

win32 bug (long command line) OCaml 3.06 #7975

vicuna opened this issue Dec 19, 2002 · 2 comments
Labels

Comments

@vicuna
Copy link

vicuna commented Dec 19, 2002

Original bug ID: 1500
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Hello,

I try compile ocaml 3.06 from source on my Windows98 platform (msvc6 +
cygwin), but make exit with error when comile tcl/tk caml libraies. I
look to source code and found what in byterun/winr2.c, function
win32_system:

  1. suppose max command line length is 4000, I don't know about NT or XP
    windows, but in win <= 98, max command line is 1024;

  2. not properly handle key "/nologo" for cl.exe and link.exe, /nologo
    must present directly in command line, not in @-file;

  3. not properly handle quoted string for long command line. For ex.:
    cl.exe arg1 arg2 arg3 arg4 "subarg1 subarg2 subargr3" .....
    translate to

    arg1
    arg2
    arg3
    arg4
    "subarg1
    subarg2
    subarg3"

but right way, do it:

arg1
arg2
arg3
arg4
subarg1 subarg2 subarg3

it's very important for argument passed to linker.

I also think what good idea is separate win32_system function, to two
function. One for internal use to call linker and compiler, they work properly
with '@file' in command line, and second for external use in application,
if user call it function with command line > 1024, exception will be
raised, for example Invalid_argument "system: line too long". Now if
user call system with long command line it's has unexpected and
undocumented behaviour.

Next trouble I found in asmcomp/asmlink.ml and /bytecomp/bytelink.ml,
files. Args passed from cl.exe to link.exe, must be in end line after
other args passed to cl.exe. It's not important for gcc, but for MS cl.exe
it's important.

Best regards
Artem Prisyaznuk
tema@sit.kiev.ua


diff -ru ocaml-3.06/asmcomp/asmlink.ml G:\cygwin\home\tema\ocaml\ocaml-3.06/asmcomp/asmlink.ml
--- ocaml-3.06/asmcomp/asmlink.ml Mon Jul 22 08:07:26 2002
+++ G:\cygwin\home\tema\ocaml\ocaml-3.06/asmcomp/asmlink.ml Thu Dec 12 11:13:08 2002
@@ -248,7 +248,27 @@
(Ccomp.quote_files (List.rev file_list))
| "msvc" ->
if not !Clflags.output_c_object then

  •      Printf.sprintf "%s /Fe%s %s %s %s %s %s %s %s"
    
  •      let link_templ = "/link" in
    
  •      let link_templ_len = String.length link_templ in
    
  •      let ccopts_link,ccopts_other =
    
  •        List.partition
    
  •          (fun s ->
    
  •          	if String.length s < link_templ_len then false
    
  •          	else
    
  •              let substr =
    
  •                String.lowercase (String.sub s 0 link_templ_len) in
    
  •              if substr <> link_templ
    
  •              then false
    
  •              else
    
  •                true
    
  •          ) !Clflags.ccopts in
    
  •      let ccopts_link' =
    
  •        List.map
    
  •          (fun s ->
    
  •            String.sub s link_templ_len
    
  •              (String.length s - link_templ_len)
    
  •          ) ccopts_link in
    
  •      Printf.sprintf "%s /Fe%s %s %s %s %s %s %s %s %s"
           !Clflags.c_linker
           (Filename.quote output_name)
           (Clflags.std_include_flag "-I")
    

@@ -258,7 +278,10 @@
(List.rev_map Ccomp.expand_libname !Clflags.ccobjs))
(Filename.quote runtime_lib)
c_lib

  •        (String.concat " " (List.rev !Clflags.ccopts))
    
  •        (String.concat " " (List.rev ccopts_other))
    
  •        (if List.length ccopts_link' = 0
    
  •        then ""
    
  •        else "\"/link "^(String.concat " " (List.rev ccopts_link'))^"\"")
       else
         Printf.sprintf "%s /out:%s %s %s"
           Config.native_partial_linker
    

diff -ru ocaml-3.06/bytecomp/bytelink.ml G:\cygwin\home\tema\ocaml\ocaml-3.06/bytecomp/bytelink.ml
--- ocaml-3.06/bytecomp/bytelink.ml Tue Jul 2 16:13:12 2002
+++ G:\cygwin\home\tema\ocaml\ocaml-3.06/bytecomp/bytelink.ml Thu Dec 12 11:13:08 2002
@@ -442,10 +442,30 @@
(Ccomp.quote_files (List.rev !Clflags.ccobjs))
Config.bytecomp_c_libraries)
| "msvc" ->

  •      let link_templ = "/link" in
    
  •      let link_templ_len = String.length link_templ in
    
  •      let ccopts_link,ccopts_other =
    
  •        List.partition
    
  •          (fun s ->
    
  •          	if String.length s < link_templ_len then false
    
  •          	else
    
  •              let substr =
    
  •                String.lowercase (String.sub s 0 link_templ_len) in
    
  •              if substr <> link_templ
    
  •              then false
    
  •              else
    
  •                true
    
  •          ) !Clflags.ccopts in
    
  •      let ccopts_link' =
    
  •        List.map
    
  •          (fun s ->
    
  •            String.sub s link_templ_len
    
  •              (String.length s - link_templ_len)
    
  •          ) ccopts_link in
     let retcode =
     Ccomp.command
      (Printf.sprintf
    
  •      "%s /Fe%s %s %s %s %s %s %s"
    
  •      "%s /Fe%s %s %s %s %s %s %s %s"
         !Clflags.c_linker
         (Filename.quote exec_name)
         (Clflags.std_include_flag "-I")
    

@@ -454,7 +474,11 @@
(List.rev_map Ccomp.expand_libname !Clflags.ccobjs))
(Filename.quote (Ccomp.expand_libname "-lcamlrun"))
Config.bytecomp_c_libraries

  •      (String.concat " " (List.rev !Clflags.ccopts))) in
    
  •      (String.concat " " (List.rev ccopts_other))
    
  •      (if List.length ccopts_link' = 0
    
  •      then ""
    
  •      else "\"/link "^(String.concat " " (List.rev ccopts_link'))^"\"")
    
  •      ) in
     (* C compiler doesn't clean up after itself.  Note that the .obj
        file is created in the current working directory. *)
     remove_file
    

diff -ru ocaml-3.06/byterun/win32.c G:\cygwin\home\tema\ocaml\ocaml-3.06/byterun/win32.c
--- ocaml-3.06/byterun/win32.c Wed Jul 24 03:22:38 2002
+++ G:\cygwin\home\tema\ocaml\ocaml-3.06/byterun/win32.c Thu Dec 12 11:13:08 2002
@@ -314,24 +314,39 @@
char * tempfile;
FILE * fd;
int len, i, j, k, retcode;

  • char its_quote = '\0';

  • char cur;

    len = strlen(cmdline);

  • if (len < 4000) {
  • if (len < 1024) {
    return system(cmdline);
    } else {
  • char nologo=" /nologo";
    /
    Skip initial blanks, if any /
    for (i = 0; cmdline[i] != 0 && isspace(cmdline[i]); i++) /nothing/;
    /
    Copy command name to buffer, stop at first blank */
    for (j = 0; cmdline[i] != 0 && ! isspace(cmdline[i]); i++) {
    if (j < MAX_CMD_LENGTH) cmd[j++] = cmdline[i];
    }
  • if (strncmp(cmdline + i ,nologo, strlen (nologo) ) == 0 &&
  •    j + strlen(nologo) < MAX_CMD_LENGTH ) {
    
  •  sprintf(cmd + j, "%s", nologo); 
    
  •  j = j + strlen(nologo);
    
  • }
    /* Save remainder of command line to temp file */
    strcpy(template, "cmXXXXXX");
    tempfile = mktemp(template);
    fd = fopen(tempfile, "w");
    if (fd == NULL) return -1;
  • for (k = i; k < len; k++)
  •  fputc((isspace(cmdline[k]) ? '\n' : cmdline[k]), fd);
    
  • for (k = i; k < len; k++) {
  •  cur = cmdline[k];
    
  •  if( cur == '"' || cur =='\'' )
    
  •    if( its_quote == '\0' )
    
  •      its_quote = cur;
    
  •    else
    
  •      its_quote = its_quote == cur ? '\0' : its_quote;
    
  •  fputc(((isspace(cur) && !its_quote) ? '\n' : cur), fd);
    
  • }
    fclose(fd);
    /* Add " @tempfile" to the command line */
    sprintf(cmd + j, " @%s", tempfile);


@vicuna
Copy link
Author

vicuna commented Jan 6, 2003

Comment author: administrator

  1. suppose max command line length is 4000, I don't know about NT or XP
    windows, but in win <= 98, max command line is 1024;

The 4000 comes from NT/XP, indeed.

  1. not properly handle key "/nologo" for cl.exe and link.exe, /nologo
    must present directly in command line, not in @-file;
  2. not properly handle quoted string for long command line. For ex.:
    cl.exe arg1 arg2 arg3 arg4 "subarg1 subarg2 subargr3" .....
    translate to

arg1
arg2
arg3
arg4
"subarg1
subarg2
subarg3"

but right way, do it:

arg1
arg2
arg3
arg4
subarg1 subarg2 subarg3

You meant "subarg1 subarg2 subarg3" (with the quotes) on the last
line, right?

I also think what good idea is separate win32_system function, to
two function. One for internal use to call linker and compiler, they
work properly with '@file' in command line, and second for external
use in application, if user call it function with command line >
1024, exception will be raised, for example Invalid_argument
"system: line too long". Now if user call system with long command
line it's has unexpected and undocumented behaviour.

That's an option, and we could even handle the generation of the @file
from the Caml code in Ccomp.quote_files, thus avoiding the re-parsing
of the quotes in sys_command. (Properly skipping quotes is delicate;
I believe your patch doesn't handle the case "foo"bar", i.e. with an
escaped quote inside the quotes.) However, we need @files not just
when calling the C compiler, but also when calling OCaml from the
ocamlmktop and ocamlmklib tools. Still, these could also go through
Ccomp.quote_files... Let me think about this for a while.

Next trouble I found in asmcomp/asmlink.ml and /bytecomp/bytelink.ml,
files. Args passed from cl.exe to link.exe, must be in end line after
other args passed to cl.exe. It's not important for gcc, but for MS cl.exe
it's important.

Another user pointed out this issue, but suggested a much simpler fix:
put the contents of OCaml's -ccopt option last on the CL command line,
so that if this option contains /link, it ends up correctly positioned.
Do you need /link in other contexts than in OCaml's -ccopt option?

Thanks for your input,

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Mar 24, 2003

Comment author: administrator

Fxied 2003-03-24 by XL. @responsefiles now handled in Caml, function
Ccomp.quote_files

@vicuna vicuna closed this as completed Mar 24, 2003
@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant