Saturday, October 29, 2022

[SOLVED] VCPKG and CMAKE not using static libraries when compiling a .exe

Issue

I have a project that uses gRPC and I have gRPC installed on Windows with VCPKG. I have the -x64-windows-static triplet installed and I have the target triplet set in my CMakePresets.json file as shown below:

"name": "windows-base",
        "hidden": true,
        "generator": "Visual Studio 17 2022",
        "binaryDir": "${sourceDir}/out/build/${presetName}",
        "installDir": "${sourceDir}/out/install/${presetName}",
        "cacheVariables": {
          "CMAKE_C_COMPILER": "cl.exe",
          "CMAKE_CXX_COMPILER": "cl.exe",
          "VCPKG_TARGET_TRIPLET": "x64-windows-static",
          "CMAKE_TOOLCHAIN_FILE": {
            "value": "C:/src/vcpkg/scripts/buildsystems/vcpkg.cmake",
            "type": "FILEPATH"
          }
        },
        "condition": {
          "type": "equals",
          "lhs": "${hostSystemName}",
          "rhs": "Windows"
        }

Prior to this, using dynamic libraries, the project built fine and the build folder was populated with the .exe and the .dll libraries. I wish to instead use static libraries with this project and get a single .exe. Compiling with the static triplet option I only get the .exe file but when I run I get several errors that .dlls are missing. Specifically zlib1.dll, cares.dll, re2.dll, and abseil_dll.dll. I have confirmed that the static packages exist at C:\src\vcpkg\packages, so I am not sure why they are not being used.

My cmake files are as follows:

Top Level:

cmake_minimum_required (VERSION 3.8)

project ("server")

set(DBUILD_SHARED_LIBS OFF)

set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")


find_package(  gRPC CONFIG REQUIRED )

find_package(Protobuf REQUIRED)

# Include sub-projects.

add_subdirectory("library")

add_subdirectory("proto")

add_subdirectory("example")

library:

add_library(client_library STATIC "client_library.cpp" "client_library.h")
target_link_libraries(client_library PUBLIC proto_library gRPC::grpc++ gRPC::grpc++_reflection gRPC::gpr gRPC::grpc gRPC::grpc++ protobuf::libprotoc protobuf::libprotobuf protobuf::libprotobuf-lite)
target_include_directories(client_library PUBLIC "${PROJECT_SOURCE_DIR}/proto")

proto:

add_library(proto_library STATIC "example.pb.cc" "example.pb.h" "example.grpc.pb.cc" "example.grpc.pb.h")

target_link_libraries(proto_library PRIVATE gRPC::grpc++ gRPC::grpc++_reflection gRPC::gpr gRPC::grpc gRPC::grpc++ protobuf::libprotoc protobuf::libprotobuf protobuf::libprotobuf-lite)

example:


add_executable(example "example.cpp" "example.h")
target_link_libraries(example PRIVATE client_library proto_library)
target_include_directories(example PUBLIC "${PROJECT_SOURCE_DIR}/library")


Any advice? Apologize if this has been asked before but I searched and could not find anything. I can't tell if this is a cmake issue or some sort of vcpkg or visual studio issue.

EDIT: Here is my vcpkg package directory: vcpgk


Solution

Delete your CMakeCache and retry. You probably had VCPKG_TARGET_TRIPLET not set on first configure which defaults to x64-windows and makes find_library|file|path|program already find the x64-windows stuff. Since these are all cache variables they won't be found anew on subsequent runs! Also consider setting VCPKG_HOST_TRIPLET.

Other stuff:
set(DBUILD_SHARED_LIBS OFF) has a typo. No D at the beginning!
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") is unnecessary
cmake_minimum_required (VERSION 3.8) consider setting this higher



Answered By - Alexander Neumann
Answer Checked By - Clifford M. (WPSolving Volunteer)