CMake标准

CMake coding standards

为了使ROS包避免错误.建议遵循一定的标准  cmake coding guidelines

Call catkin_package before any targets

The following lines must always appear the CMakeLists.txt in this order:

cmake_minimum_required(VERSION 2.8.3)
project(myproject)
find_package(catkin REQUIRED <COMPONENTS ...>)
catkin_package(<...>)

While there might be additional function calls before catkin_package()(e.g. for finding other libraries or generating messages)it must be invoked before any targets are added.

Use ${PROJECT_NAME} wherever possible

Use ${PROJECT_NAME} for global variables, targets and labels instead ofrepeating the project name manually or using fixed names.

You can use ${PROJECT_NAME} as prefix for global variable names as well, as shown in examples below. Variables become global if they are set using the CACHE argument or created using the option() macro.

After you defined your project name like this:

project(myproject)

dont do this:

catkin_add_gtest(test ...)
add_executable(myproject ...)
set(use_feature 42 CACHE STRING "description")
option(use_feature "on or off" OFF)
macro(xyz) ...

do this instead:

catkin_add_gtest(${PROJECT_NAME}_test ...)
add_executable(${PROJECT_NAME} ...)
set(${PROJECT_NAME}_use_feature 42 CACHE STRING "description")
option(${PROJECT_NAME}_use_feature "on or off" OFF)
macro(${PROJECT_NAME}_xyz) ...

This will avoid conflicts between packages and errors due to copy&paste.

find_package(... REQUIRED)

Use REQUIRED on all calls to find_package if they aren’tactually optional (i.e. you’re not going to check thing_FOUNDand enable/disable features).

Avoid Pkg_config

CMake allows to use pkg-config:

find_package(PkgConfig)
pkg_check_modules(XXX xxx)

However you should (in CMakeLists.txt files) if possible always prefer the method:

find_package(xxx)

This is usually the most flexible and portable way.

Keep lists sorted

Whenever using a list of items (i.e. in find_package(COMPONENTS ...)or files which should be build or installed) keep them alphabeticallysorted. This improves readability when looking for specific items.(There are exceptions which require a specific custom order like thelist of projects inside a stack).

Lowercase keywords

Keywords like if, for etc. are all lowercase.

Upper arguments

Use UPPER_CASE for arguments to CMake functions and macros (e.g. REQUIRED, NO_MODULE, QUIET)

Closing keyword should have empty parenthesis

The closing keywords like endif() and endforeach() should not repeat the condition of the opening keyword.

Indentation

Indent all code correctly, i.e. the body of

  • if/else/endif
  • foreach/endforeach
  • while/endwhile
  • macro/endmacro
  • function/endfunction

Use spaces for indenting, 2 spaces preferably

Variable names

For custom variables, avoid the following list of suffixes in any CMakeLists.txt, those should only be set by FindXXX.cmake or XXXConfig.cmake files:

  • XXX_DEFINITIONS
  • XXX_EXECUTABLE
  • XXX_INCLUDE_DIRS
  • XXX_INCLUDE_DIR
  • XXX_YY_INCLUDE_DIR
  • XXX_LIBRARIES
  • XXX_LIBRARY_DIRS
  • XXX_LIBRARY
  • XXX_YY_LIBRARY
  • XXX_ROOT_DIR
  • XXX_FOUND
  • XXX_YY_FOUND
  • XXX_RUNTIME_LIBRARY_DIRS
  • XXX_VERSION_STRING
  • XXX_VERSION_MAJOR
  • XXX_VERSION_MINOR
  • XXX_VERSION_PATCH
  • XXX_VERSION_YY
  • XXX_WRAP_YY

You may use such variables of course by reading their value after calling find_package(), but do not manually change them.

Forbidden variables

Do not set

  • CMAKE_CXX_FLAGS
  • CMAKE_FIND_ROOT_PATH
  • CMAKE_MODULE_PATH

Conditions and Variables

Always quote variable that represent a string:

set(myvar "foo")
if("${myvar}" STREQUAL "bar")
# ...
endif()

Do not quote variable that are booleans:

set(mybvar ON)
set(mybvar OFF)
if(${myvar})
# ...
endif()

When storing paths in variables, do NOT have the cmake variables end up with a slash:

# YES:
set(_my_path "path/to/foo")
set(_my_other_path "${_my_path}/${_my_var}")
# NO:
set(my_path "path/to/foo/")
set(_my_other_path "${_my_path}${_my_var}")   # wrong: this is ugly

Use if(DEFINED varname) to check if a variable is set:

if(DEFINED myvar)
#  ...
endif()

