I am trying to build a ‘C’ python extension on Windows, the core C code compiles absolutely fine, but I am unable to build the python module using setuptool as I am getting
mandlebrot.c(36): fatal error C1083: Cannot open include file: 'stdio.h': No such file or directory
error: command ‘e:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.35.32215binHostX86x86cl.exe’ failed with exit code 2
I am trying to build using:
python3.9 setup.py build_ext --inplace --plat-name win32
Any help would be welcome as I have spent a long time trying to work out how to get this to work.
The setup file:
from setuptools import setup, Extension
from subprocess import getoutput
LIB_DIRS=['.mandlebrot_setlibs']
INCLUDE_DIRS=['.mandlebrot_setincludes']
module1 = Extension("mandlebrot",
sources = ["mandlebrot.c", "mandlebrot_python.c"],
libraries = ['mpfr', 'mpir'],
library_dirs = LIB_DIRS,
include_dirs = INCLUDE_DIRS)
setup(name = "PackageName",
version = '0.1',
description = 'Mandlebrot Set calculator',
author = '',
author_email = '',
ext_modules = [module1]
)
2
Answers
1. The error
By default, Python is built on Win with VStudio ([Python.Wiki]: WindowsCompilers), and it also uses that to build C / C++ code (unless otherwise instructed).
It seems like you don’t have VStudio‘s cross build tools (for 032bit) installed. A quick search revealed:
[SO]: Cannot open include file: ‘stdio.h’ – Visual Studio Community 2017 – C++ Error
[MSDN.Social]: how to resolve fatal error C1083: Cannot open include file: ‘stdio.h’: No such file or directory
My installation (Visual Studio Installer) looks like:
Make sure you have installed:
The build tools
At least one Windows SDK version
Try building a simple Hello World application ([MS.DevBlogs]: C++ Tutorial: Hello World) for 032bit (Win32)
Some VStudio links that might help:
[SO]: Visual Studio NMake build fails with: fatal error U1052: file ‘win32.mak’ not found (@CristiFati’s answer)
[SO]: LNK2005 Error in CLR Windows Form (@CristiFati’s answer)
[SO]: Calling Python function with parametrs from C++ project (Visual Studio) (@CristiFati’s answer)
[SO]: How to include OpenSSL in Visual Studio (@CristiFati’s answer)
Once the build works, try again the extension
If any of the 2 previous steps still fails, you might think of repairing (or even reinstalling – as a last resort) your VStudio installation
2. Setup
Since there are files not provided for a MCVE ([SO]: How to create a Minimal, Reproducible Example (reprex (mcve))), I’m going to use some from [SO]: How to create python C++ extension with submodule that can be imported (@CristiFati’s answer) (latest one that I worked on involving extension modules).
I also want to point out setup.py deprecation ([SO]: ‘setup.py install is deprecated’ warning shows up every time I open a terminal in VSCode), but I’m not going to insist on that.
setup.py:
I have 2 separate dirs for 064bit (pc064) and 032bit (pc032) builds (1) (you’ll see later why).
3. Build for pc064
This is native (or direct) build, as (CPU and) default Python installation (that I’m going to use) is pc064.
Output:
So far, so good.
4. Build for pc032
This is cross build (as host and target architectures don’t match).
According to [Python.Docs]: Creating Built Distributions – Cross-compiling on Windows (emphasis is mine):
Although it’s old, and the other way around it also applies (partially) to our situation.
As explained in the (build related) URLs above, when building for Win, the linker needs the .lib files (${PYTHONCORE}.lib in our case) for the target architecture, so they are required to exist on the host, and also setup.py (SetupTools) needs to find them.
Output (I’ll reuse this console):
Notes:
The .pyd name is the same as for pc064 case, which is not correct (this is why I used 2 dirs (check note #1.), otherwise the pc064 .pyd would have been overwritten). Check:
[SO]: What does version name ‘cp27’ or ‘cp35’ mean in Python? (@WayneWerner’s answer) for naming details
[SO]: How do I determine if my python shell is executing in 32bit or 64bit mode on OS X? (@CristiFati’s answer)
[SO]: Python Ctypes – loading dll throws OSError: [WinError 193] %1 is not a valid Win32 application (@CristiFati’s answer) for the encountered error
Things are definitely wrong, could be a SetupTools bug (maybe fixed in later versions), this might not be the case on your side. Simplest way is to rename the .pyd (there might also be a setup.py argument?).
Output (continued):
Worked like a charm!
This is the most generic way of doing things, and it should work for any target build (pc032, aarch64, arm32), once the cross build tools and the appropriate .lib files are present on the host machine.
But, if aiming for pc032 (win32) only, there’s a shortcut:
Download and install the pc032 Python (which runs on pc064 machines)
Use it (like in #3.) to build natively
Error hear facing was’stdio.h’ header file is not found during compilation
To resolve this issue,
First , Verify that you have a C compiler and Check ‘stdio.h’ file present in the appropriate location and then Update setup.py file to provide the correct include directories
from setuptools import setup, Extension
from subprocess import getoutput
LIB_DIRS = [‘path/to/libs’]
INCLUDE_DIRS = [‘path/to/includes’]
module1 = Extension("mandlebrot",
setup(name="PackageName",
)
Change ‘path/to/libs’ to the absolute path to the library directory, and ‘path/to/includes’ to the absolute path to the include directory
python3.9 setup.py build_ext –inplace –plat-name win32