En Microsoft Windows, al compilar una extensión de Python (a partir de la versión 3.5) escrita en C o C++ o bien intentar instalar un paquete que requiere ser compilado utilizando Microsoft Visual C++ 14.0 (Visual Studio 2015), se obtiene el siguiente error.
pyconfig.h(68): fatal error C1083: No se puede abrir el archivo incluir: ‘io.h’: No such file or directory
Explicación
A partir de la versión 14.0 de Microsoft Visual C++ (distribuido en Visual Studio 2015) se incorpora el llamado Universal CRT, un conjunto de componentes que incluye, entre otros, la librería estándar de C. El objetivo de esta implementación es la unificación y compatibilidad entre las distintas versiones del compilador, en lugar de mantener diferentes CRT (C Runtime) para cada una de ellas, como se hacía hasta el momento (desde Visual Studio 2002 hasta 2013).
Al ser cada CRT específico de una versión del compilador, las librerías y los archivos de cabecera se incluian dentro de la carpeta de instalación, por ejemplo, C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib
y C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include
. Con la introducción del Universal CRT, estos componentes se encuentran en un SDK independiente, instalado junto con Visual Studio pero en una ubicación diferente (por defecto C:\Program Files (x86)\Windows Kits\10
). En mi caso, los archivos de cabecera se encuentran en C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt
y las librerías en C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10150.0\ucrt\x86
(32 bit) y C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10150.0\ucrt\x64
(64 bit).
El archivo io.h
y tantos otros pertenecen al CRT y, al no ser encontrados en los directorios anteriores, el compilador se queja imprimiendo el error anterior.
Solución
Simplemente hay que indicarle al compilador (vía los parámetros include_dirs
y library_dirs
de distutils.core.Extension
) los directorios en donde debe buscar los archivos del Universal CRT en el archivo setup.py
de tu extensión o el paquete que deseas compilar e instalar.
Considerando el siguiente fichero de ejemplo.
from distutils.core import setup, Extension setup(name='foo', version='1.0', ext_modules=[Extension('foo', ['foo.c'])], )
Especificamos los directorios del UCRT (para una extensión de 64 bit).
from distutils.core import setup, Extension ucrt_include = r'C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt' ucrt_lib = r'C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10150.0\ucrt\x64' setup(name='foo', version='1.0', ext_modules=[Extension('foo', ['foo.c'], include_dirs=[ucrt_include], library_dirs=[ucrt_lib])], )
Y para una de 32 bit:
ucrt_lib = r'C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10150.0\ucrt\x86'
¡Ya podés compilar tu extensión sin problemas!
Para usuarios de Cython, considerando el siguiente setup.py
.
from distutils.core import setup from Cython.Build import cythonize setup( name = 'Hello world app', ext_modules = cythonize("helloword.pyx") )
Deben crear manualmente una instancia de la clase Extension
.
from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize ucrt_include = r'C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt' ucrt_lib = r'C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10150.0\ucrt\x64' ext = Extension("helloworld", ["helloword.pyx"], include_dirs=[ucrt_include], library_dirs=[ucrt_lib]) setup( name = 'Hello world app', ext_modules = cythonize([ext]) )
Curso online 👨💻
¡Ya lanzamos el curso oficial de Recursos Python en Udemy!
Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter
en 2024.
Consultoría 💡
Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.