zoukankan      html  css  js  c++  java
  • CMake

    资源: 

      https://github.com/xiaoweiChen/CMake-Cookbook

      生成器表达式章节:参考

      find_package和pkg_check_modules

      qt的国际化:ts文件的更新   参考wiki

    1. 一些命令

    cmake -S . -B build       # 自动创建 build 文件夹
    cmake -S . -B build && cmake --build build --target all -- -j$(nproc)
    cmake --help-command ADD_SUBDIRECTORY
    apt rdepends qtbase5-dev-tools # 查找哪些软件依赖于这个 from: dpkg -S qdbusxml2cpp

      cmake 的 clean 方式:参考

      优雅的构建CMake项目:参考

      集成GTest:参考,相关命令:enable_testing()    add_test()   详细参考

      在cmake中优雅的使用pkgconfig参考

      cmake的函数以及参数传递参考

    alex@alex-PC:~/Desktop/Test/translator/example1$ dpkg -S Qt5LinguistTools
    qttools5-dev:amd64: /usr/lib/x86_64-linux-gnu/cmake/Qt5LinguistTools/Qt5LinguistToolsMacros.cmake
    qttools5-dev:amd64: /usr/lib/x86_64-linux-gnu/cmake/Qt5LinguistTools/Qt5LinguistToolsConfig.cmake
    qttools5-dev:amd64: /usr/lib/x86_64-linux-gnu/cmake/Qt5LinguistTools/Qt5LinguistToolsConfigVersion.cmake
    qttools5-dev:amd64: /usr/lib/x86_64-linux-gnu/cmake/Qt5LinguistTools
    函数参数

      安装路径的指定:知乎 

      安装权限的指定:参考

      现代cmake技巧:参考

      cmake生成器表达式参考    生成器表达式的简单示例:参考    参考   参考   参考   官方参考    详参

      include_directories 和 link_directories参考(LINK_DIRECTORIES放在ADD_EXECUTABLE之前)

      GNU开发工具——CMake构建Qt工程实践

      编译 Debug 或 Release 版本的坑:参考

      aux_source_directory

      get_filename_component

      strip --strip-unneeded

      install -m 644 -p 

      在编译时下载:参考

      对于龙芯的支持:参考

      添加单元测试: 参考

      CMakePrintHelpers

      打印所有可见变量:参考

    cmake_minimum_required(VERSION 3.7)

    打印可见变量及其值
    message("内置变量 -----------------------------------------------------------------------------------") get_cmake_property(_variableNames VARIABLES) foreach (_variableName ${_variableNames}) message(STATUS "${_variableName}=${${_variableName}}") endforeach()
    message("环境变量 -----------------------------------------------------------------------------------") 打印环境变量及其值 execute_process(COMMAND "${CMAKE_COMMAND}" "-E" "environment")

      使用Qt的私有库,重要参考

    The package qt5-base:x86-windows provides CMake targets:
    
        find_package(Qt5AccessibilitySupport CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::AccessibilitySupport Qt5::AccessibilitySupport Qt::AccessibilitySupportPrivate Qt5::AccessibilitySupportPrivate)
    
        find_package(Qt5Bootstrap CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::Bootstrap Qt5::Bootstrap Qt::BootstrapPrivate Qt5::BootstrapPrivate)
    
        find_package(Qt5Concurrent CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::Concurrent Qt5::Concurrent Qt::ConcurrentPrivate Qt5::ConcurrentPrivate)
    
        find_package(Qt5Core CONFIG REQUIRED)
        # Note: 2 target(s) were omitted.
        target_link_libraries(main PRIVATE Qt::Core Qt5::Core Qt::WinMain Qt5::WinMain)
    
        find_package(Qt5DBus CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::DBus Qt5::DBus Qt::DBusPrivate Qt5::DBusPrivate)
    
        find_package(Qt5DeviceDiscoverySupport CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::DeviceDiscoverySupport Qt5::DeviceDiscoverySupport Qt::DeviceDiscoverySupportPrivate Qt5::DeviceDiscoverySupportPrivate)
    
        find_package(Qt5EdidSupport CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::EdidSupport Qt5::EdidSupport Qt::EdidSupportPrivate Qt5::EdidSupportPrivate)
    
        find_package(Qt5EventDispatcherSupport CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::EventDispatcherSupport Qt5::EventDispatcherSupport Qt::EventDispatcherSupportPrivate Qt5::EventDispatcherSupportPrivate)
    
        find_package(Qt5FbSupport CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::FbSupport Qt5::FbSupport Qt::FbSupportPrivate Qt5::FbSupportPrivate)
    
        find_package(Qt5FontDatabaseSupport CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::FontDatabaseSupport Qt5::FontDatabaseSupport Qt::FontDatabaseSupportPrivate Qt5::FontDatabaseSupportPrivate)
    
        find_package(Qt5Gui CONFIG REQUIRED)
        # Note: 9 target(s) were omitted.
        target_link_libraries(main PRIVATE Qt::Gui Qt5::Gui Qt::GuiPrivate Qt5::GuiPrivate)
    
        find_package(Qt5Network CONFIG REQUIRED)
        # Note: 1 target(s) were omitted.
        target_link_libraries(main PRIVATE Qt::Network Qt5::Network Qt::NetworkPrivate Qt5::NetworkPrivate)
    
        find_package(Qt5OpenGL CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::OpenGL Qt5::OpenGL Qt::OpenGLPrivate Qt5::OpenGLPrivate)
    
        find_package(Qt5OpenGLExtensions CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::OpenGLExtensions Qt5::OpenGLExtensions Qt::OpenGLExtensionsPrivate Qt5::OpenGLExtensionsPrivate)
    
        find_package(Qt5PlatformCompositorSupport CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::PlatformCompositorSupport Qt5::PlatformCompositorSupport Qt::PlatformCompositorSupportPrivate Qt5::PlatformCompositorSupportPrivate)
    
        find_package(Qt5PrintSupport CONFIG REQUIRED)
        # Note: 1 target(s) were omitted.
        target_link_libraries(main PRIVATE Qt::PrintSupport Qt5::PrintSupport Qt::PrintSupportPrivate Qt5::PrintSupportPrivate)
    
        find_package(Qt5Sql CONFIG REQUIRED)
        # Note: 3 target(s) were omitted.
        target_link_libraries(main PRIVATE Qt::Sql Qt5::Sql Qt::SqlPrivate Qt5::SqlPrivate)
    
        find_package(Qt5Test CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::Test Qt5::Test Qt::TestPrivate Qt5::TestPrivate)
    
        find_package(Qt5ThemeSupport CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::ThemeSupport Qt5::ThemeSupport Qt::ThemeSupportPrivate Qt5::ThemeSupportPrivate)
    
        find_package(Qt5Widgets CONFIG REQUIRED)
        # Note: 1 target(s) were omitted.
        target_link_libraries(main PRIVATE Qt::Widgets Qt5::Widgets Qt::WidgetsPrivate Qt5::WidgetsPrivate)
    
        find_package(Qt5WindowsUIAutomationSupport CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::WindowsUIAutomationSupport Qt5::WindowsUIAutomationSupport Qt::WindowsUIAutomationSupportPrivate Qt5::WindowsUIAutomationSupportPrivate)
    
        find_package(Qt5Xml CONFIG REQUIRED)
        target_link_libraries(main PRIVATE Qt::Xml Qt5::Xml Qt::XmlPrivate Qt5::XmlPrivate)
    View Code

      cmake 中 ts 转 qm 文件: 参考   参考   参考   官方翻译)   git-example   qt国际化   参考

      添加 ui 文件、资源文件等:参考

      使用OpenGL:参考   参考

      关于 moc_predefs.h

    2. 内置变量

      cmake 中使用 Qt 的 private module:参考   官方   参考   参考   这有个不错的示例

    # qtbase 中搜索 CorePrivate 这个:
    set_target_properties(QtLibraryInfo PROPERTIES COMPILE_OPTIONS $
    <TARGET_PROPERTY:Qt::Core,INTERFACE_COMPILE_OPTIONS> COMPILE_DEFINITIONS $<TARGET_PROPERTY:Qt::Core,INTERFACE_COMPILE_DEFINITIONS> INCLUDE_DIRECTORIES $<TARGET_PROPERTY:Qt::Core,INTERFACE_INCLUDE_DIRECTORIES> INCLUDE_DIRECTORIES $<TARGET_PROPERTY:Qt::CorePrivate,INTERFACE_INCLUDE_DIRECTORIES> )

      参考(不错的文章)

      add_subdirectory(添加一个子目录并构建该子目录):参考

      include_directories() 用于添加 Headers 搜索路径( -I 标志), add_subdirectory() 在这种情况下没有区别 .

      include_directories 和 target_include_directories 区别: 参考   和生成器使用

    find_package( Threads REQUIRED )
    target_link_libraries(demo ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
    set_and_check 代替普通的
    target_include_directories(t x y) # 添加 x y 到目标的包含路径 t
    # 这种方法的优点是你可以控制选项传播到依赖于这个PUBLIC和PRIVATE的其他目标. same as CMAKE_EXE_LINKER_FLAGS :
    target_compile_options(first-test PRIVATE -fexceptions)

      target_compile_options add_compile_options  reference

      自动处理版本号:参考

    cmake_minimum_required(VERSION 3.10)
    
    if(NOT DTK_CORE_VERSION)
        set(DTK_CORE_VERSION 5.4.3)
    endif()
    
    project(dtkcore VERSION ${DTK_CORE_VERSION} LANGUAGES CXX)
    
    message("CMAKE_PROJECT_NAME = ${CMAKE_PROJECT_NAME}")
    message("PROJECT_VERSION = ${PROJECT_VERSION}")
    message("PROJECT_VERSION_MAJOR = ${PROJECT_VERSION_MAJOR}")
    message("PROJECT_VERSION_MINOR = ${PROJECT_VERSION_MINOR}")
    message("PROJECT_VERSION_PATCH = ${PROJECT_VERSION_PATCH}")
    message("PROJECT_VERSION_TWEAK = ${PROJECT_VERSION_TWEAK}")
    
    # cmake -DDTK_CORE_VERSION=10.2.1.3 CMakeLists.txt
    # cmake -S . -B build
    View Code

      外部传入字符串:参考

      同时编译动态、静态库的方法

      参考

      cmake的RPATH:

    SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) 
    SET(CMAKE_INSTALL_RPATH "\${ORIGIN}/lib") #指定运行时动态库的加载路径,ORIGIN指运行文件所在目录

    3. 常用

      cmake gui:参考

      参考

    if (UNIX) 
         set(CMAKE_CXX_FLAGS "-pthread")
         set(CMAKE_CXX_FLAGS "-dl")
    endif (UNIX)
    ADD_DEFINITIONS(-DXXX -DXXX)

    4. 安装

      参考   

      cmake -DCMAKE_INSTALL_PREFIX=<你想要安装的路径>

      set(CMAKE_INSTALL_PREFIX /usr/local)
      install(TARGETS test DESTINATION bin) #将test安装到/usr/local/bin目录下

      关于 EXPORT 和 configuration :参考,结合这个一起看

    5. 动态、静态的生成

      BUILD_SHARED_LIBS这个开关用来控制默认的库编译方式,如果不进行设置,

      使用ADD_LIBRARY 并没有指定库类型的情况下,默认编译生成的库都是静态库。

      如果 SET(BUILD_SHARED_LIBS ON) 后,默认生成的为动态库。

    6. 其它

      CMake 的查找规则:参考

      GLOB的陷阱

      PUBLIC_HEADER 主要是用于mac系统安装的:参考

      CMake 里面使用sed命令

    execute_process(COMMAND
          sh -c "sed -i 's#\\;#\\\n#g'  ${CMAKE_CURRENT_LIST_DIR}/dtkcore_config.h"
    )

    对于关键字的解释:

    依赖关系 描述
    PRIVATE 我需要,但是依赖者不需要
    PUBLIC 我和依赖者都需要
    INTERFACE 我不需要,但是依赖者需要

    生成器表达式中使用C++11:

      

    实例代码:

      编译时执行命令从ts文件生成qm文件:

    cmake_minimum_required(VERSION 3.10)
    # git clean -dfx . && cmake CMakeLists.txt && make && find . -name "*.qm"
    project(generate_qm)
    
    if (NOT TARGET Qt5::release)
        add_executable(Qt5::lrelease IMPORTED)
        set(imported_location "/usr/bin/lrelease")
        if (NOT EXISTS "${imported_location}")
            message(FATAL_ERROR "/usr/bin/lrelease does not exist. please install dependences qttools5-dev-tools.")
        endif()
    
        set_target_properties(Qt5::lrelease PROPERTIES
            IMPORTED_LOCATION ${imported_location}
        )
    endif()
    
    set(Qt5_LRELEASE_EXECUTABLE Qt5::lrelease)
    
    
    function(DTK_CREATE_QM_FROM_TS QM_FILE_LIST)
        set(options)
        set(oneValueArgs)
        set(multiValueArgs OPTIONS)
        cmake_parse_arguments(_LRELEASE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
        set(LRELEASE_FILES ${_LRELEASE_UNPARSED_ARGUMENTS})
    
    
        set(QM_FILES_OUTPUT_PATH ${CMAKE_CURRENT_LIST_DIR}/qm_files)
        # foreach(TS_FILE_PATH ${LRELEASE_FILES})
        #     message(STATUS ${TS_FILE_PATH})
        #     get_filename_component(FILE_NAME_NO_SUFFIX ${TS_FILE_PATH} NAME_WE) 
        #     set(QM_FILE_LOCATION ${QM_FILES_OUTPUT_PATH}/${FILE_NAME_NO_SUFFIX}.qm)
        #     # message("${Qt5_LRELEASE_EXECUTABLE} ARGS ${TS_FILE_PATH} -qm ${QM_FILE_LOCATION} ????")
        #     # add_custom_command(OUTPUT ${QM_FILE_LOCATION}
        #     #     COMMAND ${Qt5_LRELEASE_EXECUTABLE} ARGS ${TS_FILE_PATH} -qm ${QM_FILE_LOCATION}
        #     #     DEPENDS ${QM_FILE_LOCATION} VERBATIM
        #     # )
        #     list(APPEND ${QM_FILE_LIST} ${QM_FILE_LOCATION})
        # endforeach()
        dtk_add_translation(${QM_FILE_LIST} ${LRELEASE_FILES})
        set(${QM_FILE_LIST} ${${QM_FILE_LIST}} PARENT_SCOPE)
        file(MAKE_DIRECTORY "${QM_FILES_OUTPUT_PATH}")
    endfunction()
    
    function(DTK_ADD_TRANSLATION _qm_files)
        set(options)
        set(oneValueArgs)
        set(multiValueArgs OPTIONS)
    
        cmake_parse_arguments(_LRELEASE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
        set(_lrelease_files ${_LRELEASE_UNPARSED_ARGUMENTS})
    
        foreach(_current_FILE ${_lrelease_files})
            get_filename_component(_abs_FILE ${_current_FILE} ABSOLUTE)
            get_filename_component(qm ${_abs_FILE} NAME)
            # everything before the last dot has to be considered the file name (including other dots)
            string(REGEX REPLACE "\\.[^.]*$" "" FILE_NAME ${qm})
            get_source_file_property(output_location ${_abs_FILE} OUTPUT_LOCATION)
            if(output_location)
                file(MAKE_DIRECTORY "${output_location}")
                set(qm "${output_location}/${FILE_NAME}.qm")
            else()
                set(qm "${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}.qm")
            endif()
    
            add_custom_command(OUTPUT ${qm}
                COMMAND ${Qt5_LRELEASE_EXECUTABLE}
                ARGS ${_LRELEASE_OPTIONS} ${_abs_FILE} -qm ${qm}
                DEPENDS ${_abs_FILE} VERBATIM
            )
            list(APPEND ${_qm_files} ${qm})
        endforeach()
        set(${_qm_files} ${${_qm_files}} PARENT_SCOPE)
    endfunction()
    
    file(GLOB LANGUAGE_TS_FILES "*.ts")
    dtk_create_qm_from_ts(QM_FILES
        ${LANGUAGE_TS_FILES}
    )
    
    add_custom_target(${PROJECT_NAME} ALL DEPENDS ${QM_FILES})
    View Code

      原来使用这个函数,只要把Translate加到target中或者depends中就能生成:

    file(GLOB_RECURSE LANGUAGE_TS_FILES "*.ts")
    qt5_create_translation(Translate
        # main.cpp                # 扫描源文件,如果有 tr 的也会被替换
        # dialog.ui
        # en.ts
        ${LANGUAGE_TS_FILES}
    )
    View Code

    遇到的重要问题记录:

       rpmlint -c BinariesCheck

      使用 link_directories 链接本地库可以比 add_directories 提供更好的编译并行性能。

    技巧,同一个目录生成多个可执行文件:

    cmake_minimum_required(VERSION 3.14)
    # https://stackoverflow.com/questions/35696103/cmake-wildcard-for-target-objects
    project(myTestDemo)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    add_library(Client OBJECT main1.cpp)
    add_library(Server OBJECT main2.cpp)
    
    function(DTK_ADD_EXECUTABLE _target)
        foreach(_source IN ITEMS ${ARGN})
            if (NOT TARGET "${_source}")
                list(APPEND _source_list "${_source}")
            else()
                get_target_property(_type "${_source}" TYPE)
                if (_type STREQUAL "OBJECT_LIBRARY")
                    list(APPEND _source_list "$<TARGET_OBJECTS:${_source}>")
                else()
                    message(SEND_ERROR "my_add_executable: '${_source}' given as parameter is not a object-library target.")
                endif()
            endif()
        endforeach()
        add_executable(${_target} ${_source_list})
    endfunction()
    
    dtk_add_executable(target1 main1.cpp )  # 非main的对象写在后面 Client、Server
    dtk_add_executable(target2 main2.cpp )  
    
    add_custom_target(target3)
    add_dependencies(target3 target1 target2)
    multi executable

    生成代码测试覆盖率:

      参考 

    CMAKE_EXE_LINKER_FLAGS 的坑:参考 

    添加子文件夹:

       gerrit链接

    # https://stackoverflow.com/questions/8934295/add-source-in-a-subdirectory-to-a-cmake-project
    # https://crascit.com/2016/01/31/enhanced-source-file-handling-with-target_sources/
    # 正规写法: https://www.jianshu.com/p/cbee27847638
    
    cmake_minimum_required(VERSION 3.10)
    project(dtkcore VERSION 5.5)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    
    set(REQUIRED_QT_VERSION 5.11.3)
    
    find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS Core DBus Xml Concurrent)
    
    include_directories(base filesystem log settings util)
    
    find_library(QGSETTINGS_LIB gsettings-qt)
    
    set(Qt_LIBS
        Qt5::Core
        Qt5::DBus
        Qt5::Xml
        Qt5::Concurrent
    )
    
    add_library(${PROJECT_NAME} STATIC SHARED ${HEADERS} ${SOURCES} ${RESOURCES} ${QMLS} ${QGSETTINGS_LIB})
    
    add_subdirectory("log")
    add_subdirectory("base")
    add_subdirectory("util")
    add_subdirectory("settings")
    add_subdirectory("filesystem")
    
    set(HEADERS
        dtkcore_global.h
        dsysinfo.h
        dsecurestring.h
        ddesktopentry.h
    )
    
    set(SOURCES
        dsysinfo.cpp
        dsecurestring.cpp
        ddesktopentry.cpp
        dtkcore_global.cpp
    )
    
    set(RESOURCES
        util/util.qrc
    )
    
    target_link_libraries(${PROJECT_NAME} PRIVATE ${Qt_LIBS} pthread)
    main cmake
    set(HEADERS ${HEADERS}
            ${CMAKE_CURRENT_SOURCE_DIR}/dbasefilewatcher.h
            ${CMAKE_CURRENT_SOURCE_DIR}/dfilesystemwatcher.h
            ${CMAKE_CURRENT_SOURCE_DIR}/dfilewatcher.h          
            ${CMAKE_CURRENT_SOURCE_DIR}/dfilewatchermanager.h
            ${CMAKE_CURRENT_SOURCE_DIR}/dpathbuf.h
            ${CMAKE_CURRENT_SOURCE_DIR}/dstandardpaths.h
            ${CMAKE_CURRENT_SOURCE_DIR}/dtrashmanager.h
    
    
            ${CMAKE_CURRENT_SOURCE_DIR}/private/dbasefilewatcher_p.h
            ${CMAKE_CURRENT_SOURCE_DIR}/private/dfilesystemwatcher_linux_p.h
    
            # DFileWatcher
            # DBaseFileWatcher
            # DFileSystemWatcher
            # DFileWatcherManager
            # DPathBuf
            # DStandardPaths
            # DTrashManager
    )
    
    set(SOURCES
            ${CMAKE_CURRENT_SOURCE_DIR}/dbasefilewatcher.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/dfilewatcher.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/dfilewatchermanager.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/dstandardpaths.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/dpathbuf.cpp
    
            ${CMAKE_CURRENT_SOURCE_DIR}/dfilesystemwatcher_linux.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/dtrashmanager_linux.cpp
    )
    
    target_sources(${PROJECT_NAME} PRIVATE ${HEADERS} ${SOURCES})
    sub cmake
  • 相关阅读:
    java实现第五届蓝桥杯出栈次序
    java实现第五届蓝桥杯年龄巧合
    java实现第五届蓝桥杯年龄巧合
    java实现第五届蓝桥杯年龄巧合
    java实现第五届蓝桥杯年龄巧合
    java实现第五届蓝桥杯年龄巧合
    Java使用RandomAccessFile读写文件
    Java 实现文件随机读写-RandomAccessFile
    NIO 中文乱码自我解决的简单DEMO
    NIO 中文乱码问题的解决代码实现
  • 原文地址:https://www.cnblogs.com/abnk/p/15095325.html
Copyright © 2011-2022 走看看