ROS之CMakeLists.txt 文件

 http://blog.csdn.net/u013243710/article/details/35795841

 http://wiki.ros.org/catkin/CMakeLists.txt 

文件CMakeLists.txt是用於構建軟件包的CMake構建系統的輸入。任何符合cmake的包都包含一個或多個CMakeLists。txt文件描述如何構建代碼並將其安裝到何處。

 

結構和機制

1.      Required CMake Version(cmake_minimum_required)

cmake_minimum_required(VERSION 2.8.3)   //catkin必須是2.8.3,或以上版本

2.      Package Name (project())

project(robot_brain)    //project作用 // 在CMake中,您可以在任何需要的地方使用變量${PROJECT_NAME}在CMake腳本的任何地方引用項目名稱。

3.      Find other CMake/Catkinpackages needed for build (find_package())

find_package(catkin REQUIRED)   //:我們需要指定使用CMakefind_package函數來構建我們的項目所需的其他CMake包。至少有一個:    //如果您的項目依賴於其他的包,它們將自動轉換成catkin的組件(在CMake中)。如果您將其指定爲組件,而不是在這些包上使用find_package,它將使活更輕鬆。例如,如果您使用package nodelet:find_package(catkin REQUIRED COMPONENTS nodelet)

4.      Enable Python module support(catkin_python_setup())

5.      Message/Service/ActionGenerators (add_message_files(), add_service_files(), add_action_files())

6.      Invoke message/service/actiongeneration (generate_messages())

7.      Specify package build infoexport (catkin_package())

8.      Libraries/Executables to build(add_library()/add_executable()/target_link_libraries())

9.      Tests to build(catkin_add_gtest())

10.  Install rules (install())

 

find_package()的工作機制

一個包被find_package,那麼就會導致一些CMake變量的產生,從而去找到這個包,這些變量後面將在CMake的腳本中用到,這些變量描述了所依賴的包輸出的頭文件、源文件、庫文件在哪裏。和包所依賴的庫,

這些變量的名字依照的慣例是<PACKAGENAME>_<PROPERTY>,比如:

<NAME>_FOUND:這個變量說明這個庫是否被找到,如果找到就被設置爲true,否則設爲false;

<NAME>_INCLUDE_DIRSor<NAME>_INCLUDES:這個包輸出的頭文件目錄;

<NAME>_LIBRARIES or <NAME>_LIBS:這個包輸出的庫文件。

需要的所有包我們都可用這種方式包含進來,比如我們還需要roscpp,rospy,std_msgs。我們可以寫成:

find_package(roscpp REQUIRED)

find_package(rospy REQUIRED)

find_package(std_msgs REQUIRED)

這樣的話,每個依賴的package都會產生幾個變量,這樣很不方便。所以還有另外一種方式:

find_package(catkin REQUIRED COMPONENTS

               roscpp

               rospy

               std_msgs

               message_generation

)

 

Catkin包並不是Catkin的真正組成部分。相反,CMake的組件特性在catkin的設計中得到了利用,從而節省了大量的輸入時間。

對於catkin包,如果將它們作爲catkin的組件打包,這是一種優勢,因爲使用catkin_前綴創建了一組環境變量。例如,讓我們假設您在代碼中使用了package nodelet 引用的的方法是:

find_package(catkin REQUIRED COMPONENTSnodelet)

這意味着nodelet導出的include路徑、庫等也被附加到catkin_變量中。例如,catkin_INCLUDE_DIRS包含了不僅用於catkin的路徑,還包含了nodelet !

 

可以選擇find_package nodelet本身:

find_package(nodelet)   //這意味着nodelet路徑、庫等不會被添加到catkin_變量中。

 

find_package(catkin REQUIRED COMPONENTSnodelet)   //這將導致nodelet_INCLUDE_DIRS、nodelet_LIBRARIES等。同樣的變量也可以使用。

 

5.3 Boost--

如果使用c++和Boost,您需要在Boost上調用find_package(),並指定作爲組件使用的Boost的哪些方面。例如,如果您想使用Boost線程,您會說:

find_package(Boost REQUIRED COMPONENTSthread)

 

6-catkin_package()

      這是一個catkin提供的cmake宏,當我們要給構建系統指定catkin的特定的信息時就需要了,或者反過來利用他產生pkg-config和CMake文件。這個函數必須在聲明add_library()或者 add_executable()生成target之前使用。

