fatal error: Python.h: No such file or directory 해결

1. 문제 정의

Python의 C 확장 모듈(shared library)을 빌드하려고 C 파일을 컴파일하는 과정에서 아래와 같은 컴파일 에러가 발생합니다.

1
gcc -Wall utilsmodule.c -o Utilc

실행 결과:

1
2
utilsmodule.c:1:20: fatal error: Python.h: No such file or directory
compilation terminated.

utilsmodule.c 의 첫 줄에 있는 #include <Python.h> 를 컴파일러가 찾지 못해 빌드가 중단된 상황입니다. 컴파일러(전처리기)는 헤더 파일을 찾지 못하면 fatal error 를 내고 즉시 종료합니다.

에러 발생 환경 요약

항목내용
증상fatal error: Python.h: No such file or directory
발생 지점컴파일 단계 (전처리기에서 #include <Python.h> 탐색 실패)
주요 원인 후보Python 개발 헤더 미설치, 컴파일러가 헤더 경로를 모름
대상Python C/C++ 확장 모듈 빌더

2. 원인 탐구

#include <Python.h> 는 C 전처리기가 헤더 탐색 경로(include path)에서 Python.h 라는 파일을 찾도록 지시합니다. 이 에러가 나는 이유는 크게 두 가지로 나뉩니다.

1) Python 개발 헤더 패키지가 설치되지 않은 경우

  • 대부분의 리눅스 배포판은 Python을 실행용 런타임과 개발용 헤더로 나누어 제공합니다.
  • python 이 설치되어 있어도 Python.h 는 별도의 -dev 패키지에 포함되는 경우가 많습니다.
  • 흔한 착각: Python이 잘 동작하는데도 이 에러가 나는 것은 런타임과 헤더가 별개이기 때문입니다.

2) 헤더가 설치되어 있어도 컴파일러가 경로를 모르는 경우

  • 기본 include 경로(/usr/include 등)에 Python.h 가 없는데, 사용자가 -I 옵션으로 경로를 알려주지 않으면 동일한 에러가 발생합니다.
  • StackOverflow의 해당 질문 작성자처럼 “Python.h 파일이 내 컴퓨터 어디 있는지는 아는데” 컴파일러가 그 위치를 모르는 경우가 전형적입니다.

3. 근본 원인 분석

근본 원인은 단순합니다. Python.h 파일이 컴파일러의 헤더 탐색 경로 밖에 있거나, 아예 설치되어 있지 않은 것입니다.

확인해 보는 명령은 아래와 같습니다.

1
2
3
# Python.h 가 실제로 존재하는지 확인
find /usr/include -name "Python.h" 2>/dev/null
python-config --includes   # Python이 제공하는 include 경로 출력
  • python-config --includes 의 출력 예: -I/usr/include/python2.7 -I/usr/include/python2.7
  • 이 경로가 바로 컴파일러에 넘겨줘야 할 include 경로입니다.

즉, “내가 실행 중인 Python의 헤더 경로가 어디인지” 를 찾아서 -I 옵션으로 명시해 주면 컴파일러는 Python.h 를 찾을 수 있습니다.

4. 코드 해결책

아래 두 가지 방법 중 상황에 맞게 선택하면 됩니다.

방법 A. 개발 헤더 패키지 설치 (권장)

Python 개발 헤더가 누락된 환경이라면 해당 OS에 맞는 패키지를 설치합니다.

1
2
3
4
5
6
7
# Debian / Ubuntu
sudo apt-get install python-dev        # Python 2.x
sudo apt-get install python3-dev       # Python 3.x

# RHEL / CentOS / Fedora
sudo yum install python-devel          # Python 2.x
sudo yum install python3-devel         # Python 3.x

설치 후 다시 컴파일하면 헤더가 기본 경로에 들어와 대부분 해결됩니다.

방법 B. 컴파일러에 헤더 경로 명시 (헤더가 이미 있는 경우)

Python.h 가 이미 시스템에 있는데 컴파일러가 못 찾는 경우, -I 옵션으로 디렉토리를 지정합니다. 공유 라이브러리로 빌드할 때는 -fPIC-lpython2.7 도 함께 지정해야 합니다.

StackOverflow에서 채택된 해결책은 아래 한 줄 명령입니다.

1
gcc -shared -o UtilcS.so -fPIC -I/usr/include/python2.7 -lpython2.7 utilsmodule.c
옵션의미
-shared공유 라이브러리(.so)로 빌드
-o UtilcS.so출력 파일명 지정
-fPIC위치 독립 코드(Position Independent Code) 생성 — 공유 라이브러리 필수
-I/usr/include/python2.7Python.h 가 있는 include 디렉토리 지정
-lpython2.7Python 라이브러리 링크

Python 버전에 따라 경로가 달라지므로 아래처럼 python-config 를 활용하면 정확합니다.

1
2
# Python 3 기준 자동 경로 추출
gcc -shared -o UtilcS.so -fPIC $(python3-config --includes) -lpython3.12 utilsmodule.c

단계별 요약

  1. python-config --includes 로 include 경로를 확인한다.
  2. 개발 패키지(python-dev/python3-dev) 미설치면 설치하거나, 헤더 경로가 이미 있으면 확인한다.
  3. gcc 컴파일 시 -I<헤더경로> 옵션을 추가한다.
  4. .so 공유 라이브러리라면 -fPIC-lpython 를 함께 지정한다.
  5. 컴파일이 성공하면 .so 파일이 생성되었는지 확인한다.

5. 향후 예방 조치

  • 개발 헤더는 런타임과 별개다. 서버나 CI 환경에 Python만 설치하고 빌드할 때는 -dev 패키지를 함께 설치해야 합니다.
  • 빌드 자동화를 쓴다면 python3-config --includespkg-config --cflags python3 처럼 시스템이 스스로 경로를 뽑아주는 명령을 사용하세요. 하드코딩된 경로는 Python 버전이 바뀌면 깨집니다.
  • 가상환경에서 빌드할 때는 시스템 Python 대신 해당 가상환경의 헤더 경로를 사용하는지 확인합니다.
  • setuptools/distutils 기반 프로젝트setup.pyExtension 이 include 경로를 자동 처리하므로, 가능하면 bare gcc 대신 빌드 시스템을 이용하는 것이 안전합니다.

출처: StackOverflow — fatal error: Python.h: No such file or directory (Q 21530577)