如何在Linux上使用vcpkg安装soci db库?

问题描述 投票:0回答:1

我正在尝试使用 VCPKG 在 Linux 上安装

soci[sqlite3]
甚至
soci[sqlite3,boost]
(根据 有关 vcpkg 中依赖项的外部信息)。不幸的是它没有发挥应有的作用。我尝试在单独的环境中执行此操作,因为我创建了 docker 实例:

$ docker run -it --rm --network=host -v $(pwd):/home/ --workdir /home --name='ubuntu_test' ubuntu:22.04
# apt-get update && apt-get upgrade -y --no-install-recommends
# apt-get install g++ git cmake curl zip unzip tar ca-certificates make pkg-config --no-install-recommends  -y

然后我已经下载并构建了

vcpkg

# git clone https://github.com/Microsoft/vcpkg.git --depth=1
# ./vcpkg/bootstrap-vcpkg.sh

下一步是使用 vcpkg 安装

soci[sqlite3]
,所以我使用了命令:

# ./vcpkg/vcpkg install 'soci[sqlite3]'

安装成功后我看到输出:

...
  find_package(SOCI CONFIG REQUIRED)
  target_link_libraries(main PRIVATE SOCI::soci_core_static SOCI::soci_empty_static SOCI::soci_sqlite3_static)

然后我尝试通过 caling 来获取 CMake 参数:

# ./vcpkg/vcpkg integrate install
Applied user-wide integration for this vcpkg root.
CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=/home/vcpkg/scripts/buildsystems/vcpkg.cmake"

然后我使用最简单的

CMakeLists.txt
(从官方vcpkg
教程
中获取
,并根据
vcpkg
的建议进行修改):

cmake_minimum_required(VERSION 3.16)
project(Learning_VCPKG LANGUAGES CXX)

find_package(SOCI CONFIG REQUIRED)

if (SOCI_FOUND)
    message("Soci found: ${SOCI_INCLUDE_DIRS} and ${SOCI_LIBRARY_DIRS}")
endif ()

add_executable(${PROJECT_NAME} main.cpp)

target_link_libraries(${PROJECT_NAME} PRIVATE SOCI::soci_core_static SOCI::soci_empty_static SOCI::soci_sqlite3_static)

然后我构建并编译:

# cmake . -DCMAKE_TOOLCHAIN_FILE=/home/vcpkg/scripts/buildsystems/vcpkg.cmake
Soci found:  and 
-- Configuring done
-- Generating done
-- Build files have been written to: /home
root@agh-legion:/home# make
[ 50%] Building CXX object CMakeFiles/Learning_VCPKG.dir/main.cpp.o
[100%] Linking CXX executable Learning_VCPKG
/usr/bin/ld: vcpkg/installed/x64-linux/debug/lib/libsoci_sqlite3.a(vector-into-type.cpp.o): in function `soci::sqlite3_vector_into_type_backend::post_fetch(bool, soci::indicator*)':
/home/vcpkg/buildtrees/soci/src/v4.0.3-7f07d34610.clean/src/backends/sqlite3/vector-into-type.cpp:260: undefined reference to `soci::details::parse_std_tm(char const*, tm&)'
/usr/bin/ld: vcpkg/installed/x64-linux/debug/lib/libsoci_sqlite3.a(standard-into-type.cpp.o): in function `soci::sqlite3_standard_into_type_backend::post_fetch(bool, bool, soci::indicator*)':
/home/vcpkg/buildtrees/soci/src/v4.0.3-7f07d34610.clean/src/backends/sqlite3/standard-into-type.cpp:139: undefined reference to `soci::details::parse_std_tm(char const*, tm&)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Learning_VCPKG.dir/build.make:102: Learning_VCPKG] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/Learning_VCPKG.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

这是代码(灵感来自官方示例):

#include <exception>
#include <iostream>
#include <soci/soci.h>
#include <soci/sqlite3/soci-sqlite3.h>
#include <string>

using namespace soci;
using namespace std;

