-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 port build with Mingw: -link -static-libgcc is required for flexlink call #6411
Comments
Comment author: furuse After investigating what is happening I found that the stublib dllbigarray.dll depends on libgcc_s_sjlj-1.dll but it is missing. Googling about it I found a fix: we need -static-libgcc linker option at the creation of dllbigarray.dll. I do not know exactly which mingw64-i686-gcc versions require this but at least the following patch works fine with 4.8.2-2. Longer and probably redundant explanation is available at: http://d.hatena.ne.jp/camlspotter/20140502/1399024687 *** ocaml-4.01.0.old/config/Makefile Fri May 2 17:25:36 2014 *** 100,106 **** Flexlink! FLEXLINK=flexlink -chain mingw -stack 16777216 Flexlink! FLEXLINK=flexlink -chain mingw -stack 16777216 -link -static-libgcc |
Comment author: @protz Right, but -static-libgcc is not the only way to fix that: you can just dynamically load libgcc_s_sjlj-1.dll by making sure the directory where the dll lives is in the PATH. jonathan@farquaad:~/Code/ocaml (trunk) $ export PATH=/usr/i686-w64-mingw32/sys-root/mingw/bin/:$PATH jonathan@farquaad:~/Code/ocaml (trunk) $ ocaml bigarray.cma OCaml version 4.03.0+dev0-2014-05-12 # exit 1;; I kind of think that the motto these days is that static linking should be avoided, but I don't have enough background to determine whether having Alain add -static-libgcc to the flexlink invocations or having users of OCaml on Windows tweak their path is the right thing to do. Alain, do you have an opinion on that? |
Comment author: @protz After some investigations, it turns out that mmap_win32.c contains an int64 division (line 89) and an int64 modulo (line 109). Both of these lines, when compiled by gcc (http://stackoverflow.com/questions/18448343/divdi3-division-used-for-long-long-by-gcc-on-x86), generate calls to external library functions (___divi3 and ___modi3), hence requiring libgcc_s_sjlj-1.dll. As far as Damien and I could tell, these are the only places which generate a dependency on the runtime library. We could probably get away with replacing the division and the modulo by bit-shifting and masking respectively, since the divisor is a power of two in both cases. |
Comment author: @alainfrisch If we can manage to get rid of the dependency to the external library, this seems good to me. I don't think we can tell users to add a non-default directory to their PATH. Cannot we instruct the linker to add the directory to the dynamic load path when building executables? |
Comment author: furuse If we can remove the dependency completely it is the best. If we dynamically link it then users of binary executables by OCaml+MinGW may need to install the library, which is not good. I am not sure about the license of the library but libgcc_s_sjlj-1.dll sounds pretty GNU. Not good for whom want to build closed source OCaml apps. |
Comment author: @protz I believe we all agree that the dependency ought to be removed. The only question is whether we should do it by rewriting the two operations on long long's by hand, or by static-linking libgcc. We would have to figure out the license implications of the latter solution, though. After a quick search, it seems to be fine (http://www.gnu.org/licenses/gcc-exception.html). |
Comment author: @damiendoligez I vote for rewriting: inelegant, but it's only a few lines. |
Comment author: Camarade_Tux
Your toolchain sounds broken too. |
Comment author: @xavierleroy On line 89, "array_size" (the divisor) is definitely not a power of 2. I probably miss the obvious, but aren't those helper functions __divd3 already used by the runtime system, and if so why aren't they available for DLLs thanks to FlexDLL magic? |
Comment author: @mshinwell Alain, are you able to help with this? |
Comment author: @alainfrisch I did not look at the issue concretely, and there might indeed be an issue with flexlink, but if the runtime system depends on those functions and they are provided by a dll which is not in the default dll load path, how is a standalone program (either ocamlrun or a bytecode program compiled with -custom) supposed to work out of the box on a machine without cygwin? |
Comment author: @protz I believe the two options are as follows.
Alain, do you think option 1) would be ok for you? |
Comment author: @alainfrisch Why should flexlink's default be changed? Wouldn't it be enough to add the option to utils/Makefile.{mingw,mingw6464}? |
Comment author: Camarade_Tux As far as I'm concerned, I expect the dependency on this DLL and I don't see what the issue is. If someone wants static linking (especially for C libs), it should be done explicitely. If I'm right, you're building from Cygwin and knowing who makes the packages, I doubt that DLL is missing. In other words, it sounds like an issue with the library lookup paths. If you're cross-compiling (which you are if you're using Cygwin), it's expected that the file is not in a standard place (and even more so for libgcc on Cygwin which, iirc, is the reason it's not in the usual paths). I definitely acknowledge the use of static linking and I do so to distribute my yypkg.exe from http://win-builds.org but I don't think it should be the default, especially when you can do it fairly easily. PS: I vote against rewriting: if there's a whole library and it's built as shared library, it's because there are more than a couple functions and you're likely to pull that library for other symbols and reasons too (especially if you interface with C and C++). |
Comment author: @protz
The DLL is definitely not missing. It's just that I'm unsure which one of switching to static linking or distributing the DLL along with the OCaml binaries is the best choice. |
Comment author: @alainfrisch
The native ports (mingw / msvc) are supposed to produce standalone programs, i.e. programs which can run on a bare Windows machine. This is not strictly the case for the msvc ports, because they create dependencies to e.g. msvcr90.dll, which are not parts of Windows, but is still widely available (e.g. it is installed with recent .Net). Visual Studio C++ itself has the same problem. Until recently, the mingw port only created a dependency to msvcrt.dll, which is shipped with Windows. It was a very nice property, and it would be bad to loose it. It seems quite bad to require OCaml users to ship a copy of a Cygwin DLL, even if licensing is ok, together with their native executables. |
Comment author: Camarade_Tux It's part of the C toolchain and it comes with the C toolchain and if it's not there, it's an issue with the C toolchain. It's simply in a different path. For instance, in my cross-toolchains, it's in something like: And there's even an autotools variable for that place: toolexeclibdir which is used by nothing but GCC and for that shared library. You can have a look at : It's really only an issue with the lookup path. Btw, you CANNOT ship that library because it changes depending on the exception handling system and it's not possible to foresee that. And if you don't want to change lookup paths, simply copy the file at the end of OCaml's installation on Windows. Crude but effective. |
Comment author: @alainfrisch I'm not sure to follow the discussion. Why should we require people who need to execute a native OCaml program to have a C toolchain? Or are we only talking about making a native OCaml distribution? |
Comment author: Camarade_Tux This is a GCC file, definitely not a Cygwin one. The reason cygwin is involved is because the C toolchain is Cygwin's and is a cross-compiler which makes it write that .dll file in a specific location which is compatible with cross-compilation and multilib systems. If you check the original error message it is for bytecode but it also mentions bigarray which has C stubs and I guess that's how libgcc gets linked in. Apart from that, it should only matter to native-compiled executables except maybe that ocamlrun.exe itself might depend on it (it seems it currently doesn't or it would have failed earlier than when loading bigarray.cma stubs and if it did, there would have been no reason for the OS to lookup the library again [ and fail that ]) As for distributing additional files, I doubt most applications distribute 0 additional files and if they do, they can explicitely link statically. I'm doing just that in yypkg. |
Comment author: @protz I think we're conflating two issues here.
|
Comment author: @alainfrisch
I think this is the most important question. The decision about the first one (OCaml binary distribution) can be made by the guys creating the Windows binary distributions; it's more a packaging issue.
I still don't understand why we need to change the default behavior of flexlink. It seems to me that Jun's patch would also work. The FLEXLINK variable in config/Makefile.{mingw,msvc,...} affects how ocamlopt invokes flexlink. |
Comment author: @mshinwell Documentation for -{static,shared}-libgcc: |
Comment author: @alainfrisch Unless someone objects: let's add the -static-libgcc by default in config/Makefile.mingw |
Comment author: @mshinwell And let's reference the GCC documentation. |
Comment author: @alainfrisch Fixed on 4.02 only (for now). |
git-svn-id: http://caml.inria.fr/svn/ocaml/version/4.02@15008 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
git-svn-id: http://caml.inria.fr/svn/ocaml/version/4.02@15009 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Original bug ID: 6411
Reporter: furuse
Assigned to: @alainfrisch
Status: closed (set by @xavierleroy on 2015-12-11T18:28:14Z)
Resolution: open
Priority: normal
Severity: major
Version: 4.01.0
Target version: 4.02.0+dev
Fixed in version: 4.02.0+dev
Category: platform support (windows, cross-compilation, etc)
Tags: patch
Bug description
I built OCaml 4.01.0 with mingw64-i686-gcc 4.8.2-2. The build and installation were successful, but I got a linking problem of bigarray.cma:
$ ocaml bigarray.cma
Cannot load required shared library dllbigarray.
Reason: C:/ocamlmgw/lib/stublibs\dllbigarray.dll: The specified module could not be found.
The text was updated successfully, but these errors were encountered: