C++で書いたプログラムを、docker-composeで立ち上げたUbuntu 18.04で動かして、macOS上のCLionからデバッグする。
タイトルのとおりです。
(普通にkqueueで良いんじゃないのと思いはしたものの、)Linuxのepollシステムコールを使ってソケット処理を書こうとするとどうなるのかを試してみたかったのですが、手元にあったマシンがmacOSだったので、ちょうど最近業務でも使い始めたがまだ慣れていないdocker-composeで開発環境を用意してみようとやってみました。
軽い気持ちでやり始めたものの、なんだかんだで結構ハマったのでメモを残します。
やろうと思えば、docker-composeの操作もすべてCLion上で完結できるようですが、なんかうまくいかないことがあったので、docker-compose startとかはコンソール上でやって、デバッグの部分だけCLionでやってます。
(一応公式ヘルプに使い方 Docker - ヘルプ | CLion が書いてありましたが)
また、以下のソースはリポジトリ GitHub - rkmathi/dockerfiles に置いてます。
動作環境は
- MacBook Pro Late 2018, 2.6 GHz Intel Core i7, 32 GB 2400 MHz DDR4
- macOS 10.14.4
- CLion 2019.1
- Docker version 18.09.2, build 6247962 (普通のDocker for mac)
- (docker上) Ubuntu 18.04
な感じです。
とりあえず、CLionなのでまずは CMakeLists.txt
を用意しました。
cmake_minimum_required(VERSION 3.0) set(CMAKE_VERBOSE_MAKEFILE OFF) set(out_dir ${CMAKE_BINARY_DIR}/out) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${out_dir}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${out_dir}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${out_dir}) project(work) enable_language(CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CXX_EXTENSIONS OFF) ADD_COMPILE_OPTIONS(-Werror -Wall -Wextra) add_executable(work main.cc)
main.cc
も最初なので適当です。
#include <iostream> int main() { std::cout << "main.cc" << std::endl; return 0; }
Dockerfile
は、イロイロなところを見ながら次のようにしました。
流石にプロダクション環境で使うことは全く想定していないので、rootユーザにパスワードログインしちゃいます。
FROM ubuntu:18.04 # Configure working directory ADD . /work WORKDIR /work # Install packages RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y build-essential cmake gcc g++ gdb gdbserver openssh-server rsync # Enable ssh for root user # see also: https://docs.docker.com/engine/examples/running_ssh_service/ RUN mkdir /var/run/sshd && \ echo 'root:root' | chpasswd && \ sed -i 's/#\?PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \ sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile # Expose port for ssh & gdbserver EXPOSE 22 7777 # Run sshd CMD ["/usr/sbin/sshd", "-D"]
docker-compose.yml
は、こんな感じです。
本当は version: '3'
の部分はマイナーバージョンまで指定したほうが良いのかもしれないですがまだ良くわかってないので一旦適当になってます。
version: '3' services: ubuntu-gdbserver: build: . security_opt: # For gdb debugging - seccomp:unconfined - apparmor:unconfined ports: - "7776:22" # For ssh - "7777:7777" # For gdbserver volumes: - .:/work
1. ↑で用意したubuntu-gdbserverサービスを立ち上げておく。
$ docker-compose build ubuntu-gdbserver
$ docker-compose start ubuntu-gdbserver
この後、 ssh root@localhost -p 7776
を試してSSHできることを確認した。 (パスワードは↑のままセットアップしたなら root
)
2. CLionを開いて、Docker integrationプラグインをインストールする。
3. Preferences → Build, Execution, Deployment → Toolchainsから追加する。
Nameは何でも良いが、Nameの隣の入力欄は Remote Host
にする。
4. Preferences → Build, Execution, Deployment → CMakeから追加する。
ここもNameは何でも良い
5. CLion上で適当にbrake pointをはる
6. Debug実行するときのターゲットで、さっき作ったToolchain選択する。
7. Debug実行すると、ちゃんとremote debugできるようになる。
おわり