C++C++C++ REST SDK (cpprestsdk)编译ASIO版本过程
OQSC++ REST SDK (cpprestsdk)编译ASIO版本过程
1. 下载源码
使用git命令下载cpprest代码:
1
| git clone -b v2.10.12 https://github.com/microsoft/cpprestsdk.git
|
2. 修改下载的源码
2.1 修复CMakeLists文件Bug
cpprestsdk的2.10.12版本的CMakeLists是有bug的,asio异步所需要的threadpool.cpp文件只有不排除websocket库的情况下才会链接到项目。显然目前项目是不需要websocket的,所以得强制让threadpool链接到项目里去,否则报无法解析的外部符号。
需要根据GitHub上该开源库的pull request修改:
- 修改
Release/src/CmakeLists.txt 文件
- 修改
Release/src/pplx/threadpool.cpp 文件
参考链接:https://github.com/microsoft/cpprestsdk/pull/1466/files
2.2 修改警告设置
Release下的CMakeLists文件的第18行,默认开启将警告视为报错,cmake不会报错,但make的时候会将所有的warning都会作为错误抛出,需要将ON改为OFF。
1 2 3 4
| set(WERROR ON CACHE BOOL "Treat Warnings as Errors.")
set(WERROR OFF CACHE BOOL "Treat Warnings as Errors.")
|
或者可以在cmake命令中将该宏设置为OFF:-DWERROR=OFF
参考链接:https://github.com/microsoft/cpprestsdk/issues/1290
3. 编写cmake命令
3.1 Windows
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| "D:\software\CMake\bin\cmake.exe" ^ -DCMAKE_BUILD_TYPE=Debug ^ -G"Visual Studio 15 2017 Win64" ^ -DOPENSSL_ROOT_DIR="D:/DevThirdpartyLib_2017/Openssl/openssl-1.1.1g/" ^ -DOPENSSL_LIBRARIES="D:/DevThirdpartyLib_2017/Openssl/openssl-1.1.1g/lib64" ^ -DOPENSSL_SSL_LIBRARY="D:/DevThirdpartyLib_2017/Openssl/openssl-1.1.1g/lib64/libssl.lib" ^ -DOPENSSL_CRYPTO_LIBRARY="D:/DevThirdpartyLib_2017/Openssl/openssl-1.1.1g/lib64/libcrypto.lib" ^ -DOPENSSL_INCLUDE_DIR="D:/DevThirdpartyLib_2017/Openssl/openssl-1.1.1g/include" ^ -DZLIB_INCLUDE_DIR="D:/DevThirdpartyLib_2017/Zlib/zlib_1_2_11/include" ^ -DZLIB_LIBRARY="D:/DevThirdpartyLib_2017/Zlib/zlib_1_2_11/lib64/zlibd1.lib" ^ -DCPPREST_EXCLUDE_WEBSOCKETS:BOOL=ON ^ -DBoost_INCLUDE_DIRS="D:/DevThirdpartyLib_2017/boost/boost_1_68" ^ -DBOOST_LIBRARYDIR="D:/DevThirdpartyLib_2017/boost/boost_1_68/lib/x64" ^ -DBOOST_ROOT="D:/DevThirdpartyLib_2017/boost/boost_1_68" ^ -DBoost_SYSTEM_LIBRARY_DEBUG="D:/DevThirdpartyLib_2017/boost/boost_1_68/lib/x64/libboost_system-vc141-mt-gd-x64-1_68.lib" ^ -DBoost_DATE_TIME_LIBRARY_DEBUG="D:/DevThirdpartyLib_2017/boost/boost_1_68/lib/x64/libboost_date_time-vc141-mt-gd-x64-1_68.lib" ^ -DBoost_REGEX_LIBRARY_DEBUG="D:/DevThirdpartyLib_2017/boost/boost_1_68/lib/x64/libboost_regex-vc141-mt-gd-x64-1_68.lib" ^ -DCPPREST_HTTP_CLIENT_IMPL:STRING="asio" ^ -DCPPREST_HTTP_LISTENER_IMPL:STRING="asio" ^ -DBUILD_TESTS:BOOL=OFF ^ -DBUILD_SAMPLES:BOOL=OFF
|
参数说明:
D:\software\CMake\bin\cmake.exe 替换为实际的cmake安装路径
-DCMAKE_BUILD_TYPE 和 Win64 根据所需Debug还是Release替换
- 在Windows上指定boost的根目录路径没生效,可能是由于boost的lib命名过于复杂,所以直接指定了所需要的库
-DCPPREST_EXCLUDE_WEBSOCKETS:BOOL=ON 这个宏是为了排除websocket模块
-DCPPREST_HTTP_CLIENT_IMPL:STRING="asio" -DCPPREST_HTTP_LISTENER_IMPL:STRING="asio" 是为了让cmake将cpprest的请求和监听底层实现指定为使用boost.asio
-DBUILD_TESTS:BOOL=OFF -DBUILD_SAMPLES:BOOL=OFF 不要生成不必要的sample项目解决方案
注意: 生成的sln的配置可能还不完善,一些库的路径可能是不对的,有问题的还需要配置一下。
3.2 Linux
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| cmake \ -DCMAKE_INSTALL_PREFIX=/root/oqs/cpprestsdk_build/cpprestsdk \ -DCMAKE_BUILD_TYPE=Release \ -DCPPREST_EXCLUDE_WEBSOCKETS=ON \ -DZLIB_INCLUDE_DIR=/root/oqs/cpprestsdk_build/zlib/include \ -DZLIB_LIBRARY=/root/oqs/cpprestsdk_build/zlib/lib/libz.so \ -DZLIB_ROOT_DIR=/root/oqs/cpprestsdk_build/zlib/ \ -DOPENSSL_ROOT_DIR=/root/oqs/cpprestsdk_build/openssl/ \ -DOPENSSL_INCLUDE_DIR=/root/oqs/cpprestsdk_build/openssl/include \ -DBOOST_LIBRARYDIR=/root/oqs/cpprestsdk_build/boost/lib \ -DBOOST_ROOT=/root/oqs/cpprestsdk_build/boost/include \ -DCPPREST_HTTP_CLIENT_IMPL:STRING="asio" \ -DCPPREST_HTTP_LISTENER_IMPL:STRING="asio" \ -DBUILD_TESTS:BOOL=OFF \ -DBUILD_SAMPLES:BOOL=OFF
|
宏的作用跟Windows上的大差不差。
4. 编译
4.1 Windows
直接用Visual Studio
4.2 Linux
使用make命令或者 make -j8(多线程编译)
5. 使用
5.1 Linux和Windows都需要修改的地方
CPPRest配置:
cpprest的ssl_context函数是根据这个宏决定是否打开的,在Windows上使用asio版本的cpprest,需要在项目上根据需要在代码或者预处理器上加上这两个宏:
1 2
| CPPREST_FORCE_HTTP_CLIENT_ASIO CPPREST_FORCE_HTTP_LISTENER_ASIO
|
gSOAP配置:
1 2
| WITH_IPV6 WITH_NO_IPV6_V6ONLY
|
5.2 Windows特定配置
在Windows上使用boost,由于boost自身有文件引用了winsock.h头文件,且我们的项目中stdafx.h中可能已经通过某些宏或者直接添加了该头文件,导致编译过程会报:
1
| WinSock.h has already been included
|
解决方案:
- 将stdafx.h中引入该头文件的代码注释掉
- 在项目方案加上该宏:
WIN32_LEAN_AND_MEAN
参考链接:https://stackoverflow.com/questions/30731173/error-winsock-h-has-already-been-included-boost-windows-qt
IPv6地址格式: IPv6地址注意要带上中括号 []
5.3 Linux特定配置
IPv6地址格式: 在Linux上,IPv6地址是不需要添加中括号的,否则会解析失败。
双栈支持配置:
在Linux上使用PF_UNSPEC在getaddrinfo后会得到INET(IPv4),这不是期望的结果。期望的效果是得到PF_INET6+WITH_NO_IPV6_V6ONLY(也就是WITH_IPV6 WITH_NO_IPV6_V6ONLY)从而达到双栈的效果。
原因是PF_UNSPEC在Linux上通过getaddrinfo获取协议族过程中,找到协议后(无论是IPv4还是IPv6)就直接返回了。
修改方法:
在 stdsoap.cpp 的第5714行将:
1
| hints.ai_family = PF_UNSPEC
|
改为:
1
| hints.ai_family = PF_INET6
|
注意: 在Windows上同样修改也没发现同样的问题,所以应该可以不区分平台。