可能有点长,因为我也不知道我哪一步出错了,所以尽量多写一点信息:
之前完全没有做过 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++用起第三方库感觉真的好麻烦……
1
InkStone 175 天前 1
代码提示是看头文件能不能找到,link 能不能通过是看静态或者动态库能不能找到,这俩是两个路径,确实没什么必然联系。
可以考虑用 vcpkg 装,稍微友好一点 |
2
yolee599 175 天前
报什么错误贴出来看看?
|
3
LaTero 175 天前 via Android
C++是这样的,试试 vcpkg 吧,有 JKQtPlotter 。C++最最最最难的就是管理依赖,完全没做过 C++就更难了,光 cmake 就得学不少,完事还有时遇到不用 cmake 的库。你这能补全说明头文件在 include 里的,提示无法找到函数我猜是链接问题。C++是没有标准的引入库的步骤的,以前比较多的是编译完复制到几个目录,然后手动添加 include 和 link 目录,当然结果是依赖乱七八糟,能用就用,绝不敢更新/重编译,几年后留下一万个 CVE 。现在如果有的选,建议上了 vcpkg 的库一律用 vcpkg ,vcpkg 没有的库尽可能不用。
|
4
WangLiCha OP @yolee599 我把之前的编译文件都删掉了重新编译了一下,现在复现不了报错了……
现在的提示是编译输出提示 msvc_make.bat 正常退出,应用程序输出提示 程序异常结束,单独运行一下 msvc_make.bat 提示 Error: File Makefile doesn't exist. |
6
LaTero 175 天前 via Android
@WangLiCha vcpkg 有类似的文件。
不用包管理器的话,之前看 cppon 关于包管理器的一集,他们做了个简单的问卷调查,有的大团队会有自己的方案,但个人小项目很多时候就是不管理,不更新,走一步算一步,不崩溃就不管。包管理器出来之前 headers only 流行就是因为复制进去就能用。 |
7
SHIINASAMA 175 天前
单说包管理器的话推荐 vcpkg ,在 Windows 下已经很方便了,同时其他平台也支持,具体看库。好处是基本上一个 vcpkg.json 走天下,也可以自建注册表;但是要用一些重量级依赖,vcpkg 可能会非常吃你的储存和耗时,例如 Qt...
|
8
vituralfuture 175 天前 via Android
linux➕cmake 我已经摸索出一套方法,主要使用 cmake 的 ExternalProject ,写好下载源码,configure ,编译安装的命令,这样管理的项目在其他机器上也能照样跑。下载源码可以是 git clone 也可以是下载官网的源码发布包。需要注意一下版本,一般来说按照语义化版本选择相同大版本就没问题,更保险一点可以直接锁版本,对应 ExternalProject 就是 git clone 之后 check out 一下,或者下载 tarball 的时候 url 里一般也会写明版本。不用 linux 的包管理器主要也是这个原因,没法用老版本的包,或者用老版本的麻烦,其次不同软件源的包不太一样
|
9
vituralfuture 175 天前 via Android
@vituralfuture 另外 ExternalProject 能控制第三方库的编译过程,如果需要定制第三方库的功能,比如传递编译参数,打开关闭编译开关,甚至修改部分源码,都是能做到的,非常灵活
|
10
yuzii 175 天前
Qt Creator 应该要写 qmake 或者 cmake ,看看 lib 有没有链接
find_package(JKQTPlotter5 REQUIRED) target_link_libraries(${PROJECT_NAME} JKQTPlotter5::JKQTPlotter5) |
11
WangLiCha OP @yuzii Qt Creator 里选择导入库配置好了过后会自动生成几行添加在 pro 文件后面的代码,只靠那个不够吗?还需要手动写一下 makefile ?
|
12
WangLiCha OP @SHIINASAMA 是说用 vcpkg 管理 Qt 项目的第三方库还是把整个 Qt 作为第三方库用 vcpkg 管理?
|
13
listenerri 175 天前 via Android
要先明确是找不到函数的声明,还是找不到函数的定义( IDE 能补全不一定代表编译系统也能正常)
前者的话是因为第三方库的头文件没有添加进编译器搜索范围中,后者的话是因为找不到静态库或动态库文件,一般是因为库文件所在目录不在编译器/链接器搜索范围中,或是没有明确写出要链接第三方库 |
14
cnbatch 174 天前
做 C++(以及 C 开发)需要严格区分以下种类:
32 位与 64 位 debug 与 release 动态库与静态库 从你给出的编译命令来看,是编译出 x64 debug 版本,至于是动态库还是静态库我就不去挖掘了。 然后在 qt creator 内用的是哪一种组合?这也是要注意的,如果能够贴出具体的报错提示和设置,那么大家可以更容易帮你给出编译设置步骤 |
15
chouxw112233 174 天前
试了下,没有问题
编译的库: 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) |
16
guyeu 174 天前 via iPhone
Conan 可解你忧
|
17
tr1v1z 174 天前 via Android
没有用 xmake 的吗
|
18
424778940 174 天前
推荐使用 msys2 套装, 然后 qt 项目不要用 qmake 工程, 而是使用 cmake 工程
我一般就算在 win 上, 除非一定要用 msvc 的场景, 比如要用 nv 的 cuda, 否则一律 msys2 的 mingw 工具链, 这样的代码移植到 linux 和其他平台特别方便, 基本不需要改什么, 另外 msvc 总喜欢定义一些名字很怪的宏这点我不太喜欢 |
19
liuhai233 174 天前 via Android
|
20
ysc3839 174 天前
@liuhai233 NuGet 要配合 MSBuild 使用,配合 CMake 的话会麻烦很多,而且 NuGet 源里第三方 C++ 库可能没那么多。个人只建议写 Windows 程序、不跨平台的情况下使用。
|
21
Nosub 174 天前
建议用 vcpkg ,大部分第三库都有,不过要配合 vs 门槛更低,花点时间学习下 vcpkg ,如果要更进一步,需要学习下 cmake 脚本语言,学习 C++就是这样,库管理乱的一塌糊涂,c++ 20 才引入 Module ,只能等时间积累,你要对比 Maven 或是 npm ,只能说 c++还有很长的路要走,不过大部分项目,也会提供库的使用方法,无非是你现在不懂 cmake ;
|
23
SHIINASAMA 172 天前
@WangLiCha 因为 vcpkg 导入包基本都是从源码在本地构建的,如果你直接用来导入 Qt 的,那相当于编译一次 Qt ,更何况 Qt 的每个模块其实都挺大的。Qt 用预编译的安装包,其他不是很重量级的依赖可以用 vcpkg 管理,这个是可行的,我试过预编译的 Qt + vcpkg 的 ffmpeg ,没问题。
|
24
WangLiCha OP @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 |
25
SHIINASAMA 172 天前
@WangLiCha 🤔那就看这个编译时长你能不能接受了,不能就用预编译的咯。我主要想表达的是预编译包+vcpkg 是可行的...
|