解决 Cmake 腾讯云COS SDK 编译失败问题

解决 Cmake 腾讯云COS SDK 编译失败问题

对象存储 COS 的 XML C++ SDK 源码下载地址:

如果用比较漂亮的语言来描述腾讯云cos-cpp-sdk,我觉得可以说是站在巨人肩膀上的健将,结构设计的还是比较漂亮的。 不过仍然存在一些小问题,这里进行一点小小的调整。

uint64_t 不是一个类型名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h:82:3: 错误:‘uint64_t’不是一个类型名
82 | uint64_t GetRealByte() const { return m_real_byte; }
| ^~~~~~~~
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h:14:1: 附注:‘uint64_t’ is defined in header ‘<cstdint>’; did you forget to ‘#include <cstdint>’?
13 | #include <string>
+++ |+#include <cstdint>
14 |
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h:98:20: 错误:‘uint64_t’未声明
98 | void SetRealByte(uint64_t real_byte) { m_real_byte = real_byte; }
| ^~~~~~~~
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h:118:3: 错误:‘uint64_t’不是一个类型名
118 | uint64_t m_real_byte;
| ^~~~~~~~
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h:118:3: 附注:‘uint64_t’ is defined in header ‘<cstdint>’; did you forget to ‘#include <cstdint>’?
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h: In copy constructor ‘qcloud_cos::CosResult::CosResult(const qcloud_cos::CosResult&)’:
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h:40:5: 错误:‘m_real_byte’在此作用域中尚未声明
40 | m_real_byte = other.m_real_byte;
| ^~~~~~~~~~~
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h:40:25: 错误:‘const class qcloud_cos::CosResult’ has no member named ‘m_real_byte’
40 | m_real_byte = other.m_real_byte;
| ^~~~~~~~~~~
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h: In member function ‘qcloud_cos::CosResult& qcloud_cos::CosResult::operator=(const qcloud_cos::CosResult&)’:
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h:52:7: 错误:‘m_real_byte’在此作用域中尚未声明
52 | m_real_byte = other.m_real_byte;
| ^~~~~~~~~~~
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h:52:27: 错误:‘const class qcloud_cos::CosResult’ has no member named ‘m_real_byte’
52 | m_real_byte = other.m_real_byte;
| ^~~~~~~~~~~
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h: In member function ‘void qcloud_cos::CosResult::SetRealByte(int)’:
/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/include/op/cos_result.h:98:42: 错误:‘m_real_byte’ was not declared in this scope; did you mean ‘real_byte’?
98 | void SetRealByte(uint64_t real_byte) { m_real_byte = real_byte; }
| ^~~~~~~~~~~
| real_byte
make[2]: *** [src/CMakeFiles/cossdk.dir/build.make:149:src/CMakeFiles/cossdk.dir/op/cos_result.cpp.o] 错误 1
make[2]: 离开目录“/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/build”
make[1]: *** [CMakeFiles/Makefile2:121:src/CMakeFiles/cossdk.dir/all] 错误 2
make[1]: 离开目录“/home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/build”
make: *** [Makefile:94:all] 错误 2

修复方式

  1. 转到 include/op/cos_result.h 添加头文件<cstdint>或者<stdint.h>

    1
    2
    3
    #include <cstdint>
    #include <map>
    #include <string>
  2. 转到include/util/test_utils.h 添加头文件 <cstdint> 或者 <cstdint.h>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #pragma once

    #include <iostream>
    #include <string>
    #include <cstdint>

    namespace qcloud_cos {
    class TestUtils {
    public:
    static void WriteStringtoFile(const std::string& file,
    const std::string& str);
    static void WriteRandomDatatoFile(const std::string& file, unsigned len);
    static void RemoveFile(const std::string& file);
    static std::string GetRandomString(unsigned size);
    static std::string CalcFileMd5(const std::string& file);
    static std::string CalcStreamMd5(std::istream& is);
    static std::string CalcStringMd5(const std::string& str);
    static std::string CalcStreamSHA1(std::istream& is);
    static std::string GetEnvVar(const std::string& env_var_name);
    };
    #define GetEnvVar TestUtils::GetEnvVar

    struct FileInfo {
    std::string m_object_name;
    std::string m_local_file;
    std::string m_local_file_download;
    uint64_t m_file_size;
    uint64_t m_file_crc64_origin;
    std::string m_file_md5_origin;
    int m_op_type;
    };

    } // namespace qcloud_cos

undefined referenct to ‘xxxx.so’

1
2
3
4
5
6
7
8
9
10
11
/usr/bin/ld: /home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/third_party/lib/linux/poco/libPocoCrypto.so: undefined reference to `EVP_get_cipherbyname@libcrypto.so.10'
/usr/bin/ld: /home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/third_party/lib/linux/poco/libPocoNetSSL.so: undefined reference to `SSL_CTX_flush_sessions@libssl.so.10'
/usr/bin/ld: /home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/third_party/lib/linux/poco/libPocoCrypto.so: undefined reference to `d2i_PKCS12_bio@libcrypto.so.10'
/usr/bin/ld: /home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/third_party/lib/linux/poco/libPocoNetSSL.so: undefined reference to `FIPS_mode@libcrypto.so.10'
/usr/bin/ld: /home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/third_party/lib/linux/poco/libPocoCrypto.so: undefined reference to `BN_bn2bin@libcrypto.so.10'
/usr/bin/ld: /home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/third_party/lib/linux/poco/libPocoCrypto.so: undefined reference to `sk_num@libcrypto.so.10'
/usr/bin/ld: /home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/third_party/lib/linux/poco/libPocoCrypto.so: undefined reference to `EVP_BytesToKey@libcrypto.so.10'
/usr/bin/ld: /home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/third_party/lib/linux/poco/libPocoCrypto.so: undefined reference to `BIO_new_mem_buf@libcrypto.so.10'
/usr/bin/ld: /home/cvrain/下载/cos-cpp-sdk-v5-5.5.10/third_party/lib/linux/poco/libPocoNetSSL.so: undefined reference to `SSL_CTX_use_PrivateKey_file@libssl.so.10'
# 还有一堆 undefined referenct to 'xxxx'

是因为现在的poco库默认已经使用c++14标准库,然而CMakeList.txt中设置仍然是c++11标准,于是修改为C++14

将-std=c11 修改为 -std=c14或者17

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
cmake_minimum_required(VERSION 2.8)
CMAKE_policy(SET CMP0015 NEW)
project(cos-cpp-sdk)

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 17)

option(BUILD_UNITTEST "Build unittest" OFF)
option(BUILD_DEMO "Build demo" ON)
option(BUILD_SHARED_LIB "Build shared library" OFF)
option(ENABLE_COVERAGE "Enable Coverage" OFF)

if(APPLE)
set(OS_TYPE "APPLE")
elseif(UNIX)
set(OS_TYPE "LINUX")
elseif(WIN32)
set(OS_TYPE "WINDOWS")
else()
message(FATAL_ERROR "unkonwn os type")
endif()

if(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
set(OS_TYPE "Android")
message(STATUS "SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
set(OS_TYPE "iOS")
message(STATUS "SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
endif()

message(STATUS "OS type: ${OS_TYPE}")

set(POCO_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/third_party/include/)
set(POCO_LIBS PocoNetSSL PocoNet PocoCrypto PocoUtil PocoJSON PocoXML PocoFoundation)
if (${OS_TYPE} STREQUAL "WINDOWS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(BUILD_TARGET "Win32")
if (CMAKE_CL_64)
set(BUILD_TARGET "x64")
endif()
message(STATUS "Build target: ${BUILD_TARGET}")
if (NOT DEFINED ${CMAKE_BUILD_TYPE})
set(CMAKE_BUILD_TYPE "Release")
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

set(POCO_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${BUILD_TARGET}/poco)

set(SYSTEM_LIBS "")
#需要加该参数,不然VS会报错
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
elseif(${OS_TYPE} STREQUAL "iOS")
set(POCO_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}/poco/)
set(OPENSSL_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}/openssl/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra")
set(SYSTEM_LIBS stdc++ pthread)
set(OPENSSL_LIBS ssl crypto)
elseif(${OS_TYPE} STREQUAL "Android")
set(POCO_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}/poco/)
set(OPENSSL_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}/openssl/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra")
set(SYSTEM_LIBS stdc++)
set(OPENSSL_LIBS ssl crypto)
# Linux or MacOs
else()
if (${OS_TYPE} STREQUAL "APPLE")
set(POCO_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/macOS/poco/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra")
else()
set(POCO_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/linux/poco/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra")
endif()

set(SYSTEM_LIBS stdc++ pthread)
endif()

if(ENABLE_COVERAGE)
# coverage option
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
endif()

add_subdirectory(src)

if(BUILD_UNITTEST)
message(STATUS "Build unittest")

set(GTEST_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/third_party/include/gtest/)
set(GTEST_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/linux/gtest/)
if (${OS_TYPE} STREQUAL "WINDOWS")
set(GTEST_LINK_DIR ${CMAKE_SOURCE_DIR}/third_party/lib/${BUILD_TARGET}/gtest)
endif()
set(GTEST_LIBS gtest gtest_main)

set(UT_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/unittest/include/)

add_subdirectory(unittest)
endif()

if(BUILD_DEMO)
message(STATUS "Build demo")
add_subdirectory(demo)
endif()

编译出来的文件存在于 build/lib/中

其他问题

  1. 如果仍然在编译中出现失败的问题,尝试将编译demo选项关闭
    1
    2
    3
    4
    option(BUILD_UNITTEST "Build unittest" OFF) #配置编译单元测试
    # option(BUILD_DEMO "Build demo" ON) #配置编译 demo 测试代码
    option(BUILD_DEMO "Build demo" OFF) #配置编译 demo 测试代码
    option(BUILD_SHARED_LIB "Build shared library" OFF) #配置编译动态库
  2. POCO链接问题
    1. 尝试将源代码中third_party中poco的库替换和当前系统环境一样的库
    2. 重新编译poco代码
  3. 小甜品
    CMakeLists.txt中的单词还有一个拼错了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if(APPLE)
    set(OS_TYPE "APPLE")
    elseif(UNIX)
    set(OS_TYPE "LINUX")
    elseif(WIN32)
    set(OS_TYPE "WINDOWS")
    else()
    message(FATAL_ERROR "unkonwn os type") # 拼错了
    endif()

个人输出

tmd这个cos sdk真的是依托答辩,用了那么多库,疯狂叠buff, 即使是我使用了vcpkg来配置依赖库仍然麻烦的一批,有一种就是在用poco封装了一层的感觉。里面的详细代码就不评价了。最后奉上我个人测试使用的CMakeLists.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
cmake_minimum_required(VERSION 3.26)
project(TestCos)

set(CMAKE_CXX_STANDARD 20)

enable_testing()

find_package(GTest CONFIG REQUIRED)
find_package(fmt CONFIG REQUIRED)
find_package(loguru CONFIG REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(Poco REQUIRED COMPONENTS Foundation Crypto XML JSON Util Net NetSSL)

set(COS_SDK_H src/cos-cpp-sdk-v5/include)

include_directories(${COS_SDK_H})

if (WIN32)
link_directories(libs/Win32)
elseif (UNIX)
link_directories(libs/linux)
elseif (APPLE)
link_directories(libs/macOS)
else ()
link_directories(libs/x64)

endif ()

set(SRC src/main.cpp)

add_executable(TestCos ${SRC})
target_link_libraries(TestCos PRIVATE fmt::fmt loguru
GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main
OpenSSL::SSL OpenSSL::Crypto
Poco::Foundation Poco::Crypto Poco::XML Poco::JSON Poco::Util Poco::Net Poco::NetSSL
libcossdk.a)

解决 Cmake 腾讯云COS SDK 编译失败问题
http://cvrain.cloudvl.cn/2023/12/03/Cpp/cpp-cos-compile/
作者
ClaudeRainer
发布于
2023年12月3日
许可协议