Use if(varname) to check it a variable has a non-empty value:

mpty value:if(myvar)
#  ...
endif() 


Policies/CMake Coding Style

his document describes the recommended coding style for CMake files in KDE, i.e. CMakeLists.txt files and *.cmake files.

Contents

 [hide] 
  • 1 General
    • 1.1 Indentation
    • 1.2 Upper/lower casing
    • 1.3 End commands
  • 2 Writing CMake Find-modules
    • 2.1 (Not) Using pkg-config
    • 2.2 Follow CMake's readme.txt
    • 2.3 Use FindPackageHandleStandardArgs.cmake
    • 2.4 Avoid Micro-Optimizations
  • 3 Writing FooConfig.cmake files

General

To put in in one sentence: be as careful when writing the CMake files as when you are writing C++ code.

Indentation

Indent all code correctly, i.e. the body of

  • if/else/endif
  • foreach/endforeach
  • while/endwhile
  • macro/endmacro
  • function/endfunction

Use spaces for indenting, 2, 3 or 4 spaces preferably. Use the same amountof spaces for indenting as is used in the rest of the file. Do not use tabs.

Upper/lower casing

Most important: use consistent upper- or lowercasing within one file !

In general, in KDE the all-lowercase style is preferred.

So, this is recommended:

add_executable(foo foo.c)

This is also acceptable:

ADD_EXECUTABLE(bar bar.c)

Mixed casing as shown below works too, but should not be done within KDE:

Add_Executable(hello hello.c)
aDd_ExEcUtAbLe(blub blub.c)

End commands

To make the code easier to read, use empty commands for endforeach(), endif(), endfunction(), endmacro() and endwhile(). Also, use empty else() commands.

For example, do this:

if(FOOVAR)
   some_command(...)
else()
   another_command(...)
endif()

and not this:

if(BARVAR)
   some_other_command(...)
endif(BARVAR)

Writing CMake Find-modules

(Not) Using pkg-config

You are free to use pkg-config in FindXXX.cmake modules, as long as the following conditions are met:

  • the FindXXX.cmake must also work without pkg-config, as long as the package is either installed to one of the default locations (as /usr or /usr/local) or if CMAKE_PREFIX_PATH is set accordingly
  • use only find_package(PkgConfig), don't use include(UsePkgConfig), this one is deprecated
  • make sure the variables created by pkg_check_modules() are all prefixed with "PC_", so they don't mix up with other variables, e.g. set via find_path() etc.
  • FindLibXml2.cmake as shipped with CMake 2.8.5 is a good example how pkg-config should be handled
  • putting something like if(NOT WIN32) around the pkg-config stuff is not necessary (and should be removed if it is somewhere). If pkg-config is not found, e.g. on Windows, the macros simply do nothing.

Follow CMake's readme.txt

Follow the style guide from CMake when writing some FindFoo.cmake module: readme.txt

Use FindPackageHandleStandardArgs.cmake

For checking the results inside the Find-module, the macro find_package_handle_standard_args() (coming with CMake) should be used, using the new extended syntax, which supports also version checking.

Avoid Micro-Optimizations

Micro-optimizations like

if(FOO_LIBRARY AND FOO_INCLUDE_DIR)
   set(FOO_FOUND TRUE)
else()
   ... execute the whole find-logic
endif()

should be removed, the find-logic should be executed always. These shortcuts can cause problems e.g. when the same file is used from multiple directories but e.g. with different required versions or components etc.

Also manually quieting the module should not be done:

if ( SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES )
   set(Sqlite_FIND_QUIETLY TRUE)
endif ( SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES )

If find_package_handle_standard_args() is used, this is completely unnecessary, since find_package_handle_standard_args() only prints something if the result has changed compared to the previous run. So if, as in this example, sqlite has already been found, find_package_handle_standard_args() will only print this information during the first CMake run, but not on successive runs.

So, do not add such code. It is unnecessary and makes the modules look more complicated than necessary.

Writing FooConfig.cmake files

  • See http://quickgit.kde.org/?p=kdeexamples.git&a=tree&hb=HEAD&f=buildsystem/HowToInstallALibrary for a fully commented example
  • See also:
    • http://www.cmake.org/Wiki/CMake/Tutorials/Exporting_and_Importing_Targets
    • http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file
    • http://www.cmake.org/Wiki/CMake/Tutorials/Packaging


转自:

http://docs.ros.org/jade/api/catkin/html/user_guide/standards.html

https://techbase.kde.org/Policies/CMake_Coding_Style







你可能感兴趣的:(编译器,cmake)