Estoy intentando (y fallando) compilar un módulo de fortran (específicamente igrf12.f de BGS) usando f2py y Python 3.6 en Windows 10. Python se instaló usando Anaconda 4.4.10.

Mi configuración:

  • Python 3.6.3 | Anaconda personalizado (64 bits) | (predeterminado, 15 de octubre de 2017, 03:27:45) [MSC v.1900 64 bit (AMD64)] en win32
  • Windows 10 Enterprise (versión 1703)
  • NumPy 1.14.0

Seguí las instrucciones f2py de la documentación de SciPy y una guía útil del doctor Michael Hirsch. Dr. Hirsch ha creado el módulo pyigrf12, pero la instalación a través de pip me falló, que es lo que inicialmente despertó mi interés en f2py.

Resumiré algunos de los métodos que estoy usando. Independientemente del método, siempre comienzo creando un archivo de firma * .pyf usando f2py igrf12.f -m pyigrf12 -h igrf12.pyf y agregando atributos de intención (entrada / salida) de manera apropiada.

  • Método 1: use C: \ MinGW y --compiler=mingw32
  • Método 2: use C: \ MinGW y --compiler=msvc
  • Método 3: use la versión anaconda de mingw y --compiler=mingw32
  • Método 4: use la versión anaconda de mingw y --compiler=msvc

Método 1:

Para el fondo, tengo MinGW en C: \ MinGW y he agregado C: \ MinGW \ bin a mi ruta de usuario. Desafortunadamente, no instalé esta versión de MinGW (heredé esta computadora de un colega), por lo que no sé de dónde proviene. La versión gcc --version y gfortran --version es 5.3.0.

Ejecuto f2py -c igrf12.pyf igrf12.f --compiler=mingw32. Esto falla con este mensaje de error:

Building import library (arch=AMD64):
"C:\Users\Sholes\AppData\Local\Continuum\anaconda3\libs\libpython36.a" 
(from C:\Users\Sholes\AppData\Local\Continuum\anaconda3\python36.dll)
    objdump.exe: C:\Users\Sholes\AppData\Local\Continuum\anaconda3\python36.dll: File format not recognized

Traceback (most recent call last):
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\Scripts\\f2py.py", line 28, in <module>
    main()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\f2py\f2py2e.py", line 648, in main
    run_compile()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\f2py\f2py2e.py", line 633, in run_compile
    setup(ext_modules=[ext])
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\core.py", line 169, in setup
    return old_setup(**new_attr)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\core.py", line 148, in setup
    dist.run_commands()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 955, in run_commands
    self.run_command(cmd)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 974, in run_command
    cmd_obj.run()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\command\build.py", line 47, in run
    old_build.run(self)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\command\build.py", line 135, in run
    self.run_command(cmd_name)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\cmd.py", line 313, in run_command
    self.distribution.run_command(command)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 974, in run_command
    cmd_obj.run()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\command\build_ext.py", line 117, in run
    force=self.force)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\ccompiler.py", line 733, in new_compiler
    compiler = klass(None, dry_run, force)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 104, in __init__
    build_import_library()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 416, in build_import_library
    return _build_import_library_amd64()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 472, in _build_import_library_amd64
    generate_def(dll_file, def_file)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 302, in generate_def
    raise ValueError("Symbol table not found")
ValueError: Symbol table not found

El problema parece estar relacionado con la compilación de libpython36.a desde python36.dll .

Después de una búsqueda rápida en Google, se utilizó una sugerencia sobre un foro de github para pywafo el compilador msvc en lugar de mingw32, lo que lleva al método 2.

Método 2: Para el fondo, los archivos relacionados con mi msvc se están extrayendo de C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX86\x64\. No estoy seguro si eso es útil.

Ejecuto f2py -c igrf12.pyf igrf12.f --compiler=msvc. Esto produce dos archivos:

  • pyigrf12.cp36-win_amd64.pyd en mi directorio de trabajo actual y,
  • libigrf12.BMWM6WD5Y3O3UTOEQITBXCIICXVMBEZS.gfortran-win_amd64.dll en .\UNKNOWN\.libs\

Cuando intento import pyigrf12, primero recibo ImportError: DLL load failed: The specified module could not be found. Al usar Dependency Walker, recibo muchos errores:

f2py Dependency Walker Output

Pero el más obvio para abordar está relacionado con el libigrf12.BMWM6WD5Y3O3UTOEQITBXCIICXVMBEZS.gfortran-win_amd64.dll. Muevo este archivo dll libigrf12 a mi directorio de trabajo actual, junto con pyigrf12.cp36-win_amd64.pyd.

Ahora, cuando pruebo import pyigrf12, recibo ImportError: DLL load failed: %1 is not a valid Win32 application.. Algunas publicaciones de stackoverflow parecen indicar que se trata de un problema con un conflicto entre un dll de 32 bits y un Python de 64 bits. ¿Alguien puede ofrecer información sobre esto? Después de más búsquedas, decidí intentar usar la versión anaconda de mingw y libpython.

Método 3:

Ejecuto conda install mingw libpython e instala mingw 4.7-1 y libpython 2.1-py36_0. Ejecuto f2py -c igrf12.pyf igrf12.f --compiler=mingw32 y falla con el siguiente mensaje de error:

Building msvcr library: 
"C:\Users\Sholes\AppData\Local\Continuum\anaconda3\libs\libvcruntime140.a" 
(from C:\Users\Sholes\AppData\Local\Continuum\anaconda3\vcruntime140.dll)
    objdump.exe: C:\Users\Sholes\AppData\Local\Continuum\anaconda3\vcruntime140.dll: File format not recognized
    Traceback (most recent call last):
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\Scripts\\f2py.py", line 28, in <module>
        main()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\f2py\f2py2e.py", line 648, in main
        run_compile()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\f2py\f2py2e.py", line 633, in run_compile
        setup(ext_modules=[ext])
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\core.py", line 169, in setup
        return old_setup(**new_attr)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\core.py", line 148, in setup
        dist.run_commands()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 955, in run_commands
        self.run_command(cmd)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 974, in run_command
        cmd_obj.run()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\command\build.py", line 47, in run
        old_build.run(self)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\command\build.py", line 135, in run
        self.run_command(cmd_name)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\cmd.py", line 313, in run_command
        self.distribution.run_command(command)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 974, in run_command
        cmd_obj.run()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\command\build_ext.py", line 117, in run
        force=self.force)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\ccompiler.py", line 733, in new_compiler
        compiler = klass(None, dry_run, force)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 107, in __init__
        msvcr_success = build_msvcr_library()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 399, in build_msvcr_library
        generate_def(dll_file, def_file)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 302, in generate_def
        raise ValueError("Symbol table not found")
    ValueError: Symbol table not found

Ahora el problema parece estar relacionado con la construcción de lib vcruntime140.a desde vcruntime140.dll. Una vez más, objdump.exe no reconoce el formato de archivo dll.

Método 4:

Mi último intento fue ejecutar f2py -c igrf12.pyf igrf12.f --compiler=msvc con la versión anaconda de mingw instalada. Para este caso, gfortran falló con este error:

   C:\Users\Sholes\AppData\Local\Continuum\anaconda3\Scripts\gfortran.bat -Wall -g -Wall -g -shared 
..\..\..\AppData\Local\Temp\tmpugo__0q9\Release\igrf12.o -Lc:\users\sholes\appdata\local\continuum\anaconda3\mingw\lib\gcc\x86_64-w64-mingw32\4.7.0 -LC:\Users\Sholes\AppData\Local\Continuum\anaconda3\libs -LC:\Users\Sholes\AppData\Local\Continuum\anaconda3\PCbuild\amd64 -o C:\Users\Sholes\AppData\Local\Temp\tmpugo__0q9\Release\extra-dll\libigrf12.75XJA5DX6DTO7YIZ7X6ZHJYTRDCCYQYR.gfortran-win_amd64.dll -Wl,--allow-multiple-definition -Wl,--output-def,C:\Users\Sholes\AppData\Local\Temp\tmpugo__0q9\Release\libigrf12.75XJA5DX6DTO7YIZ7X6ZHJYTRDCCYQYR.gfortran-win_amd64.def -Wl,--export-all-symbols -Wl,--enable-auto-import -static -mlong-double-64

gfortran.exe: error: unrecognized command line option '-mlong-double-64'

En este punto, solo quiero saber si es posible crear extensiones de fortran con mi configuración y f2py. No tengo experiencia en la compilación de extensiones C o fortran en Windows, y según todas las preguntas relacionadas con problemas con la instalación de Python 3.6 scipy y numpy en Windows, parece que este es un problema común sin una solución simple.

Cualquier comentario o conocimiento será muy apreciado.

7
dsholes 16 feb. 2018 a las 14:57

2 respuestas

La mejor respuesta

Finalmente conseguí que esto funcionara.

Versión corta:

Asegúrese de utilizar compiladores de 64 bits (verifique tres veces la compilación para mingw-w64) para Python de 64 bits. No es tan obvio como parece para un f2py novato en Windows.

Versión larga:

Desinstalé mi copia existente de MinGW (sospecho que era una versión de 32 bits) y en su lugar descargué una compilación específica de 64 bits de mingw-w64 7.2.0 de sourceforge, específicamente x86_64-7.2.0-release-posix-seh-rt_v5-rev1.7z. Esta pregunta de stackoverflow fue útil.

Descomprimí y copié la carpeta "mingw64" en mi unidad C: (C:\mingw64). Agregué C:\mingw64\bin a mi ruta de usuario.

Desinstalé la versión anaconda de MinGW con conda uninstall mingw. Tenga en cuenta que esto solo es necesario si instaló previamente MinGW con conda.

Al ejecutar f2py -c igrf12.pyf igrf12.f --compiler=mingw32 (en el mismo directorio que igrf12.pyf, consulte Documentación de Scipy sobre cómo generar un archivo * .pyf), pyigrf12.cp36-win_amd64.pyd se crea sin ningún error. Finalmente puedo import pyigrf12 con éxito y acceder a las subrutinas Fortran subyacentes (por ejemplo, igrf12syn).

Tenga en cuenta que también puedo ejecutar f2py -c igrf12.pyf igrf12.f --compiler=msvc correctamente, pero luego tengo que copiar y pegar manualmente libigrf12....gfortran-win_amd64.dll (generado en .\UNKNOWN\.libs\) en el mismo directorio que pyigrf12.cp36-win_amd64.pyd para evitar { {X4}} mencionado en el Método 2 de mi pregunta.

Solo para repetir: ¡Asegúrese de que C:\mingw64\bin se agregue a su ruta!

Por cierto, f2py fue sencillo para mí en macOS Sierra y Ubuntu. Si lo anterior aún no funciona para usted, le recomiendo probar en Linux, macOS o Subsistema de Windows para Linux.

9
talonmies 7 may. 2020 a las 19:11

Tuve el mismo problema, en particular: ValueError: Symbol table not found del método 3.

respuesta de dsholes fue la solución, más 2 puntos menores:

  • desinstalar todas las versiones de mingw
  • descargar mingw64 (en mi caso: x86_64-8.1.0-posix-seh-rt_v6-rev0), instalarlo
  • Agregar mingw64/bin a la RUTA
  • Luego la compilación con f2py -c fortran_file.F90 -m module_name --compiler = mingw32 funciona bien y se puede importar correctamente en Python: import module_name

Sin embargo:

  1. sus módulos deben compilarse en la misma partición de Windows en la que está instalado Mingw32. De lo contrario (mingw estaba en C:\, mi proyecto en D:\, obtengo el siguiente error, debido a que las rutas relativas no se leen de una partición a otra: f2py target file 'C:\\...' not generated

  2. el archivo compilado aún puede requerir algunas bibliotecas externas. En mi caso, el libquadmath-0.dll en mingw64 \ bin es necesario y debería permanecer en la RUTA en todo momento. De lo contrario, aparece el siguiente error: ImportError: DLL load failed:. Terminé identificando estos dll y copiándolos dentro de mi proyecto.

0
erwanp 4 jul. 2018 a las 22:17