JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.41k stars 5.45k forks source link

remove msys Windows build instructions #5961

Closed cmundi closed 10 years ago

cmundi commented 10 years ago

Ok, so woe is me... I actually am crazy enough to attempt this...

A few issues with README.windows.md...

Step 4 should actually call out the bin package of the replacement make:

make-3.81-3-msys-1.0.13-bin.tar.lzma

because the sourceforge URL in step 4 actually is one level up from the needed file.

Step 5. I assume that if we're using the msys 'make' to replace "the one in the mingw64\bin subdirectory of the MinGW-builds installation" then we're replacing the one named mingw32-make.exe. Just to hedge this bet, I copied msys "make.exe" to both "make.exe" and "mingw32-make.exe" in mingw/bin.

Step 6 is not self-consistent. If .../mingw/bin is mounted at /mingw, then the path to be added to $PATH is /mingw and not /mingw/bin.

Finally, make fails for me (Windows 7, following instructions exactly except for the corrections noted above) as follows from the MINGW32 prompt (via msys.bat):

$ cd c:\julia
$ make
make: *** No rule to make target `/c/julia/usr/bin', needed by `release'.  Stop.

I have not dived into the Makefile. I have built julia for Linux recently, so I hope I'm not completely clueless when I ask for some clues on the Windows build. :)

Thanks.

cmundi commented 10 years ago

I probably should have included the debugging info from make...

Note that I cloned the julia repo into C:\, so JULIAHOME is c\julia\

$ make -d
GNU Make 3.82.90
Built for i686-pc-msys
Copyright (C) 2010  Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Reading makefile `Makefile'...
Reading makefile `/c/julia/Make.inc' (search path) (no ~ expansion)...
Updating makefiles....
 Considering target file `/c/julia/Make.inc'.
  Looking for an implicit rule for `/c/julia/Make.inc'.
  Trying pattern rule with stem `Make.inc'.
  Trying implicit prerequisite `/c/julia/Make.inc,v'.
  Trying pattern rule with stem `Make.inc'.
  Trying implicit prerequisite `/c/julia/RCS/Make.inc,v'.
  Trying pattern rule with stem `Make.inc'.
  Trying implicit prerequisite `/c/julia/RCS/Make.inc'.
  Trying pattern rule with stem `Make.inc'.
  Trying implicit prerequisite `/c/julia/s.Make.inc'.
  Trying pattern rule with stem `Make.inc'.
  Trying implicit prerequisite `/c/julia/SCCS/s.Make.inc'.
  No implicit rule found for `/c/julia/Make.inc'.
  Finished prerequisites of target file `/c/julia/Make.inc'.
 No need to remake target `/c/julia/Make.inc'.
 Considering target file `Makefile'.
  Looking for an implicit rule for `Makefile'.
  Trying pattern rule with stem `Makefile'.
  Trying implicit prerequisite `Makefile,v'.
  Trying pattern rule with stem `Makefile'.
  Trying implicit prerequisite `RCS/Makefile,v'.
  Trying pattern rule with stem `Makefile'.
  Trying implicit prerequisite `RCS/Makefile'.
  Trying pattern rule with stem `Makefile'.
  Trying implicit prerequisite `s.Makefile'.
  Trying pattern rule with stem `Makefile'.
  Trying implicit prerequisite `SCCS/s.Makefile'.
  No implicit rule found for `Makefile'.
  Finished prerequisites of target file `Makefile'.
 No need to remake target `Makefile'.
Updating goal targets....
Considering target file `all'.
 File `all' does not exist.
 Looking for an implicit rule for `all'.
 Trying pattern rule with stem `all'.
 Trying implicit prerequisite `all,v'.
 Trying pattern rule with stem `all'.
 Trying implicit prerequisite `RCS/all,v'.
 Trying pattern rule with stem `all'.
 Trying implicit prerequisite `RCS/all'.
 Trying pattern rule with stem `all'.
 Trying implicit prerequisite `s.all'.
 Trying pattern rule with stem `all'.
 Trying implicit prerequisite `SCCS/s.all'.
 No implicit rule found for `all'.
  Considering target file `default'.
   File `default' does not exist.
    Considering target file `release'.
     File `release' does not exist.
      Considering target file `/c/julia/usr/bin'.
       File `/c/julia/usr/bin' does not exist.
       Looking for an implicit rule for `/c/julia/usr/bin'.
       Trying pattern rule with stem `bin'.
       Trying implicit prerequisite `/c/julia/usr/bin,v'.
       Trying pattern rule with stem `bin'.
       Trying implicit prerequisite `/c/julia/usr/RCS/bin,v'.
       Trying pattern rule with stem `bin'.
       Trying implicit prerequisite `/c/julia/usr/RCS/bin'.
       Trying pattern rule with stem `bin'.
       Trying implicit prerequisite `/c/julia/usr/s.bin'.
       Trying pattern rule with stem `bin'.
       Trying implicit prerequisite `/c/julia/usr/SCCS/s.bin'.
       No implicit rule found for `/c/julia/usr/bin'.
       Finished prerequisites of target file `/c/julia/usr/bin'.
      Must remake target `/c/julia/usr/bin'.
make: *** No rule to make target `/c/julia/usr/bin', needed by `release'.  Stop.

Hope this helps!

vtjnash commented 10 years ago

If you've built on linux, you'll find the cross build much easier. That said msys is broken badly and msys2 is a much better choice. I've updated the title of this issue to reflect the best option here: deleting the msys instruction and use msys2.

cmundi commented 10 years ago

Thanks. I will consider cross-building. I generally prefer to build with a platform's own tool chain. But I'm really not doing that with mingw and msys...which have brought me a decade frustration now that I think about it...I wonder how hard a truly native build would be using Intel's C++ compiler or even MS. I'd hate to see Julia end up in the gawd awful state python is in...with fragile Windows support and an even more brittle package ecosystem. I've wandered off point but for a good cause I hope. Thanks! I'll try msys2. On Feb 25, 2014 8:04 PM, "Jameson Nash" notifications@github.com wrote:

If you've built on linux, you'll find the cross build much easier. That said msys is broken badly and msys2 is a much better choice. I've updated the title of this issue to reflect the best option here: deleting the msys instruction and use msys2.

Reply to this email directly or view it on GitHubhttps://github.com/JuliaLang/julia/issues/5961#issuecomment-36086210 .

vtjnash commented 10 years ago

I was going to reply that msys/mingw is technically also a cross-build, but you already recognized that.

Julia also builds with the Intel and MSVC compilers, although the latter may still need some TLC. (and a few of the external dependencies may require msys)

tkelman commented 10 years ago

You'd need Intel's proprietary Fortran compiler for several of the dependencies, and any Fortran libraries won't be able to inter-operate with those compiled by MinGW gfortran due to the difference in mangling.

I was going to reply that msys/mingw is technically also a cross-build, but you already recognized that.

How so? All the compiler and shell executables are native, and there's no need to specify --host. It's a GNU toolchain and there is some fishiness with path translation, but the whole point of Msys is to allow native compilation. Quoting Alexey from https://www.mail-archive.com/mingw-w64-public@lists.sourceforge.net/msg07478.html,

MSYS is about mixing W32 tools (mingw-gcc, binutils) headers and libraries with *nixy (or cygwinny, if you prefer) buildtools and scripts, with the aim of building W32 libraries and applications.

In Cygwin (or when running a real GNU system) you have to use a cross-compiler to build W32 binaries. In MSYS you don't have to. That's it.

Has anyone other than me tried a Cygwin-to-MinGW cross compile of Julia? Cygwin is in much better shape than it used to be (it now has a proper 64-bit version for example), I switched from Msys1 to Cygwin for Windows development. The MinGW-w64 compilers ship as Cygwin packages, and if you configure an autotools project with --host=x86_64-w64-mingw32 then your executables and libraries won't require cygwin1.dll. Currently Julia's cross-compilation assumes that the only type of cross compilation is from Linux to Windows via Wine.

vtjnash commented 10 years ago

It's certainly closer to native windows, but it is not native windows, and the msys gcc (as opposed to the mingw compiler that you are referring to and which is separate from the msys), makes msys executables which are not also not quite native windows binaries. so, it is a cross-compile.

I've never tried it, but in theory, if the build system thinks HOST_OS != WINNT && OS == WINNT (by setting the cross compile variable per linux), it should be possible to make the compile work

msys2 is forked from a newer version of cygwin to pick up on those improvements, like 64-bit support and faster fork.

tkelman commented 10 years ago

It's certainly closer to native windows, but it is not native windows, and the msys gcc (as opposed to the mingw compiler that you are referring to and which is separate from the msys), makes msys executables which are not also not quite native windows binaries. so, it is a cross-compile.

Thanks for the clarification. You mean msys2 here, right? msys1 never came with its own version of gcc, at least none of the msys1 versions I ever installed did (some were bundled and installed together as a subfolder of 32-bit MinGW however). So it sounds like msys2 functions very much like Cygwin then, just with a different package manager. All the trouble of a fork just to avoid specifying --host?

I've never tried it, but in theory, if the build system thinks HOST_OS != WINNT && OS == WINNT (by setting the cross compile variable per linux), it should be possible to make the compile work

The first thing I ran into when I tried this yesterday was some trouble around here https://github.com/JuliaLang/julia/blob/master/Makefile#L148-170 in finding where x86_64-w64-mingw32-gcc keeps its standard libs. I fiddled a bit with changing winepath to cygpath and adding some Cygwin-specific lines around here https://github.com/JuliaLang/julia/blob/master/Make.inc#L116-142 but gave up for now. Edit: found a fix for this https://github.com/tkelman/julia/commit/ed5bfc6fdb76c782f8582cfd10648f209f2c14bc, chugging along building LLVM now. Will see what breaks next.

At the moment it seems like no one has been asking about Cygwin-to-MinGW cross compiles so I might be the only one wanting to do it that way. But there could be some advantages, there are some CI services for Windows that might help automate things. I have played with Wercker and been meaning to look into AppVeyor, you should be able to get Cygwin running in those but the CI time limit is probably way too short for building Julia.

vtjnash commented 10 years ago

msys had a gcc, but it wasn't easy to install. since msys is not native, it needs to have it's own gcc for it's environment. building in a more native windows environment has many advantages (as you have perhaps started to notice in trying to get it to work in cygwin), but yes, the distinction is quite hazy

I prefer linux-to-mingw compiles since they are better supported by the mingw folks, and I have less problems with corruption due to race conditions that seem to be sometimes present in calling fork and pipe on cygwin. (and it builds much faster)

cmundi commented 10 years ago

Yes. I have been a user of Intel's fortran since back in the day when it was called MS powerstation. :) Since DEC that compiler saw little love until Intel gave it new life. Point taken on the name mangling. Thanks. On Feb 25, 2014 9:32 PM, "Tony Kelman" notifications@github.com wrote:

You'll need Intel's proprietary Fortran compiler for several of the dependencies, and any Fortran libraries won't be able to inter-operate with those compiled by MinGW gfortran due to the difference in mangling.

I was going to reply that msys/mingw is technically also a cross-build, but you already recognized that.

How so? All the compiler and shell executables are native, and there's no need to specify --host. It's a GNU toolchain and there is some fishiness with path translation, but the whole point of Msys is to allow native compilation. Quoting Alexey from https://www.mail-archive.com/mingw-w64-public@lists.sourceforge.net/msg07478.html ,

MSYS is about mixing W32 tools (mingw-gcc, binutils) headers and libraries with *nixy (or cygwinny, if you prefer) buildtools and scripts, with the aim of building W32 libraries and applications.

In Cygwin (or when running a real GNU system) you have to use a cross-compiler to build W32 binaries. In MSYS you don't have to. That's it.

Has anyone other than me tried a Cygwin-to-MinGW cross compile of Julia? Cygwin is in much better shape than it used to be (it now has a native 64-bit version for example), I switched from Msys1 to Cygwin for Windows development. The MinGW-w64 compilers ship as Cygwin packages, and if you configure an autotools project with --host=x86_64-w64-mingw32 then your executable won't require cygwin1.dll. Currently Julia's cross-compilation assumes that the only type of cross compilation is from Linux to Windows via Wine.

Reply to this email directly or view it on GitHubhttps://github.com/JuliaLang/julia/issues/5961#issuecomment-36090020 .

tknopp commented 10 years ago

Regarding the native build. I have made quite some progress and this is mostly in master. I have concentrated on compiling libjulia. The repl has more dependencies and I have therefore not tried that. With REPL.jl integreted (0.4?) this should become easier.

I have not build all the third party libs as these are compatible with a native julia build.

I got libjulia compiled with the Intel compiler which was pretty straight forward as it supports C99. One remaining issue is the setlongjmp functions.

MSVC is more complicated as it does not support C99 and my approach was to compile everything with the MSVC C++ compiler. It almost works, there are only some name mangeling issues to be solved which should be doable.

The question is a little bit if there is enough interest in pushing this further as the MinGW builds actually work pretty well. The issue with the intel compiler is that it requires a commercial license. MSVC is free in the Express edition and therefore much more suitable.

tkelman commented 10 years ago

The ideal combination would be easy to set up, freely available, not too slow to compile, and not too much different than the build process on other OS'es. Cmake can let you do that with MSVC only if every single dependency is also using Cmake. And the only freely available production-usable Fortran compiler on Windows is gfortran.

It almost works, there are only some name mangeling issues to be solved which should be doable.

For Fortran the mangling could be solved by finding every single instance of a Fortran function being called, and replace the ccall with a new fcall (this is open as #2167) that adds the underscore for a gfortran-compiled dependency library, or doesn't for an ifort-compiled dependency library.

All libraries that use C++ API's will need to use the same compiler. Makes you wonder whether there's a possible use case of a Windows application that absolutely must use MSVC (or Intel) compiler, and wants to embed both Julia and its own LLVM for separate non-Julia-related things that require C++ API's... That might be problematic if Julia's version of LLVM is MinGW compiled.

tknopp commented 10 years ago

The name mangling issue has nothing to do with fortran but that one has to put extern "C" at the right places when compiling Julia with a C++ compiler. Julia itself does also not use fortran, i.e. compiling all the ccall dependencies (fftw, Lapack, ...) is IMHO a different issue than compiling Julia itself. libjulia depends on libuv and LLVM. Both can be compiled with Intel and MSVC.

My main motivation for all this was/is that the MinGW builds are not debuggable with Visual Studio.

vtjnash commented 10 years ago

That might be problematic if Julia's version of LLVM is MinGW compiled.

MinGW's ABI is designed to be 100% compatible with MSVC (that's what makes it a native windows compiler). It doesn't matter how you mix and match between the MSVC, Intel, and MinGW C/C++ compilers.

tknopp commented 10 years ago

Correct me if I am wrong, but I thought this would be only valid for C and not for C++ (which does not matter in our case as libjulia and all our dependencies have C interfaces)

vtjnash commented 10 years ago

Should be fixed since gcc 4.7/4.8

cmundi commented 10 years ago

Yes extern C does the trick as long as we're clear about 32 bit vs 64 bit mangling on x86. Don't know about other targets.

As for gfortran...I've also been impressed technically with g95 though I've not used it for production. On Feb 26, 2014 7:31 AM, "Tobias Knopp" notifications@github.com wrote:

The name mangling issue has nothing to do with fortran but that one has to put extern "C" at the right places when compiling Julia with a C++ compiler. Julia itself does also not use fortran, i.e. compiling all the ccall dependencies (fftw, Lapack, ...) is IMHO a different issue than compiling Julia itself. libjulia depends on libuv and LLVM. Both can be compiled with Intel and MSVC.

My main motivation for all this was/is that the MinGW builds are not debuggable with Visual Studio.

Reply to this email directly or view it on GitHubhttps://github.com/JuliaLang/julia/issues/5961#issuecomment-36130267 .

cmundi commented 10 years ago

I'm going to second the call to remove the msys build instructions. msys2 is working well for me, although I did take a path slightly different from the path outlined in the experimental msys2 instructions. Key differences include using the Windows build of phython 2.7 instead of the msys2 build, and (big one) needing to restart the msys2 shell twice -- once right after msys2 install which we all all know and again after the pacman -S{y|u} but before the pacman -S make inter alia.

It is sooo good to have parallel make back!

jiahao commented 10 years ago

@cmundi you could do a us a huge service by updating the documentation with new msys2 instructions, now that you're the most up to date with the install process.

cmundi commented 10 years ago

@jiahao - Agreed. I'm actually already working on it -- probably should have said so to save others the time. I will create a(nother) fresh VM and take fresh notes tomorrow!

Thanks again guys!

quinnj commented 10 years ago

@cmundi, thanks for taking on the task of updating the notes. Not sure if anyone else has run into this, but one issue that I've run into before and that happened in my most recent build was not having my /mingw64/bin FIRST in my system path. This led to a weird bug when making FFTW that when googling the generic error referred to something or other but needing to make sure /mingw64/bin was first in my path. Sure enough, moving it from last to first in my path (I think because it needs to be before some of the core windows stuff) did the trick. It might be worth mentioning in a footnote.

cmundi commented 10 years ago

@karbarcca - will do in the path ordering, and if I can see why that might happen I'll try to get at the root cause - thanks!

tkelman commented 10 years ago

I've seen issues with some MSYS builds in the past that had to do with libtool using the Windows versions of find, link, or sort instead of the MSYS version, so that's one possibility where path ordering could make a difference. Those should be in MSYS's bin instead of MinGW's bin though, so maybe it's something else. Any recollection of what the error was?

Should be fixed since gcc 4.7/4.8

In http://gcc.gnu.org/gcc-4.7/changes.html it states that "Windows mingw targets are using the -mms-bitfields option by default." and "Windows x86 targets are using the __thiscall calling convention for C++ class-member functions." This was described here http://gcc.gnu.org/ml/gcc-help/2012-05/msg00080.html as "an ongoing effort to make them compatible, though not any time soon, this is one of the first steps."

I was under the impression that LLVM was using a C++ interface, but that's probably wrong so this is probably irrelevant.

cmundi commented 10 years ago

I'm working through some remaining build questions for julia using msys2. One thing I'm noticing is that the build of llvm (and possibly other things) is looking for 'fetch' as evidenced by messages like

which: no fetch in ( <imagine your hideously long search path here> )

Can that be safely ignored, or is that a real problem? Never noticed it on my unix builds of julia, but those are my fast boxes. :)

cmundi commented 10 years ago

Here's another one. Running single-threaded make for clarity. Right after we get past pcre (with a 0-length 'checked' file), we see this:

Can't open openblas-v0.2.9.rc1/config.status.system: No such file or directory.
ln: failed to create symbolic link ‘libopenblas.a’: No such file or directory

whereupon we drop into a build of cblas. Are these just an awkward way of confirming that openblas hasn't been built yet?

It's looking like I'm goiing to have to instrument the Makefile a bit before the -d output is enough to tell me what I'm looking for. :)

tkelman commented 10 years ago

I've seen the fetch path-spewing here too, happens on every dependency download. It's from https://github.com/JuliaLang/julia/blob/master/deps/jldownload and should be harmless. Can silence it by changing FETCH=$(which fetch) to FETCH=$(which fetch 2>/dev/null) (and similarly for WGET and CURL).

cmundi commented 10 years ago

@tkelman - thanks. I wondered about that. I did install wget just to shut that one up, since that seemed to be the right thing to do. I'll probably not pipe the fetch errors to /dev/null just because the moment I do that will be the moment we really need fetch. But I really hope we do not need fetch -- at least not until there's a stable pacman pkg for it. Thanks!

Ah yes... I see that jldownload is cleverly (?) designed to fail-in-a-good-way instead of fail-in-a-bad-way. It might be preferable to establish which url-getters are available early, cache the result, and then use it.

vtjnash commented 10 years ago

the openblas error also happens on linux; it's normal

tkelman commented 10 years ago

Nah, you only need one of wget, curl, or fetch. jldownload checks whether the result from which is executable, and uses the first working one it finds, or errors if it can't find any of them. fetch should really only be needed on BSD where it's more commonly pre-installed than wget or curl.

cmundi commented 10 years ago

@vtjnash - Thanks for confirmation that those openblas build messages are normal. I'm goig to go through the build a couple times, from scratch, and try to catalog the stuff tat pops up but is ignorable. For its complexity, Julia is a remarkably clean build.

cmundi commented 10 years ago

Closing this as it is superseded by #5982. Thanks.