본문 바로가기

ROS

package.xml/CMakelist.txt 각 태그 내용 정리

package.xml

스스로 만든 코드를 빌드하는데 있어서는 누락되어도 문제는 없지만, 다른 사람과 패키지를 공유할 때 누락되어있다면 실행이 되지 않는다.

 

<depend>

의존성을 정의한다. 그러나 이게 어떤 때에 의존되는 지는 명시하지 않는다.

어떤 때에 의존되는지 알고있다면 아래의 세부내용을 적어도 된다.

 

<buildtool_depend>

빌드 툴 의존성을 정의한다. 예를들어 catkin빌드 시스템을 이용한다면, <buildtoold_depend>catkin</buildtool_depend>라고 적는다.

 

<build_depend>

빌드 시에만 사용하고, 런타임에는 사용하지 않는 의존성을 정의한다.

예를 들자면, 어떤 메시지를 msg파일에다가 정의했다고 해보자. message_generation패키지는 이 msg파일을 읽고, 해당 데이터타입을 정의하는 헤더파일을 만들어주는 역할을 한다. 따라서, 이는 빌드 시에는 필요하지만 런타임에는 필요하지 않기에 <build_depend>message_generation</build_depend>라고 적는다.

하지만, 내가 만든 패키지가 다른 패키지에서 가져온 파일을 인클루드하고 있는 파일을 익스포트 해야한다면, <build_export_depend>도 적어주어야 한다.

 

<build_export_depend>

예를 들자면 내가 만들고자 하는 cpp파일이나 h파일이 angle패키지의 헤더파일을 인클루드 하고있다고 쳐보자(#include <angles/angles.h>). 그렇다면 <build_depend>angles</build_depend>뿐 아니라, <build_export_depend>angles</build_export_depend> 또한 적어주어야 한다.(주로 헤더파일이나 cmake설정파일).

그런데, 실제 내가 만든 라이브러리 패키지가 다른 패키지의 동작까지 필요로 한다면 이렇게 적는거보다 차라리 <depend>로 적는게 낫다. 왜냐면 어차피 실행중에도 필요하기 때문이다.

 

<exec_depend>

런타임에서의 의존성이다. 예를들어 파이썬은 인터프리터 언어니까, 파이썬 코드를 실행시켜 주는 모듈을 필요로 한다. 따라서 <exec_depend>rospy</exec_depend>를 적어주어야 한다. 또 다른 예로는, 메시지를 주고받는 패키지를 만들었다고 한다면, 이는 런타임에서 ros의 메시지 서비스를 필요로 한다. 그렇기에 표준 메시지의 경우는 <depend>std_msgs</depend>, 사용자 정의 메시지의 경우는 <depend>message_runtime</depend>을 적어준다.

 

그 이외에 라이센스나, 작성자, 연락처등을 적는 태그도 있으나, 이는 catkin_create_pkg할때 자동으로 다 기입되는거니까 대략적으로 감을 잡을 수 있을 것이라고 생각되므로 생략한다.

 

 

 

CMakelist.txt

package.xml은 다른사람들과 공유할 때 사용되는 것이고, 이는 패키지를 빌드할 때 사용된다. catkin은 package.xml과 CMakelist.txt 를 모두 인식하지만, CMake는 package.xml을 인식할 수 없기에, 빌드용 의존성을 여기에 따로 적어주어야 한다.

일반적인 빌드스크립트에서 쓰이는 add_executable나 target_link_libraries외에도 몇 가지 적어주어야 하는 것들이 있다.

또, 참고문헌을 보면, 이들을 정의하는 순서도 지키지 않으면 안되지만, 어차피 워크스페이스 처음 빌드할때 만들어주는 빌드스크립트가 이 순서에 따르고 있으니, 이를 수정해서 빌드스크립트를 만든다면 구태여 그 순서는 외울 필요가 없을 듯 하다.

 

cmake_minimum_required

cmake최소 필요버전을 적어준다. 일반적인 빌드 스크립트에서도 쓰임.

예시)

cmake_minimum_required(VERSION 2.8.3)

 

project

인수로 패키지명을 그대로 적어준다. 일반적인 빌드 스크립트에서도 쓰이긴 하는데, 패키지명을 그대로 적어주어야 한다는 차이점이 있다.

예시)
project(package_A)

 

find_package

빌드시에 필요한 의존성들을 적어준다.

예를 들자면, c++로 직접 정의한 메시지를 다루는 노드를 사용하는 패키지라면 roscpp패키지와 message_generation패키지를 명시해준다.

예시)

find_package(catkin REQUIRED COMPONENTS 
roscpp
message_generation
)

주의: catkin REQUIRED COMPONENTS 를 적지 않고, find_package(roscpp)와 find_package(message_generation)라고 적어주어도 가능하지만, 아래의 target_include_directories나 target_link_libraries에서 ${catkin_INCLUDE_DIRS}나 ${catkin_LIBRARIES}와 같이 한 큐에 할수 없고, ${roscpp_INCLUDE_DIRS} / ${message_generation_INCLUDE_DIRS}을 따로적어주어야 하는 번거로움이 생긴다.

 

