학습 목표
- 워크스페이스의 네 폴더가 각각 무엇인지 설명할 수 있다.
- ament_python 패키지를 만들고 실행 파일을 등록할 수 있다.
- setup.py에서 자주 틀리는 세 곳을 알고 피할 수 있다.
- colcon build의 주요 옵션을 상황에 맞게 쓸 수 있다.
- underlay와 overlay를 이해하고 왜 새 터미널마다 source 하는지 설명할 수 있다.
- 빌드와 실행이 안 될 때 순서대로 원인을 좁힐 수 있다.
- Package Discovery와 의존성 Graph를 읽고 올바른 선택 빌드 범위를 결정할 수 있다.
- CMake·Python Package의 설치 결과와 Test를 검증할 수 있다.
- colcon Default, Mixin, Metadata와 CI 설정으로 팀 빌드를 재현할 수 있다.
1. 워크스페이스는 폴더 네 개다
ROS 2에서 여러분이 짠 코드가 사는 곳이 워크스페이스입니다. 구조는 단순합니다. 루트 아래에 폴더 네 개가 있고, 여러분이 손대는 것은 하나뿐입니다.
src/ — 여러분이 만드는 유일한 폴더입니다. 패키지들이 여기 들어갑니다. git으로 관리하는 것도 이것뿐입니다.
build/ — 빌드 중간 산물. colcon이 만듭니다. 지워도 됩니다.
install/ — 실제로 실행되는 것들이 설치되는 곳. source install/setup.bash가 가리키는 곳이 바로 여기입니다.
log/ — 빌드 로그. 빌드가 실패했을 때 여기를 봅니다.
핵심 규칙 세 가지
① colcon build는 팀이 정한 Workspace Root에서 실행합니다. colcon은 현재 위치를 기준으로 Source를 발견하고 Output Directory를 만들 수 있으므로 src 안에서 실행하면 거기에 또 build/install/log가 생겨 상황이 엉킵니다. pwd와 colcon list를 확인한 뒤 Root에서 실행하는 습관을 들입니다.
② build, install, log는 일반적으로 Git에 넣지 않습니다. .gitignore에 포함하고 Source·Config·Bag 같은 원본을 이 Directory에 저장하지 않습니다. 그래야 명확히 확인한 후 산출물을 재생성할 수 있습니다.
③ 이상하다고 바로 전체를 지우지 않습니다. 먼저 첫 Error와 log/latest_build를 확인하고 영향받은 Package만 다시 빌드합니다. CMake Cache 문제라면 --cmake-clean-cache를 사용합니다. 전체 산출물을 초기화해야 할 때는 현재 위치와 대상이 정확히 Workspace의 build, install, log인지 확인하고 Backup 또는 명시적 경로로 처리합니다.
워크스페이스 생성, .gitignore, 그리고 꼬였을 때의 초기화 절차.
# ── 워크스페이스 만들기 ─────────────────────────────────
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
# 처음에는 src 하나뿐이다. 나머지 셋은 빌드하면 생긴다.
colcon build
ls
# build install log src
# ── .gitignore 는 반드시 이렇게 ─────────────────────────
cat > ~/ros2_ws/.gitignore <<EOF
build/
install/
log/
__pycache__/
*.pyc
EOF
# ── 이상할 때는 첫 오류와 CMake Cache부터 확인 ──────────
cd ~/ros2_ws
colcon build --event-handlers console_direct+
colcon build --cmake-clean-cache --packages-select <패키지이름>
source install/setup.bash
# ── 흔한 실수: src 안에서 빌드해 버렸다 ──────────────────
# ~/ros2_ws/src/build 같은 폴더가 생겼다면 잘못 실행한 것이다.
# 즉시 삭제하기 전에 pwd와 각 Directory 내용을 확인하고,
# 필요한 파일이 없는 것이 확실할 때 Workspace 밖 Backup으로 옮긴다.
개념도 · stack
- 단계/참여자
- ros2_ws/ — 워크스페이스 루트. 여기서 colcon build
- src/ — 내가 만드는 패키지들. git 대상
- build/ — 빌드 중간 산물. 지워도 된다
- install/ — 실제 실행되는 것. source가 가리키는 곳
- log/ — 빌드 로그. 실패하면 여기를 본다
- 연결/행
반드시 여기서유일하게 손대는 곳- ``
- ``
- ``
여러분이 손대는 것은 src뿐입니다. 나머지 셋은 언제든 지웠다 다시 만들 수 있습니다.
주의 colcon build를 src 안에서 실행하면 그 자리에 또 build/install/log가 생깁니다. 그러면 어느 install을 source 했는지 알 수 없게 되어 "분명히 빌드했는데 옛날 코드가 돈다" 같은 상황이 벌어집니다. 반드시 워크스페이스 루트에서 실행하세요.
2. 패키지 만들기 — ament_python과 ament_cmake
패키지는 ros2 pkg create로 만듭니다. 이때 빌드 타입을 골라야 합니다.
ament_python — 순수 Python 패키지. setup.py로 설정합니다.
ament_cmake — C++ 패키지. CMakeLists.txt로 설정합니다. 메시지 정의(.msg/.srv/.action)를 만드는 인터페이스 패키지도 이쪽입니다.
어떤 패키지를 몇 개 만들 것인가 초보자는 모든 것을 한 패키지에 넣으려 합니다. 나중에 반드시 후회합니다. 실무의 관례는 이렇습니다.
• 내프로젝트_interfaces — .msg/.srv/.action만. ament_cmake
• 내프로젝트_nodes — 실제 노드들. ament_python 또는 ament_cmake
• 내프로젝트_bringup — launch 파일과 설정 YAML만
왜 나누는가? 인터페이스를 따로 두면 다른 팀이 여러분의 메시지 타입만 쓰고 싶을 때 노드 코드와 그 의존성까지 끌어오지 않아도 됩니다. launch를 따로 두면 로봇마다 다른 구성을 만들기 쉽습니다.
package.xml이 하는 일
이 파일은 의존성 선언서입니다. 여기 적힌 것을 보고 colcon이 빌드 순서를 정합니다. lab_nodes가 lab_interfaces에 의존한다고 적으면, colcon은 반드시 인터페이스를 먼저 빌드합니다.
자주 쓰는 태그는 셋입니다.
• <depend> — 빌드에도 실행에도 필요. 대부분 이것으로 충분합니다
• <build_depend> — 빌드할 때만
• <exec_depend> — 실행할 때만
의존성을 적지 않아도 당장은 빌드가 됩니다. 여러분의 컴퓨터에 이미 깔려 있으니까요. 문제는 다른 사람이 받았을 때입니다. rosdep install --from-paths src --ignore-src -r -y가 package.xml을 읽어 필요한 것을 자동 설치하는데, 안 적혀 있으면 설치되지 않습니다.
| 패키지 종류 | 빌드 타입 | 들어가는 것 |
|---|---|---|
| 내프로젝트_interfaces | ament_cmake | .msg, .srv, .action만 |
| 내프로젝트_nodes | ament_python | 노드 코드 |
| 내프로젝트_bringup | ament_python | launch 파일, 설정 YAML |
| C++ 노드 패키지 | ament_cmake | C++ 소스와 CMakeLists.txt |
패키지 3종을 만드는 명령과 package.xml의 역할. 인터페이스를 분리하는 것이 관례입니다.
# ── 인터페이스 패키지 (메시지 전용) ──────────────────────
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake lab_interfaces
mkdir -p lab_interfaces/msg lab_interfaces/srv lab_interfaces/action
# 여기에 .msg / .srv / .action 파일을 넣는다
# ── 노드 패키지 (Python) ────────────────────────────────
ros2 pkg create --build-type ament_python lab_nodes \
--dependencies rclpy std_msgs geometry_msgs sensor_msgs lab_interfaces
# 만들어진 구조
# lab_nodes/
# package.xml <- 의존성 선언서
# setup.py <- 설치와 실행 파일 등록
# setup.cfg
# resource/lab_nodes <- 빈 파일. 지우면 안 된다
# lab_nodes/ <- 실제 파이썬 코드가 들어갈 곳
# __init__.py
# ── launch 전용 패키지 ──────────────────────────────────
ros2 pkg create --build-type ament_python lab_bringup
mkdir -p lab_bringup/launch lab_bringup/config
# ── package.xml 의 핵심 부분 ────────────────────────────
# <depend>rclpy</depend>
# <depend>geometry_msgs</depend>
# <depend>sensor_msgs</depend>
# <depend>lab_interfaces</depend> <- 이것을 적어야 빌드 순서가 정해진다
#
# 빌드 순서 확인:
# colcon graph
# colcon list --topological-order
# ── 남이 받았을 때 의존성 한 번에 설치 ───────────────────
cd ~/ros2_ws
rosdep install --from-paths src --ignore-src -r -y
# package.xml 을 읽어 필요한 것을 apt 로 설치해 준다.
# 그래서 의존성을 제대로 적어 두는 것이 협업의 기본이다.
3. setup.py — 가장 많이 틀리는 세 곳
Python 패키지에서 문제가 생기는 곳은 거의 항상 setup.py입니다. 세 가지만 정확히 알면 됩니다.
① entry_points의 console_scripts
"실행이름 = 패키지.모듈:함수" 형식입니다.
"safe_driver = lab_nodes.safe_driver:main"이라면 ros2 run lab_nodes safe_driver로 실행되고, lab_nodes/safe_driver.py의 main 함수가 불립니다.
여기 적은 이름이 ros2 run의 두 번째 인자입니다. launch 파일의 executable도 이 이름이어야 합니다. 파일 이름이나 노드 이름과는 별개입니다. "실행 파일을 찾을 수 없다"는 오류의 90 %가 여기서 옵니다.
② data_files의 첫 두 줄은 지우면 안 됩니다
resource/패키지이름을 설치하는 줄과 package.xml을 설치하는 줄입니다. 이것이 없으면 ROS가 그 패키지를 아예 인식하지 못합니다. ros2 pkg create가 자동으로 넣어 주니 손대지 마세요.
③ launch와 config 파일은 직접 추가해야 합니다
Python 파일은 자동으로 설치되지만 launch 파일과 YAML은 아닙니다. data_files에 명시적으로 적어야 install/ 아래로 복사됩니다. 적지 않으면 ros2 launch가 파일을 못 찾습니다. glob을 써서 폴더 통째로 넣는 것이 관례입니다.
주의: data_files를 고쳤다면 --symlink-install을 썼더라도 반드시 다시 빌드해야 합니다. 설치 목록 자체가 바뀐 것이기 때문입니다.
setup.py 전체. ①entry_points ②data_files 필수 두 줄 ③launch·config 추가가 핵심입니다.
# 파일: ~/ros2_ws/src/lab_nodes/setup.py
import os
from glob import glob
from setuptools import find_packages, setup
package_name = "lab_nodes"
setup(
name=package_name,
version="0.0.1",
packages=find_packages(exclude=["test"]),
data_files=[
# ---- ② 이 두 줄은 절대 지우지 않는다 ----
# 없으면 ROS 가 이 패키지를 아예 인식하지 못한다.
("share/ament_index/resource_index/packages",
["resource/" + package_name]),
("share/" + package_name, ["package.xml"]),
# ---- ③ launch 와 config 는 직접 적어야 설치된다 ----
# 적지 않으면 ros2 launch 가 파일을 찾지 못한다.
(os.path.join("share", package_name, "launch"),
glob("launch/*.launch.py")),
(os.path.join("share", package_name, "config"),
glob("config/*.yaml")),
],
install_requires=["setuptools"],
zip_safe=True,
maintainer="your name",
maintainer_email="you@example.com",
description="실습용 노드 모음",
license="Apache-2.0",
tests_require=["pytest"],
entry_points={
# ---- ① "실행이름 = 패키지.모듈:함수" ----
# 여기 적은 왼쪽 이름이 ros2 run 의 두 번째 인자이고,
# launch 파일의 executable 도 이 이름이어야 한다.
"console_scripts": [
"safe_driver = lab_nodes.safe_driver:main",
"mode_server = lab_nodes.mode_server:main",
"mode_client = lab_nodes.mode_client:main",
],
},
)
# ============================================================
# 확인 방법
# ============================================================
# 등록된 실행 이름 목록 보기
# ros2 pkg executables lab_nodes
# -> lab_nodes safe_driver
# lab_nodes mode_server
# lab_nodes mode_client
#
# 설치된 파일이 실제로 있는지 확인
# ls ~/ros2_ws/install/lab_nodes/share/lab_nodes/launch/
# ls ~/ros2_ws/install/lab_nodes/share/lab_nodes/config/
#
# 패키지의 설치 경로 자체를 확인
# ros2 pkg prefix lab_nodes
주의 launch 파일과 YAML을 만들고 setup.py의 data_files에 추가하지 않으면, 코드는 멀쩡한데 ros2 launch가 "파일을 찾을 수 없다"고 합니다. 원본은 src에 있지만 install 아래로 복사되지 않았기 때문입니다. 새 폴더를 만들 때마다 data_files를 확인하세요.
4. colcon build — 알아야 할 옵션 다섯
colcon build만으로도 되지만, 패키지가 늘어나면 옵션을 알아야 시간을 아낍니다.
① --packages-select 이름 — 그 패키지만 빌드합니다.
스무 개 패키지가 있는데 하나만 고쳤다면 이것을 쓰세요. 빌드 시간이 수십 배 줄어듭니다.
② --packages-up-to 이름 — 그 패키지와 그것이 의존하는 것들까지 빌드합니다.
인터페이스를 고쳤을 때 유용합니다. --packages-select만 쓰면 인터페이스는 새 버전인데 노드는 옛 버전을 물고 있는 상태가 됩니다.
③ --symlink-install — 설치본을 복사 대신 심볼릭 링크로 만듭니다.
이미 등록된 Python 파일의 내용을 고쳤다면 다시 빌드하지 않아도 반영됩니다. 개발 중에는 거의 항상 켭니다.
다만 새 파일 추가, entry_points 변경, data_files 변경은 재빌드가 필요합니다.
④ --event-handlers console_direct+ — 빌드 출력을 그대로 보여 줍니다.
기본은 요약만 보여 주므로 컴파일 오류의 자세한 내용이 감춰집니다. 빌드가 실패했을 때 이 옵션으로 다시 돌리면 진짜 오류가 보입니다.
⑤ --cmake-args -DCMAKE_BUILD_TYPE=Release — C++ 최적화를 켭니다.
기본은 최적화 없이 빌드되므로 C++ 노드가 예상보다 훨씬 느릴 수 있습니다. 성능을 측정하기 전에 이것부터 확인하세요.
메모리가 부족해 빌드가 죽는다면 --parallel-workers 1로 병렬도를 낮춥니다. Raspberry Pi나 Jetson처럼 메모리가 작은 보드에서 C++를 빌드할 때 자주 필요합니다.
| 상황 | 명령 | 효과 |
|---|---|---|
| 한 패키지만 고쳤다 | colcon build --packages-select 이름 | 빌드 시간이 크게 준다 |
| 인터페이스를 고쳤다 | colcon build --packages-up-to 이름 | 의존하는 것까지 함께 빌드 |
| Python 개발 중 | colcon build --symlink-install | 내용 수정은 재빌드 불필요 |
| 빌드가 실패했다 | --event-handlers console_direct+ | 진짜 오류 메시지가 보인다 |
| C++가 느리다 | --cmake-args -DCMAKE_BUILD_TYPE=Release | 최적화를 켠다 |
| 빌드 중 메모리 부족 | --parallel-workers 1 | 한 번에 하나씩 빌드 |
colcon 실전 명령 모음. 빌드 실패 시 console_direct+ 로 다시 돌리는 습관이 중요합니다.
# ── 개발 중 가장 자주 쓰는 형태 ─────────────────────────
cd ~/ros2_ws
colcon build --symlink-install --packages-select lab_nodes
source install/setup.bash
# ── 인터페이스를 고쳤을 때 ──────────────────────────────
# 인터페이스와 그것을 쓰는 노드를 함께 빌드해야 한다.
colcon build --packages-up-to lab_nodes
source install/setup.bash # 새 터미널이라면 반드시
# ── 빌드가 실패했을 때 진짜 오류 보기 ────────────────────
colcon build --packages-select lab_nodes \
--event-handlers console_direct+
# 로그 파일로도 볼 수 있다
cat log/latest_build/lab_nodes/stdout_stderr.log
# ── C++ 성능을 측정하기 전에 ────────────────────────────
colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release
# ── 메모리가 작은 보드에서 ──────────────────────────────
colcon build --executor sequential
# ── 테스트 실행 ─────────────────────────────────────────
colcon test --packages-select lab_nodes
colcon test-result --verbose
# ── 무엇이 무엇에 의존하는지 보기 ───────────────────────
colcon list --topological-order
colcon graph
5. source의 원리 — underlay와 overlay
"왜 새 터미널을 열 때마다 source를 해야 하나요?"는 가장 많이 받는 질문입니다. 원리를 알면 납득이 됩니다.
source가 하는 일은 환경변수를 설정하는 것뿐입니다.
AMENT_PREFIX_PATH, PYTHONPATH, PATH, LD_LIBRARY_PATH 같은 것들에 경로를 추가합니다. 환경변수는 그 셸에만 적용됩니다. 새 터미널은 새 셸이므로 아무것도 모릅니다. source는 설치가 아니라 "이 터미널에서 이 워크스페이스를 쓰겠다"는 선언입니다.
underlay와 overlay
ROS 2는 환경을 겹겹이 쌓습니다.
• underlay — /opt/ros/<배포판>/setup.bash. ROS 2 본체입니다
• overlay — ~/ros2_ws/install/setup.bash. 여러분의 워크스페이스입니다
순서가 중요합니다. underlay를 먼저, overlay를 나중에 source 합니다. 나중에 올린 것이 이깁니다. 그래서 nav2_bringup 같은 표준 패키지를 여러분이 고쳐 워크스페이스에 두면, 시스템에 설치된 원본 대신 여러분 것이 쓰입니다.
setup.bash와 local_setup.bash의 차이
• setup.bash — 이 워크스페이스 + 이것이 빌드될 때 쌓여 있던 underlay 전부
• local_setup.bash — 이 워크스페이스만
보통은 setup.bash를 쓰면 됩니다.
.bashrc에 넣어도 될까?
underlay(/opt/ros/...)는 넣어도 됩니다. 편합니다.
overlay는 권하지 않습니다. 워크스페이스가 여러 개가 되면 어느 것이 켜져 있는지 헷갈리고, 빌드하기 전 상태의 환경이 필요할 때 곤란해집니다.
가장 흔한 사고: 빌드한 터미널에서만 source하고, 다른 터미널에서 실행하면서 "왜 옛날 코드가 도나" 하는 것입니다. 빌드 후에는 실행할 모든 터미널에서 다시 source 해야 합니다.
요점
- source는 설치가 아니라 그 셸의 환경변수를 설정하는 것뿐이다.
- underlay를 먼저, overlay를 나중에. 나중에 올린 것이 이긴다.
- 빌드 후에는 실행할 모든 터미널에서 다시 source 해야 한다.
- overlay는 .bashrc에 넣지 않는 편이 안전하다.
- 어느 것이 쓰이는지는 ros2 pkg prefix로 확인한다.
source의 순서와 확인 명령. AMENT_PREFIX_PATH 앞쪽이 우선한다는 점이 핵심입니다.
# ── 매번 해야 하는 것 ───────────────────────────────────
source /opt/ros/<배포판>/setup.bash # underlay (먼저)
source ~/ros2_ws/install/setup.bash # overlay (나중)
# .bashrc 에는 underlay 만 넣기를 권한다
echo "source /opt/ros/<배포판>/setup.bash" >> ~/.bashrc
# ── 지금 무엇이 켜져 있는지 확인 ────────────────────────
echo $AMENT_PREFIX_PATH
# /home/me/ros2_ws/install/lab_nodes:/opt/ros/<배포판>
# 앞에 있는 것이 우선한다
printenv | grep -i ros
# ── 이 이름의 패키지가 실제로 어디에서 오는가 ────────────
ros2 pkg prefix lab_nodes
# /home/me/ros2_ws/install/lab_nodes <- 내 것이 쓰인다
which ros2
python3 -c "import lab_nodes, os; print(os.path.dirname(lab_nodes.__file__))"
# ── 자주 나는 사고 ──────────────────────────────────────
# (1) 빌드한 터미널에서만 source 하고 다른 터미널에서 실행
# -> 실행할 모든 터미널에서 다시 source 한다
#
# (2) 환경이 꼬였다 싶으면 깨끗한 새 터미널을 연다
# 한 셸에서 여러 워크스페이스를 겹쳐 source 하면
# 어느 것이 이기는지 알기 어려워진다
#
# (3) 패키지가 안 보인다
ros2 pkg list | grep lab_nodes
# 안 나오면: 빌드가 실패했거나, source 를 안 했거나,
# setup.py 의 data_files 필수 두 줄을 지웠다
개념도 · stack
- 단계/참여자
- 내 워크스페이스 overlay — 가장 나중, 가장 우선
- 다른 워크스페이스 overlay — 있다면 그 다음
- ROS 2 배포판 underlay — /opt/ros 아래 본체
- 운영체제 — Ubuntu, Python
- 연결/행
여기가 이긴다- ``
기본 제공- ``
나중에 올린 것이 이깁니다. 그래서 표준 패키지를 내 워크스페이스에서 덮어쓸 수 있습니다.
6. 빌드와 실행이 안 될 때 — 순서대로
증상은 다양해 보이지만 원인은 몇 가지로 수렴합니다. 아래 순서로 좁히세요.
① "Package not found"
→ source를 했는가? → 빌드가 성공했는가(log/latest_build 확인)? → setup.py의 data_files 필수 두 줄이 있는가?
② "No executable found"
→ setup.py의 entry_points에 그 이름을 등록했는가? → ros2 pkg executables 패키지이름으로 실제 등록된 이름을 확인합니다. 오타가 대부분입니다.
③ "ModuleNotFoundError"
→ package.xml에 <depend>를 적었는가? → rosdep install을 돌렸는가? → 다른 패키지를 import 한다면 그 패키지도 빌드되어 있는가?
④ launch 파일을 못 찾는다
→ setup.py의 data_files에 launch 폴더를 추가했는가? → install/패키지/share/패키지/launch/ 아래에 실제로 있는지 눈으로 확인합니다.
⑤ 커스텀 메시지를 못 찾는다
→ 인터페이스 패키지를 빌드했는가? → 다시 source 했는가? → ros2 interface list | grep 내타입으로 확인합니다.
⑥ 고쳤는데 옛날 대로 동작한다
→ 다른 터미널에서 실행하고 있지 않은가? → --symlink-install 없이 빌드했는가? → 이전 프로세스가 아직 살아 있지 않은가(ros2 node list로 확인)?
⑦ 설명할 수 없는 오류
→ 첫 Error와 Build Log, Package Prefix를 확인하고 Package 선택 재Build와 --cmake-clean-cache를 시도합니다. 전체 Clean은 Section 15의 순서에 따라 Workspace Root와 정확한 산출물 대상을 검증한 뒤 수행합니다.
진짜 오류 메시지를 보는 법: colcon은 기본적으로 요약만 보여 줍니다. --event-handlers console_direct+를 붙이거나 log/latest_build/패키지이름/stdout_stderr.log를 직접 여세요. "빌드 실패"라는 한 줄만 보고 헤매는 시간이 가장 아깝습니다.
| 오류 메시지 | 가장 유력한 원인 | 먼저 확인할 것 |
|---|---|---|
| Package not found | source 누락 또는 빌드 실패 | ros2 pkg list |
| No executable found | entry_points 미등록 또는 오타 | ros2 pkg executables 패키지 |
| ModuleNotFoundError | package.xml 의존성 누락 | rosdep install 실행 |
| launch 파일 없음 | data_files에 launch 미추가 | install 아래를 직접 확인 |
| 메시지 타입 없음 | 인터페이스 미빌드 또는 미source | ros2 interface list |
| 고쳤는데 그대로 | 다른 터미널 또는 옛 프로세스 | ros2 node list 로 중복 확인 |
| 설명 불가한 오류 | Cache·환경·중복 Prefix | 첫 Error, Prefix, Package 선택 Clean |
7. colcon은 Package Graph를 먼저 만든다
colcon은 단순히 src의 모든 Directory를 차례로 Compile하지 않습니다. Package Discovery Extension이 package.xml, setup.py, CMakeLists.txt 등을 찾아 Package를 식별하고 의존성 Graph를 만든 뒤 Topological Order로 작업합니다.
lab_interfaces
│
├──────────────┐
↓ ↓
lab_driver lab_navigation
│ │
└──────┬───────┘
↓
lab_bringup
이 Graph에서 lab_bringup을 실행하려면 앞 Package가 필요합니다. 반대로 lab_interfaces가 바뀌면 이를 사용하는 Consumer를 다시 Build·Test해야 할 수 있습니다.
cd "$HOME/ros2_ws"
# 발견된 Package, 경로와 Build Type
colcon list
# 의존성 순서
colcon list --topological-order
# Graph Extension이 설치된 환경
colcon graph
# 특정 Package의 Manifest Dependency 점검
rosdep keys --from-paths src/lab_nodes --ignore-src
Package가 발견되지 않을 때
package.xml이 Package Root에 있는지 확인합니다.- Package 이름이 Workspace 안에서 중복되지 않는지 확인합니다.
COLCON_IGNORE파일이 상위 Directory에 있는지 확인합니다.- Python Package라면
resource/<package_name>과 Setup Metadata를 확인합니다. colcon list결과에서부터 문제를 확인합니다. Build 전에 발견되지 않으면 Build Option을 바꿔도 해결되지 않습니다.
find src -name COLCON_IGNORE -o -name AMENT_IGNORE
colcon list | rg '^lab_nodes\s'
COLCON_IGNORE는 큰 Monorepo에서 현재 Platform에 필요 없는 Package Tree를 Discovery에서 제외할 때 유용하지만, 실수로 Commit되면 CI에서 Package가 조용히 사라질 수 있습니다.
8. 선택 빌드 옵션의 방향을 정확히 이해한다
비슷한 이름의 Option은 Graph 방향이 다릅니다.
| 옵션 | 포함 범위 | 대표 상황 |
|---|---|---|
--packages-select A |
A만 | 독립 Python Node 한 개 수정 |
--packages-up-to A |
A와 A의 재귀 Dependency | A를 실행할 수 있는 기반까지 Build |
--packages-above A |
A에 재귀적으로 의존하는 Consumer | Interface A 변경 영향 확인 |
--packages-above-and-dependencies A |
Consumer와 그 Dependency | Interface 변경 후 영향 범위 전체 Test |
--packages-select-by-dep A |
A에 직접 의존하는 Package | 직접 Consumer만 선택 |
--packages-skip A |
A 제외 | 일시적으로 지원 불가 Package 제외 |
설치된 colcon Extension에 따라 사용 가능한 Option이 다를 수 있으므로 실제 Help를 기준으로 합니다.
colcon build --help | less
colcon list --help | less
# Node와 그 Dependency까지
colcon build --packages-up-to lab_navigation --symlink-install
# Interface 변경의 Consumer까지 Test하는 예
colcon build --packages-above-and-dependencies lab_interfaces \
--symlink-install
colcon test --packages-above-and-dependencies lab_interfaces
colcon test-result --verbose
--packages-select는 Dependency를 자동 Build하지 않습니다. 이미 Underlay나 install에 필요한 Dependency가 없다면 선택 Package가 실패합니다. 반대로 이전 install에 오래된 Dependency가 남아 있으면 Build는 성공해도 잘못된 Version을 사용할 수 있으므로 ros2 pkg prefix와 Build Summary를 확인합니다.
9. ament_cmake Package의 설치를 읽는다
Python Package의 entry_points만큼 C++ Package에서는 add_executable, ament_target_dependencies와 install이 중요합니다.
cmake_minimum_required(VERSION 3.8)
project(lab_cpp_nodes)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
add_executable(status_publisher src/status_publisher.cpp)
ament_target_dependencies(status_publisher rclcpp std_msgs)
target_compile_features(status_publisher PUBLIC cxx_std_17)
target_compile_options(status_publisher PRIVATE -Wall -Wextra -Wpedantic)
install(TARGETS
status_publisher
DESTINATION lib/${PROJECT_NAME}
)
install(DIRECTORY
launch
config
DESTINATION share/${PROJECT_NAME}
)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
줄별 핵심
find_package는 CMake가 Dependency Config를 찾게 합니다.add_executable은 Source로 실행 Binary Target을 만듭니다.ament_target_dependencies는 Include·Library와 Build 순서를 Target에 연결합니다.install(TARGETS ...)가 없으면 Build Directory에는 Binary가 있어도ros2 run이 찾지 못합니다.install(DIRECTORY ...)가 없으면 Launch·YAML이 Source에만 있고 Install Space에는 없습니다.ament_package()는 Package Config와 ament Index 정보를 완성하며 일반적으로 마지막에 둡니다.
colcon build --packages-select lab_cpp_nodes \
--cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
source install/setup.bash
ros2 pkg executables lab_cpp_nodes
ros2 pkg prefix lab_cpp_nodes
find install/lab_cpp_nodes -maxdepth 4 -type f | sort
RelWithDebInfo는 최적화와 Debug Symbol을 함께 원할 때 유용합니다. 성능 측정은 Build Type뿐 아니라 Compiler, CPU Governor와 입력 Data를 고정해야 의미가 있습니다.
10. Isolated Install과 Merge Install
기본 colcon Build는 Package별 Prefix를 갖는 Isolated Install을 사용합니다.
install/
├── lab_interfaces/
├── lab_nodes/
├── lab_bringup/
├── local_setup.bash
└── setup.bash
--merge-install은 여러 Package를 하나의 Prefix에 합칩니다.
install/
├── bin/
├── lib/
├── share/
├── local_setup.bash
└── setup.bash
| 방식 | 장점 | 주의점 |
|---|---|---|
| Isolated | Package 경계와 누락 Dependency가 잘 드러남 | Environment Path가 길어질 수 있음 |
| Merge | 짧은 Environment, Windows Path 길이 완화 | 선언하지 않은 Dependency가 우연히 보여 누락을 숨길 수 있음 |
하나의 Workspace에서 두 Layout을 번갈아 쓰면 기존 Install 구조와 섞일 수 있습니다. Layout을 바꿀 때는 팀 정책과 CI를 맞추고 기존 산출물을 별도 Backup한 뒤 깨끗한 Build를 만듭니다.
--symlink-install은 Layout과 다른 축의 Option입니다. Python Source나 Resource를 Link하여 개발 편의를 높이지만 C++ Source는 다시 Compile해야 하고 Setup Metadata, 새 File, Entry Point와 Install Rule 변경도 재Build가 필요합니다.
11. Build 성공과 품질 통과는 다르다
colcon build가 성공했다는 것은 Compile·Install 단계가 끝났다는 뜻이지 기능이 맞다는 뜻은 아닙니다.
# Build
colcon build --symlink-install \
--event-handlers console_cohesion+
# 전체 Test
colcon test --event-handlers console_direct+
# 실패 상세
colcon test-result --verbose
# 실패한 Package만 다시 Test
colcon test --packages-select lab_nodes \
--pytest-args -k test_safe_stop
ROS 2 Package Test에는 다음이 포함될 수 있습니다.
- Python Unit Test와 Lint
- C++ gtest·gmock
ament_lint_auto의 Copyright·Style·CMake·XML 검사- Launch Test와 여러 Node Integration Test
- Bag 기반 Algorithm Regression Test
CI에서는 Build와 Test 결과 File을 Artifact로 보존합니다. test-result의 Exit Code가 실패인데 Console 끝부분만 보고 성공으로 처리하지 않도록 Pipeline을 구성합니다.
colcon test
colcon test-result --verbose
colcon test-result --result-files-only
12. 반복 Option은 defaults.yaml과 Mixin으로 관리한다
개발자마다 다른 Build Option을 손으로 입력하면 결과가 달라집니다. colcon Default File은 Verb별 기본 Option을 공유하는 데 사용합니다.
# colcon-defaults.yaml
build:
symlink-install: true
event-handlers:
- console_cohesion+
cmake-args:
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
- -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
test:
event-handlers:
- console_direct+
export COLCON_DEFAULTS_FILE="$PWD/colcon-defaults.yaml"
colcon build
colcon test
Mixin은 debug, release, Sanitizer처럼 이름 있는 Option 묶음을 재사용할 때 편리합니다. Mixin Repository를 추가·갱신하는 명령은 외부 Configuration을 내려받으므로 Source를 검토하고 팀에서 승인한 Definition을 사용합니다.
colcon mixin list
colcon build --mixin release
재현 가능한 Build에는 Default File뿐 아니라 다음도 함께 필요합니다.
- ROS Distribution과 OS Image
- Source Repository Commit 또는
.reposFile - rosdep Dependency와 Apt Snapshot·Version 정책
- Compiler·Python Version
- Environment Variables와 RMW
- Build Command, Default·Mixin Definition
13. vcs와 rosdep으로 Source와 Dependency를 복원한다
여러 Repository를 Workspace에 넣는 Project는 .repos File로 Source 위치와 Revision을 기록할 수 있습니다.
# robot_ws.repos
repositories:
lab_interfaces:
type: git
url: https://example.com/lab_interfaces.git
version: 4f7c2a1
lab_navigation:
type: git
url: https://example.com/lab_navigation.git
version: v2.3.0
mkdir -p "$HOME/robot_ws/src"
cd "$HOME/robot_ws"
vcs import src < robot_ws.repos
vcs status src
vcs export --exact src > resolved.repos
rosdep install --from-paths src --ignore-src -r -y
colcon build --symlink-install
Branch 이름만 기록하면 시간이 지나 같은 명령이 다른 Commit을 가져올 수 있습니다. Release·CI에서는 Tag 또는 Commit Hash를 사용하고 vcs export --exact 결과를 Artifact로 남깁니다. Private Repository Credential은 .repos에 넣지 않습니다.
14. CI에서 깨끗한 Workspace를 검증한다
개발 PC의 오래된 Install Space가 누락 Dependency를 숨길 수 있습니다. CI는 매번 깨끗한 Container나 Runner에서 다음 순서를 수행합니다.
검증된 OS·ROS Image
→ Source Revision Checkout
→ rosdep Dependency 설치
→ colcon list로 발견 Package 기록
→ colcon build
→ colcon test
→ test-result 판정
→ Build·Test Log와 환경 명세 보존
set -euo pipefail
source "/opt/ros/${ROS_DISTRO}/setup.bash"
rosdep install --from-paths src --ignore-src -r -y
colcon list --topological-order
colcon build --merge-install \
--event-handlers console_cohesion+
source install/setup.bash
colcon test --event-handlers console_direct+
colcon test-result --verbose
set -e만 믿지 말고 각 Tool의 Exit Code와 Result File을 확인합니다. Cache는 Build 시간을 줄이지만 Key에 OS·ROS·Compiler·Dependency Lock이 빠지면 잘못된 Artifact를 재사용할 수 있습니다.
15. 안전한 Clean Build 전략
전체 build, install, log 삭제는 상태를 초기화하지만 원인 증거도 없애고 큰 Workspace를 다시 Build하게 만듭니다. 다음 순서로 범위를 넓힙니다.
- 첫 Error 확인 — 뒤따르는 Error 수십 개보다 가장 처음 실패를 봅니다.
- Package 선택 재Build —
--packages-select와 상세 Event Handler를 사용합니다. - CMake Cache만 초기화 —
--cmake-clean-cache또는--cmake-clean-first를 검토합니다. - 영향 Graph 재Build — Interface면 Consumer와 Dependency 범위를 선택합니다.
- 산출물 Backup 후 전체 Clean — 정확한 Workspace Root와 대상 Directory를 확인한 경우에만 수행합니다.
cd "$HOME/ros2_ws"
pwd
# 실패 Log 확인
find log/latest_build -name stdout_stderr.log -type f -print
sed -n '1,200p' log/latest_build/lab_nodes/stdout_stderr.log
# Package 범위 재Build
colcon build --packages-select lab_nodes \
--event-handlers console_direct+
# CMake Package Cache 재구성
colcon build --packages-select lab_cpp_nodes \
--cmake-clean-cache
전체 초기화가 필요하면 자동 Script가 광범위한 경로나 미확정 환경변수를 대상에 포함하지 않도록 합니다. Source와 Bag·Config가 산출물 Directory 안에 잘못 저장되지 않았는지도 먼저 확인합니다.
16. 실제 오류를 계층별로 추적한다
사례 A — Build는 성공했지만 ros2 run이 실행 파일을 못 찾는다
colcon list | rg '^lab_nodes\s'
ros2 pkg prefix lab_nodes
ros2 pkg executables lab_nodes
find install -path '*lab_nodes*' -maxdepth 6 -type f | sort
Discovery가 되면 Package Metadata는 설치됐습니다. Executable 목록이 비었다면 Python console_scripts 또는 CMake install(TARGETS)를 확인하고 Metadata 변경 후 다시 Build·Source합니다.
사례 B — Launch YAML 수정이 반영되지 않는다
--symlink-install을 사용해도 Resource 설치 방식과 Package 설정에 따라 Copy일 수 있습니다. 실제 Install File과 Source를 비교하고 data_files 또는 CMake install(DIRECTORY)를 확인합니다.
pkg_prefix="$(ros2 pkg prefix lab_bringup)"
find "$pkg_prefix/share/lab_bringup" -maxdepth 3 -type f -print
사례 C — Custom Message를 바꾼 뒤 Import Error
Interface Package와 Consumer의 Manifest Dependency, Build 순서, 새 Terminal Source와 중복 설치를 확인합니다.
ros2 interface show lab_interfaces/msg/RobotState
ros2 pkg prefix lab_interfaces
colcon build --packages-above-and-dependencies lab_interfaces
source install/setup.bash
17. 확인 퀴즈 15문항
1. 워크스페이스에서 사용자가 직접 만들고 관리하는 폴더는?
- (1) build
- (2) src 정답
- (3) install
- (4) log
해설: src만 사용자가 만들고 git으로 관리합니다. build, install, log는 colcon이 생성하는 산물이므로 언제든 지웠다 다시 만들 수 있고, .gitignore에 반드시 넣어야 합니다. 이 구분을 알면 무엇을 백업하고 무엇을 지워도 되는지 명확해집니다.
2. colcon build를 src 폴더 안에서 실행하면 어떤 문제가 생기는가?
- (1) 빌드가 더 빨라진다
- (2) src 안에 또 build/install/log가 생겨 어느 install을 source 했는지 알 수 없게 된다 정답
- (3) 아무 문제도 없다
- (4) 자동으로 루트로 이동한다
해설: colcon은 실행한 자리에 산출물을 만듭니다. src 안에서 실행하면 그곳에 또 하나의 install이 생겨 "분명히 빌드했는데 옛날 코드가 돈다" 같은 혼란이 벌어집니다. 반드시 워크스페이스 루트에서 실행해야 합니다.
3. 메시지 정의(.msg, .srv, .action)를 별도 인터페이스 패키지로 분리하는 이유는?
- (1) 빌드가 빨라지기 때문
- (2) 다른 팀이 타입만 쓰고 싶을 때 노드 코드와 그 의존성까지 끌어오지 않아도 되기 때문 정답
- (3) ROS 2가 그것을 강제하기 때문
- (4) 메시지 크기가 줄어들기 때문
해설: 인터페이스를 노드 패키지에 섞어 두면, 나중에 다른 패키지가 그 타입만 쓰려 해도 노드의 모든 의존성이 딸려 옵니다. 타입만 담은 가벼운 패키지로 분리하는 것이 실무의 표준이며, 배포와 버전 관리도 훨씬 수월해집니다.
4. package.xml에 의존성을 적어야 하는 실질적인 이유는?
- (1) 적지 않으면 내 컴퓨터에서도 빌드가 안 되기 때문
- (2) colcon이 빌드 순서를 정하고 rosdep이 자동으로 설치할 수 있게 하기 위해 정답
- (3) 메시지 타입이 생성되지 않기 때문
- (4) 노드 이름이 결정되기 때문
해설: 내 컴퓨터에는 이미 깔려 있어 안 적어도 빌드됩니다. 문제는 다른 사람이 받았을 때입니다. rosdep install은 package.xml을 읽어 필요한 것을 설치하므로, 적혀 있지 않으면 설치되지 않고 실행 시점에 실패합니다. 빌드 순서 결정에도 이 선언이 쓰입니다.
5. setup.py의 entry_points에 적은 왼쪽 이름은 어디에 쓰이는가?
- (1) ros2 node list에 표시되는 노드 이름
- (2) ros2 run의 두 번째 인자이자 launch 파일의 executable 이름 정답
- (3) 파이썬 파일 이름
- (4) 패키지 이름
해설: "실행이름 = 패키지.모듈:함수" 형식에서 왼쪽이 실행 이름입니다. 이것이 ros2 run의 두 번째 인자이며 launch의 executable도 이 이름이어야 합니다. 노드 이름은 별개로 super().init()에서 정해지므로 혼동하지 말아야 합니다.
6. setup.py의 data_files에서 resource와 package.xml을 설치하는 두 줄을 지우면?
- (1) launch 파일만 설치되지 않는다
- (2) ROS가 그 패키지를 아예 인식하지 못한다 정답
- (3) 빌드 속도가 빨라진다
- (4) 노드 이름이 사라진다
해설: ament 인덱스에 등록되지 않으면 ros2 pkg list에도 나타나지 않고 ros2 run도 패키지를 찾지 못합니다. ros2 pkg create가 자동으로 넣어 주는 부분이므로 손대지 않는 것이 정답입니다. "Package not found" 오류의 원인 중 하나입니다.
7. launch 파일을 만들었는데 ros2 launch가 찾지 못한다면 가장 먼저 확인할 것은?
- (1) 노드 이름
- (2) setup.py의 data_files에 launch 폴더를 추가했는지 정답
- (3) QoS 설정
- (4) package.xml의 버전
해설: Python 소스는 자동으로 설치되지만 launch 파일과 YAML은 data_files에 명시해야 install 아래로 복사됩니다. 원본은 src에 있어도 설치되지 않았으면 찾을 수 없습니다. install 폴더를 직접 열어 파일이 있는지 눈으로 확인하는 것이 가장 확실합니다.
8. --symlink-install 옵션의 효과로 옳은 것은?
- (1) 빌드 속도가 두 배 빨라진다
- (2) 이미 등록된 Python 파일의 내용을 고치면 재빌드 없이 반영된다 정답
- (3) C++ 최적화를 켠다
- (4) 의존성을 자동으로 설치한다
해설: 설치본을 복사가 아닌 심볼릭 링크로 만들기 때문에 원본을 고치면 그대로 반영됩니다. 다만 새 파일을 추가하거나 entry_points 또는 data_files를 바꾸면 설치 목록 자체가 달라지므로 다시 빌드해야 합니다.
9. 인터페이스 패키지를 고쳤을 때 권장되는 빌드 명령은?
- (1) colcon build --packages-select 인터페이스패키지
- (2) colcon build --packages-up-to 노드패키지 정답
- (3) colcon build --symlink-install만
- (4) colcon test
해설: --packages-select로 인터페이스만 빌드하면 그것을 쓰는 노드는 옛 타입을 물고 있게 되어 두 노드가 서로를 발견하지 못하는 조용한 실패가 생깁니다. --packages-up-to를 쓰면 의존 관계를 따라 필요한 것까지 함께 빌드해 줍니다.
10. 빌드가 실패했는데 요약만 보이고 원인을 알 수 없을 때 쓰는 옵션은?
- (1) --symlink-install
- (2) --event-handlers console_direct+ 정답
- (3) --packages-select
- (4) --parallel-workers 1
해설: colcon은 기본적으로 출력을 요약하므로 컴파일 오류의 자세한 내용이 감춰집니다. 이 옵션을 붙이면 빌드 출력이 그대로 나오고, log/latest_build 아래의 stdout_stderr.log를 직접 열어도 같은 내용을 볼 수 있습니다.
11. C++ 노드의 성능을 측정하기 전에 반드시 확인해야 할 것은?
- (1) QoS가 RELIABLE인지
- (2) -DCMAKE_BUILD_TYPE=Release로 최적화를 켜고 빌드했는지 정답
- (3) 로그 수준이 INFO인지
- (4) 네임스페이스가 붙었는지
해설: 기본 빌드는 최적화 없이 진행되므로 C++ 노드가 실제 성능보다 훨씬 느리게 나옵니다. 이 상태에서 측정하고 "C++인데도 느리다"고 판단하면 잘못된 결론에 이릅니다. 성능 비교는 반드시 Release 빌드로 해야 합니다.
12. 새 터미널을 열 때마다 source를 해야 하는 이유는?
- (1) 패키지를 다시 설치하기 위해서
- (2) source는 그 셸의 환경변수만 설정하며 새 셸은 그것을 모르기 때문 정답
- (3) 빌드가 초기화되기 때문
- (4) DDS가 재시작되기 때문
해설: source는 설치가 아니라 AMENT_PREFIX_PATH나 PYTHONPATH 같은 환경변수를 그 셸에 설정하는 것뿐입니다. 환경변수는 셸마다 독립적이므로 새 터미널은 아무것도 모릅니다. 빌드 후에는 실행할 모든 터미널에서 다시 source 해야 합니다.
13. underlay와 overlay를 source하는 순서와 우선순위는?
- (1) overlay를 먼저, underlay가 우선한다
- (2) underlay를 먼저, 나중에 올린 overlay가 우선한다 정답
- (3) 순서는 상관없고 항상 underlay가 우선한다
- (4) 동시에 해야 한다
해설: ROS 2 본체인 underlay를 먼저 source하고 내 워크스페이스 overlay를 나중에 올립니다. 나중에 올린 것이 앞쪽 경로를 차지해 우선하므로, 표준 패키지를 내 워크스페이스에서 고쳐 덮어쓸 수 있습니다. 어느 것이 쓰이는지는 ros2 pkg prefix로 확인합니다.
14. "고쳤는데 옛날 대로 동작한다"의 원인으로 가장 가능성이 낮은 것은?
- (1) 다른 터미널에서 source하지 않고 실행하고 있다
- (2) 이전 프로세스가 아직 살아 있다
- (3) --symlink-install 없이 빌드하고 재빌드하지 않았다
- (4) QoS가 BEST_EFFORT로 설정되어 있다 정답
해설: QoS는 전달 방식에 관한 설정일 뿐 어느 코드가 실행되는지와는 무관합니다. 실제 원인은 대개 source를 하지 않은 터미널에서 실행했거나, 이전 노드가 아직 떠 있거나, 심볼릭 링크 없이 빌드한 뒤 재빌드를 빠뜨린 경우입니다.
15. 설명할 수 없는 빌드 오류를 만났을 때 가장 먼저 할 조치는?
- (1) ROS 2를 재설치한다
- (2) 첫 Error와 Build Log를 확인하고 영향 Package만 상세 출력으로 다시 빌드한다 정답
- (3) 패키지를 새로 만든다
- (4) QoS를 바꾼다
해설: 전체 삭제부터 하면 원인 증거와 시간을 잃습니다. 첫 Error, stdout_stderr.log와 Package Prefix를 확인하고 선택 Build·CMake Cache Clean으로 범위를 좁힙니다. 전체 Clean은 정확한 Workspace와 산출물을 검증하고 필요한 원본이 없을 때 마지막 단계로 수행합니다.
- Workspace워크스페이스
- 여러 ROS Package Source와 colcon Build·Install·Log 결과를 함께 관리하는 개발 Directory 구조입니다.
- Package패키지
- Manifest, Source, Build 설정과 Resource를 묶은 ROS Software 배포·의존성 관리 단위입니다.
- colcon통합 빌드 도구
- Package를 발견하고 Dependency Graph에 따라 다양한 Build Type의 Build·Test·Install Task를 실행하는 Tool입니다.
- Package Graph패키지 의존성 그래프
- Package를 정점, 의존 관계를 방향 Edge로 표현해 Build 순서와 변경 영향 범위를 나타낸 구조입니다.
- Topological Order위상 순서
- 모든 Dependency가 이를 사용하는 Consumer보다 먼저 오도록 Graph Node를 정렬한 순서입니다.
- ament_python에이먼트 파이썬
- setuptools Metadata와 ament Index를 이용해 Python ROS Package를 Build·Install하는 Build Type입니다.
- ament_cmake에이먼트 CMake
- CMake Macro와 ament Index를 이용해 C++·Interface·Resource Package를 구성하는 Build Type입니다.
- package.xml패키지 매니페스트
- Package 이름, Version, Maintainer, License, Build Type과 Dependency를 선언하는 XML File입니다.
- Entry Point실행 진입점
- 실행 이름을 Python Module 함수나 설치된 Program과 연결하는 등록 정보입니다.
- ament Index에이먼트 리소스 인덱스
- 설치 Prefix에서 Package와 Resource 위치를 빠르게 찾기 위한 Marker 기반 Index입니다.
- Underlay기반 작업공간
- 다른 Workspace가 Dependency로 사용하며 먼저 Source되는 ROS 설치 또는 Workspace입니다.
- Overlay상위 작업공간
- Underlay 위에 Source되어 Package와 Resource를 추가하거나 같은 이름을 우선시할 수 있는 Workspace입니다.
- Symlink Install심볼릭 링크 설치
- 가능한 Resource를 Install Space에 복사하지 않고 Source로 연결해 개발 수정 반영을 빠르게 하는 방식입니다.
- Isolated Install분리 설치
- 각 Package가 Install Space 안에서 별도의 Prefix를 갖도록 설치하는 기본 Layout입니다.
- Merge Install병합 설치
- 여러 Package 결과를 하나의 Install Prefix에 합치는 colcon Layout입니다.
- Build Cache빌드 캐시
- CMake 설정과 Compile 결과 등 다음 Build에서 재사용해 시간을 줄이는 중간 상태입니다.
- colcon Defaults콜콘 기본 설정
- Build·Test Verb의 반복 Option을 YAML File로 제공하는 colcon 구성 방식입니다.
- Mixin믹스인
- Debug·Release·Sanitizer처럼 이름으로 선택할 수 있는 colcon Command Option 묶음입니다.
- vcstool다중 저장소 도구
- repos File을 이용해 여러 Version Control Repository를 Import·Export·상태 확인하는 Tool입니다.
- Clean Build클린 빌드
- 이전 Build Cache와 Install 결과의 영향을 제거한 상태에서 Source와 Dependency로 Build를 다시 수행하는 방식입니다.
연습 문제
- Workspace의
src,build,install,log역할과 Git 관리 범위를 설명하세요. - colcon이 Package를 발견하고 Build 순서를 정하는 과정을 설명하세요.
- Interface·Node·Bringup Package를 분리하는 이유와 Build Type을 쓰세요.
package.xmlDependency가 Build, rosdep과 배포에 미치는 영향을 설명하세요.- ament_python의
console_scripts, Resource Index와data_files역할을 설명하세요. - ament_cmake의
add_executable,ament_target_dependencies,install과ament_package역할을 설명하세요. --packages-select,--packages-up-to와--packages-above-and-dependencies의 Graph 방향을 비교하세요.--symlink-install로 바로 반영되는 변경과 재Build가 필요한 변경을 구분하세요.- Isolated Install과 Merge Install의 장단점을 설명하세요.
setup.bash와local_setup.bash, Underlay와 Overlay의 관계를 설명하세요.- Build 성공 후에도
colcon test-result --verbose를 확인해야 하는 이유는 무엇인가요? colcon-defaults.yaml과 Mixin을 어떤 상황에 사용하나요?.reposFile과vcs export --exact가 재현 가능한 Source 관리에 필요한 이유는 무엇인가요?- CI가 개발 PC와 달리 깨끗한 환경에서 Build해야 하는 이유를 설명하세요.
No executable found, Launch File 누락과 Custom Message Import 오류를 각각 진단하는 순서를 쓰세요.
COMMUNITY
강의 댓글
질문과 학습 경험을 함께 나눠보세요.댓글을 불러오는 중입니다.