Reputation: 634
I'm trying to build the grpc helloworld example with changed file tree structure and my own CMakeLists.txt with msys2/mingw64. I want to build grpc from sources as a static library using add_subdirectory and build grpc's dependencies recursevily from sources as well.
Doing that I was getting linking errors with undefined references. After some research it seems that boringssl has problems with building in msys2/mingw64 or at least the way boringssl is included in grpc's repo isn't compatible with msys2/mingw64.
Since the grpc package in msys2 is built using openssl as dependency I decided to build openssl from sources during the build and let grpc statically link to that. I hope it is enough to just clone grpc without the boringssl submodule.
I was able to succesfully link and run the example when openssl was linked dynamically to libssl.dll.a. However when I try to link to static openssl build I'm getting undefined references errors again.`grpc_test2_server.exe
This are the linking errors I'm getting:
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.`
And this is my CMakeLists.txt that I'm currently using:
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)
My directory structure looks like the following:
What could be the reason of my problems? Am I missing something? Thanks in advance.
Upvotes: 0
Views: 1012
Reputation: 1638
EDIT3: I've actually realized a big blunder here. You can't link against the ws2_32.lib
as it was built with MSVC and not MinGW. However the issue to your problem stems from here.
I feel like a donkey, but apparently newer versions of MSYS2/MinGW should be able to link against these static libraries. So the following solution is worth a try.
EDIT: After some digging in I think I found the reason why MSVC is supported and mingw is not. The reason why you're having issues is because they are most likely using #pragma
to link their libraries (this is a MSVC specific feature).
Try additionaly linking to this library: ws2_32
(maybe the 64 bit version is called ws2_64
) - (more precisely you want to link against winsock2 64 bit version)
EDIT2: They are all named ws2_32
and the #pragma
picks the right one for you, i.e. the only thing different is the path to the correct SDK
Based on this official github issue. The GRPC
team does not support MinGW for Windows builds.
They describe the same issue that you are describing and they also have a suggestion on how to fix boringssl
to work i.e.
boringssl
with the following define OPENSSL_NO_ASM
.Long story short, I would switch to MSVC on Windows if I were you - I don't see a reason why not to use it if your target platform is Windows anyway.
EDIT: However if you are still persistent on using MinGW then maybe to maybe get you closer to how to fix your issue I would maybe point out that gai_strerrorW
is a function defined in ws2tcpip.h
Upvotes: 1