CMake高级用法实例分析(学习paddle官方的CMakeLists)

这篇具有很好参考价值的文章主要介绍了CMake高级用法实例分析(学习paddle官方的CMakeLists)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

cmake基础学习教程
https://juejin.cn/post/6844903557183832078

官方完整CMakeLists

cmake_minimum_required(VERSION 3.0)
project(PaddleObjectDetector CXX C)

option(WITH_MKL        "Compile demo with MKL/OpenBlas support,defaultuseMKL."          ON)
option(WITH_GPU        "Compile demo with GPU/CPU, default use CPU."                    ON)
option(WITH_TENSORRT   "Compile demo with TensorRT."                                    OFF)

option(WITH_KEYPOINT        "Whether to Compile KeyPoint detector"                    OFF)
option(WITH_MOT       "Whether to Compile MOT detector" OFF)

SET(PADDLE_DIR "" CACHE PATH "Location of libraries")
SET(PADDLE_LIB_NAME "" CACHE STRING "libpaddle_inference")
SET(OPENCV_DIR "" CACHE PATH "Location of libraries")
SET(CUDA_LIB "" CACHE PATH "Location of libraries")
SET(CUDNN_LIB "" CACHE PATH "Location of libraries")
SET(TENSORRT_INC_DIR "" CACHE PATH "Compile demo with TensorRT")
SET(TENSORRT_LIB_DIR "" CACHE PATH "Compile demo with TensorRT")

include(cmake/yaml-cpp.cmake)

include_directories("${CMAKE_SOURCE_DIR}/")
include_directories("${CMAKE_CURRENT_BINARY_DIR}/ext/yaml-cpp/src/ext-yaml-cpp/include")
link_directories("${CMAKE_CURRENT_BINARY_DIR}/ext/yaml-cpp/lib")

if (WITH_KEYPOINT)
    set(SRCS src/main_keypoint.cc src/preprocess_op.cc src/object_detector.cc src/picodet_postprocess.cc src/utils.cc src/keypoint_detector.cc src/keypoint_postprocess.cc)
elseif (WITH_MOT)
    set(SRCS src/main_jde.cc src/preprocess_op.cc src/object_detector.cc src/jde_detector.cc src/tracker.cc src/trajectory.cc src/lapjv.cpp src/picodet_postprocess.cc src/utils.cc)
else ()
    set(SRCS src/main.cc src/preprocess_op.cc src/object_detector.cc src/picodet_postprocess.cc src/utils.cc)
endif()

