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

lndjwyie  于 2023-10-16  发布在  Linux
关注(0)|答案(1)|浏览(129)

我正尝试使用VCPKG在Linux上安装soci[sqlite3]甚至soci[sqlite3,boost](根据external information about dependencies in 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的建议修改了from official vcpkg tutorial):

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

下面是代码(灵感来自official example):

#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';
    }
}

我检查了编译命令(VERBOSE标志到makefile):

# 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.我做错了什么(更可能的解决方案)-请帮助

  1. 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
muk1a3rh

muk1a3rh1#

这是VCPKG的soci端口中的错误,已在new versionlink to issue requestlink to 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>)

相关问题