int main()
{
    try {
        soci::session sql(sqlite3, "test.db");

        sql << "CREATE TABLE IF NOT EXISTS Employees("
               "ID     INT PRIMARY KEY NOT NULL,"
               "name   TEXT            NOT NULL,"
               "Age   INT             NOT NULL,"
               "Address  TEXT,"
               "Salary REAL);";
        sql << "INSERT INTO Employees (ID, name, Age, Address, Salary) VALUES (1, 'Tadeusz', 24, 'Krakow', 2000.01 ); ";
        sql << "INSERT INTO Employees (ID, name, Age, Address, Salary) VALUES (2, 'Symeon', 25, 'Texas', 15000.00 ); ";
        sql << "INSERT INTO Employees (ID, name, Age, Address, Salary) VALUES (3, 'Rodion', 23, 'Norway', 20000.00 );";

        int count;
        sql << "select count(*) from Employees", into(count);

        cout << "We have " << count << " entries in the Employees table.\n";
    } catch (exception const& e) {
        cerr << "Error: " << e.what() << '\n';
    }
}

我检查了编译命令(makefile 的

VERBOSE
标志):

# make VERBOSE=True
/usr/bin/c++ CMakeFiles/Learning_VCPKG.dir/main.cpp.o -o Learning_VCPKG  vcpkg/installed/x64-linux/debug/lib/libsoci_core.a vcpkg/installed/x64-linux/debug/lib/libsoci_empty.a vcpkg/installed/x64-linux/debug/lib/libsoci_sqlite3.a /usr/lib/x86_64-linux-gnu/libdl.a vcpkg/installed/x64-linux/debug/lib/libsqlite3.a 

奇怪的是 - 更改编译命令后它起作用了!:

# /usr/bin/c++ CMakeFiles/Learning_VCPKG.dir/main.cpp.o vcpkg/installed/x64-linux/debug/lib/libsoci_core.a vcpkg/installed/x64-linux/debug/lib/libsoci_empty.a vcpkg/installed/x64-linux/debug/lib/libsoci_sqlite3.a /usr/lib/x86_64-linux-gnu/libdl.a vcpkg/installed/x64-linux/debug/lib/libsqlite3.a -o Learning_VCPKG -L./vcpkg/installed/x64-linux/debug/lib/ -lsoci_core
root@agh-legion:/home# ./Learning_VCPKG 
We have 3 entries in the Employees table.

为了确保我检查了编译的库并且它确实包含丢失的符号:

# nm -C  vcpkg/installed/x64-linux/debug/lib/libsoci_core.a | grep "parse_std_tm"
00000000000002bd T soci::details::parse_std_tm(char const*, tm&)

**正如您所注意到的,有两种可能性:

  1. 我做错了什么(更可能是解决方案) - 请帮忙
  2. VCPKG 有 bug,不知道如何编译 C++ 程序? (不太可能)**

在这里提供所有必要的信息是库和 vcpkg 的版本:

# ./vcpkg/vcpkg list
soci:x64-linux                                    4.0.3#1             SOCI database access library
soci[sqlite3]:x64-linux                                               Build sqlite3 backend
sqlite3:x64-linux                                 3.43.0              SQLite is a software library that implements a s...
sqlite3[json1]:x64-linux                                              Enable JSON functionality for sqlite3
vcpkg-cmake-config:x64-linux                      2022-02-06#1        
vcpkg-cmake:x64-linux                             2023-05-04 
# ./vcpkg/vcpkg version
vcpkg package management program version 2023-09-15-ac02a9f660977426b8ec6392919fbb1d51b10998
c++ linux sqlite cmake soci
1个回答
0
投票

这是 VCPKG 的 soci 端口中的错误,已在新版本中修复(发出请求的链接PR的链接)。

现在运行问题中提供的命令后,VCPKG 正在打印:

    find_package(soci CONFIG REQUIRED)
    target_link_libraries(main PRIVATE $<IF:$<TARGET_EXISTS:SOCI::soci_core>,SOCI::soci_core,SOCI::soci_core_static>)

    # Linking specific backends (enabled: sqlite3)
    target_link_libraries(main PRIVATE $<IF:$<TARGET_EXISTS:SOCI::soci_<BACKEND>,SOCI::soci_<BACKEND>,SOCI::soci_<BACKEND>_static>)

在代码中,您需要将

<BACKEND>
替换为 backend_name (在带有
sqlite3
的问题中)。所以在 CMakeLists.txt 中链接的正确方法是:

target_link_libraries(${PROJECT_NAME} PRIVATE $<IF:$<TARGET_EXISTS:SOCI::soci_core>,SOCI::soci_core,SOCI::soci_core_static>)
target_link_libraries(${PROJECT_NAME} PRIVATE $<IF:$<TARGET_EXISTS:SOCI::soci_sqlite3>,SOCI::soci_sqlite3,SOCI::soci_sqlite3_static>)
© www.soinside.com 2019 - 2024. All rights reserved.