target_include_directories

인클루드 디렉토리를 지정해준다. 특히 ros의 경우 ${catkin_LIBRARIES} 을 지정해주지 않으면 ros/ros.h를 인클루드 할수 없게 된다.

예시)

include_directories(
  ${catkin_INCLUDE_DIRS}
)

 

target_link_libraries

타겟에 라이브러리를 연결해준다. 이걸 하지 않는다면 include_directories를 사용해서 디렉토리를 연결했다고 했더라도, 라이브러리에는 연결하지 않기때문에 링크에러가 난다.

예를 들자면, main이라는 타겟(라이브러리인지 실행파일인지는 모름)에 catkin의 라이브러리들을 연결해주고싶다면 아래와 같이 쓴다.

예시)

target_link_libraries(main
  ${catkin_LIBRARIES}
)

 

add_executable
add_library

실행파일 또는 라이브러리를 만들게 한다.(일반적인 빌드스크립트에서도 쓰임)

예시)

program이라는 이름의 실행파일을 main.cc를 빌드해서 작성하고 싶은 경우

add_executable (program main.cc)

program이라는 이름의 정적 라이브러리를 main.cc를 빌드해서 작성하고 싶은 경우

add_executable (program STATIC main.cc)

 

add_message_files(service file)

msg디렉토리 안의 메시지 정의파일을 지정해준다.

예시)

add_message_files(
  FILES
  Msg1.msg
)

 

add_dependencies

실행파일이나 라이브러리를 빌드할때, 생성해야 하는 의존성이 있는 경우에 사용한다. 예를들어 내가 만들고자 하는 패키지가 빌드되려면, 그보다 먼저 빌드되어야할 의존성이 있을 경우, 그 때 적어준다. 예를 들면 커스터마이징된 메시지의 경우, 메시지의 정의부터 먼저 정의되어있어야 이를 이용하는 소스코드도 컴파일이 가능하기때문에, 메시지 관련 파일들을 추가해준다.

예시)

target_name이라는 타겟(실행가능파일)을 빌드하기 전에 package_name이라는 패키지의 메시지 정의헤더를 먼저 만들어야 하는 경우 아래와 같이 적어준다. 

add_dependencies(target_name package_name_generate_messages_cpp)

패키지명을 하드코딩으로 적는게 귀찮거나 깔끔한게 좋다면

add_dependencies(target_name ${PROJECT_NAME}_generate_messages_cpp)

이라고 적어도 되는 듯! {PROJECT_NAME}변수는 어차피 위에 프로젝트 태그로 정의가 되어있을테니까.

 

 

catkin_package

캐킨 빌드옵션이다. 이 패키지를 의존할 경우, 그에 따라 연쇄적으로 의존하게 되는 패키지들과 그 방식을 적어주는데, 예시로는 CATKIN_DEPENDS만 적어줌.

사실 이는 catkin의 매크로인데, CMake의 통상적인 스니펫인 add_dependencies, target_include_directories라거나 target_link_libraries의 역할을 좀 더 사용하게 쉽게 해주는 듯 하다. 자세한건 http://wiki.ros.org/catkin/CMakeLists.txt 참조

이걸 쓰던가 아니면 CMake의 일반적 문법을 사용하던가 이건 사용자 입맛이긴 한데, 레퍼런스들 보면, CMake의 일반적 문법을 더 많이사용하는 듯 하다.

예시)

이 패키지를 의존할 경우,  message_runtime 와 std_msgs도 의존하게 하고 싶은 경우(즉, add_dependencies로도 똑같은 동작을 하게 할 수 있음):

catkin_package(
  CATKIN_DEPENDS message_runtime std_msgs
)

 

 

참고사이트

http://docs.ros.org/en/jade/api/catkin/html/howto/format2/catkin_library_dependencies.html

 

C++ catkin library dependencies — catkin 0.6.19 documentation

C++ catkin library dependencies Catkin libraries are provided by ROS packages whether you install them from Ubuntu packages or build from source. When your package depends on a catkin C++ library, there are usually several kinds of dependencies which must

docs.ros.org

https://qiita.com/srs/items/30c81c3f26f1987b0afa#%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B%E4%BE%8B%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E5%81%B4%E3%81%B8%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%81%8C%E6%8A%9C%E3%81%91%E3%81%A6%E3%81%84%E3%82%8B

 

ROS講座97 CMakeList.txtとpackage.xmlの書き方 - Qiita

環境 この記事は以下の環境で動いています。 項目 値 CPU Core i5-8250U Ubuntu 16.04 ROS Kinetic インストールについてはROS講座02 インストールを参照...

qiita.com

https://velog.io/@717lumos/ROS-%ED%8C%A8%ED%82%A4%EC%A7%80-%EB%B9%8C%EB%93%9C%EC%99%80-%EB%85%B8%EB%93%9C-%EC%9E%91%EC%84%B1

 

[ROS] 패키지 빌드와 노드 작성

ROS에서의 패키지 빌드와 노드 작성, 실행 과정

velog.io