Скомпилируйте модуль fortran с помощью f2py и Python 3.6 в Windows 10

Я пытаюсь (и не могу) скомпилировать модуль fortran (в частности, igrf12.f из BGS), используя f2py и Python 3.6 в Windows 10. Python был установлен с использованием Anaconda 4.4.10.

Моя настройка:

  • Python 3.6.3 | Anaconda custom (64-bit) | (по умолчанию 15 октября 2017 г., 03:27:45) [MSC v.1900 64 бит (AMD64)] на win32
  • Windows 10 Enterprise (версия 1703)
  • NumPy 1.14.0

Я следовал инструкциям f2py из документации SciPy и очень полезному руководству от доктора Майкла Хирша. Dr.Hirsch создал модуль pyigrf12, но мне не удалось выполнить установку через pip, что изначально вызвало у меня интерес к f2py.

Я опишу несколько методов, которые я использую. Независимо от метода, я всегда начинаю с создания файла подписи *.pyf, используя f2py igrf12.f -m pyigrf12 -h igrf12.pyf и добавление целевых (входных / выходных) атрибутов соответствующим образом.

  • Способ 1: используйте C:\MinGW и --compiler=mingw32
  • Способ 2: используйте C:\MinGW и --compiler=msvc
  • Способ 3: использовать анаконду версию Mingw и --compiler=mingw32
  • Способ 4: использовать анаконду версию Mingw и --compiler=msvc

Способ 1:

Для фона у меня есть MinGW в C:\MinGW, и я добавил C:\MinGW\bin в мой пользовательский путь. К сожалению, я не установил эту версию MinGW (я унаследовал этот компьютер от коллеги), поэтому я не знаю, откуда он был взят. Версия gcc - и версия gfortran - 5.3.0.

я бегу f2py -c igrf12.pyf igrf12.f --compiler=mingw32, Это не с этим сообщением об ошибке:

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

Кажется, проблема связана с сборкой libpython36.a из python36.dll.

После быстрого поиска в Google, на форуме github для pywafo было предложено использовать компилятор msvc вместо mingw32, что привело к методу 2.

Способ 2: для фона, файлы, связанные с моим msvc извлекаются из C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX86\x64\, Не уверен, что это полезно.

я бегу f2py -c igrf12.pyf igrf12.f --compiler=msvc, Это производит два файла:

  • pyigrf12.cp36-win_amd64.pyd в моем текущем рабочем каталоге и,
  • libigrf12.BMWM6WD5Y3O3UTOEQITBXCIICXVMBEZS.gfortran-win_amd64.dll в .\UNKNOWN\.libs\

Когда я пытаюсь import pyigrf12сначала получаю ImportError: DLL load failed: The specified module could not be found. Используя Dependency Walker, я получаю много ошибок:

Вывод зависимостей f2py

но самый очевидный для рассмотрения связан с libigrf12.BMWM6WD5Y3O3UTOEQITBXCIICXVMBEZS.gfortran-win_amd64.dll, Я перемещаю этот DLL-файл libigrf12 в свой текущий рабочий каталог, pyigrf12.cp36-win_amd64.pyd,

Теперь, когда я пытаюсь import pyigrf12, Я получил ImportError: DLL load failed: %1 is not a valid Win32 application., Кажется, что некоторые сообщения stackru указывают, что это проблема с конфликтом между 32-битным dll и 64-битным Python. Кто-нибудь может предложить понимание этого? После долгих поисков я решил попробовать использовать анаконду версии mingw и libpython.

Способ 3:

я бегу conda install mingw libpythonи устанавливает mingw 4.7-1 и libpython 2.1-py36_0. я бегу f2py -c igrf12.pyf igrf12.f --compiler=mingw32, и это терпит неудачу со следующим сообщением об ошибке:

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

Теперь проблема, похоже, связана со сборкой libvcruntime140.a из vcruntime140.dll. Еще раз формат файла dll не распознается objdump.exe.

Способ 4:

Моя последняя попытка была запустить f2py -c igrf12.pyf igrf12.f --compiler=msvc с установленной версией анаконды mingw. В этом случае gfortran не удалось с этой ошибкой:

   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'

На данный момент, я просто хочу знать, возможно ли создавать расширения на Fortran с моими настройками и f2py. У меня нет фоновой компиляции расширений C или Fortran в Windows, и, основываясь на всех вопросах, связанных с проблемами со скриптовой и неповоротливой установкой Python 3.6 в Windows, кажется, что это обычная проблема без простого решения.

Любая обратная связь или понимание будет принята с благодарностью.

2 ответа

Решение

Наконец-то все заработало.

Укороченная версия:

Убедитесь, что вы используете 64-битные компиляторы (трижды проверьте сборку для mingw-w64) для 64-битного Python. Не так очевидно, как кажется f2py новичок в Windows.

Длинная версия:

Я удалил свою существующую копию MinGW (я подозреваю, что это была 32-битная версия) и вместо этого загрузил конкретную 64-битную сборку mingw-w64 7.2.0 из sourceforge, в частности x86_64-7.2.0-release-posix-seh-rt_v5-rev1.7z, Этот вопрос о переполнении стека был полезен.

Я разархивировал и скопировал папку "mingw64" в мой диск C: (C:\mingw64). я добавил C:\mingw64\bin на мой пользовательский путь.

Я удалил версию MinGW для анаконды с conda uninstall mingw, Обратите внимание, это необходимо, только если вы ранее установили MinGW, используя conda,

После запуска f2py -c igrf12.pyf igrf12.f --compiler=mingw32 (в том же каталоге, что и igrf12.pyf, см. документацию Scipy для получения информации о создании файла *.pyf), pyigrf12.cp36-win_amd64.pyd создается без ошибок. Я могу наконец import pyigrf12 успешно и получить доступ к базовым подпрограммам Fortran (например, igrf12syn).

Обратите внимание, я также могу запустить f2py -c igrf12.pyf igrf12.f --compiler=msvc успешно, но затем я должен вручную скопировать и вставить libigrf12....gfortran-win_amd64.dll (генерируется в .\UNKNOWN\.libs\) в тот же каталог, что и pyigrf12.cp36-win_amd64.pyd избежать ImportError: DLL load failed: The specified module could not be found. упоминается в методе 2 моего вопроса.

Просто повторить: убедитесь, что C:\mingw64\bin добавлен на ваш путь!

Кстати, f2py было безболезненно для меня на macOS Sierra и Ubuntu. Если вышеупомянутое все еще не работает для вас, я рекомендую попробовать на Linux, macOS или Windows Subsystem для Linux.

Я была такая же проблема. Главный ответ очень помогает. Я хотел бы добавить несколько комментариев по поводу отсутствующих DLL. Полезный инструмент, который поможет вам узнать, какие библиотеки DLL отсутствуют, - это Process Monitor. Вам нужно только добавить фильтр python.exeи отслеживать, какие библиотеки DLL не удалось загрузить. Для меня отсутствуют следующие:

  • libgcc_s_seh-1.dll
  • libgfortran-5.dll
  • libquadmath-0.dll
  • libwinpthread-1.dll

Мне просто нужно скопировать их из bin/ каталог моей инструментальной цепочки MinGW в тот же каталог python.exe

У меня была такая же проблема, в частности: ValueError: Symbol table not found Способ 3.

Ответом dsholes было решение, плюс 2 незначительных момента:

  • удалить все версии minggw
  • скачать mingw64 (в моем случае: x86_64-8.1.0-posix-seh-rt_v6-rev0), установите его
  • добавлять mingw64/bin в путь
  • Тогда компиляция с f2py -c fortran_file.F90 -m module_name --compiler=mingw32 отлично работает и может быть правильно импортирован в Python: import module_name

Тем не мение:

  1. Ваши модули должны быть скомпилированы в том же разделе Windows, где установлен Mingw32. Остальное (mingw был под C:\Мой проект под D:\, Я получаю следующую ошибку, потому что относительные пути не читаются из одного раздела в другой: f2py target file 'C:\\...' not generated

  2. скомпилированный файл может все еще потребовать некоторых внешних библиотек. В моем случае libquadmath-0.dll в mingw64\bin необходим и должен всегда оставаться в PATH. В противном случае я получаю следующую ошибку: ImportError: DLL load failed:, В итоге я определил эти dll и скопировал их в свой проект.

Другие вопросы по тегам