CMake

Example:

D:\Dev\Open3D\ycdev-cpp\realsense\CMakeLists.txt

 

http://www.elpauer.org/stuff/learning_cmake.pdf Learning Cmake

 

  • cmake --help-command-list //Get a list command used in Cmake
  • Cmake --debug-output  ../src  //See what camke really does
  • Cmake -- trace ../src  //Lots of output  or --trace-expand(trace and expanded variables)

 

Cmake variable are case sensitive, while commands are case insensitive

message(STATUS foo)  //Message is command. STATUS is key word, it is case sensitive

MESSAGE(status foo)

Output:

foo

Statusfoo

Set(foo 42)

MESSAGE(STATUS ${foo})

MESSAGE(STATUS %{Foo})

Output:

-- 42

-- (nothing)

 

Have this tree:

  • Myapp
    • Src
    • Build
  • Cd myapp/build
  • Cmake ../src  //It will generate VS project and solution in Build folder

 

 

 

Very simple executable:

  • cmake_minimum_required(VERSION 3.17)   //My installation Cmake 3.17
  • PROJECT( helloworld)
  • SET (hello_SRCS hello.cpp)
  • ADD_EXECUTABLE(hello ${hello_SRCS})  //VS project use hello.proj

 

Very simple library:

  • PROJECT( mylibrary)  //Solution use this name
  • SET (mylib_SRCS library.cpp)
  • ADD_LIBRARY(my SHARED ${mylib_SRCS})   //If without SHARED, generate a static library

 

 

 

The Cmake cache stores values which are not usually changed. Edit cache use CMakeSetup(Windows)

 

SET (var1 13)

  • If "var1" already existed in the cache, it is shadowed by this value
  • This call does not overwite "var1" value in the cache, it existed

SET(var2 17 ... CACHE ...)  //Reuse the cache

  • "var2" already in cache => keep cache
  • "var2" not yet un cache, var2 is set to 17

SET(var3 23 ... CACHE FORCE) //Unconditional set and overwrite cache

  • "var3" always takes this value, whether it was already in the cache or not

 

Flow control

  • IF(expression)

...

ELSEIF(expression2)  //the expression2 or expression in else and endif is optional. Add them is good style

...

ELSE(expression)

...

ENDIF(expression)

If(FOO)  //FOO is true if it is 1, ON, YES, TRUE, Y

EndIf(FOO) 

if(var) if(NOT var)  if(var AND var)  if(var OR var)  if(DEFINED var) if(EXISTS filename) if(EXISTS dirname)

if(n1 IS_NEWER_THAN n2)  if(var MATCHES regex) if(1 LESS 3) if(FOO STRLESS BAR)

 

  • Process a list:

FOREACH(loop_var)

...

ENDFOREACH(loop_var)

 

  • WHILE(condition)

...

ENDWHILE(condition)

 

Managing Debug and Release builds

  • SET(CMAKE_BUILD_TYPE Debug)
  • As any other variable, it can be set from the command line:

Cmake -DCMAKE_BUILD_TYPE=Release  ../src

  • Specify debug and release targets and 3rdparty libs:

TARGET_LINK_LIBRARIES(wakeup RELASEE ${wakeup_SRCS})

TARGET_LINK_LIBRARIES(wakeup DEBUG ${wakeup_SRCS})

 

Directories

  • Libraries built in your project (even if in a different CmakeLists.txt) is automatic (in rare occasions: ADD_DEPENDENCIES)
  • If the 3rd party library or .h is in a “standard” directory (PATH and/or LD_LIBRARY_PATH) is automatic
  • If in a nonstandard dir:
    • Headers: use INCLUDE_DIRECTORIES
    • Libraries: use FIND_LIBRARY and link with the result of it (try to avoid LINK_DIRECTORIES)

 

 

Make install

  • INSTALL(TARGETS clock wakeup RUNTIME DESTINATION bin LIBRARY DESTINATION lib)
  • Would install in /usr/local/bin and /usr/local/lib(Unix) or %PROGRAMFILES%\projectname(Windows)

 

 

Macros

  • MACRO( <name> [arg1 [arg2 [arg3 ...]]] )

COMMAND1(ARGS ...)

COMMAND2(ARGS ...)

...

ENDMACRO( <name> )

 

  • They perform text substitution, just like #define does in C

 

 