#这个宏定义的意思是如果这些flag中有MD即动态版本,都要替换成静态版本
macro(safe_set_static_flag)
    foreach(flag_var
        CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
        CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
      if(${flag_var} MATCHES "/MD")
        string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
      endif(${flag_var} MATCHES "/MD")
    endforeach(flag_var)
endmacro()

if (WITH_MKL)
    ADD_DEFINITIONS(-DUSE_MKL)
endif()

if (NOT DEFINED PADDLE_DIR OR ${PADDLE_DIR} STREQUAL "")
    message(FATAL_ERROR "please set PADDLE_DIR with -DPADDLE_DIR=/path/paddle_influence_dir")
endif()
message("PADDLE_DIR IS:" ${PADDLE_DIR})

if (NOT DEFINED OPENCV_DIR OR ${OPENCV_DIR} STREQUAL "")
    message(FATAL_ERROR "please set OPENCV_DIR with -DOPENCV_DIR=/path/opencv")
endif()

include_directories("${CMAKE_SOURCE_DIR}/")
include_directories("${PADDLE_DIR}/")
include_directories("${PADDLE_DIR}/third_party/install/protobuf/include")
include_directories("${PADDLE_DIR}/third_party/install/glog/include")
include_directories("${PADDLE_DIR}/third_party/install/gflags/include")
include_directories("${PADDLE_DIR}/third_party/install/xxhash/include")
if (EXISTS "${PADDLE_DIR}/third_party/install/snappy/include")
    include_directories("${PADDLE_DIR}/third_party/install/snappy/include")
endif()
if(EXISTS "${PADDLE_DIR}/third_party/install/snappystream/include")
    include_directories("${PADDLE_DIR}/third_party/install/snappystream/include")
endif()
include_directories("${PADDLE_DIR}/third_party/boost")
include_directories("${PADDLE_DIR}/third_party/eigen3")

if (EXISTS "${PADDLE_DIR}/third_party/install/snappy/lib")
    link_directories("${PADDLE_DIR}/third_party/install/snappy/lib")
endif()
if(EXISTS "${PADDLE_DIR}/third_party/install/snappystream/lib")
    link_directories("${PADDLE_DIR}/third_party/install/snappystream/lib")
endif()

link_directories("${PADDLE_DIR}/third_party/install/protobuf/lib")
link_directories("${PADDLE_DIR}/third_party/install/glog/lib")
link_directories("${PADDLE_DIR}/third_party/install/gflags/lib")
link_directories("${PADDLE_DIR}/third_party/install/xxhash/lib")
link_directories("${PADDLE_DIR}/third_party/install/paddle2onnx/lib")
link_directories("${PADDLE_DIR}/third_party/install/onnxruntime/lib")
link_directories("${PADDLE_DIR}/paddle/lib/")
link_directories("${CMAKE_CURRENT_BINARY_DIR}")



if (WIN32)
  include_directories("${PADDLE_DIR}/paddle/fluid/inference")
  include_directories("${PADDLE_DIR}/paddle/include")
  link_directories("${PADDLE_DIR}/paddle/fluid/inference")
  find_package(OpenCV REQUIRED PATHS ${OPENCV_DIR}/build/ NO_DEFAULT_PATH)

else ()
  find_package(OpenCV REQUIRED PATHS ${OPENCV_DIR}/share/OpenCV NO_DEFAULT_PATH)
  include_directories("${PADDLE_DIR}/paddle/include")
  link_directories("${PADDLE_DIR}/paddle/lib")
endif ()
include_directories(${OpenCV_INCLUDE_DIRS})

if (WIN32)
    add_definitions("/DGOOGLE_GLOG_DLL_DECL=")
    set(CMAKE_C_FLAGS_DEBUG   "${CMAKE_C_FLAGS_DEBUG} /bigobj /MTd")
    set(CMAKE_C_FLAGS_RELEASE  "${CMAKE_C_FLAGS_RELEASE} /bigobj /MT")
    set(CMAKE_CXX_FLAGS_DEBUG  "${CMAKE_CXX_FLAGS_DEBUG} /bigobj /MTd")
    set(CMAKE_CXX_FLAGS_RELEASE   "${CMAKE_CXX_FLAGS_RELEASE} /bigobj /MT")
else()
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -o2 -fopenmp -std=c++11")
    set(CMAKE_STATIC_LIBRARY_PREFIX "")
endif()

# TODO let users define cuda lib path
if (WITH_GPU)
    if (NOT DEFINED CUDA_LIB OR ${CUDA_LIB} STREQUAL "")
        message(FATAL_ERROR "please set CUDA_LIB with -DCUDA_LIB=/path/cuda-8.0/lib64")
    endif()
    if (NOT WIN32)
        if (NOT DEFINED CUDNN_LIB)
            message(FATAL_ERROR "please set CUDNN_LIB with -DCUDNN_LIB=/path/cudnn_v7.4/cuda/lib64")
        endif()
    endif(NOT WIN32)
endif()


if (NOT WIN32)
  if (WITH_TENSORRT AND WITH_GPU)
	  include_directories("${TENSORRT_INC_DIR}/")
	  link_directories("${TENSORRT_LIB_DIR}/")
  endif()
endif(NOT WIN32)

if (NOT WIN32)
    set(NGRAPH_PATH "${PADDLE_DIR}/third_party/install/ngraph")
    if(EXISTS ${NGRAPH_PATH})
        include(GNUInstallDirs)
        include_directories("${NGRAPH_PATH}/include")
        link_directories("${NGRAPH_PATH}/${CMAKE_INSTALL_LIBDIR}")
        set(NGRAPH_LIB ${NGRAPH_PATH}/${CMAKE_INSTALL_LIBDIR}/libngraph${CMAKE_SHARED_LIBRARY_SUFFIX})
    endif()
endif()

if(WITH_MKL)
  include_directories("${PADDLE_DIR}/third_party/install/mklml/include")
  if (WIN32)
    set(MATH_LIB ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.lib
            ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.lib)
  else ()
    set(MATH_LIB ${PADDLE_DIR}/third_party/install/mklml/lib/libmklml_intel${CMAKE_SHARED_LIBRARY_SUFFIX}
            ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5${CMAKE_SHARED_LIBRARY_SUFFIX})
    execute_process(COMMAND cp -r ${PADDLE_DIR}/third_party/install/mklml/lib/libmklml_intel${CMAKE_SHARED_LIBRARY_SUFFIX} /usr/lib)
  endif ()
  set(MKLDNN_PATH "${PADDLE_DIR}/third_party/install/mkldnn")
  if(EXISTS ${MKLDNN_PATH})
    include_directories("${MKLDNN_PATH}/include")
    if (WIN32)
      set(MKLDNN_LIB ${MKLDNN_PATH}/lib/mkldnn.lib)
    else ()
      set(MKLDNN_LIB ${MKLDNN_PATH}/lib/libmkldnn.so.0)
    endif ()
  endif()
else()
  set(MATH_LIB ${PADDLE_DIR}/third_party/install/openblas/lib/libopenblas${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()


if (WIN32)
    if(EXISTS "${PADDLE_DIR}/paddle/fluid/inference/${PADDLE_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}")
        set(DEPS
            ${PADDLE_DIR}/paddle/fluid/inference/${PADDLE_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
    else()
        set(DEPS
            ${PADDLE_DIR}/paddle/lib/${PADDLE_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
    endif()
endif()


if (WIN32)
    set(DEPS ${PADDLE_DIR}/paddle/lib/${PADDLE_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
else()
    set(DEPS ${PADDLE_DIR}/paddle/lib/${PADDLE_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
endif()

message("PADDLE_LIB_NAME:" ${PADDLE_LIB_NAME})
message("DEPS:" $DEPS)

if (NOT WIN32)
    set(DEPS ${DEPS}
        ${MATH_LIB} ${MKLDNN_LIB}
        glog gflags protobuf z xxhash yaml-cpp
        )
    if(EXISTS "${PADDLE_DIR}/third_party/install/snappystream/lib")
        set(DEPS ${DEPS} snappystream)
    endif()
    if (EXISTS "${PADDLE_DIR}/third_party/install/snappy/lib")
        set(DEPS ${DEPS} snappy)
    endif()
else()
    set(DEPS ${DEPS}
        ${MATH_LIB} ${MKLDNN_LIB}
        glog gflags_static libprotobuf xxhash libyaml-cppmt)
    set(DEPS ${DEPS} libcmt shlwapi)
    if (EXISTS "${PADDLE_DIR}/third_party/install/snappy/lib")
        set(DEPS ${DEPS} snappy)
    endif()
    if(EXISTS "${PADDLE_DIR}/third_party/install/snappystream/lib")
        set(DEPS ${DEPS} snappystream)
    endif()
endif(NOT WIN32)

if(WITH_GPU)
  if(NOT WIN32)
    if (WITH_TENSORRT)
	    set(DEPS ${DEPS} ${TENSORRT_LIB_DIR}/libnvinfer${CMAKE_SHARED_LIBRARY_SUFFIX})
	    set(DEPS ${DEPS} ${TENSORRT_LIB_DIR}/libnvinfer_plugin${CMAKE_SHARED_LIBRARY_SUFFIX})
    endif()
    set(DEPS ${DEPS} ${CUDA_LIB}/libcudart${CMAKE_SHARED_LIBRARY_SUFFIX})
    set(DEPS ${DEPS} ${CUDNN_LIB}/libcudnn${CMAKE_SHARED_LIBRARY_SUFFIX})
  else()
    set(DEPS ${DEPS} ${CUDA_LIB}/cudart${CMAKE_STATIC_LIBRARY_SUFFIX} )
    set(DEPS ${DEPS} ${CUDA_LIB}/cublas${CMAKE_STATIC_LIBRARY_SUFFIX} )
    set(DEPS ${DEPS} ${CUDNN_LIB}/cudnn${CMAKE_STATIC_LIBRARY_SUFFIX})
  endif()
endif()

if (NOT WIN32)
    set(EXTERNAL_LIB "-ldl -lrt -lgomp -lz -lm -lpthread")
    set(DEPS ${DEPS} ${EXTERNAL_LIB})
endif()

set(DEPS ${DEPS} ${OpenCV_LIBS})
add_executable(main ${SRCS})
ADD_DEPENDENCIES(main ext-yaml-cpp)
message("DEPS:" $DEPS)
target_link_libraries(main ${DEPS})

if (WIN32 AND WITH_MKL)
    add_custom_command(TARGET main POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.dll ./mklml.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.dll ./libiomp5md.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mkldnn/lib/mkldnn.dll ./mkldnn.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.dll ./release/mklml.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.dll ./release/libiomp5md.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mkldnn/lib/mkldnn.dll ./release/mkldnn.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/paddle/lib/${PADDLE_LIB_NAME}.dll ./release/${PADDLE_LIB_NAME}.dll
    )
endif()

if (WIN32 AND NOT WITH_MKL)
    add_custom_command(TARGET main POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/openblas/lib/openblas.dll ./openblas.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/openblas/lib/openblas.dll ./release/openblas.dll
    )
endif()

if (WIN32)
    add_custom_command(TARGET main POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/onnxruntime/lib/onnxruntime.dll ./onnxruntime.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/paddle2onnx/lib/paddle2onnx.dll ./paddle2onnx.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/onnxruntime/lib/onnxruntime.dll ./release/onnxruntime.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/paddle2onnx/lib/paddle2onnx.dll ./release/paddle2onnx.dll
        COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/paddle/lib/${PADDLE_LIB_NAME}.dll ./release/${PADDLE_LIB_NAME}.dll
    )
endif()

project()

项目名CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

option(

variable 选项名
help_text 描述、解释、备注
value 选项初始化值(除ON而外全为OFF))
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

SET()

这个大写的SET其实和小写的set是一样的,CMake中的命令不区分大小写,CMake中的变量区分大小写
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

官方手册

Set a normal, cache, or environment variable to a given value.
See the :ref:`cmake-language(7) variables <CMake Language Variables>`
documentation for the scopes and interaction of normal variables
and cache entries.

Signatures of this command that specify a ``<value>...`` placeholder
expect zero or more arguments.  Multiple arguments will be joined as
a :ref:`semicolon-separated list <CMake Language Lists>` to form the actual variable
value to be set.  Zero arguments will cause normal variables to be
unset.  See the ``unset()`` command to unset variables explicitly.

Set Normal Variable
^^^^^^^^^^^^^^^^^^^

 set(<variable> <value>... [PARENT_SCOPE])

Sets the given ``<variable>`` in the current function or directory scope.
  • 比较好的案例博客https://blog.csdn.net/Calvin_zhou/article/details/104060927

CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

include(cmake/yaml-cpp.cmake)

加载cmake文件的

Load and run CMake code from a file or module.

 include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>]
                       [NO_POLICY_SCOPE])

Loads and runs CMake code from the file given.  Variable reads and
writes access the scope of the caller (dynamic scoping).  If ``OPTIONAL``
is present, then no error is raised if the file does not exist.  If
``RESULT_VARIABLE`` is given the variable ``<var>`` will be set to the
full filename which has been included or ``NOTFOUND`` if it failed.

If a module is specified instead of a file, the file with name
``<modulename>.cmake`` is searched first in ``CMAKE_MODULE_PATH``,
then in the CMake module directory.  There is one exception to this: if
the file which calls ``include()`` is located itself in the CMake builtin
module directory, then first the CMake builtin module directory is searched and
``CMAKE_MODULE_PATH`` afterwards.  See also policy ``CMP0017``.

include_directories(“${CMAKE_SOURCE_DIR}/”)

加载头文件文件夹

Add include directories to the build.

 include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])

Add the given directories to those the compiler uses to search for
include files.  Relative paths are interpreted as relative to the
current source directory.

The include directories are added to the ``INCLUDE_DIRECTORIES``
directory property for the current ``CMakeLists`` file.  They are also
added to the ``INCLUDE_DIRECTORIES`` target property for each
target in the current ``CMakeLists`` file.  The target property values
are the ones used by the generators.

By default the directories specified are appended onto the current list of
directories.  This default behavior can be changed by setting
``CMAKE_INCLUDE_DIRECTORIES_BEFORE`` to ``ON``.  By using

link_directories()

加载库文件夹地址

Add directories in which the linker will look for libraries.

 link_directories([AFTER|BEFORE] directory1 [directory2 ...])

Adds the paths in which the linker should search for libraries.
Relative paths given to this command are interpreted as relative to
the current source directory, see ``CMP0015``.

The command will apply only to targets created after it is called.

.. versionadded:: 3.13
  The directories are added to the ``LINK_DIRECTORIES`` directory
  property for the current ``CMakeLists.txt`` file, converting relative
  paths to absolute as needed.  See the ``cmake-buildsystem(7)``
  manual for more on defining buildsystem properties.

.. versionadded:: 3.13

macro(safe_set_static_flag)函数

内容
**endmacro**()

这个函数属于宏定义,简单的说就是出现宏的地方进行代码替换,
解析的很清楚的博文:
https://blog.csdn.net/qq_21438461/article/details/129729530
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++
官方文档:

Start recording a macro for later invocation as a command

 macro(<name> [<arg1> ...])
   <commands>
 endmacro()

Defines a macro named ``<name>`` that takes arguments named
``<arg1>``, ... Commands listed after macro, but before the
matching ``endmacro()``, are not executed until the macro
is invoked.

Per legacy, the ``endmacro()`` command admits an optional
``<name>`` argument. If used, it must be a verbatim repeat of the
argument of the opening ``macro`` command.

See the ``cmake_policy()`` command documentation for the behavior
of policies inside macros.

foreach(参数,循环列表)函数

用于循环列表中的每一项

CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++
https://blog.csdn.net/wzj_110/article/details/116110014

Evaluate a group of commands for each value in a list.

 foreach(<loop_var> <items>)
   <commands>
 endforeach()

where ``<items>`` is a list of items that are separated by
semicolon or whitespace.
All commands between ``foreach`` and the matching ``endforeach`` are recorded
without being invoked.  Once the ``endforeach`` is evaluated, the recorded
list of commands is invoked once for each item in ``<items>``.
At the beginning of each iteration the variable ``<loop_var>`` will be set
to the value of the current item.

The scope of ``<loop_var>`` is restricted to the loop scope. See policy
``CMP0124`` for details.

MATCHES关键字

条件判断
https://blog.csdn.net/steptoward/article/details/128848733
可用于正则表达式
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

  • string(REGEX REPLACE 查找值 替换值 输出 输入)
    REGEX REPLACE指正则替换
    https://blog.csdn.net/weixin_41923935/article/details/122155064
    https://blog.csdn.net/m0_57845572/article/details/118520561
    CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++
String operations.

Synopsis
^^^^^^^^

 Search and Replace
   string(FIND <string> <substring> <out-var> [...])
   string(REPLACE <match-string> <replace-string> <out-var> <input>...)
   string(REGEX MATCH <match-regex> <out-var> <input>...)
   string(REGEX MATCHALL <match-regex> <out-var> <input>...)
   string(REGEX REPLACE <match-regex> <replace-expr> <out-var> <input>...)

 Manipulation
   string(APPEND <string-var> [<input>...])
   string(PREPEND <string-var> [<input>...])
   string(CONCAT <out-var> [<input>...])
   string(JOIN <glue> <out-var> [<input>...])

“/MD” “/MT”

CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

ADD_DEFINITIONS(-DUSE_MKL)

这种可以在我们更改别人代码做实验时使用,既不对其源码进行破坏,又可以添加自己的功能。有了这个后可以直接在编译的时候进行选择。具体的,在工程CMakeLists.txt 中,使用add_definitions()函数控制代码的开启和关闭:
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++
https://blog.csdn.net/fb_941219/article/details/107376017
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

Add -D define flags to the compilation of source files.

 add_definitions(-DFOO -DBAR ...)

Adds definitions to the compiler command line for targets in the current
directory, whether added before or after this command is invoked, and for
the ones in sub-directories added after. This command can be used to add any
flags, but it is intended to add preprocessor definitions.

.. note::

  This command has been superseded by alternatives:

  * Use ``add_compile_definitions()`` to add preprocessor definitions.
  * Use ``include_directories()`` to add include directories.
  * Use ``add_compile_options()`` to add other options.

cmake关系操作符号

CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

find_package(OpenCV REQUIRED PATHS ${OPENCV_DIR}/build/ NO_DEFAULT_PATH)函数

简单的说就是用这个如果找到了.cmake文件,就不用专门写link_directories,include_directories等函数来找头文件和库文件

Find a package (usually provided by something external to the project),
and load its package-specific details.

Search Modes
^^^^^^^^^^^^

The command has two very distinct ways of conducting the search:

**Module mode**
  In this mode, CMake searches for a file called ``Find<PackageName>.cmake``,
  looking first in the locations listed in the ``CMAKE_MODULE_PATH``,
  then among the :ref:`Find Modules` provided by the CMake installation.
  If the file is found, it is read and processed by CMake.  It is responsible
  for finding the package, checking the version, and producing any needed
  messages.  Some Find modules provide limited or no support for versioning;
  check the Find module's documentation.

写的最好的关于find_package的博文
https://blog.csdn.net/zhanghm1995/article/details/105466372
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

${CMAKE_SHARED_LIBRARY_SUFFIX}关键字

${CMAKE_STATIC_LIBRARY_SUFFIX}关键字

这个关键字能根据平台不同,自动为动态库静态库安排后缀,比如windows端的动态库后缀为dll,静态库为.lib,linux端的动态库后缀为.so,静态库后缀为.a
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

The suffix for shared libraries that you link to.

The suffix to use for the end of a shared library filename, ``.dll`` on
Windows.

add_dependencies()

大致意思是在同时生成可执行文件a和库b时,恰好可执行文件a的生成需要依赖b这个库时需要用这个函数来指定先生成库b再生成可执行文件a,如果不指定会报错找不到b依赖库
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

有案例的博文http://t.csdn.cn/FZdWN

Add a dependency between top-level targets.

 add_dependencies(<target> [<target-dependency>]...)

Makes a top-level ``<target>`` depend on other top-level targets to
ensure that they build before ``<target>`` does.  A top-level target
is one created by one of the ``add_executable()``,
``add_library()``, or ``add_custom_target()`` commands
(but not targets generated by CMake like ``install``).

Dependencies added to an :ref:`imported target <Imported Targets>`
or an :ref:`interface library <Interface Libraries>` are followed
transitively in its place since the target itself does not build.

.. versionadded:: 3.3
  Allow adding dependencies to interface libraries.

target_link_libraries

后面加具体依赖库的库名字,不需要加后缀
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

Specify libraries or flags to use when linking a given target and/or
its dependents.  :ref:`Usage requirements <Target Usage Requirements>`
from linked library targets will be propagated.  Usage requirements
of a target's dependencies affect compilation of its own sources.

Overview
^^^^^^^^

This command has several signatures as detailed in subsections below.
All of them have the general form

 target_link_libraries(<target> ... <item>... ...)

The named ``<target>`` must have been created by a command such as
``add_executable()`` or ``add_library()`` and must not be an
:ref:`ALIAS target <Alias Targets>`.  If policy ``CMP0079`` is not
set to ``NEW`` then the target must have been created in the current

add_custom_command

CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++

Add a custom build rule to the generated build system.

There are two main signatures for ``add_custom_command``.

Generating Files
^^^^^^^^^^^^^^^^

The first signature is for adding a custom command to produce an output:

 add_custom_command(OUTPUT output1 [output2 ...]
                    COMMAND command1 [ARGS] [args1...]
                    [COMMAND command2 [ARGS] [args2...] ...]
                    [MAIN_DEPENDENCY depend]
                    [DEPENDS [depends...]]
                    [BYPRODUCTS [files...]]
                    [IMPLICIT_DEPENDS <lang1> depend1
                                     [<lang2> depend2] ...]

相关博文:
https://www.jianshu.com/p/47370c584356
https://blog.csdn.net/weixin_39766005/article/details/122866375
CMake高级用法实例分析(学习paddle官方的CMakeLists),paddle,c++文章来源地址https://www.toymoban.com/news/detail-701935.html

到了这里,关于CMake高级用法实例分析(学习paddle官方的CMakeLists)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python实例分析

    Python是一种高级编程语言,具有简单易学、可读性强和易用性等特点,因此在Web开发、科学计算、数据分析、人工智能等领域被广泛使用。Python的语法简单明了,易于阅读和理解,使得开发者可以更快地编写代码,而不用花费过多的时间和精力去学习语言本身的复杂性。 与其

    2023年04月08日
    浏览(38)
  • Webshell实例分析解析

    LD_PRELOAD 是 Linux/Unix 系统的一个环境变量,它影响程序的运行时的链接(Runtime linker),它允许在程序运行前定义优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别

    2024年02月12日
    浏览(30)
  • FlinkSQL【分组聚合-多维分析-性能调优】应用实例分析

    FlinkSQL处理如下实时数据需求: 实时聚合不同 类型/账号/发布时间 的各个指标数据,比如: 初始化/初始化后删除/初始化后取消/推送/成功/失败 的指标数据。要求实时产出指标数据,数据源是mysql cdc binlog数据。 其他配置 flink集群参数 检查点配置 job运行资源 管理节点(JM)

    2024年01月17日
    浏览(59)
  • LLVM(5)ORC实例分析

    总结 因为API茫茫多,逻辑上的一些概念需要搞清,编码时会容易很多。 JIT的运行实体使用LLVMOrcCreateLLJIT可以创建出来,逻辑上的JIT实例。 JIT实例需要加入运行库(依赖库)和用户定义的context(运行内容)才能运行,LLVMOrcLLJITAddLLVMIRModule函数负责将运行库和ctx加入JIT实例。

    2024年02月07日
    浏览(77)
  • PID算法详解及实例分析

    PID算法算是控制领域最经典,最重要,也是最实用的算法了。所谓的PID,指的是proportion,integration,differentiation,比例,积分,微分。 因此,PID是结合了比例积分微分三个模块于一身的控制算法。 先看公式: u ( t ) = K p ( e ( t ) + 1 T i ∫ 0 t e ( t ) d t + T d d e ( t ) d t ) u(t) = K_p

    2024年01月21日
    浏览(41)
  • 音频信号的频谱分析实例

    在前面的文章 信号频谱分析与功率谱密度 中,我们初步探讨了信号频谱分析的概念,并介绍了其数学工具。本篇文章将结合实例,进一步探讨频谱分析在音频信号处理中的应用。 音频信号的频谱分析是一种将时域中的音频信号转换为频域表示的过程,从而可以观察信号在不

    2024年04月16日
    浏览(44)
  • layui表格事件分析实例

    在 layui 的表格组件中,区分表头事件和行内事件是通过事件类型(toolbar 和 tool)以及 lay-filter 值来实现的。 我们有一个表格,其中有一个工具栏按钮和操作按钮。我们将使用 layui 的 table 组件来处理这些事件。 HTML 结构: JavaScript 代码: 通过在按钮的 HTML 模板中使用 lay-e

    2024年02月11日
    浏览(38)
  • TCP/IP详解与实例分析

    TCP/IP并不是一个具体的协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇,只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。 TCP/IP协议在一定程度上参考了OSI的体系结构,在TCP/IP协议中,它们被简化为了四个层次。 OSI七层模型 TCP/IP概念层

    2024年02月08日
    浏览(88)
  • AAC 音频数据结构实例分析:

    AAC 音频数据结构实例分析: AAC 有两种数据交换格式:ADTS 和 ADIF ADIF: Audio Data Interchange Format, 一个文件只有一个头,可类比dvd中使用的ps流。 ADTS:Audio Data Transport Stream, 每个frame中都有这个同步头, 可类比dvb中的ts流. 本博客只介绍 ADTS 格式AAC 基本构成是7bytes 头部+原始数据. 循

    2024年02月02日
    浏览(35)
  • 适合中小企业的组网实例分析

    我国中小企业拥有60%的国民经济产值,为社会提供70%以上的就业机会,但是许多中小企业的信息化程度还很低,本文就向中小企业介绍几种实用的企业信息化方案。企业信息化的表现有多种多样,从简单的文件共享、办公自动化到复杂的电子商务、ERP,形形色色,千差万别。

    2024年02月07日
    浏览(76)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包