美文网首页
C++ CMake和vcpkg进行包管理

C++ CMake和vcpkg进行包管理

作者: FredricZhu | 来源:发表于2021-09-26 10:14 被阅读0次

因为想要做一个C++的docker,这样大家都可以用,但是又不想把已经安装和配置完成的库重新在docker上面安一遍。所以想看下C++有没有类似java的Maven的包管理工具。

结果谷歌了一圈,发现两个工具,一个是conan,好评很高,但是尴尬的是直接在本机上面跑之后,发现没法连接到官网,这可坑了。所以放弃了。

另一个是微软的vcpkg。包管理的策略和maven有些类似。

步骤如下,

  1. 需要先下载微软的vcpkg工程,然后在vcpkg/ports下面新建一个工程,例如我的工程是cppwork,建立方法如下,
    cd /vcpkg/ports
    创建的配置文件保存在cppwork目录下,远端工程URL为cppwork-master.zip,下载到本地的包名为cppwork.zip。
    vcpkg create cppwork https://git.appannie.org/fzhu/cppwork/-/archive/master/cppwork-master.zip cppwork.zip

  2. 修改一下/vcpkg/ports/cppwork目录下的vcpkg.json文件,添加上自己想要的依赖包。

{
  "name": "cppwork",
  "version-string": "",
  "homepage": "",
  "description": "",
  "dependencies": [
    {
      "name": "boost",
      "version>=": "1.76.0"
    },
    {
      "name": "pthread",
      "version>=": "3.0.0"
    },
    {
      "name": "nanodbc",
      "version>=": "2.13.0#4"
    },
    {
      "name": "pystring",
      "version>=": "1.1.3#4"
    },
    {
      "name": "yaml-cpp",
      "version>=": "0.7.0#1"
    },
    {
      "name": "protobuf",
      "version>=": "3.18.0"
    },
    {
      "name": "gtest",
      "version>=": "1.11.0"
    },
    {
      "name": "openssl",
      "version>=": "1.1.1l#1"
    },
    {
      "name": "opencv",
      "version>=": "4.5.3"
    }
 ],
  "builtin-baseline": "8275003fd8c5119cb9438fea1425ebe774f2e527"
}

注意这个builtin-baseline的来历和用途,可以参考知乎。主要是用来限定版本用的。
https://zhuanlan.zhihu.com/p/390410760

  1. 在/vcpkg/ports/cppwork目录下面执行vcpkg install,就可以安装所有依赖包了。
    其中 boost库因为包比较多,大概要安装30分钟到1小时左右。
    nanodbc库需要依赖autoconf进行配置。而且少了一个#include <limits> 声明,需要自己处理。
    autoconf需要依赖perl,所以要先安装perl。

其他的包就比较顺利了。

  1. vcpkg安装的包被安装在这个目录下,
    /vcpkg/ports/cppwork/vcpkg_installed/x64-linux
    目录格式如下,


    image.png
  2. 使用CMakeLists.txt文件来兼容Mac和Linux构建。

以前文《C++ 操作status io API生成yaml配置文件》的CMakeLists.txt文件为例,可以配置如下的CMakeLists.txt文件。
CMakeLists.txt

cmake_minimum_required(VERSION 2.6)

if(APPLE)
    message(STATUS "This is Apple, do nothing.")
elseif(UNIX)
    message(STATUS "This is linux, set CMAKE_PREFIX_PATH.")
    set(CMAKE_PREFIX_PATH /vcpkg/ports/cppwork/vcpkg_installed/x64-linux/share)
endif(APPLE)

project(get_incident_file)

add_definitions(-std=c++14)
add_definitions(-g)

find_package(ZLIB)

find_package(OpenCV REQUIRED )

find_package(Boost REQUIRED COMPONENTS
    system
    filesystem
    serialization
    program_options
    thread
    )


if(APPLE)
    MESSAGE(STATUS "This is APPLE, set INCLUDE_DIRS")
set(INCLUDE_DIRS ${Boost_INCLUDE_DIRS} /usr/local/include /usr/local/iODBC/include /opt/snowflake/snowflakeodbc/include/ ${CMAKE_CURRENT_SOURCE_DIR}/../../)
elseif(UNIX)
    MESSAGE(STATUS "This is linux, set INCLUDE_DIRS")
    set(INCLUDE_DIRS ${Boost_INCLUDE_DIRS} /usr/local/include ${CMAKE_CURRENT_SOURCE_DIR}/../../)
endif(APPLE)


if(APPLE)
    MESSAGE(STATUS "This is APPLE, set LINK_DIRS")
    set(LINK_DIRS /usr/local/lib /usr/local/iODBC/lib /opt/snowflake/snowflakeodbc/lib/universal)
elseif(UNIX)
    MESSAGE(STATUS "This is linux, set LINK_DIRS")
    set(LINK_DIRS ${Boost_INCLUDE_DIRS} /usr/local/lib /vcpkg/ports/cppwork/vcpkg_installed/x64-linux/lib)
endif(APPLE)

if(APPLE)
    MESSAGE(STATUS "This is APPLE, set ODBC_LIBS")
    set(ODBC_LIBS iodbc iodbcinst)
elseif(UNIX)
    MESSAGE(STATUS "This is linux, set LINK_DIRS")
    set(ODBC_LIBS odbc odbcinst ltdl)
endif(APPLE)

include_directories(${INCLUDE_DIRS})
LINK_DIRECTORIES(${LINK_DIRS})


file( GLOB APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../impl/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp  ${CMAKE_CURRENT_SOURCE_DIR}/../../http/impl/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../yaml/impl/*.cpp)
foreach( sourcefile ${APP_SOURCES} )
        file(RELATIVE_PATH filename ${CMAKE_CURRENT_SOURCE_DIR} ${sourcefile})
    
        string(FIND "${filename}"  "test.cpp" "TEMP")
    if( NOT "${TEMP}" STREQUAL "-1" )
        string(REPLACE ".cpp" "" file ${filename})
        add_executable(${file}  ${APP_SOURCES})
        target_link_libraries(${file} ${Boost_LIBRARIES} ZLIB::ZLIB ${OpenCV_LIBS})
        target_link_libraries(${file}  ssl crypto libgtest.a libgtest_main.a pystring libyaml-cpp.a libgmock.a ${ODBC_LIBS} libnanodbc.a pthread)
    endif()
endforeach( sourcefile ${APP_SOURCES})

其中最重要的一点是Linux系统下需要设置CMAKE_PREFIX_PATH为vcpkg的share路径,这个路径下主要是存放,CMake find_package指令需要的各种.cmake文件。如果不加这一句,就会发现find_package各种不好用。

  1. Linux ~/.bash_profile环境变量文件里面加上这几个环境变量。


    image.png

其中,
这个是使用vcpkg必须。
export PATH=/vcpkg:$PATH

这两个是CMake查找头文件和库文件的路径。
export CMAKE_INCLUDE_PATH=/vcpkg/ports/cppwork/vcpkg_installed/x64-linux/include
export CMAKE_LIBRARY_PATH=/vcpkg/ports/cppwork/vcpkg_installed/x64-linux/lib

这两个是 Linux ODBC必须。
export ODBCINI=/etc/odbc.ini
export ODBCSYSINI=/etc

  1. 本文的实验环境, Fedora linux 35[最新版本]。
    使用Fedora最新版本的原因是Centos系比较稳定。
    另外最新的Fedora的gcc可以支持C++最新的C++2a版本。

相关文章

网友评论

      本文标题:C++ CMake和vcpkg进行包管理

      本文链接:https://www.haomeiwen.com/subject/rycqnltx.html