Boost::process 在 Windows - 使用 MinGW?
Boost::process on Windows - with MinGW?
我有一个 C++17 应用程序,只使用 STL 和 boost 1.71.0
。应用程序需要在 Windows、Linux 和 BSD 上 运行。在 Windows 上,我使用 MinGW-w64 提供的 GCC 9.2。我用的是MSYS2自带的发行版。
我需要能够创建系统进程(从我的 C++ 应用程序中启动外部应用程序)。
过去我为此使用了 Qt 库的 QProcess
。但是,此应用程序没有任何 Qt 依赖项,我想阻止仅为这一功能添加 Qt 依赖项。
寻找我遇到的解决方案 boost::process
。乍一看,这似乎是 QProcess
.
的一个非常合适的替代方案
我首先使用 C++17、cmake 和 boost 创建了一个最小的应用程序:
#include <iostream>
#include <boost/process.hpp>
int main() {
int result = boost::process::system("g++ main.cpp");
return 0;
}
不幸的是,我运行直接进入编译错误:
====================[ Build | boost_process_test | Debug ]======================
C:\Users\joel\AppData\Local\JetBrains\Toolbox\apps\CLion\ch-03.5233.103\bin\cmake\win\bin\cmake.exe --build C:\Users\joel\Documents\projects\boost_process_test\cmake-build-debug --target boost_process_test -- -j 6
Scanning dependencies of target boost_process_test
[ 50%] Building CXX object CMakeFiles/boost_process_test.dir/main.cpp.obj
In file included from C:/msys64/mingw64/include/boost/process/detail/windows/handles.hpp:11,
from C:/msys64/mingw64/include/boost/process/detail/used_handles.hpp:17,
from C:/msys64/mingw64/include/boost/process/detail/windows/async_in.hpp:20,
from C:/msys64/mingw64/include/boost/process/async.hpp:49,
from C:/msys64/mingw64/include/boost/process.hpp:23,
from C:\Users\joel\Documents\projects\boost_process_test\main.cpp:2:
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:208:51: error: expected ')' before '*' token
208 | typedef ::boost::winapi::NTSTATUS_ (__kernel_entry *nt_system_query_information_p )(
| ~ ^~
| )
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:223:51: error: expected ')' before '*' token
223 | typedef ::boost::winapi::NTSTATUS_ (__kernel_entry *nt_query_object_p )(
| ~ ^~
| )
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp: In function 'boost::winapi::NTSTATUS_ boost::process::detail::windows::workaround::nt_system_query_information(boost::process::detail::windows::workaround::SYSTEM_INFORMATION_CLASS_, void*, boost::winapi::ULONG_, boost::winapi::PULONG_)':
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:239:12: error: 'nt_system_query_information_p' does not name a type; did you mean 'nt_system_query_information'?
239 | static nt_system_query_information_p f = reinterpret_cast<nt_system_query_information_p>(::boost::winapi::get_proc_address(h, "NtQuerySystemInformation"));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| nt_system_query_information
In file included from C:/msys64/mingw64/include/boost/process/detail/windows/handles.hpp:11,
from C:/msys64/mingw64/include/boost/process/detail/used_handles.hpp:17,
from C:/msys64/mingw64/include/boost/process/detail/windows/async_in.hpp:20,
from C:/msys64/mingw64/include/boost/process/async.hpp:49,
from C:/msys64/mingw64/include/boost/process.hpp:23,
from C:\Users\joel\Documents\projects\boost_process_test\main.cpp:2:
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:241:14: error: 'f' was not declared in this scope
241 | return (*f)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
| ^
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp: In function 'boost::winapi::BOOL_ boost::process::detail::windows::workaround::nt_query_object(boost::winapi::HANDLE_, boost::process::detail::windows::workaround::OBJECT_INFORMATION_CLASS_, void*, boost::winapi::ULONG_, boost::winapi::PULONG_)':
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:253:12: error: 'nt_query_object_p' does not name a type; did you mean 'nt_query_object'?
253 | static nt_query_object_p f = reinterpret_cast<nt_query_object_p>(::boost::winapi::get_proc_address(h, "NtQueryObject"));
| ^~~~~~~~~~~~~~~~~
| nt_query_object
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:255:14: error: 'f' was not declared in this scope
255 | return (*f)(Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength);
| ^
mingw32-make.exe[3]: *** [CMakeFiles\boost_process_test.dir\build.make:62: CMakeFiles/boost_process_test.dir/main.cpp.obj] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:75: CMakeFiles/boost_process_test.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/boost_process_test.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: boost_process_test] Error 2
这里是我对应的CMakeLists.txt
:
cmake_minimum_required(VERSION 3.15)
project(boost_process_test)
set(CMAKE_CXX_STANDARD 17)
find_package(Boost 1.71.0 REQUIRED)
add_executable(boost_process_test main.cpp)
我查阅了 boost.process 文档来弄清楚有哪些依赖性和兼容性。不幸的是,我找不到太多这方面的信息。
在我开始深入实际调试之前 - 有人知道 boost.process
版本 1.71.0
是否实际上 运行s 在 Windows 上,如果是 -它是否适用于 GCC / MinGW 而不仅仅是 MSVC?如果支持 MinGW/GCC - 它依赖于 posix 还是 win32api?
解决方案
我在 boost::process
存储库中遇到了 this github issue,其中 OP 提到了相同的问题。这似乎是一个 MinGW 问题。问题中提出了一个解决方法,涉及在包含 boost/process.hpp
header.
之前定义 __kernel_entry
pre-processor 符号
将其应用于我的代码如下所示:
// Workaround for a boost/mingw bug.
// This must occur before the inclusion of the boost/process.hpp header.
// Taken from https://github.com/boostorg/process/issues/96
#ifndef __kernel_entry
#define __kernel_entry
#endif
#include <boost/process.hpp>
int main() {
int result = boost::process::system("g++ main.cpp");
return 0;
}
这消除了编译错误并生成了正确运行的程序二进制文件。
进一步的步骤
应用修复程序后,问题中显示的初始编译器错误不再出现。但是,程序仍然没有编译 & link 因为我没有正确包含 boost 库。
我的 CMakeLists.txt
工作示例如下所示:
cmake_minimum_required(VERSION 3.15)
project(boost_process_test)
set(CMAKE_CXX_STANDARD 17)
find_package(Boost 1.71.0 REQUIRED
COMPONENTS
filesystem
system
)
add_executable(boost_process_test main.cpp)
target_link_libraries(boost_process_test
PRIVATE
$<$<BOOL:${WIN32}>:ws2_32>
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
)
请注意 link 在 Windows 平台上 ws2_32
库。
学分
感谢来自 Qt 社区的 @mrjj 指出 github 问题帮助我解决了这个编译问题。
我有一个 C++17 应用程序,只使用 STL 和 boost 1.71.0
。应用程序需要在 Windows、Linux 和 BSD 上 运行。在 Windows 上,我使用 MinGW-w64 提供的 GCC 9.2。我用的是MSYS2自带的发行版。
我需要能够创建系统进程(从我的 C++ 应用程序中启动外部应用程序)。
过去我为此使用了 Qt 库的 QProcess
。但是,此应用程序没有任何 Qt 依赖项,我想阻止仅为这一功能添加 Qt 依赖项。
寻找我遇到的解决方案 boost::process
。乍一看,这似乎是 QProcess
.
我首先使用 C++17、cmake 和 boost 创建了一个最小的应用程序:
#include <iostream>
#include <boost/process.hpp>
int main() {
int result = boost::process::system("g++ main.cpp");
return 0;
}
不幸的是,我运行直接进入编译错误:
====================[ Build | boost_process_test | Debug ]======================
C:\Users\joel\AppData\Local\JetBrains\Toolbox\apps\CLion\ch-03.5233.103\bin\cmake\win\bin\cmake.exe --build C:\Users\joel\Documents\projects\boost_process_test\cmake-build-debug --target boost_process_test -- -j 6
Scanning dependencies of target boost_process_test
[ 50%] Building CXX object CMakeFiles/boost_process_test.dir/main.cpp.obj
In file included from C:/msys64/mingw64/include/boost/process/detail/windows/handles.hpp:11,
from C:/msys64/mingw64/include/boost/process/detail/used_handles.hpp:17,
from C:/msys64/mingw64/include/boost/process/detail/windows/async_in.hpp:20,
from C:/msys64/mingw64/include/boost/process/async.hpp:49,
from C:/msys64/mingw64/include/boost/process.hpp:23,
from C:\Users\joel\Documents\projects\boost_process_test\main.cpp:2:
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:208:51: error: expected ')' before '*' token
208 | typedef ::boost::winapi::NTSTATUS_ (__kernel_entry *nt_system_query_information_p )(
| ~ ^~
| )
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:223:51: error: expected ')' before '*' token
223 | typedef ::boost::winapi::NTSTATUS_ (__kernel_entry *nt_query_object_p )(
| ~ ^~
| )
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp: In function 'boost::winapi::NTSTATUS_ boost::process::detail::windows::workaround::nt_system_query_information(boost::process::detail::windows::workaround::SYSTEM_INFORMATION_CLASS_, void*, boost::winapi::ULONG_, boost::winapi::PULONG_)':
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:239:12: error: 'nt_system_query_information_p' does not name a type; did you mean 'nt_system_query_information'?
239 | static nt_system_query_information_p f = reinterpret_cast<nt_system_query_information_p>(::boost::winapi::get_proc_address(h, "NtQuerySystemInformation"));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| nt_system_query_information
In file included from C:/msys64/mingw64/include/boost/process/detail/windows/handles.hpp:11,
from C:/msys64/mingw64/include/boost/process/detail/used_handles.hpp:17,
from C:/msys64/mingw64/include/boost/process/detail/windows/async_in.hpp:20,
from C:/msys64/mingw64/include/boost/process/async.hpp:49,
from C:/msys64/mingw64/include/boost/process.hpp:23,
from C:\Users\joel\Documents\projects\boost_process_test\main.cpp:2:
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:241:14: error: 'f' was not declared in this scope
241 | return (*f)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
| ^
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp: In function 'boost::winapi::BOOL_ boost::process::detail::windows::workaround::nt_query_object(boost::winapi::HANDLE_, boost::process::detail::windows::workaround::OBJECT_INFORMATION_CLASS_, void*, boost::winapi::ULONG_, boost::winapi::PULONG_)':
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:253:12: error: 'nt_query_object_p' does not name a type; did you mean 'nt_query_object'?
253 | static nt_query_object_p f = reinterpret_cast<nt_query_object_p>(::boost::winapi::get_proc_address(h, "NtQueryObject"));
| ^~~~~~~~~~~~~~~~~
| nt_query_object
C:/msys64/mingw64/include/boost/process/detail/windows/handle_workaround.hpp:255:14: error: 'f' was not declared in this scope
255 | return (*f)(Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength);
| ^
mingw32-make.exe[3]: *** [CMakeFiles\boost_process_test.dir\build.make:62: CMakeFiles/boost_process_test.dir/main.cpp.obj] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:75: CMakeFiles/boost_process_test.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/boost_process_test.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: boost_process_test] Error 2
这里是我对应的CMakeLists.txt
:
cmake_minimum_required(VERSION 3.15)
project(boost_process_test)
set(CMAKE_CXX_STANDARD 17)
find_package(Boost 1.71.0 REQUIRED)
add_executable(boost_process_test main.cpp)
我查阅了 boost.process 文档来弄清楚有哪些依赖性和兼容性。不幸的是,我找不到太多这方面的信息。
在我开始深入实际调试之前 - 有人知道 boost.process
版本 1.71.0
是否实际上 运行s 在 Windows 上,如果是 -它是否适用于 GCC / MinGW 而不仅仅是 MSVC?如果支持 MinGW/GCC - 它依赖于 posix 还是 win32api?
解决方案
我在 boost::process
存储库中遇到了 this github issue,其中 OP 提到了相同的问题。这似乎是一个 MinGW 问题。问题中提出了一个解决方法,涉及在包含 boost/process.hpp
header.
__kernel_entry
pre-processor 符号
将其应用于我的代码如下所示:
// Workaround for a boost/mingw bug.
// This must occur before the inclusion of the boost/process.hpp header.
// Taken from https://github.com/boostorg/process/issues/96
#ifndef __kernel_entry
#define __kernel_entry
#endif
#include <boost/process.hpp>
int main() {
int result = boost::process::system("g++ main.cpp");
return 0;
}
这消除了编译错误并生成了正确运行的程序二进制文件。
进一步的步骤
应用修复程序后,问题中显示的初始编译器错误不再出现。但是,程序仍然没有编译 & link 因为我没有正确包含 boost 库。
我的 CMakeLists.txt
工作示例如下所示:
cmake_minimum_required(VERSION 3.15)
project(boost_process_test)
set(CMAKE_CXX_STANDARD 17)
find_package(Boost 1.71.0 REQUIRED
COMPONENTS
filesystem
system
)
add_executable(boost_process_test main.cpp)
target_link_libraries(boost_process_test
PRIVATE
$<$<BOOL:${WIN32}>:ws2_32>
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
)
请注意 link 在 Windows 平台上 ws2_32
库。
学分
感谢来自 Qt 社区的 @mrjj 指出 github 问题帮助我解决了这个编译问题。