0

我已经查看了类似的问题,但没有找到适合这个基本场景的问题。我对 CMake 比较陌生。我有一个基于 CMake 的 Qt 5 项目。这是一个简单的测试应用程序;在其构建期间,我想构建并静态链接开源 Paho MQTT C lib 和 C++ 包装器。这是两个独立的项目,有自己的 CMakeLists.txt 文件。

根据 Qt 的默认设置,它构建到源代码树之外的目录中。

我已经在我的项目的父目录下复制了这些开源库的源代码树,并将顶级 CMakeLists.txt 文件编辑为 add_subdirectory 它们。

我还添加了 target_link_libraries。我可以自己获取 C lib 来构建并链接到父项目,但是如果我添加 C++ 包装器,C++ 包装器的处理会抱怨它找不到 C lib...这是真的,因为它没有还没有建成。简单地使用 Qt 的“构建所有项目”菜单项解决了对 C 库的类似投诉,但是当添加 C++ 包装器库时,这不起作用。包装器的 CMakeLists.txt 文件问题如下:

paho.mqtt.cpp/src/CMakeLists.txt:150 处的 CMake 错误(消息):找不到 Paho MQTT C 库

果然它不存在,因为当这个预处理完成时它还没有被构建。

更新:这是我的顶级 CMakeLists.txt 文件,根据 Corristo 的建议进行了修改,它成功地让 CMake 解析了整个层次结构。该项目现在构建。不过,我很困惑这里的最后两行会导致一个空字符串。对链接目录的类似尝试也是如此。

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

set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
    task.h
    task.cpp
    task.ui
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(MQTTTest
        ${PROJECT_SOURCES}
    )
else()
    if(ANDROID)
        add_library(MQTTTest SHARED
            ${PROJECT_SOURCES}
        )
    else()
        add_executable(MQTTTest
            ${PROJECT_SOURCES}
        )
    endif()
endif()

add_subdirectory(paho.mqtt.c)
set(PAHO_MQTT_C_LIB paho-mqtt3a)
set(PAHO_MQTT_C_PATH "${CMAKE_CURRENT_LIST_DIR}/paho.mqtt.c")
add_subdirectory(paho.mqtt.cpp)

target_link_libraries(MQTTTest PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
target_link_directories(MQTTTest PUBLIC
                        "${CMAKE_CURRENT_LIST_DIR}/build/paho.mqtt.c/src"
                        "${CMAKE_CURRENT_LIST_DIR}/build/paho.mqtt.cpp/src")

target_link_libraries(MQTTTest PUBLIC paho-mqtt3a)
target_link_libraries(MQTTTest PUBLIC paho-mqttpp3)

target_include_directories(MQTTTest PUBLIC
                        "${PROJECT_BINARY_DIR}"
                        "${CMAKE_CURRENT_LIST_DIR}/paho.mqtt.c/src"
                        "${CMAKE_CURRENT_LIST_DIR}/paho.mqtt.cpp/src")

get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
message("Top-level include dirs = ${inc_dirs}")

在此处输入图像描述

4

1 回答 1

1

这有点 hack,但是find_*如果结果变量已经设置,您可以使用 CMake 命令不执行搜索的事实。

paho.mqtt.cpp/src/CMakeLists.txt文件中,我们发现输出变量 forfind_library被调用PAHO_MQTT_C_LIB,并且包含目录预计位于1.0.0 版(似乎是您正在使用的版本)PAHO_MQTT_C_INC_DIR原始 CMakeLists.txtPAHO_MQTT_C_PATH中,它本身是根据计算得出的.

add_subdirectory在两个调用之间设置这两个变量应该可以使这个工作:

add_subdirectory(paho.mqtt.c)
set(PAHO_MQTT_C_LIB paho-mqtt3a)
set(PAHO_MQTT_C_PATH "${CMAKE_CURRENT_LIST_DIR}/paho.mqtt.c")
add_subdirectory(paho.mqtt.cpp)

这利用了target_link_libraries可以使用库文件(这是原始 paho.mqtt.cpp 项目所期望的)和现有 CMake 目标(这是我们替换它的目标)调用的事实。链接到 CMake 目标还会自动引入构建顺序依赖项,因此这同时确保了 c 库在 cpp 库之前构建。

但是,由于这依赖于paho.mqtt.cpp项目中使用的变量的名称以及项目中库目标的目标名称,因此在paho.mqtt.c您将这些库之一更新到较新版本时,这可能会中断。

于 2021-03-07T11:03:09.213 回答