我尝试使用msys 2/mingw 64构建具有更改的文件树结构和我自己的CMakeLists.txt的grpc helloworld示例。我希望使用add_subdirectory从源代码构建grpc作为静态库,并从源代码递归构建grpc的依赖项。
这样做的时候我会遇到未定义引用的链接错误,经过一些研究,似乎boringssl在msys 2/mingw 64中构建时有问题,或者至少boringssl包含在grpc的repo中的方式与msys 2/mingw 64不兼容。
由于msys 2中的grpc包是使用openssl作为依赖项构建的,所以我决定在构建过程中从源代码构建openssl,并让grpc静态链接到它,我希望只克隆grpc而不使用无聊的ssl子模块就足够了。
当openssl动态链接到libssl.dll.a时,我能够成功链接并运行示例。但是,当我尝试链接到静态openssl构建版本时,我再次收到未定义引用错误。
这是我得到的链接错误:
cmd.exe /C "cd . && C:\msys64\mingw64\bin\c++.exe -g @CMakeFiles\grpc_test2_server.rsp -o grpc_test2_server.exe -Wl,--out-implib,libgrpc_test2_server.dll.a -Wl,--major-image-version,0,--minor-image-version,0 && cd ."
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(b_addr.o): in function `addr_strings':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/crypto/bio/b_addr.c:208: undefined reference to `__imp_getnameinfo'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/crypto/bio/b_addr.c:220: undefined reference to `gai_strerrorW'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(b_addr.o): in function `BIO_lookup_ex':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/crypto/bio/b_addr.c:731: undefined reference to `gai_strerrorW'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(b_sock.o): in function `BIO_sock_error':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/crypto/bio/b_sock.c:99: undefined reference to `__imp_getsockopt'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(b_sock.o): in function `BIO_gethostbyname':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/crypto/bio/b_sock.c:113: undefined reference to `__imp_gethostbyname'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(b_sock2.o): in function `BIO_listen':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/crypto/bio/b_sock2.c:217: undefined reference to `__imp_getsockopt'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(b_sock2.o): in function `BIO_accept_ex':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/crypto/bio/b_sock2.c:290: undefined reference to `__imp_accept'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(e_capi.o): in function `capi_get_prov_info':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1281: undefined reference to `__imp_CertGetCertificateContextProperty'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1289: undefined reference to `__imp_CertGetCertificateContextProperty'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(e_capi.o): in function `capi_cert_get_fname':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1329: undefined reference to `__imp_CertGetCertificateContextProperty'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1335: undefined reference to `__imp_CertGetCertificateContextProperty'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(e_capi.o): in function `capi_open_store':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1400: undefined reference to `__imp_CertOpenStore'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(e_capi.o): in function `capi_list_certs':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1432: undefined reference to `__imp_CertFreeCertificateContext'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1435: undefined reference to `__imp_CertEnumCertificatesInStore'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1443: undefined reference to `__imp_CertCloseStore'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(e_capi.o): in function `capi_find_cert':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1455: undefined reference to `__imp_CertFindCertificateInStore'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1459: undefined reference to `__imp_CertEnumCertificatesInStore'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(e_capi.o): in function `capi_find_key':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1559: undefined reference to `__imp_CertFreeCertificateContext'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1561: undefined reference to `__imp_CertCloseStore'
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1593: undefined reference to `__imp_CertFreeCertificateC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: third-party/openssl/lib/libcrypto.a(e_capi.o): in function `capi_load_ssl_client_cert':
C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1720: undefined reference to `__imp_CertEnumCertificatesInStore'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1740: undefined reference to `__imp_CertDuplicateCertificateContext'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1754: undefined reference to `__imp_CertFreeCertificateContext'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\PatVax\Workspace\cpp\grpc_test2\build-debug\third-party\openssl_build/../../../third-party/openssl/engines/e_capi.c:1756: undefined reference to `__imp_CertCloseStore'
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.`
这是我现在使用的CMakeLists.txt文件:
cmake_minimum_required(VERSION 3.24)
project(grpc_test2 C CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_C_STANDARD 17)
set(BUILD_SHARED_LIBS OFF)
set(gRPC_BUILD_SHARED_LIBS OFF)
set(gRPC_BUILD_GRPC_CSHARP_EXT OFF)
set(gRPC_BUILD_GRPC_PHP_EXT OFF)
set(gRPC_BUILD_GRPC_PYTHON_EXT OFF)
set(gRPC_BUILD_GRPC_NODE_EXT OFF)
set(gRPC_BUILD_GRPC_RUBY_EXT OFF)
set(gRPC_BUILD_GRPC_OBJC_EXT OFF)
set(gRPC_BUILD_GRPC_OBJC_PLUGIN OFF)
set(_gRPC_BASELIB_LIBRARIES libws2_32 libcrypt32)
include(ProcessorCount)
ProcessorCount(N)
set(OPENSSL_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third-party/openssl)
set(OPENSSL_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/third-party/openssl_build)
set(OPENSSL_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/third-party/openssl)
set(OPENSSL_INCLUDE_DIR ${OPENSSL_INSTALL_DIR}/include)
set(MSYS_SHELL ${MSYS2_ROOT}/msys2_shell.cmd)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(OPENSSL_CONFIGURE_COMMAND ${MSYS_SHELL} -mingw64 -no-start -here -defterm -c
"${OPENSSL_SOURCE_DIR}/Configure --prefix=${OPENSSL_INSTALL_DIR} --openssldir=${OPENSSL_INSTALL_DIR} --release -static no-shared mingw64")
elseif(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(OPENSSL_CONFIGURE_COMMAND ${MSYS_SHELL} -mingw64 -no-start -here -defterm -c
"${OPENSSL_SOURCE_DIR}/Configure --prefix=${OPENSSL_INSTALL_DIR} --openssldir=${OPENSSL_INSTALL_DIR} --debug -static no-shared mingw64")
else()
set(OPENSSL_CONFIGURE_COMMAND ${MSYS_SHELL} -mingw64 -no-start -here -defterm -c
"${OPENSSL_SOURCE_DIR}/Configure --prefix=${OPENSSL_INSTALL_DIR} --openssldir=${OPENSSL_INSTALL_DIR} -static no-shared mingw64")
endif()
add_custom_target(OpenSSL_Configured
COMMAND ${OPENSSL_CONFIGURE_COMMAND}
WORKING_DIRECTORY ${OPENSSL_BINARY_DIR}
BYPRODUCTS ${OPENSSL_BINARY_DIR}/Makefile
DEPENDS ${OPENSSL_SOURCE_DIR}/Configure
COMMENT "OpenSSL is configuring")
add_custom_target(OpenSSL_Built
COMMAND ${MSYS_SHELL} -mingw64 -no-start -here -defterm -c "make -j${N}"
WORKING_DIRECTORY ${OPENSSL_BINARY_DIR}
BYPRODUCTS ${OPENSSL_BINARY_DIR}/libssl.a ${OPENSSL_BINARY_DIR}/libcrypto.a
DEPENDS OpenSSL_Configured
COMMENT "OpenSSL is building")
add_custom_target(OpenSSL_Installed
COMMAND ${MSYS_SHELL} -mingw64 -no-start -here -defterm -c "make install"
WORKING_DIRECTORY ${OPENSSL_BINARY_DIR}
BYPRODUCTS ${OPENSSL_INSTALL_DIR}/lib/libssl.a ${OPENSSL_INSTALL_DIR}/lib/libcrypto.a ${OPENSSL_INSTALL_DIR}/lib/libssl.dll.a ${OPENSSL_INSTALL_DIR}/lib/libcrypto.dll.a ${OPENSSL_INSTALL_DIR}/lib/libssl.dll ${OPENSSL_INSTALL_DIR}/lib/libcrypto.dll
DEPENDS OpenSSL_Built
COMMENT "OpenSSL is installing")
add_custom_target(OpenSSL DEPENDS OpenSSL_Installed COMMENT "OpenSSL is ready")
file(MAKE_DIRECTORY ${OPENSSL_INCLUDE_DIR})
add_library(OpenSSL::SSL STATIC IMPORTED GLOBAL)
set_property(TARGET OpenSSL::SSL PROPERTY IMPORTED_LOCATION ${OPENSSL_INSTALL_DIR}/lib/libssl.a)
set_property(TARGET OpenSSL::SSL PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${OPENSSL_INCLUDE_DIR})
add_dependencies(OpenSSL::SSL OpenSSL)
add_library(OpenSSL::Crypto STATIC IMPORTED GLOBAL)
set_property(TARGET OpenSSL::Crypto PROPERTY IMPORTED_LOCATION ${OPENSSL_INSTALL_DIR}/lib/libcrypto.a)
set_property(TARGET OpenSSL::Crypto PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${OPENSSL_INCLUDE_DIR})
add_dependencies(OpenSSL::Crypto OpenSSL)
add_library(ssl STATIC IMPORTED GLOBAL)
set_property(TARGET ssl PROPERTY IMPORTED_LOCATION ${OPENSSL_INSTALL_DIR}/lib/libssl.a)
set_property(TARGET ssl PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${OPENSSL_INCLUDE_DIR})
add_dependencies(ssl OpenSSL)
add_library(crypto STATIC IMPORTED GLOBAL)
set_property(TARGET crypto PROPERTY IMPORTED_LOCATION ${OPENSSL_INSTALL_DIR}/lib/libcrypto.a)
set_property(TARGET crypto PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${OPENSSL_INCLUDE_DIR})
add_dependencies(crypto OpenSSL)
set(_gRPC_SSL_LIBRARIES ssl crypto)
set(_gRPC_SSL_INCLUDE_DIR ${OPENSSL_INCLUDE_DIR})
add_subdirectory(third-party/grpc ${CMAKE_CURRENT_BINARY_DIR}/third-party/grpc)
get_filename_component(hw_proto "${CMAKE_CURRENT_SOURCE_DIR}/protobufs/helloworld.proto" ABSOLUTE)
get_filename_component(hw_proto_path "${hw_proto}" PATH)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.cc")
set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.h")
set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.cc")
set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.h")
add_custom_command(
OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}" "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
COMMAND protobuf::protoc
ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
--cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
-I "${hw_proto_path}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${hw_proto}"
DEPENDS "${hw_proto}")
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
add_library(hw_grpc_proto
${hw_grpc_srcs}
${hw_grpc_hdrs}
${hw_proto_srcs}
${hw_proto_hdrs})
target_link_libraries(hw_grpc_proto grpc++ grpc++_reflection libprotobuf)
add_executable(${CMAKE_PROJECT_NAME}_server server.cpp)
add_executable(${CMAKE_PROJECT_NAME}_client client.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME}_server grpc++ grpc++_reflection libprotobuf hw_grpc_proto)
target_link_libraries(${CMAKE_PROJECT_NAME}_client grpc++ grpc++_reflection libprotobuf hw_grpc_proto)
我的目录结构如下所示:
- grpc与所有子模块一起被克隆,而没有boringssl
- openssl与所有子模块一起克隆
- protobufs包含在生成过程中编译的.proto文件
- cpp文件的内容与grpc存储库的helloworld示例中的内容相同
我的问题可能是什么原因?我错过了什么吗?先谢了。
1条答案
按热度按时间kgqe7b3p1#
编辑3:我实际上意识到了一个大错误。你不能链接到
ws2_32.lib
,因为它是用MSVC而不是MinGW构建的。但是你的问题源于这里。我觉得自己像头驴,但显然MSYS 2/MinGW的新版本应该能够链接到这些静态库,所以下面的解决方案值得一试。
编辑:经过一番挖掘,我想我找到了MSVC受支持而mingw不受支持的原因。您遇到问题的原因是因为他们很可能使用
#pragma
来链接他们的库(这是MSVC特有的特性)。尝试额外链接到此库:
ws2_32
(也许64位版本被称为ws2_64
)-(更准确地说,你想链接到winsock 2 64位版本)编辑2:它们都命名为
ws2_32
,#pragma
为您选择了正确的名称,也就是说,唯一不同的是指向正确SDK的路径基于**this official github issue**。
GRPC
团队不支持Windows版本的MinGW。他们描述了与您描述的相同的问题,他们还就如何修复
boringssl
以使其工作提出了建议。OPENSSL_NO_ASM
构建boringssl
。长话短说,如果我是你,我会在Windows上切换到MSVC--如果你的目标平台是Windows,我看不出有什么理由不使用它。
编辑:但是,如果您仍然坚持使用MinGW,那么为了让您更接近如何解决您的问题,我可能会指出**
gai_strerrorW
is a function defined in ws2tcpip.h**