Vcpkg 是微软推出的用于在 Windows 上管理 C/C++ 库的工具。通过它能够方便的安装常用的 C/C++ 库,而且提供了 CMake 的集成。这使得使用 CMake 的项目在 Windows 下构建方便了很多,不需要自己手动去指定在 Windows 下如何找到依赖的库了。
不过实际使用中还是碰到一些问题。为了减少依赖,直接复制一个可执行程序就能在其它机器上运行,经常会需要静态链接依赖的库。而在 Windows 上使用 vcpkg 静态链接需要一些特殊的操作。
在 Linux 下,只需要在链接中使用 .a
的静态库就行了。以 boost
为例,CMake 自带的 FindBoost
就可以指定搜索静态库
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
这样 Boost_LIBRARIES
中包含的就是静态库了,按平常方式使用 link_libraries
或者 target_link_libraries
就可以了。
但是设置了上面的参数后,在 Windows 下使用 vcpkg 会提示找不到静态库。看来是 Windows 下没有办法同时提供静态和动态库,所以 vcpkg 需要额外安装静态库的版本,以 boost 的 64 位的静态库为例,安装命令如下:
vcpkg install zlib:x64-windows-static
而在使用 CMake 生成 Visual Studio 项目的时候也需要指定 VCPKG_TARGET_TRIPLET
cmake .. \
-DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg.cmake \
-DVCPKG_TARGET_TRIPLET=x64-windows-static \
-G "Visual Studio 14 2015 Win64"
不过这样生成的项目在链接阶段会报错的,因为 VC 的编译器在生成 obj 文件的时候就需要指定链接时是使用动态链接还是静态链接,默认 CMake 生成的项目都是使用动态链接,导致链接时 obj 文件和库的格式不符,这个可以参考 Stack Overflow 上这个问题 CMake compile with /MT instead of /MD 的回答来修改,最终的 CMake 如下
cmake_minimum_required(VERSION 3.0)
project(static_link_test CXX)
set(CMAKE_CXX_STANDARD 11)
if(MSVC)
string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
else(MSVC)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
endif(MSVC)
find_package(Boost 1.36.0 REQUIRED COMPONENTS filesystem program_options)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/src
${Boost_INCLUDE_DIRS}
)
link_libraries(
${Boost_LIBRARIES}
)
add_executable(static_link_test
src/main.cpp
)
install(TARGETS static_link_test RUNTIME DESTINATION bin)