Title: Correct compilaton and linking flags for building python c/c++ extension on Windows, linux and OSX
Tags: python

Question: Environment:
Python 3.8.10
Windows 10
Ubuntu 22.04.2 LTS (GNU/Linux 5.15.90.1-microsoft-standard-WSL2 x86_64)
Msys2 (Mingw64)

This post is about getting the correct set of compilation and linking flags as well as set of libraries for building Python extensions using c/c++ on three major OS.
MS Windows Mingw64
The command
python -m sysconfig

gives you a very small set of flags compared to Linux and no information is available for compilation and linking flags. I'm using the Mingw64 compiler toolchain on Windows which I believe is not officially supported on Windows. After following everything that was once required to build extension using MinGW on Windows I was still not able to get it correctly done.
For e.g cython is using gcc for compilation and g++ for linking and adding msvc flags while linking.
After doing things manually, I came up with these flags:
Compilation C/C++: '-c', '-Ofast', '-fpic', '-mdll', '-Wall'
Linking: '-shared' '-O', '-Wall'
Macros: "-DMS_WIN64"
Includes: "from sysconfig import get_paths as gp; gp()["include"]"
Libraries: "-lPythonXX"

MS Windows MSVC
I'm not using MSVC as of now but I would switch to it soon. I would really appreciate if someone could post the required flags.
for MSVC.
Linux
On Linux you have two options:
python3 -m sysconfig
&
python-config --cflags
python-config --ldflags

and I came up with these flags:
Compilation C/C++ : "-Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2"
Linking : "-shared -fPIC -Wl, -O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -g -fwrapv -O2"
Macros: ""
Includes: "from sysconfig import get_paths as gp; gp()["include"]"
Libraries: "-lcrypt -ldl  -lm -lm -lPythonXX"

OSX
I don't have access to Apple Mac OSX but I believe flags would be the same as of Linux. Please correct me if I'm wrong.
Prashant

Answer: Firstly, a note about building Python extensions. The safest way to build Python extensions is to use Python's distutils or setuptools which automatically figure out all the compiler and linker flags. However, if you need to manually set flags, you should ideally use the flags provided by Python's sysconfig module or python-config script as these are guaranteed to be compatible with your Python installation. The flags you provided seem reasonable for the most part, but might need minor tweaks.
MS Windows Mingw64
Your flags look reasonable. You might not need "-Ofast" as Python might not be compatible with all optimizations this flag turns on. It might be safer to use "-O2".
MS Windows MSVC
For MSVC, you can get the flags by running python -m sysconfig as with Mingw64. Note that MSVC does not understand gcc-style flags like '-Wall', '-O2', etc., so you would have to translate these to the equivalent MSVC flags, like '/W4', '/O2', etc. Also note that MSVC does not support '-fPIC', '-shared', etc. Instead, you would use '/LD' or '/LDd' for dynamic libraries, and '/MT' or '/MTd' for static libraries.
Linux
The flags you listed for Linux seem fine, although they might not be optimal. You can get the optimal flags for your particular Python installation by running python3 -m sysconfig.
OSX
For OSX, the flags should be similar to Linux, but there might be minor differences. Again, you can get the flags for your particular Python installation by running python3 -m sysconfig. You can also use the python-config script on OSX, which might give you more detailed information. Note that on OSX, you might need to add '-bundle' to the linker flags instead of '-shared'. And instead of '-fPIC', you might need to use '-dynamiclib'.
One more note, if you want to build an extension that's compatible with various Python versions, you should compile against the oldest Python version you want to support, and use the -undefined dynamic_lookup flag on OSX and -Wl,--unresolved-symbols=ignore-all flag on Linux to ignore unresolved symbols. These flags allow your extension to find symbols in the Python executable at runtime, instead of needing them at compile time.