其包括5個可選的成分:

INCLUDE_DIRS - --導出的包含包的路徑(即cflags)。

LIBRARIES - --//從項目中導出的庫。

CATKIN_DEPENDS ---其他catkin項目的依賴。

DEPENDS- ---非catkin CMake項目,這個項目依賴於。

CFG_EXTRAS----附加配置選項。

例如

catkin_package(

  INCLUDE_DIRS include     //導出包的文件夾路徑

  LIBRARIES ${PROJECT_NAME}   //引用項目名,導出項目名稱

  CATKIN_DEPENDS roscpp nodelet   //“roscpp”+“nodelet”是需要提供來構建/運行這個包

  DEPENDS eigen opencv)    //而“eigen”+“opencv”是系統依賴項,需要存在來構建/運行這個包。

 

7,指定編譯的target

     編譯產生的target有多種形式,通常有兩種:

Executable Target程序可以運行的可執行文件

ibrary Target在可執行文件編譯和運行時要用到的庫。

1)target的命名:

target的命名很重要,在catkin中target的名字必須是唯一的,和你之前構建產生的和安裝的都不能相同。這只是cmake內部的需要。可以利用set_target_properties()函數將target進行重命名。例如:

set_target_properties(rviz_image_view

                      PROPERTIES OUTPUT_NAMEimage_view

                      PREFIX "")

這樣就可改舊的那個target 即rviz_image_view 改爲image_view。

2)設置輸出路徑:

雖然可執行程序和庫的默認輸出目錄通常設置爲一個合理的值,但在某些情況下必須對其進行自定義。例如,包含Python綁定的庫必須放置在Python中可輸入的另一個文件夾中:

set_target_properties(python_module_library

PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION})

3)頭文件路徑和庫文件路徑:

在我們指定target之前,我們需要指明對target而言,在哪裏找源文件,特別是在哪裏找頭文件,在哪裏找庫文件。

Include Paths:指明編譯代碼時在哪裏尋找頭文件;

Library Paths:指明可執行文件需要的庫文件在哪裏。

include_directories(<dir1>,<dir2>, ..., <dirN>)

link_directories(<dir1>,<dir2>, ..., <dirN>)

函數:

include_directories:他的參數是通過find_package產生的*_INCLUDE_DIRS變量和其他所有額外的頭文件路徑。例如 ,如果您正在使用catkin和Boost,您的include_directory()調用應該是::

include_directories(include${Boost_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS})

這裏"include"表示你的pacakge裏面的the include/ directory也包含在裏面。

link_directories():這個函數用來添加額外的庫的路徑,然而,這並不鼓勵使用,因爲所有的catkin和cmake的package在使用find_package時就已經自動的有他們的鏈接信息。簡單的連接可以通過target_link_libraries()來進行。如

link_directories(~/my_libs)        //

4)Executable Targets/可執行target:

要指定必須構建的可執行目標,我們必須使用add_executable() CMake函數。例如:

add_executable(myProgram src/main.cppsrc/some_file.cpp src/another_file.cpp)

這將構建一個名爲myProgram的目標可執行程序,它由3個源文件構建:src/main.cpp src / some_file.cpp src / another_file.cpp。

5)Library Targets庫target:

add_library()用來指定編譯產生的庫。默認的catkin編譯產生共享庫:

add_library(${PROJECT_NAME} ${${PROJECT_NAME}_SRCS})

6)target_link_libraries鏈接庫:

使用target_link_libraries函數來指定可執行文件鏈接的庫。這個要用在add_executable()後面。形如:

target_link_libraries(<executableTargetName>,<lib1>, <lib2>, ... <libN>)

比如:

add_executable(foo src/foo.cpp)

add_library(moo src/moo.cpp)

target_link_libraries(foo moo)

這就是將可執行文件foo鏈接到庫文件libmoo.so

請注意,在大多數用例中不需要使用link_directory(),因爲該信息是通過find_package()自動提取的。

 

8 messages, services and actions Targets

      當我們需要使用.msg .srv .action形式的文件時,我們需要特殊的預處理器把他們轉化爲系統可以識別特定編程語言(.h   .cpp)。系統會用裏面所有的(一些編程語言)生成器(比如gencpp, genpy, genlisp, etc)生成相應的.cpp .py文件。這就需要三個宏:add_message_files, add_service_files,add_action_files來相應的控制.msg .srv .action。這些宏後面必須跟着一個調用generate_messages()。他們的運用要注意一下幾點:

1)這些宏必須在catkin_package()宏前面,即:

find_package(catkin REQUIRED COMPONENTS ...)

 add_message_files(...)

 add_service_files(...)

 add_action_files(...)

 generate_messages(...)

 catkin_package(...)

 ...

2)catkin_package()宏中必須有CATKIN_DEPENDS依賴於message_runtime,即:

catkin_package(

 ...

 CATKIN_DEPENDS message_runtime ...

 ...)

3)find_package()必須依賴包message_generation

find_package(catkin REQUIRED COMPONENTSmessage_generation)

 

4)package.xml文件build_depend必須包含message_generation,run_depend必須包含 message_runtime。

 

5)如果你有一個包編譯.msg .srv,並且可執行文件要使用他們,那麼你就需要創建一個顯式的依賴項,自動生成message的target。這樣才能按順序來進行編譯:

 add_dependencies(some_target ${PROJECT_NAME}_generate_messages_cpp)

這裏的some_target是add_executable()設置的target的名字。

 

如果你有一個目標(甚至軌跡)取決於其他目標,需要建立消息/服務/行動,您需要添加一個顯式的依賴目標catkin_EXPORTED_TARGETS,所以他們是建立在正確的順序。這種情況幾乎總是適用,除非您的包真的不使用ROS的任何部分。不幸的是,這種依賴性不能自動傳播。(some_target是add_executable設置的目標的名稱。

add_dependencies(some_target${catkin_EXPORTED_TARGETS})

 

如果您有一個構建消息和/或服務的包,以及使用這些的可執行文件,那麼您需要創建一個對自動生成的消息目標的顯式依賴,以使它們以正確的順序構建。(some_target是add_executable設置的目標的名稱。

add_dependencies(some_target${${PROJECT_NAME}_EXPORTED_TARGETS})

 

如果您的包滿足上述兩個條件,則需要添加兩個依賴項,即。

add_dependencies(some_target${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

 

 

8.2舉例

如果您的包在名爲“MyMessage1”的目錄中有兩個消息。msg”和“MyMessage2。這些消息依賴於std_msgs和sensor_msgs,這是一個名爲“srv”的服務,名爲“MyService”。srv“定義了可執行的message_program,它使用這些消息和服務,而可執行的do_not_use_local_messages_program,它使用了一些ROS的部分,但不是在這個包中定義的消息/服務,那麼您將需要在CMakeLists.txt中執行以下操作。

  1   # Get the information aboutthis package's buildtime dependencies

  2   find_package(catkin REQUIRED

  3     COMPONENTSmessage_generation std_msgs sensor_msgs)

   4

  5   # Declare the message files tobe built

  6   add_message_files(FILES

  7     MyMessage1.msg

  8     MyMessage2.msg

  9   )

  10

 11   # Declare the service filesto be built

 12   add_service_files(FILES

 13     MyService.srv

 14   )

  15

 16   # Actually generate thelanguage-specific message and service files

 17  generate_messages(DEPENDENCIES std_msgs sensor_msgs)

  18

 19   # Declare that this catkinpackage's runtime dependencies

 20   catkin_package(

 21    CATKIN_DEPENDSmessage_runtime std_msgs sensor_msgs

 22   )

  23

 24   # define executable usingMyMessage1 etc.

 25  add_executable(message_program src/main.cpp)

 26  add_dependencies(message_program ${${PROJECT_NAME}_EXPORTED_TARGETS}${catkin_EXPORTED_TARGETS})

  27

 28   # define executable not usingany messages/services provided by this package

 29  add_executable(does_not_use_local_messages_program src/main.cpp)

 30   add_dependencies(does_not_use_local_messages_program${catkin_EXPORTED_TARGETS})

 

另外,如果您希望構建actionlib操作,並有一個名爲“MyAction”的操作規範文件。在“操作”目錄中,您必須將actionlib_msgs添加到與catkin打包的組件列表中,並在調用generate_messages(…)之前添加以下調用

add_action_files(FILES

 MyAction.action

)

此外,該包必須具有對actionlib_msgs的構建依賴。

發佈了25 篇原創文章 · 獲贊 12 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章