Qt Creator+Cmake 编译带UI的动态链接库(share Lib)

223 阅读2分钟

编译动态库

image.png

这里可以选择继承的类 image.png

创建一个同名的“设计师UI类”进行覆盖

image.png

删除重复的h和cpp文件

image.png

编译之后会报错

image.png

这是因为在头文件里面构造函数是这样的:

public:
    explicit TestLib(QWidget *parent = nullptr);

所以在cpp文件里面我们要修改成为

#include "testlib.h"

TestLib::TestLib(QWidget *parent):
    QWidget(parent),
    ui(new Ui::TestLib)
{
    ui->setupUi(this) ;
}


TestLib::~TestLib()
{
    delete ui ;
}

注意析构函数里面要delete ui ,但是仍然会报错如下:

image.png

直接删除_global.h 文件,将里面的文件移动到头文件,同时添加XXX_EXPORT 标志,包含ui头文件

image.png

现在就可以编译成功了

提取出来头文件和ui头文件以及动态库 xx.h,ui_xx.h,xx.lib,xx.lib.a (我是使用mingw编译的所以有.a问价)

导入库

在新的项目里面创建include和lib两个文件夹,其中include文件夹里面放ui头文件和库头文件,lib里面放入库

打开一个文件在camkelists里面写入

set(LIB_RTOOLS_LIB_PATH "D:/myQtSoftwares/SerialPanel/lib/")  # 修改为实际路径
set(LIB_RTOOLS_INCLUDE_PATH "D:/myQtSoftwares/SerialPanel/include/")  # 修改为实际路径

# 包含库的头文件路径
include_directories(${LIB_RTOOLS_INCLUDE_PATH})


find_library(LIB_RTOOLS_LIB NAMES libRTools PATHS ${LIB_RTOOLS_LIB_PATH})


if(NOT LIB_RTOOLS_LIB)
    message(FATAL_ERROR "libRTools.dll.a not found!")
endif()

target_link_libraries(SerialPanel PRIVATE ${LIB_RTOOLS_LIB})

if(WIN32)
    add_custom_command(TARGET SerialPanel POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
        "${LIB_RTOOLS_LIB_PATH}/libRTools.dll"
        $<TARGET_FILE_DIR:SerialPanel>)
endif()

注意替换库的名字和信息,最后在头文件里面尝试包含库头文件,再编译就可以了,注意包含路径需要是"/include/xxx.h"

安装库

我们也可以把库安装到指定位置,只需要在库的cmakelists里面写入


install(TARGETS TPPanel
  EXPORT TPPanelExport
  LIBRARY DESTINATION lib # 动态库的安装路径
  ARCHIVE DESTINATION lib # 静态库的安装路径 (如果有的话)
  RUNTIME DESTINATION bin # 可执行文件的安装路径 (如果有的话)
)


# 仅递归查找源代码目录中的 .h 文件
file(GLOB_RECURSE H_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/*.h")

# 筛选需要安装的头文件
set(INSTALL_FILES "")
foreach(HEADER_FILE IN LISTS H_FILES)
     if(HEADER_FILE MATCHES "ui_.*\\.h" OR (HEADER_FILE MATCHES ".*\\.h$" AND NOT HEADER_FILE MATCHES "moc_.*\\.h"))
        list(APPEND INSTALL_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FILE}")
    endif()
endforeach()

# 安装筛选后的头文件到目标目录
foreach(HEADER_FILE IN LISTS INSTALL_FILES)
    install(FILES "${HEADER_FILE}" DESTINATION include/TPPanel)
endforeach()

在这里我把库头文件和ui头文件复制到了系统目录。然后注意在构建页面需要添加上install参数

image.png