学习 QT,尝试链接静态库,但怎么都链接不上,请教一下大佬们这是怎么回事

216 天前
 chouxw112233

QT creator 12.0.2 Based on QT 6.6.0 windows 10

windows git bash 输出的各个文件名 test 是自己的测试用的静态库 target 是可执行文件项目 libtest.a 已经生成了

[pj]$ ls target/*
target/main.cpp  target/target.pro  target/target.pro.user  target/widget.cpp  target/widget.h  target/widget.ui
[pj]$ ls test/*
test/test.cpp  test/test.h  test/test.pro  test/test.pro.user  test/test_global.h
[pj]$ ls build-test-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/*
build-test-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/Makefile        build-test-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/Makefile.Release
build-test-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/Makefile.Debug

build-test-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/debug:
libtest.a  test.o

build-test-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/release:

以下是 test.pro, 我加了CONFIG += staticlib,现在在build-test-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/debug下只会生成 libtest.a ,不会生成 test.dll

QT -= gui

TEMPLATE = lib
DEFINES += TEST_LIBRARY

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    test.cpp

HEADERS += \
    test_global.h \
    test.h

CONFIG += staticlib
# Default rules for deployment.
unix {
    target.path = /usr/lib
}

!isEmpty(target.path): INSTALLS += target

我在默认的 target.pro 中添加了如下内容用来链接 libtest.a

win32: LIBS += -L$$PWD/../build-test-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/debug/ -ltest

INCLUDEPATH += $$PWD/../test
DEPENDPATH += $$PWD/../test

win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../build-test-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/debug/libtest.a
else:win32-g++: PRE_TARGETDEPS += $$PWD/../build-test-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/debug/libtest.a

main.cpp

#include "widget.h"
#include "test.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    Test t;
    t.print();  // print 是 test 的 public 函数,用 qDebug 输出函数名

    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

编译报错 undefined reference, 应该是链接不到 libtest.a:

:-1: error: debug/main.o: in function `qMain(int, char**)':
D:\Qt\pj\target\main.cpp:7: error: undefined reference to `__imp__ZN4TestC1Ev'
:-1: error: D:\Qt\pj\build-target-Desktop_Qt_6_6_3_MinGW_64_bit-Debug/../target/main.cpp:8: undefined reference to `__imp__ZN4Test5printEv'
:-1: error: collect2.exe: error: ld returned 1 exit status
:-1: error: [Makefile.Debug:72: debug/target.exe] Error 1

不知道我是不是少了什么设置

如果以上描述不到位,这是两个项目的文件。先构建 test ,后运行 target https://drive.google.com/file/d/1FxtwscpdG9Atj2-YnAnR-CCKcmIwx0P7/view?usp=drive_link

2796 次点击
所在节点    C++
12 条回复
ysc3839
216 天前
个人建议把编译工具换成 CMake ,mingw 也可以考虑直接用 MSYS2
kokutou
216 天前
msys2 装个 static 版本的 qt
cnbatch
216 天前
Windows 系统?使用微软自己的工具链会更好,不想安装 Visual Studio 也可以只安装 Microsoft Build Tools
最好直接用 vcpkg ,许多事情都会方便很多
ljyst
216 天前
肿么 win 平台用 qt
shuax
216 天前
直接 vcpkg
rocky2024
216 天前
在 Win 路径下 似乎是 \
chouxw112233
216 天前
@kokutou 搜了一下,似乎需要从源码开始编译?官方的 qt creator 不支持我这样链接吗
@cnbatch @shuax 但是我链接的是自己写的库。不是第三方发布的库
@rockyhoujinsong qt 应该都能识别。我试过 \ 和 \\ 都一样
@ljyst win 的 qt 有什么问题吗?想学着写点东西,qt 本身也跨平台
chouxw112233
215 天前
我看的 https://wiki.qt.io/MSYS2
刚才安装了 MSYS ,并执行了这些

```
pacman -S mingw-w64-x86_64-toolchain
pacman -S mingw-w64-x86_64-qt5-static
pacman -S mingw-w64-x86_64-qt-creator
pacman -S cmake
```

可以看到 D:\msys64\mingw64\bin\qtcreator.exe
打开后版本已经更新到了 Qt Creator 13.0.0 Based on Qt 6.7.0 (GCC 13.2.0, x86_64)
主楼里提到的项目还是没法静态链接。


不过 cmake 还是不能用,是否有好用的教程?😥配置了半天连编译都不行
4u1kto
211 天前
静态库在编译时会被直接链接到使用它的项目中,因此不需要额外的导出标记 Q_DECL_EXPORT 。
去掉 class 后边的 Q_DECL_EXPORT 就可以顺利编译,试试。

或者去掉 CONFIG += staticlib ,动态链接。
4u1kto
211 天前
@chouxw112233
对比其他语言后你会发现,C++编译工具链极其复杂,尽量挑一个 Qt 推荐的来使用,使用 QtCreator 来创建项目/静态库/动态库的模板,Qt5 可以用 qmake ,Qt6 要转为 cmake ,不过写 cmakelists.txt 又是一座大山,要多去 Github 学习别人构建方法。

对于初学者我能给的建议不多,投入时间、多思考、善用搜索、报大腿,(这个论坛会写 C++的很少)。
chouxw112233
211 天前
@4u1kto 非常感谢,成功了。

之前后来尝试了手动用 g++命令:
qmake -project 生成 pro 文件,修改生成的文件
qmake 生成 makefile
Mingw32-make 进行编译,提示 undefined reference
手动把最后一行 g++命令复制出来,在命令最后加上-L 库路径 -l 库名,就成功了

可以链接,但是没有像你说的去掉 Q_DECL_EXPORT 。我去研究下`Q_DECL_EXPORT`的作用


@shuax 抱歉,以前没听过 vcpkg 。网络问题,装了很久的 vcpkg 和 vs 。vs 用起来有点不习惯,但最后用 vs 确实链接了自定义静态库和 qt 自带的 lib.a 库,生成了完全静态的可执行文件。安装过程确实有点花时间了
asuraa
204 天前
vcpkg install qt:x64-windows-static

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1034435

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX