pip install 은 먼저 휠(.whl)을 찾는다. 플랫폼·파이썬 버전에 맞는 휠이 없으면 소스 배포판(.tar.gz)을 받아 그 자리에서 컴파일한다. C 확장을 쓰는 패키지에서 이때 각종 오류가 난다.
먼저 확인할 것은 정말로 휠이 없는가 이다. 있는데도 소스로 가는 것이라면 환경 쪽 문제다.
pip download --only-binary=:all: mysqlclient -d /tmp/gpt_rest_5_wheel_check
받아지면 휠이 있는 것이다. 이 경우 pip 나 setuptools 가 낡아 휠 태그를 이해하지 못하는 경우가 많다.
python -m pip install --upgrade pip setuptools wheel
ERROR: Package 'xxx' requires a different setuptools: 61.0 not in '>=61.0'
또는 72 를 깔았는데 61 이상이 필요하다고 나온다. 원인은 대개 보고 있는 환경이 다른 것이다.
빌드는 기본적으로 격리된 임시 환경에서 돈다(PEP 517). 그 환경은 pyproject.toml 의 build-system.requires 를 보고 필요한 것을 새로 받는다. 즉 현재 가상환경에 72 가 있어도 빌드 환경은 별개다.
무엇이 어디에 깔려 있는지 먼저 확정한다.
which -a python pip
python -c 'import sys, setuptools; print(sys.executable, setuptools.__version__)'
python -m pip --version
pip 명령이 다른 인터프리터를 가리키는 일이 흔하므로 python -m pip 형태로 통일한다.
격리 환경이 낡은 setuptools 를 받아 오는 것이 문제라면 격리를 끄고 현재 환경의 것을 쓰게 한다. 폐쇄망에서도 이 방법을 쓴다.
python -m pip install --no-build-isolation mysqlclient
이때는 setuptools, wheel, 그리고 그 패키지가 요구하는 빌드 도구가 현재 환경에 미리 깔려 있어야 한다.
/usr/bin/ld: cannot find -lz
/usr/bin/ld: cannot find -lssl
라이브러리 자체가 아니라 개발 패키지가 없는 것이다. 실행용 .so 는 있어도 링크에 필요한 헤더와 심볼릭 링크는 -devel 패키지에 들어 있다.
sudo dnf install -y zlib-devel openssl-devel
Debian 계열은 이름이 다르다.
sudo apt-get install -y zlib1g-dev libssl-dev
fatal error: Python.h: No such file or directory
파이썬 개발 헤더가 없다. 여러 파이썬이 깔려 있으면 빌드에 쓰는 그 버전의 헤더가 필요하다.
sudo dnf install -y python3-devel
소스 빌드로 설치한 파이썬이라면 그 설치 경로 안에 헤더가 있다. 확인한다.
python -c 'import sysconfig; print(sysconfig.get_paths()["include"])'
ls "$(python -c 'import sysconfig; print(sysconfig.get_paths()["include"])')/Python.h"
mysqlclient 는 빌드할 때 mysql_config 또는 mariadb_config 를 찾아 컴파일 옵션을 얻는다. 없으면 실패한다.
sudo dnf install -y mariadb-connector-c-devel
which mysql_config mariadb_config
표준 경로에 없으면 위치를 알려 준다.
export MYSQLCLIENT_CFLAGS="$(mariadb_config --cflags)"
export MYSQLCLIENT_LDFLAGS="$(mariadb_config --libs)"
python -m pip install mysqlclient
두 변수를 주면 mysqlclient 가 설정 도구를 찾지 않고 그 값을 그대로 쓴다.
pip list | grep -i unknown
UNKNOWN 0.0.0
패키지 메타데이터를 읽지 못한 채 설치된 것이다. 원인은 둘 중 하나다.
setuptools 가 pyproject.toml 만 있는 패키지를 이해하지 못했다.pip install . 을 돌려 빈 프로젝트를 설치했다.지우고 도구를 올린 뒤 다시 깐다.
python -m pip uninstall -y UNKNOWN
python -m pip install --upgrade pip setuptools wheel
python -m pip install --no-cache-dir <패키지>
--no-cache-dir 을 주는 이유는 잘못 만들어진 결과물이 캐시에 남아 다시 쓰이는 것을 막기 위해서다.
의존성 해결이 꼬였거나 이미 다른 경로로 깔아 둔 것이 있으면 의존성 설치를 막는다.
python -m pip install --no-deps <패키지>
의존성이 실제로 없어도 된다는 판단이 선 경우에만 쓴다. 나중에 실행 시점에 ImportError 로 되돌아온다.