728x90

간만에 Swift 환경으로 넘어오니 묵혀있던 애플 M1 환경에서의 에러 공습이 시작되었습니다. cocoapod 설치까지는 잘 진행되었으나 필요한 의존성을 Podfile에 기술하고 설치하는 작업에서 문제가 생겼습니다. 설치하고자 한 의존성은 Alamofire 였습니다. 

# Podfile
target 'ch6' do
  use_frameworks!
  pod 'Alamofire', '~> 5.4'
end

 

에러 메세지도 한번 보고나서 트러블 슈팅을 진행해 보겠습니다. M1 을 쓰기 전이었다면 다른 케이스를 먼저 의심했겠지만, M1을 쓰기 시작한 후부터 이런 단순한 작업에서 에러가 발생하면 일단 M1 환경 문제로 보는 습관이 생겼습니다 ㅎㅎ

% pod install
Analyzing dependencies
/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi/library.rb:275: [BUG] Bus Error at 0x00000001012d4000
ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.arm64e-darwin20]

-- Crash Report log information --------------------------------------------
   See Crash Report log file under the one of following:
     * ~/Library/Logs/DiagnosticReports
     * /Library/Logs/DiagnosticReports
   for more details.
Don't forget to include the above Crash Report log file in bug reports.

-- Control frame information -----------------------------------------------
c:0049 p:---- s:0307 e:000306 CFUNC  :attach
c:0048 p:0258 s:0301 e:000300 METHOD /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi/library.rb:275
c:0047 p:0050 s:0281 e:000280 CLASS  /Library/Ruby/Gems/2.6.0/gems/ethon-0.14.0/lib/ethon/libc.rb:17
...
..
..
...
  653 /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi/autopointer.rb
  654 /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi/variadic.rb
  655 /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi/enum.rb
  656 /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi/version.rb
  657 /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi/ffi.rb
  658 /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi.rb

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: https://www.ruby-lang.org/bugreport.html

[IMPORTANT]
Don't forget to include the Crash Report log file under
DiagnosticReports directory in bug reports.

zsh: abort      pod install

 

이제 정답을 찾기 위해 열심히 구글링을 했고 두가지 정도의 방법을 찾았습니다.

방법#1. cocoapod 를 실행하는 터미널을 Rosetta 로 실행하기

M1 에서 호환성 문제를 해결하기 위해 가장 먼저 사용해 볼 수 있는 것이 Rosetta 입니다. iTerm 을 터미널 클라이언트로 쓰고 있기 때문에 "파인더 > 응용프로그램"에서 iTerm을 찾아 속성에서 Rosetta 를 켜주면 됩니다. 

 

이제 동작중인 터미널을 종료하고 pod install 을 다시 수행해봅니다. 하지만 여전히 에러가 발생합니다. 

% pod install
Analyzing dependencies

[!] Automatically assigning platform `iOS` with version `15.0` on target `ch6` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.
Traceback (most recent call last):
	45: from /usr/local/bin/pod:23:in `<main>'
	44: from /usr/local/bin/pod:23:in `load'
	43: from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/bin/pod:55:in `<top (required)>'
	42: from /Library/Ruby/Gems/2.6.0/gems/cocoapods-1.11.2/lib/cocoapods/command.rb:52:in `run'
	41: from /Library/Ruby/Gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:334:in `run'
    ...
    ..
    ..
    ...
    	 1: from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': dlopen(/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi_c.bundle, 9): no suitable image found.  Did find: (LoadError)
	/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi_c.bundle: mach-o, but wrong architecture
	/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi_c.bundle: mach-o, but wrong architecture - /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi_c.bundle
	36: from /usr/local/bin/pod:23:in `<main>'
	35: from /usr/local/bin/pod:23:in `load'
    ...
    ..
    ..
    ...
    	 3: from /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi.rb:2:in `<top (required)>'
	 2: from /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi.rb:5:in `rescue in <top (required)>'
	 1: from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': dlopen(/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi_c.bundle, 9): no suitable image found.  Did find: (LoadError)
	/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi_c.bundle: mach-o, but wrong architecture
	/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi_c.bundle: mach-o, but wrong architecture - /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi_c.bundle

 

에러 메세지를 참고하여 ffi에 문제가 있다는 것을 확인하고 재설치를 진행해 봅니다. 이후 다시 pod install 을 수행하면 문제가 해결된다고 합니다. 제 경우는 아쉽게도...

% sudo gem install ffi
% pod install

 

 

방법#2. Ruby FFI 라이브러리 업데이트 후 재설치

에러 메세지에 아키텍쳐 관련한 내용이 계속 나오는 것에 착안하여 사람들이 올려둔 방법중 아키텍쳐 관련된 것들을 사용해 보았습니다. ffi를 설치할 때 아키텍쳐를 x86_64 로 지정하여 설치하는 방식입니다. (M1은 arm 기반이라 arch 명령을 수행해보면 arm64 라고 나옵니다)

% sudo arch -x86_64 gem install ffi
Password:
Fetching ffi-1.15.4.gem
Building native extensions. This could take a while...
Successfully installed ffi-1.15.4
Parsing documentation for ffi-1.15.4
Installing ri documentation for ffi-1.15.4
Done installing documentation for ffi after 9 seconds
1 gem installed

 

설치만 하면 pod install 이 동작할까요? 아닙니다. 그냥 pod install 명령을 사용하면 아키텍쳐가 arm64 로 인식되기 때문에 여전히 아키텍쳐 관련한 호환성 문제가 발생합니다. 대신 명령 앞에 아키텍쳐를 지정해서 실행해 보도록 하겠습니다. 

% arch -x86_64 pod install
Analyzing dependencies
Downloading dependencies
Installing Alamofire (5.4.4)
Generating Pods project
Integrating client project
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.

 

잘 되는군요. :-)

728x90
728x90

M1 silicon 맥북에서는 안되는게 참 많습니다. 새로운 CPU 아키텍쳐라서 여기저기서 패키지들이 오동작하거나 설치가 안되는 문제들이 많이 발생합니다. 오늘의 주인공인 파이썬 cryptography 패키지도 마찬가지입니다. 그나마 이 녀석은 에러가 나름 명확한 친구임에도 문제를 해결하기 위해 적지 않은 시간을 쏟아야 했습니다.

우선 에러 메세지 보고 가시겠습니다. :-) 이 에러 메세지는 pip install -r requirements.txt 를 수행하는 동안 발생헀고 requirements.txt 에는 cryptography가 기술되어 있었습니다. (드라마 24시에서 Following takes place... 하는 느낌이네요)

Building wheels for collected packages: cryptography
  Building wheel for cryptography (PEP 517) ... error
  ERROR: Command errored out with exit status 1:
...
...
 ...
    clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -iwithsysroot/System/Library/Frameworks/System.framework/PrivateHeaders -iwithsysroot/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/Headers -arch arm64 -arch x86_64 -Werror=implicit-function-declaration -I/Users/nopd/project/venv/include -I/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/include/python3.8 -c build/temp.macosx-10.14.6-arm64-3.8/_openssl.c -o build/temp.macosx-10.14.6-arm64-3.8/build/temp.macosx-10.14.6-arm64-3.8/_openssl.o -Wconversion -Wno-error=sign-conversion
  build/temp.macosx-10.14.6-arm64-3.8/_openssl.c:575:10: fatal error: 'openssl/opensslv.h' file not found
  #include <openssl/opensslv.h>
           ^~~~~~~~~~~~~~~~~~~~
  1 error generated.
  
      =============================DEBUG ASSISTANCE=============================
      If you are seeing a compilation error please try the following steps to
      successfully install cryptography:
      1) Upgrade to the latest pip and try again. This will fix errors for most
         users. See: https://pip.pypa.io/en/stable/installing/#upgrading-pip
      2) Read https://cryptography.io/en/latest/installation.html for specific
         instructions for your platform.
      3) Check our frequently asked questions for more information:
         https://cryptography.io/en/latest/faq.html
      =============================DEBUG ASSISTANCE=============================
  
  error: command 'clang' failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for cryptography
Failed to build cryptography
ERROR: Could not build wheels for cryptography which use PEP 517 and cannot be installed directly

 

화려한 에러 메세지이지만 결론은 설치가 잘 안되었다 입니다. DEBUG ASSISTANCE의 내용은 평이합니다. PIP가 구버전이라 그럴 수 있으니 업데이터 해보고 cryptography 설치 가이드 문서를 읽어 본 다음, faq에 단서가 있을지도 모르니 찾아보라는 내용입니다. TL;DR 하자면 아래의 한줄이 모든 것을 이야기 해주고 있었습니다.

build/temp.macosx-10.14.6-arm64-3.8/_openssl.c:575:10: fatal error: 'openssl/opensslv.h' file not found

 

Trouble Shoot #1 - Install separate openssl with brew

구글 검색을 통해 살펴봤던 문서를 종합해보면 M1 silicon 기종에 선탑재되어 나오는 openssl이 cryptography 빌드에 필요한 버전과 상이하다고 합니다. 실제로 M1 silicon 탑재 기종에서 openssl version 명령으로 버전을 확인해보면 LibreSSL 이 설치되어 있는 것을 알 수 있습니다. 아래와 같이 brew 를 이용해 openssl 을 별도로 설치해 보도록 하겠습니다. 공식 가이드에서 안내하는 1.1 버전을 지정해서 설치 진행했습니다. 

cryptography 설치 가이드의 안내  (https://cryptography.io/en/latest/installation/)

% openssl version
LibreSSL 2.8.3
% brew install openssl@1.1 rust
Updating Homebrew...

 

Trouble Shoot #2 - Uninstall cffi then install cryptography again

별도의 openssl 설치와 혹시 몰라서 rust(cryptography는 rust를 사용합니다)를 설치하는 작업이 끝나면 이제 파이썬 패키지중에서 C언어를 호출할 때 사용되는 cffi 도 삭제후에 다시 설치해 주도록 하겠습니다. 아래의 명령을 순서대로 터미널에서 입력하면 cryptography 가 설치됩니다. 제 경우 cryptography를 3.3.1 버전으로 지정해서 사용할 일이 있어서 버전을 지정했습니다만 그렇지 않은 경우에는 버전 정보를 빼고 설치하면 되겠습니다. 

% pip uninstall cffi
% LDFLAGS=-L$(brew --prefix libffi)/lib CFLAGS=-I$(brew --prefix libffi)/include pip install cffi --no-binary :all:
% LDFLAGS="-L$(brew --prefix openssl@1.1)/lib" CFLAGS="-I$(brew --prefix openssl@1.1)/include" pip install cryptography==3.3.1

 

문제가 해결되었습니다. 비슷한 이슈를 겪는 분들은 정리된 내용대로 패키지 삭제, 재설치를 진행해 보시기 바랍니다. 영어로 된 자료도 흥미롭게 읽을 수 있다면 보다 깊은 내용과 관련 링크가 공유된 stackoverflow 의 아래 스레드를 읽어 보시면 도움이 되겠습니다!

 

Installing Cryptography on an Apple Silicon M1 Mac

Help! I'm trying to install cryptography on my m1. I know I can run terminal in rosetta mode, but I'm wondering if there is a way not to do that. Output: ERROR: Command errored out with exit st...

stackoverflow.com

 

Hope this helpful to someone who experiencing similar issue.

728x90
728x90

애플실리콘 기반의 맥북이 등장하면서 세상이 참 행복해졌습니다. 베터리도 오래가고 이륙하지도 않고... 이렇게 쾌적한 맥 운영체제는 간만에 느껴보는 즐거움이었습니다. 하지만 의외의 장소에서 복병을 만나게 될줄은 몰랐고 비슷한 짜증을 경험할 수 있는 누군가(아마도 미래의 나...)를 위해 메모를 남겨 둡니다. 뜬금 없이 왜 애플실리콘 이야기인가...는 글을 읽으시면서 알 수 있게 됩니다. 


맥 환경에서 운영체제 패키지 관리를 위해 Homebrew를 보통 사용하게 됩니다. python의 유명한 라이브러리 중 하나인 magic을 사용하기 위해서는 운영체제 환경에 libmagic 패키지를 설치해 둘 필요가 있습니다. 

  1. virtualenv 로 가상 환경 구성 및 activate
  2. pip install 로 requirements.txt의 항목 설치

를 하고 디버깅을 시작하는데 import magic 에서 에러가 발생했습니다. 가상 환경에서 magic 패키지가 잘 설치되어 있고 brew 로 libmagic 설치를 확인해봐도 아무런 문제가 없는데 python이 계속 libmagic이 설치되었는지 확인하라고 짜증을 내더군요. 네, 저도 짜증이 나기 시작했습니다. 

% python3
Python 3.8.2 (default, Apr  8 2021, 23:19:18) 
[Clang 12.0.5 (clang-1205.0.22.9)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import magic
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "......./venv/lib/python3.8/site-packages/magic.py", line 176, in <module>
    raise ImportError('failed to find libmagic.  Check your installation')
ImportError: failed to find libmagic.  Check your installation

 

구글과 함께 문제의 원인과 해결방법을 찾아보면 대부분 패키지가 잘 설치되었는지 확인해봐라, brew 로 libmagic 설치하면 된다 류의 답변이 대부분입니다. 하지만 그 어떤 방법도 동작하지 않았습니다. 왜냐하면 python 패키지든 OS 패키지든 필요한 건 문제없이 다 설치되어 있었기 때문입니다.

두가지 방향으로 다시 조사를 시작했습니다. 범인은 brew와 pip 둘 중 하나일 것이라고 보고 brew에서 설치하는 libmagic과 pip를 통해 설치하는 magic(패키지명은 이것도 libmagic입니다)에 무슨 문제가 있는가... 하는 접근이었습니다. 먼저 발견한 흥미로운 단서는 brew에서 나왔습니다.

https://docs.brew.sh/FAQ

애플실리콘이 등장하면서 homebrew가 사용하는 기본 prefix 경로가 바뀌었다는 이야기가 FAQ에 등재되어 있었습니다. 기본 경로가 달라졌다는 것은 brew를 통해서 설치되는 패키지들도 경로가 달라졌다는 말이 됩니다. 그래 뭐 바뀌었겠지... 하다가 문득, python libmagic 패키지가 절대경로로 라이브러리를 참조하나? 싶은 생각이 들었고 python libmagic의 github 저장소를 들러보았습니다.

 

ahupp/python-magic

A python wrapper for libmagic. Contribute to ahupp/python-magic development by creating an account on GitHub.

github.com

유레카!

python libmagic 패키지가 운영체제의 libmagic 라이브러리를 참조하는 코드는 하드 코딩된 몇 가지 절대 경로를 탐색하도록 만들어져 있었습니다. 그 경로중 하나는 바로 brew가 인텔과 애플실리콘 환경에서 변화가 생긴 바로 그 경로였습니다. 오우... 코드에 기여할 수 있는 것인지 혹은 이미 이슈가 올라왔는지...는 조금 후에 생각하기로 하고 libmagic의 설치 경로를 확인해보고 symlink를 만들어 추정이 맞는지 시험해 보기로 했습니다.

(venv) % brew info libmagic
libmagic: stable 5.40 (bottled)
Implementation of the file(1) command
https://www.darwinsys.com/file/
/opt/homebrew/Cellar/libmagic/5.40 (339 files, 8.4MB) *
  Poured from bottle on 2021-05-18 at 15:25:48
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/libmagic.rb
License: Cannot Represent
==> Analytics
install: 13,403 (30 days), 39,666 (90 days), 127,530 (365 days)
install-on-request: 3,672 (30 days), 11,365 (90 days), 34,209 (365 days)
build-error: 0 (30 days)

 

우려했던, 그리고 Homebrew FAQ에서 알려줬던 것처럼 운영체제 패키지는 /opt/homebrew/Cellar/libmagic/{버전} 경로에 설치가 되어 있었습니다. 해당 경로에 진입하여 libmagic.dylib 의 정확한 경로를 확인하고 /usr/local/lib 로 이동해서 symlink 를 만들었습니다. 

% pwd        
/usr/local/lib
% ln -s /opt/homebrew/Cellar/libmagic/5.40/lib/libmagic.dylib libmagic.dylib
%

 

symlink 까지 만들어주고 다시 코드를 실행하니 import magic 구문에서 문제가 더 이상 발생하지 않았습니다. 보통 python 에서 패키지 문제가 생기면 1) 가상 환경에 설치가 되었는지 보고, 2) 버전을 타는 문제가 있나 확인하는 정도로 문제가 해결되었는데 이번 케이스는 좀 그렇지 않아 시간을 은근히 쓸 수 밖에 없었네요. 금방 한것처럼 보이지만 구글링을 얼마나 했던지... 


 

728x90

+ Recent posts