如何创建和使用 Qt6 库?

问题描述 投票:0回答:1

我正在尝试制作一个可以在其他项目中使用的 Qt6 库。我可以在 Qt5 上使用它(使用 qmake),但我似乎无法在 Qt6 上使用它(使用 cmake)。值得注意的是,我的 Qt6 库项目与尝试使用它的 SampleProject 位于不同的文件夹中。

  • SampleLib 位置:C:\Users\ItsAMe\Desktop\QTProjects\SampleLib
  • SampleProject 位置:C:\Users\ItsAMe\Desktop\QTProjects\SampleProject

我做错/遗漏了什么?

SampleLib 项目

SampleLibConfig.cmake.in

set(SAMPLELIB_VERSION 1.0.0)

@PACKAGE_INIT@

set_and_check(SAMPLELIB_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(SAMPLELIB_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")

check_required_components(SampleLib)

CMakeLists.txt

cmake_minimum_required(VERSION 3.14)

project(SampleLib LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Quick)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Quick)

add_library(SampleLib STATIC
  SampleLib.cpp
  SampleLib.h
  SampleRect.qml
  SampleLib_global.h
)

include(CMakePackageConfigHelpers)

set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} CACHE PATH "Location of header files" )
set(SYSCONFIG_INSTALL_DIR ${CMAKE_INSTALL_SYSCONFDIR}/${PROJECT_NAME} CACHE PATH "Location of configuration files" )

configure_package_config_file(${PROJECT_NAME}Config.cmake.in
    ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
    INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
    PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR)

write_basic_package_version_file(
  ${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
  VERSION 1.0.0
  COMPATIBILITY SameMajorVersion)

install(FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
              ${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})

target_include_directories(SampleLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

target_link_libraries(SampleLib PRIVATE
   Qt${QT_VERSION_MAJOR}::Core
   Qt${QT_VERSION_MAJOR}::Quick)

target_compile_definitions(SampleLib PRIVATE SAMPLELIB_LIBRARY)

SampleLib_global.h

#ifndef SAMPLELIB_GLOBAL_H
#define SAMPLELIB_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(SAMPLELIB_LIBRARY)
#  define SAMPLELIB_EXPORT Q_DECL_EXPORT
#else
#  define SAMPLELIB_EXPORT Q_DECL_IMPORT
#endif

#endif // SAMPLELIB_GLOBAL_H

SampleLib.h

#ifndef SAMPLELIB_H
#define SAMPLELIB_H

#include "SampleLib_global.h"

class SAMPLELIB_EXPORT SampleLib
{
public:
   SampleLib()
   {

   }
};

#endif // SAMPLELIB_H

SampleRect.qml

import QtQuick 2.15

Rectangle {
    color: "purple"
}

示例项目

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)

project(SampleProject VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

find_package(Qt6 6.4 REQUIRED COMPONENTS Quick)

qt_standard_project_setup()

qt_add_executable(SampleProject
    main.cpp
)

qt_add_qml_module(SampleProject
    URI SampleProject
    VERSION 1.0
    QML_FILES Main.qml
)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
set_target_properties(SampleProject PROPERTIES
#    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.SampleProject
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

set(SampleLib_DIR C:/Users/Ricky/Desktop/QTProjects/SampleLib/Build/Release)
find_package(SampleLib REQUIRED)

target_include_directories(SampleProject PRIVATE ${SampleLib_INCLUDE_DIRS})

#Issue: Cannot open input file 'SampleLib.lib'
target_link_libraries(SampleProject PRIVATE
   Qt6::Quick
   SampleLib
)

include(GNUInstallDirs)
install(TARGETS SampleProject
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

// Issue: I'd expect that I can format this as #include "SampleLib/SampleLib.h" (even though SampleLib is one directory above this project)
#include "../SampleLib/SampleLib.h"

int main(int argc, char *argv[])
{
   QGuiApplication app(argc, argv);

   // Unresolved external symbol...
   SampleLib test;

   QQmlApplicationEngine engine;
   const QUrl url(u"qrc:/SampleProject/Main.qml"_qs);
   QObject::connect(
      &engine,
      &QQmlApplicationEngine::objectCreationFailed,
      &app,
      []() { QCoreApplication::exit(-1); },
      Qt::QueuedConnection);
   engine.load(url);

   return app.exec();
}

主.qml

import QtQuick

// Issue: SampleLib: no such directory.
import "SampleLib"

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    SampleRect {
        anchors.fill: parent
        //color: "orange"
    }
}
qt cmake qml
1个回答
0
投票

你的问题似乎是如何在很多地方重用你自己的库。

我的建议是将你的库项目上传到 GitHub,然后使用 FetchContent 将库获取到您想要在其中使用它的任何项目。这样您的库将与您的主项目一起使用和构建,并且可以在您想要使用它的任何项目中“重新获取”。我整理了一个小例子来说明它是如何工作的。

我已将一个非常小的库项目上传到我的 GitHub,名为 workbench。里面有这些文件:

CMakeLists.txt

cmake_minimum_required(VERSION 3.22.0)

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

project(workbench VERSION 1.0.0)

# Using INTERFACE for header only library
add_library(workbench INTERFACE)

# Giving scope to files inside library
target_include_directories(workbench INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)

模块.h

#include <string>

static std::string RandomVariable = "Hello from module";

从这里开始,我创建了一个小项目,其中包含我的

workbench
库。看起来如下:

CMakeLists.txt

cmake_minimum_required(VERSION 3.22.0)

project(tester VERSION 1.0.0)

# Allows us to use FetchContent
include(FetchContent)

# Fetches the repository from GitHub
FetchContent_Declare(workbench
    GIT_REPOSITORY https://github.com/andrelehto/workbench.git
    GIT_TAG v1.0.0
)

# Makes the repository available to us
FetchContent_MakeAvailable(workbench)

add_executable(tester main.cpp)

# Link to library from GitHub
target_link_libraries(tester workbench)

main.cpp

#include <iostream>

#include "module.h"

int main() {
  std::cout << RandomVariable << std::endl;
}

请注意,

module.h
现在可以在我们的主项目中使用。

© www.soinside.com 2019 - 2024. All rights reserved.