Skip to content

MPR#7679: make sure .a files are erased before calling ar rc#1494

Merged
xavierleroy merged 3 commits intoocaml:trunkfrom
xavierleroy:MPR7679
Nov 30, 2017
Merged

MPR#7679: make sure .a files are erased before calling ar rc#1494
xavierleroy merged 3 commits intoocaml:trunkfrom
xavierleroy:MPR7679

Conversation

@xavierleroy
Copy link
Copy Markdown
Contributor

Otherwise, as shown by MPR#7679, leftover .a files from an earlier compilation may contain unwanted modules.

Also: replace ; by && when chaining several shell commands, it's safer this way.

The second commit freshens up the Mingw32 and Mingw64 configurations. They did the correct file-remove dance in MKLIB already, but the #ml block contained a different, and better, definition than the MKLIB shell command.

Otherwise leftover .a files from an earlier compilation may contain
unwanted modules.
The Caml definition in the #ml comment block is better.
We can safely assume "ar" supports the "s" option because this is "ar"
from the GNU binutils.
Copy link
Copy Markdown
Member

@dra27 dra27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if the MSVC linker does the same thing, but would it be worth deleting the .lib file in their definitions of MKLIB too?


### How to build a static library
MKLIB=rm -f $(1); $(TOOLPREF)ar rc $(1) $(2); $(RANLIB) $(1)
MKLIB=rm -f $(1) && $(TOOLPREF)ar rcs $(1) $(2)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two have been switched from using RANLIB to using the 's' option of ar, but the configure script still calls ranlib expressly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in my commit message, Mingw uses the GNU version of ar for which I'm certain the s flag is supported. In contrast the ar provided by old Unix platforms could lack the s flag and could require an explicit ranlib call.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed the commit message thanks to GitHub's tedious interface!

What bothers me with this is twofold - a difference here is "annoying" (or at least a special case) when the 4 Windows ports get moved into the configure script with autoconf. It's also a bit weird that both RANLIB and ar -s are used at various points in the build system, though I don't expect that can ever cause a problem (I'd be more inclined to have altered the #ml branch to be calling RANLIBCMD and add the optimisation to use GNU ar's -s switch everywhere properly at a later date)

MKLIB=rm -f $(1); $(TOOLPREF)ar rc $(1) $(2); $(RANLIB) $(1)
MKLIB=rm -f $(1) && $(TOOLPREF)ar rcs $(1) $(2)
#ml let mklib out files opts =
#ml Printf.sprintf "rm -f %s && %sar rcs %s %s %s"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This obviously wasn't changed as part of this GPR, but it would be better if mingw/msvc were using the del command, rather than rm (or, better yet, of the deletion were done more expressly in the compiler with a Sys.remove call)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! Actually, this mklib definition is used in only one place, namely tools/ocamlmklib.ml line 287, and the library file to be created is deleted before calling the mklib command. So, we can simplify the corresponding #ml configuration lines to not call rm nor del.

The other place in OCaml where a static library is built is utils/ccomp.ml, function create_archive. There, the destination file is also deleted first, and moreover mklib is not used, rather the use of ar+ranlib or of link /lib is hardcoded.

@xavierleroy
Copy link
Copy Markdown
Contributor Author

I don't know if the MSVC linker does the same thing, but would it be worth deleting the .lib file in their definitions of MKLIB too?

I couldn't find documentation for link -lib. (There's plenty of MSDN documentation for link but the lib option is not documented.) So, you tell me. But with the MSVC tools we've been not removing the target preventively for 20+ years and it's been OK so far...

The lines `#ml let mklib ...` are used only in utils/ocamlmklib.ml, where the destination .a file is always erased before `mklib` is invoked.  Hence there is no need for a `rm` (or `del`) shell command in `mklib`.
@xavierleroy
Copy link
Copy Markdown
Contributor Author

The latest commit removes the useless calls to rm, as discussed above.

Requesting a formal accept/reject review.

@xavierleroy xavierleroy added this to the 4.07 milestone Nov 29, 2017
@alainfrisch
Copy link
Copy Markdown
Contributor

(There's plenty of MSDN documentation for link but the lib option is not documented.)

link.exe /lib seems to be the same as lib.exe (to the point where link /lib /? gives the usage line with LIB). This allows finding https://msdn.microsoft.com/en-us/library/0xb6w1f8.aspx and https://msdn.microsoft.com/en-us/library/e17b885t.aspx , which says:

If a file already exists with the same name, the output file replaces the existing file.

Copy link
Copy Markdown
Contributor

@alainfrisch alainfrisch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

It is my understanding that MKLIB is used only in byterun/Makefile and asmrun/Makefile. Is that right?

(There are other variables called MKLIB in other Makefiles, but they refer to ocamlmklib. It would be best to rename them, but this is unrelated to this PR.)

MKLIB=rm -f $(1); $(TOOLPREF)ar rc $(1) $(2); $(RANLIB) $(1)
MKLIB=rm -f $(1) && $(TOOLPREF)ar rcs $(1) $(2)
#ml let mklib out files opts =
#ml Printf.sprintf "rm -f %s && %sar rcs %s %s %s"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rm -rf also wants to go (as in the .mingw Makefile)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is gone in the current version (commit 897c1f5, pushed yesterday). Not sure why Github is making you review an outdated version!

@xavierleroy xavierleroy merged commit 13785c9 into ocaml:trunk Nov 30, 2017
@xavierleroy xavierleroy deleted the MPR7679 branch November 30, 2017 10:25
Armael pushed a commit to Armael/ocaml that referenced this pull request Dec 1, 2017
…ml#1494)

Otherwise leftover .a files from an earlier compilation may contain
unwanted modules, as shown in MPR#7679.

However, ocamlmklib always erases the destination .a file before
calling the `mkdll` function defined in `#ml` blocks of the
configuration makefile.  Hence there is no need for a `rm` (or `del`)
shell command in `mklib`.

Finally, in the config/Makefile.mingw* files, we can safely assume
"ar" supports the "s" option because this is "ar" from the GNU
binutils, so no need to call ranlib.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants