Repository: numpy/numpy

Issue:
f2py support for MinGW-w64
I'd like to build 64-bit Python extensions on Windows using the MinGW-w64 compiler, which provides gfortran. I've [explored this question](http://stackoverflow.com/questions/16929544/building-64-bit-python-extensions-with-f2py-on-windows), and it seems that much of f2py somewhat supports it with [a small hack](http://scientificcomputingco.blogspot.com.au/2013/02/f2py-on-64bit-windows-python27.html). The hack/fix is to pass and comment out `NotImplementedError("Only MS compiler supported with gfortran on win64")`.

I can then successfully compile an extension from `cmd.exe` using:

```
set PATH=%PATH%;c:\gnu\mingw64\bin

set C_INCLUDE_PATH=C:\gnu\mingw64\include

C:\Python27\python.exe C:\Python27\Scripts\f2py.py -c --fcompiler=gnu95 --compiler=mingw32 -m foo foo.f90
```

The resulting foo.pyd file works with the same version of Python ... success!

However, this is not yet feature rich, as I cannot seem to statically link in the GCC/gfortran components, as the resulting pyd file depends on 64-bit versions of libgfortran*.dll.

I'd like to package this Python extension to others without supplying these GCC DLLs.

I've tried using either `-static` or `-static-libgfortran` flags to one of either the `--f90flags=` argument, or the environment variables `FFLAGS` and `CFLAGS`. These don't seem to work for f2py, and I'm not sure why, even though I can confirm that the same gfortran compiler can statically build executables that do not depend on the GCC DLLs.



Discussion:
Guess this should be classified as a feature request? @pearu?

Yes.
Although I'd consider this issue a numpy.distutils.fcompiler issue rather than f2py issue.
At the moment I don't have MS computer with 64bit mingw set up to test this patch myself.

I've managed to configure a `setup.py` file to successfully build an extension that does not depend on GCC DLLs by specifying `extra_link_args=['-static']`. Here is an excerpt of the magic:

``` python
from numpy.distutils.core import Extension, setup
...
setup(
    ...
    ext_modules = [Extension('my.mod', ['src/code.f95'], extra_link_args=['-static'])],
    ...
)
```

however, I still cannot seem to find a way to put `-static` as an extra link argument to `f2py.py`.

I think there is an undocumented feature how you can change the linker flags:
change (or better set) the environment variable LDFLAGS to -static (or whatever you want). 

I found this because it seems necessary to add the optimization flag -Ofast to the linker call at the end of the f2py. This improved the speed of my test cases significantly (from 2.5 s to 0.8 s) (gfortran 4.8.1)

I was even thinking about adding an additional option to f2py like --linkerflags (like --f90flags) before I found the feature in the source:
https://github.com/numpy/numpy/blob/1340fa646d414b49856314bad339b4ae8ea4c4d8/numpy/distutils/fcompiler/__init__.py#L142
https://github.com/numpy/numpy/blob/1340fa646d414b49856314bad339b4ae8ea4c4d8/numpy/distutils/fcompiler/__init__.py#L98

Folks are starting to build numpy (scipy?) with mingw-64.

@rgommers Does this need a change?

Yes. Carl Kleffner has a working static build toolchain now (search on mailing list) that seems to solve most of these issues. @mwtoews could you have a look at that? Does it fix your issues, and is this patch still needed?

Is the `NotImplementedError("Only MS compiler supported with gfortran on win64")` line still necessary? I found myself patching numpy today in the way @mwtoews pointed out, in this case to build a conda package on Windows 64bit, and had great success.

@Juanlu001 thanks, looks like we forgot about this issue. Care to send a PR to remove that line?


Resolving patch:
diff --git a/numpy/distutils/fcompiler/gnu.py b/numpy/distutils/fcompiler/gnu.py
--- a/numpy/distutils/fcompiler/gnu.py
+++ b/numpy/distutils/fcompiler/gnu.py
@@ -335,7 +335,7 @@ def get_libraries(self):
                 if c_compiler and c_compiler.compiler_type == "msvc":
                     return []
                 else:
-                    raise NotImplementedError("Only MS compiler supported with gfortran on win64")
+                    pass
         return opt
 
     def get_target(self):


Test patch: