V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
WangLiCha
V2EX  ›  C++

C++新手,求助一个关于怎么使用第三方库的问题

  •  
  •   WangLiCha · 14 天前 · 1872 次点击

    可能有点长,因为我也不知道我哪一步出错了,所以尽量多写一点信息:

    之前完全没有做过 C++,因为项目需求临时看了下 C++和 Qt 的资料开始做东西; 之前电脑里装了 Viusal Studio 2022 ,所以电脑上是 2022 版本的 MSVC 组件,然后 Qt 在版本选型的时候考虑用的是 5.12.12 。这个版本安装包带的 MSVC 的库还是 2017 版本的,但是实际原生开发没有遇到问题,可以正常编译运行。

    接下来有一个要解析展示 LaTeX 表达式的需求,找了下 GitHub 上有一个 JKQtPlotter 项目满足我的需求。按照我的理解,把 GitHub 上的库 clone 到本地,然后按照说明文档用 CMake 编译

    cmake -G "Visual Studio 17 2022" "-DCMAKE_PREFIX_PATH=D:\Qt\Qt5.12.12\5.12.12\msvc2017_64"  ..
    cmake --build . --config "Debug"
    cmake --install . --config "Debug"
    

    然后在 Qt Creator 里添加库,选择编译生成好又安装完成的.lib 文件,实际在 Qt Creator 写代码的时候也能正常给出这个库的代码提示。

    但是编译无法通过,提示找不到函数……

    我怀疑可能是编译器不匹配的问题,所以用 VS 安装工具单独安装了 MSVC2017 的生成器,但是安装完成过后 Qt Creator 依然是找不到 MSVC2017 ,CMake 的参数传-G "Visual Studio 15 2017"同样报错说找不到。

    所以想请问一下这些操作步骤大概是哪里的问题?应该怎么去解决比较好?

    之前只做过 C#和前端的项目,Nuget 和 npm 确实方便,甚至偶尔写过一点 Python 都有 pip ,相比之下 C++用起第三方库感觉真的好麻烦……

    25 条回复    2024-05-17 14:52:33 +08:00
    InkStone
        1
    InkStone  
       14 天前   ❤️ 1
    代码提示是看头文件能不能找到,link 能不能通过是看静态或者动态库能不能找到,这俩是两个路径,确实没什么必然联系。

    可以考虑用 vcpkg 装,稍微友好一点
    yolee599
        2
    yolee599  
       14 天前
    报什么错误贴出来看看?
    LaTero
        3
    LaTero  
       14 天前 via Android
    C++是这样的,试试 vcpkg 吧,有 JKQtPlotter 。C++最最最最难的就是管理依赖,完全没做过 C++就更难了,光 cmake 就得学不少,完事还有时遇到不用 cmake 的库。你这能补全说明头文件在 include 里的,提示无法找到函数我猜是链接问题。C++是没有标准的引入库的步骤的,以前比较多的是编译完复制到几个目录,然后手动添加 include 和 link 目录,当然结果是依赖乱七八糟,能用就用,绝不敢更新/重编译,几年后留下一万个 CVE 。现在如果有的选,建议上了 vcpkg 的库一律用 vcpkg ,vcpkg 没有的库尽可能不用。
    WangLiCha
        4
    WangLiCha  
    OP
       14 天前
    @yolee599 我把之前的编译文件都删掉了重新编译了一下,现在复现不了报错了……
    现在的提示是编译输出提示 msvc_make.bat 正常退出,应用程序输出提示 程序异常结束,单独运行一下 msvc_make.bat 提示 Error: File Makefile doesn't exist.
    WangLiCha
        5
    WangLiCha  
    OP
       14 天前
    @LaTero 顺带问一下,引用了第三方库的 C++项目怎么管理版本库呢?应该没有 npm 的 package.json 这种方便的配置文件吧……
    LaTero
        6
    LaTero  
       14 天前 via Android
    @WangLiCha vcpkg 有类似的文件。
    不用包管理器的话,之前看 cppon 关于包管理器的一集,他们做了个简单的问卷调查,有的大团队会有自己的方案,但个人小项目很多时候就是不管理,不更新,走一步算一步,不崩溃就不管。包管理器出来之前 headers only 流行就是因为复制进去就能用。
    SHIINASAMA
        7
    SHIINASAMA  
       14 天前
    单说包管理器的话推荐 vcpkg ,在 Windows 下已经很方便了,同时其他平台也支持,具体看库。好处是基本上一个 vcpkg.json 走天下,也可以自建注册表;但是要用一些重量级依赖,vcpkg 可能会非常吃你的储存和耗时,例如 Qt...
    vituralfuture
        8
    vituralfuture  
       14 天前 via Android
    linux➕cmake 我已经摸索出一套方法,主要使用 cmake 的 ExternalProject ,写好下载源码,configure ,编译安装的命令,这样管理的项目在其他机器上也能照样跑。下载源码可以是 git clone 也可以是下载官网的源码发布包。需要注意一下版本,一般来说按照语义化版本选择相同大版本就没问题,更保险一点可以直接锁版本,对应 ExternalProject 就是 git clone 之后 check out 一下,或者下载 tarball 的时候 url 里一般也会写明版本。不用 linux 的包管理器主要也是这个原因,没法用老版本的包,或者用老版本的麻烦,其次不同软件源的包不太一样
    vituralfuture
        9
    vituralfuture  
       14 天前 via Android
    @vituralfuture 另外 ExternalProject 能控制第三方库的编译过程,如果需要定制第三方库的功能,比如传递编译参数,打开关闭编译开关,甚至修改部分源码,都是能做到的,非常灵活
    yuzii
        10
    yuzii  
       14 天前
    Qt Creator 应该要写 qmake 或者 cmake ,看看 lib 有没有链接

    find_package(JKQTPlotter5 REQUIRED)
    target_link_libraries(${PROJECT_NAME} JKQTPlotter5::JKQTPlotter5)
    WangLiCha
        11
    WangLiCha  
    OP
       14 天前
    @yuzii Qt Creator 里选择导入库配置好了过后会自动生成几行添加在 pro 文件后面的代码,只靠那个不够吗?还需要手动写一下 makefile ?
    WangLiCha
        12
    WangLiCha  
    OP
       14 天前
    @SHIINASAMA 是说用 vcpkg 管理 Qt 项目的第三方库还是把整个 Qt 作为第三方库用 vcpkg 管理?
    listenerri
        13
    listenerri  
       14 天前 via Android
    要先明确是找不到函数的声明,还是找不到函数的定义( IDE 能补全不一定代表编译系统也能正常)

    前者的话是因为第三方库的头文件没有添加进编译器搜索范围中,后者的话是因为找不到静态库或动态库文件,一般是因为库文件所在目录不在编译器/链接器搜索范围中,或是没有明确写出要链接第三方库
    cnbatch
        14
    cnbatch  
       14 天前
    做 C++(以及 C 开发)需要严格区分以下种类:
    32 位与 64 位
    debug 与 release
    动态库与静态库

    从你给出的编译命令来看,是编译出 x64 debug 版本,至于是动态库还是静态库我就不去挖掘了。
    然后在 qt creator 内用的是哪一种组合?这也是要注意的,如果能够贴出具体的报错提示和设置,那么大家可以更容易帮你给出编译设置步骤
    chouxw112233
        15
    chouxw112233  
       14 天前
    试了下,没有问题
    编译的库:
    https://github.com/jkriege2/JKQtPlotter/releases/tag/v4.0.3

    我的环境:
    Qt Creator 12.0.2
    Based on Qt 6.6.0 (MSVC 2019, x86_64)


    testjkqtp.pro
    ```
    LIBS += -LD:\Qt\pj\build-JKQtPlotterBuildAllExamples-Desktop_Qt_6_6_3_MinGW_64_bit-Debug\qmake\staticlib\jkqtplotterlib\debug -ljkqtplotterlib_debug
    INCLUDEPATH += D:\Qt\pj\JKQtPlotter-4.0.3\lib
    ```


    mainwindow.cpp
    ```
    #include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    plot = new JKQTPlotter(true, this);
    }

    MainWindow::~MainWindow()
    {
    delete ui;
    delete plot;
    }
    ```

    hpp
    ```
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QElapsedTimer>
    #include <QCheckBox>
    #include <QLineEdit>
    #include <QTimer>
    #include <QImage>
    #include <QVBoxLayout>
    #include <QWidget>
    #include <QTabWidget>
    #include <QFormLayout>
    #include <QCheckBox>
    #include "jkqtplotter/jkqtplotter.h"

    QT_BEGIN_NAMESPACE
    namespace Ui {
    class MainWindow;
    }
    QT_END_NAMESPACE

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    private:
    Ui::MainWindow *ui;
    JKQTPlotter* plot;
    };
    #endif // MAINWINDOW_H

    ```

    效果
    ![123123]( https://img2.imgtp.com/2024/05/14/CMZCRxcq.jpg)
    guyeu
        16
    guyeu  
       14 天前 via iPhone
    Conan 可解你忧
    tr1v1z
        17
    tr1v1z  
       14 天前 via Android
    没有用 xmake 的吗
    424778940
        18
    424778940  
       14 天前
    推荐使用 msys2 套装, 然后 qt 项目不要用 qmake 工程, 而是使用 cmake 工程
    我一般就算在 win 上, 除非一定要用 msvc 的场景, 比如要用 nv 的 cuda, 否则一律 msys2 的 mingw 工具链, 这样的代码移植到 linux 和其他平台特别方便, 基本不需要改什么, 另外 msvc 总喜欢定义一些名字很怪的宏这点我不太喜欢
    liuhai233
        19
    liuhai233  
       14 天前 via Android
    ysc3839
        20
    ysc3839  
       14 天前
    @liuhai233 NuGet 要配合 MSBuild 使用,配合 CMake 的话会麻烦很多,而且 NuGet 源里第三方 C++ 库可能没那么多。个人只建议写 Windows 程序、不跨平台的情况下使用。
    Nosub
        21
    Nosub  
       13 天前
    建议用 vcpkg ,大部分第三库都有,不过要配合 vs 门槛更低,花点时间学习下 vcpkg ,如果要更进一步,需要学习下 cmake 脚本语言,学习 C++就是这样,库管理乱的一塌糊涂,c++ 20 才引入 Module ,只能等时间积累,你要对比 Maven 或是 npm ,只能说 c++还有很长的路要走,不过大部分项目,也会提供库的使用方法,无非是你现在不懂 cmake ;
    snylonue
        22
    snylonue  
       12 天前
    @guyeu 最近就在试用 conan (windows),qt 装不上,fltk 装完以后 cmake 找不到
    SHIINASAMA
        23
    SHIINASAMA  
       12 天前
    @WangLiCha 因为 vcpkg 导入包基本都是从源码在本地构建的,如果你直接用来导入 Qt 的,那相当于编译一次 Qt ,更何况 Qt 的每个模块其实都挺大的。Qt 用预编译的安装包,其他不是很重量级的依赖可以用 vcpkg 管理,这个是可行的,我试过预编译的 Qt + vcpkg 的 ffmpeg ,没问题。
    WangLiCha
        24
    WangLiCha  
    OP
       11 天前
    @SHIINASAMA 测试了一下,vcpkg 安装 jkqtplotter 会下载编译 Qt 源代码……

    Building qtbase[brotli,concurrent,core,dbus,default-features,doubleconversion,freetype,gui,harfbuzz,icu,jpeg,network,opengl,openssl,pcre2,png,sql,sql-psql,sql-sqlite,testlib,thread,widgets,zstd]:[email protected]...
    -- Downloading https://download.qt.io/archive/qt/6.7/6.7.0/submodules/qtbase-everywhere-src-6.7.0.tar.xz;https://mirrors.ocf.berkeley.edu/qt/archive/qt/6.7/6.7.0/submodules/qtbase-everywhere-src-6.7.0.tar.xz -> qtbase-everywhere-src-6.7.0.tar.xz...
    -- Extracting source C:/dev/vcpkg/downloads/qtbase-everywhere-src-6.7.0.tar.xz
    -- Applying patch allow_outside_prefix.patch
    -- Applying patch config_install.patch
    -- Applying patch fix_cmake_build.patch
    -- Applying patch harfbuzz.patch
    -- Applying patch fix_egl.patch
    -- Applying patch fix_egl_2.patch
    -- Applying patch installed_dir.patch
    -- Applying patch GLIB2-static.patch
    -- Applying patch clang-cl_source_location.patch
    -- Applying patch clang-cl_QGADGET_fix.diff
    -- Applying patch fix-host-aliasing.patch
    -- Applying patch env.patch
    -- Applying patch dont_force_cmakecache_latest.patch
    -- Using source at C:/dev/vcpkg/buildtrees/qtbase/src/here-src-6-7448f7f6e6.clean
    -- Downloading https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/download/SP_5380_5361/strawberry-perl-5.38.0.1-64bit-portable.zip -> strawberry-perl-5.38.0.1-64bit-portable.zip...
    -- Downloading https://www.python.org/ftp/python/3.11.8/python-3.11.8-embed-amd64.zip -> python-3.11.8-embed-amd64.zip...
    -- Found external ninja('1.10.2').
    -- Configuring x64-windows
    -- Building x64-windows-dbg
    SHIINASAMA
        25
    SHIINASAMA  
       11 天前
    @WangLiCha 🤔那就看这个编译时长你能不能接受了,不能就用预编译的咯。我主要想表达的是预编译包+vcpkg 是可行的...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1059 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:36 · PVG 06:36 · LAX 15:36 · JFK 18:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.