在 Windows 上编译 C++

Compile C++ on Windows

我正在尝试在 Windows 上编译 C++。 在 Linux 上编译所需的命令是:

g++ -O3 -Wall -shared -std=c++11 -fPIC `python -m pybind11 --includes` EO_functions_bipartite.cpp -o extremal_bi.so

我安装了 MinGW,但当我尝试编译时出现以下错误:

g++.exe: error: python: No such file or directory
g++.exe: error: pybind11: No such file or directory
g++.exe: error: unrecognized command line option '-m'
g++.exe: error: unrecognized command line option '--includes EO_functions_bipartite.cpp'
g++.exe: fatal error: no input files
compilation terminated.

假设您的路径中有 python。

在 g++ 中嵌入 python -m pybind11 --includes 命令的反引号转义在 Windows 中的 cmd.exe 上不起作用。

运行 python -m pybind11 --includes 命令在 cmd shell 中单独一行。获取该命令的输出并代入 g++ 命令。它应该是一堆 -I include params.

所以如果 python 命令的输出是这样的:

-IC:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\Include -IC:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\pybind11\include

将你的 g++ 命令扩展为:

g++ -O3 -Wall -shared -std=c++11 -fPIC "-IC:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\Include" -IC:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\pybind11\include EO_functions_bipartite.cpp -o extremal_bi.so

请注意我在第一个包含目录周围加上的引号,因为它的路径中有一个 space。

如果您有 Linux 背景,开始本机 Windows 的最简单方法是使用 MinGW-w64 安装 MSYS2 shell。这将提供一个实际的 bash,允许您 运行 命令几乎与 Linux 上完全相同的方式,包括对反引号的支持,就像您的问题一样。

虽然我总是建议使用 $( ... ) 而不是反引号,因为这允许嵌套。

请注意,MinGW-w64 也存在于 Windows 上,以允许从 Linux 交叉构建 Windows,但如果您从未做过任何操作,这可能会有点困难跨楼前.

另外,您命令中的 -shared ... -o extremal_bi.so 应替换为 -shared ... -o extremal_bi.dll -Wl,--out-implib,libextremal_bi.dll.a,因为 Windows 上不存在 .so 文件,因为 Windows 使用 .dll 文件用于共享库,编译器使用 .dll.a 文件作为它们的库对象。

最后在 Windows 你需要告诉编译器或 linker 你将导出哪些符号,方法是写一个 libextremal_bi.def 以行 EXPORTS 开始您要导出的所有符号并在 link 命令中包含 -def libextremal_bi.def,或者在定义这些符号时使用 __declspec(dllexport)/__declspec(dllimport),这可能会有点复杂需要一些条件定义来确定代码是否正在为 Windows 编译,以及它是否在共享库 (__declspec(dllexport)) 或使用它的代码 (__declspec(dllimport)) 的实际构建过程中。还有一种方法可以导出所有符号,但这种方法很脏,更容易引起符号冲突。