Создание модуля python и привязка его к среде MacOSX

Я пытаюсь построить расширение Python на MacOSX 10.6 и связать его с несколькими фреймворками (только для i386). Я создал файл setup.py, используя distutils и объект Extension.

Я хочу связать себя с моими фреймворками, мой LDFLAGS env var должен выглядеть так:

LDFLAGS = -lc -arch i386 -framework fwk1 -framework fwk2 

Поскольку я не нашел ключевое слово 'framework' в документации модуля расширения, вместо этого я использовал ключевое слово extra_link_args .

 Extension('test', define_macros = [('MAJOR_VERSION', '1'), ,('MINOR_VERSION', '0')], include_dirs = ['/usr/local/include', 'include/', 'include/vitale'], extra_link_args = ['-arch i386', '-framework fwk1', '-framework fwk2'], sources = "testmodule.cpp", language = 'c++' ) 

Все компилируется и хорошо связывается. Если я удаляю строку -framework из extra_link_args, мой компоновщик терпит неудачу, как и ожидалось. Вот две последние строки, созданные командой python setup.py:

 /usr/bin/g++-4.2 -arch x86_64 -arch i386 -isysroot / -L/opt/local/lib -arch x86_64 -arch i386 -bundle -undefined dynamic_lookup build/temp.macosx-10.6-intel-2.6/testmodule.o -o build/lib.macosx-10.6-intel-2.6/test.so -arch i386 -framework fwk1 -framework fwk2 

К сожалению, .so, что я только что создал, не может найти несколько символов, предоставленных этой структурой. Я попытался проверить связанную структуру с otool. Ни один из них не появляется.

 $ otool -L test.so test.so: /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.1) 

На выходе тестового двоичного файла выполняется вывод otool, созданный с помощью g ++ и ldd, используя LDFLAGS, описанные в верхней части сообщения. В этом примере работа -framework действительно работала.

 $ otool -L vitaosx vitaosx: /Library/Frameworks/fwk1.framework/Versions/A/fwk1 (compatibility version 1.0.0, current version 1.0.0) /Library/Frameworks/fwk2.framework/Versions/A/fwk2 (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.1) 

Может ли эта проблема быть связана с флагом «-undefined dynamic_lookup» на этапе связывания? Я немного смущен несколькими строками документации, которые я нахожу в Google.

Ура,

5 Solutions collect form web for “Создание модуля python и привязка его к среде MacOSX”

Это не имеет ничего общего с неопределенным dynamic_lookup, но все с distutils. Он добавляет extra_link_flags к флагам ссылок, которые он выбирает для построения python. Вместо этого он должен добавить его, потому что списки -framework должны появиться перед объектами, которые используют их в cmdline (AFAIK это связано с тем, как gcc собирает символы для привязки). Быстрое исправление, которое я лично использую,

  LDFLAGS="-framework Carbon" python setup.py build_ext --inplace 

или какие-либо рамки, в которых вы нуждаетесь. LDFLAGS добавляется к distutils собственным флагам. Обратите внимание, что ваш пакет не будет pip install пакета. Правильное исправление может исходить только от distutils – имхо они должны поддерживать frameworks такую ​​как поддержка libraries .

Кроме того, вы также можете добавить

 import os os.environ['LDFLAGS'] = '-framework Carbon' 

в вашем setup.py. После этого ваш пакет должен быть pip install .

Я не уверен, что понимаю, что вы пытаетесь сделать, и ваш желаемый результат, но, возможно, это поможет. Поскольку модули расширения C обычно запускаются в контексте выполнения интерпретатора Python, модули расширения должны быть построены для совместимости с интерпретатором. В OS X Python и distutils сталкиваются с некоторыми проблемами, чтобы обеспечить, чтобы модули расширения C были построены с тем же значением SDK ( -sysroot ), значением -arch и -arch поскольку сам интерпретатор Python был первоначально построен. Итак, если вы используете поставляемый Apple Python на 10.6, distutils будет поставлять -arch i386 -arch ppc -arch x86_64 , три арки, с которыми он был построен. Если вы используете текущий установщик python.org OS X (по 10.6, 10.5 или 10.4), он будет использовать:

 gcc-4.0 -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk 

Из предоставленных фрагментов, я предполагаю, что вы используете универсальный Python, установленный на MacPorts, и по умолчанию он построен и использует -arch x86_64 -arch i386 -isysroot / для создания модулей расширения.

Как правило, чтобы все работало, вам необходимо обеспечить:

  1. по крайней мере, одна arch среди интерпретатора, все модули расширения C и все внешние фреймворки и / или разделяемые библиотеки, к которым они ссылаются

  2. интерпретатор выполняет эту (или одну из них) общую архитектуру (ы).

В OS X 10.6 этот последний шаг не так прост, как в зависимости от того, какой Python вы используете. Например, поставляемый Apple Python 2.6 имеет модификацию для принудительного 32-разрядного исполнения (подробнее см. В руководстве пользователя Apple man python ):

 export VERSIONER_PYTHON_PREFER_32_BIT=yes 

Если вы создадите собственный 32- / 64-битный универсальный Python, в 2.6.5 есть исправления, позволяющие выбирать во время выполнения. К сожалению, способ, которым MacPorts создает Python, обходит эти исправления, поэтому не существует простого способа заставить MacPorts 32-разрядную универсальную сборку python2.6 для 32.6 / 64-разрядной версии на 10.6 для работы в 32-разрядном режиме. По сложным причинам он всегда будет предпочитать 64-битный, если он доступен, даже если вы используете /usr/bin/arch -i386 .

Таким образом, в зависимости от того, что вы пытаетесь сделать, вы можете решить эту проблему (если я правильно ее понимаю):

  1. перестройте свои рамки, чтобы включить -arch x86_64
  2. используйте поставляемый Apple Python ( /usr/bin/python ) в 32-битном режиме или python.org 2.6.5
  3. переустановите python MacPorts в 32-разрядном режиме (непроверенный!):

     sudo port selfupdate sudo port clean python26 sudo port install python26 +universal universal_archs=i386 

Хотя долго после того, как пыль уладилась, имея тот же вопрос, я немного порылся и нашел это:

/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/distutils/sysconfig.py

  if 'ARCHFLAGS' in os.environ: archflags = os.environ['ARCHFLAGS'] else: archflags = '-arch i386 -arch ppc -arch x86_64' _config_vars['ARCHFLAGS'] = archflags if archflags.strip() != '': _config_vars['CFLAGS'] = _config_vars['CFLAGS'] + ' ' + archflags _config_vars['LDFLAGS'] = _config_vars['LDFLAGS'] + ' ' + archflags 

Я подхожу к проблеме под другим углом – на 10.6 distutils пытается построить расширения C и жаловаться, потому что в 10.6 SDK нет части PPC.

Однако,

  export ARCHFLAGS="-arch i386 -arch x86_64" python setup.py build 

Работал как шарм.

Кажется, что моя структура скомпилирована для ppc и i386, но не x86_64:

 $ file /Library/Frameworks/fwk1.framework/Versions/A/fwk1 /Library/Frameworks/fwk1.framework/Versions/A/fwk1: Mach-O universal binary with 2 architectures /Library/Frameworks/fwk1.framework/Versions/A/fwk1 (for architecture ppc): Mach-O dynamically linked shared library ppc /Library/Frameworks/fwk1.framework/Versions/A/fwk1 (for architecture i386): Mach-O dynamically linked shared library i386 

Я удалил флаг -arch x86_64 из моей линии ссылок. Моя библиотека связана с моими фреймворками:

 $ otool -L test.so test.so: /Library/Frameworks/fwk1.framework/Versions/A/fwk1 (compatibility version 1.0.0, current version 1.0.0) /Library/Frameworks/fwk2.framework/Versions/A/fwk2 (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.1) 

Если кто-то знает, как заставить -arch использоваться при компиляции и времени ссылки с distutils Python …, пожалуйста, поделитесь своими советами.

Я просто наткнулся на это сам. Мне пришлось обходить distutils, потому что они, похоже, жестко кодируют -строенный динамический_очень. Вот Makefile, который я использую для эмуляции distutils:

 CC = gcc CFLAGS = -pipe -std=c99 -fno-strict-aliasing -fno-common -dynamic -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Werror -pedantic -Wall -Wstrict-prototypes -Wshorten-64-to-32 -g -Os -arch i386 -arch x86_64 -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 LD = gcc LDFLAGS = -Wl,-F. -bundle -Wl,-F. -arch i386 -arch x86_64 -framework CoreFoundation -framework CoreMIDI -framework Python project = <extension_name> library = $(project).so modules = <module_names> sources = $(foreach module,$(modules),$(module).c) objects = $(sources:.c=.o) all: $(library) $(library): $(objects) $(LD) $(LDFLAGS) $(objects) -o $@ %.o: %.c Makefile $(CC) $(CFLAGS) $< -c -o $@ install: $(library) cp $(library) /Library/Python/2.7/site-packages clean: rm -f $(library) $(objects) *~ 

Я уверен, что есть способ заставить distutils прекратить выдавать этот неопределенный аргумент, но выше это работало для меня на 10.7

  • Что я делаю неправильно при установке lxml на Mac OS X 10.8.1?
  • Несколько проектов с использованием нескольких скриптов setup.py?
  • Я не могу понять, почему в этом коде есть синтаксическая ошибка
  • Поиск текущего активного окна в Mac OS X с использованием Python
  • Python запрашивает более старые пути на Mac после удаления дублированной установки python
  • Как установить django для python 3.3
  • Настройка пункта меню меню меню приложения Mac OSX, отличного от «Python» в моем приложении Qt python
  • Как я могу найти полный путь к шрифту из его отображаемого имени на Mac?
  • Python - лучший язык программирования в мире.