Message

  • MESSAGE( [SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ... )

 

set(SRC adder.c main.c)

if(NOT DEFINED SRC)

   message (FATAL_ERROR "No sources defined“)

endif ()

foreach (file ${SRC})  //Printing all source files

   message(${file})

endforeach ()

 

 

 

Variables

Use this snippet to list all variables and their values:

  • get_cmake_property( P VARIABLES )

foreach( VAR in ${P} )

message( STATUS " ${VAR}=${${VAR}}" )

endforeach()

 

Properties

  • A very short and simple way to think about it is that properties are variables scoped to a target. For example:

add_executable(foo foo.cpp)

set_target_properties(foo PROPERTIES

    CXX_STANDARD 14

    CXX_EXTENSIONS OFF)

# Build foo with c++11 for some reason

add_executable(foo11 foo.cpp)

set_target_properties(foo11 PROPERTIES

    CXX_STANDARD 11

    CXX_EXTENSIONS OFF)

 

 

 

 

Cmake default variables

  • CMAKE_SOURCE_DIR //refer to the folder where the top-level CMakeLists.txt
  • PROJECT_SOURCE_DIR  //refers to the folder of the CMakeLists.txt containing the most recent project() command(local)

Example:

project(Outer)

add_subdirectory(Inner)

and Inner's:

project(Inner)

CMAKE_SOURCE_DIR is Outer's source dir. For Outer, PROJECT_SOURCE_DIR is the same

For Inner, PROJECT_SOURCE_DIR is the subdirectory containing its CMakeLists.txt

Subconfigs

  • Add_subdirectory(subfolder)
    • Subconfig creates its own executable/library which is used by toplevel config
    • Only describes source and header files and toplevel adds them to its build process

 

 

Find_package

Include 

 

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

Load and run CMake code from the file given.If OPTIONAL is present, then no error is raised if the file does not exist. If RESULT_VARIABLE is given the variable 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.

  • CMake 'module' is simply a file that can be used with the find_package directive. That is, when you run find_package(Module), it searches for a file in the MODULE_PATH that is named FindModule.cmake.

 

If you include a file without the extension, it too will search through your MODULE_PATH for that file.cmake. Example:

+ root/

  + CMakeLists.txt

  + cmake/

  | + FindMatlab.cmake

  | + TestInline.cmake

  | + stdint.cmake

  + src/

  + include/

 

In CMakeLists.txt:

set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake")

find_package (Matlab) # runs FindMatlab.cmake

include(TestInline) # defines a macro:

test_inline (CONFIG_C_INLINE)

include(stdint) # simply executes flat CMake code

 

 

  • CMAKE_MODULE_PATH

list of directories specifying a search path for CMake modules to be loaded by the include() or find_package() commands before checking the default modules that come with CMake. By default it is empty, it is intended to be set by the project.

To append your module path to CMAKE_MODULE_PATH

LIST(APPEND CMAKE_MODULE_PATH ${YourPath})

Or if you prefer your modules to be used first

LIST(INSERT CMAKE_MODULE_PATH 0 ${Yourpath})

 

  • Cmake has Predefined Modules

Example BZIP2: Predefined „find“-modules search for the libraries and define variables

# BZIP2_FOUND - system has BZip2

# BZIP2_INCLUDE_DIR - the BZip2 include directory

# BZIP2_LIBRARIES - Link these to use BZip2

# BZIP2_NEED_PREFIX - this is set if the functions are prefixed with

BZ2_find_package (BZip2)

include_directories(${BZIP_INCLUDE_DIRS})

target_link_libraries (cmakeexample ${BZIP2_LIBRARIES})

 

  • Find_library

Example Looking for the TCL Library

find_library (TCL_LIBRARY  NAMES tcl tcl84 tcl83 tcl82 tcl80 PATHS /usr/lib /usr/local/lib)

if (TCL_LIBRARY)

     target_link_library(fooexe ${TCL_LIBRARY})

endif ()

cmake --graphviz=graph/test.dot .  //Run it in build tree, such as under D:\Dev\Open3D\Open3D\build>

 

//Install GraphViz  it has dot command

 

dot -Tpdf graph1.dot -o graph1.pdf

 

From <https://github.com/rakhimov/cppdep/wiki/How-to-view-or-work-with-Graphviz-Dot-files>

 

# Convert dot to png via graphviz
dot -Tpng filename.dot -o filename.png

# Convert dot to svg via graphviz
dot -Tsvg filename.dot -o filename.svg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值