После появления цикла статей о встраивании PVS-Studio в различные IDE под Linux (Eclipse, Anjuta), появилось желание запустить PVS-Studio для проверки своих проектов, разрабатываемых в Eclipse под macOS. Но разработчики PVS-Studio пока не планируют выпускать версию под macOS. Ну что ж, заткнем пока эту брешь.


Дано:



Задача:



Вариантов решения на самом деле несколько:


  • Запуск Eclipse в виртуальной машине
  • Проверка кода на другом компьютере с Linux
  • Использование Docker

Остановился на Docker, т.к. виртуальная машина потребляла бы слишком много ресурсов, проверку на другом компьютере организовать теоретически можно, используя, например связку NFS+SSH, но, боюсь, это работало бы слишком медленно.


У Docker тоже были минусы. Вернее один жирный — я ничего не знал про Docker. На Хабре есть вводные статьи. С их помощью на реализацию задумки ушло полтора дня.


Быстрый старт займет буквально несколько минут. Понадобится настроить скрипты и Eclipce.


Скрипты


Понадобятся пять файлов:


run_once.sh
#!/bin/sh
echo "Fetching last timurey/docker-pvs image"
/usr/local/bin/docker pull timurey/docker-pvs:latest
echo "Testing"
/usr/local/bin/docker run -i timurey/docker-pvs echo "Ready to run"

eclipse-pvs.sh
#!/bin/bash

debug()
{
if [ "$debug" == "1" ]; then
    d=$1
    echo $d
fi
}
usage()
{
    echo "usage: eclipse-pvs [[-w <path> -n <name> [-d]]| -h]"
    echo "where args:"
    echo "      -w(--workspace)   <path>    set path to workspace directory"
    echo "      -n(--projectname) <name>    project name in eclipse"
    echo "      -c(--config)      <config>  config descriptor (Debug or Release)"
    echo "      -d(--debug)                 some debuging info"
    echo "      -h(--help)                  show this message"
}

clean ()
{
debug "Clean"
make -f makefile clean
    exit
}

analyze()
{
    debug "running command:"
    debug "/usr/local/bin/docker run --security-opt seccomp:\"""$workspace/docker-pvs/strace.json""\" -v \"""$workspace""\":/root/workspace -i timurey/docker-pvs /root/workspace/docker-pvs/client.sh -n \"""$projectname""\" -c \"""$config""\""
    /usr/local/bin/docker run --security-opt seccomp:"$workspace/docker-pvs/strace.json" -v "$workspace":/root/workspace -i timurey/docker-pvs /root/workspace/docker-pvs/client.sh -n "$projectname" -c "$config"
    exit
}

while [ "$1" != "" ]; do
    case $1 in
        -w | --workspace )      shift
                workspace=$1
                                ;;
        -c | --config )         shift
                config=$1
                                ;;
        -n | --projectname )    shift
                projectname=$1
                                ;;
        -d | --debug )          
                debug=1
                                ;;
        -h | --help )           usage
                                exit
                                ;;
        clean )                 clean
                                exit
    esac
    shift
done

if [ "$workspace" != "" ]; then
    if [ "$projectname" != "" ]; then
        if [ "$config" != "" ]; then
    debug "workspace path: \"$workspace\""
    debug "project name: \"$projectname\""
    debug "config description: \"$config\""
    analyze
        else
            echo "config description is not defined" >&2
            exit
        fi
    else
        echo "project name path is not defined" >&2
        exit
    fi
else
    echo "workspace is not defined" >&2
    exit
fi

client.sh
#!/bin/bash

while [ "$1" != "" ]; do
    case $1 in
        -n | --projectname )    shift
                projectname=$1
                                ;;
        -c | --config )         shift
                config=$1
                                ;;
    esac
    shift
done

if [ "$projectname" != "" ]; then
    TEMPLOG=$(tempfile)
    cd "/root/workspace/$projectname/$config"
    # удаляем ошмётки `strace`, которые могут появиться в некоторых случаях:
    pvs-studio-analyzer trace -- make -f makefile all 2>&1 | sed '/strace: umovestr:/d' -
    pvs-studio-analyzer analyze --compiler arm-none-eabi-gcc -o "$TEMPLOG" --cfg /root/workspace/docker-pvs/pvs-studio.cfg

    # удаляем непонятную строку, которая у меня появляется в выводе конвертера:
    RC=$(plog-converter -t errorfile "$TEMPLOG" | sed '/The documentation for all/d' -)
    rm -f "$TEMPLOG"
    echo "$RC"
fi

strace.json
{
  "defaultAction": "SCMP_ACT_ALLOW",
  "syscalls": [
    {
      "name": "strace",
      "action": "SCMP_ACT_ERRNO"
    }
  ]
}

pvs-studio.cfg
exclude-path = /usr/arm-none-eabi/include
platform = linux64
preprocessor = gcc
analysis-mode = 4
sourcetree-root = /root/workspace

В Eclipse используется директория workspace, в которой хранятся проекты. Создадим внутри неё директорию docker-pvs и сложим туда все вышеуказанные файлы. Делаем исполняемыми скрипты:


$ chmod +x run_once.sh eclipse-pvs.sh client.sh

Eclipse


Будем запускать анализатор во время компиляции. Желательно, что бы в контейнере и в Eclipse использовалась одна версия компилятора. В образе находится версия 5-2016-q3 (от 2016-09-19), так что загружаем и устанавливаем для macOS версию 5-2016-q3 (от 2016-09-28) c сайта launchpad.net


В свойствах проекта и создаем новую конфигурацию на основе Debug


Manage configurations


кликабельно


Затем в опциях новой конфигурации:


1. Снимаем галочку "Use default build command


2. В Build command ставим следующую команду:


${workspace_loc}/docker-pvs/eclipse-pvs.sh -w "${workspace_loc}" -n ${ProjName} -c Debug -d

3. Отмечаем Generate Makefiles automatically


C/C++ Build


кликабельно


Закрываем свойства проекта, делаем активной только что созданную конфигурацию и


?+B


кликабельно


Как это работает.


Команда


${workspace_loc}/docker-pvs/eclipse-pvs -w "${workspace_loc}" -n ${ProjName} -c Debug -d

Запускает наш скрипт и передает в него следующие параметры:


  • -w полный путь до workspace
  • -n имя проекта
  • -c директория, внутри которой будем проводить сборку
  • -d вывод отладочных сообщений скрипта

Скрипт eclipse-pvs.sh после проверки обязательных параметров запускает docker


/usr/local/bin/docker run --security-opt seccomp:"$workspace/docker-pvs/strace.json" -v "$workspace":/root/workspace -i timurey/docker-pvs /root/workspace/docker-pvs/client.sh -n "$projectname" -c "$config"

Здесь параметров чуть больше:


  • --security-opt seccomp: разрешает вызывать функцию strace внутри контейнера (отключена по соображениям безопасности). Подставляется полный путь до файла strace.json
  • -v монтируем директорию workspace из macOS в /root/workspace внутри контейнера (здесь находятся необходимые client.sh и pvs-studio.cfg)
  • -i используем образ timurey/docker-pvs, загруженный с hub.docker.com
  • /root/workspace/docker-pvs/client.sh запускаем скрипт запуска pvs-studio внутри контейнера.

Для тех, кто захочет собрать образ сам:


Dockerfile
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y strace software-properties-common cmake wget     && add-apt-repository ppa:team-gcc-arm-embedded/ppa     && apt-get update && apt-get install -y gcc-arm-embedded
RUN wget http://files.viva64.com/pvs-studio-6.11.20138.1-amd64.deb
RUN dpkg -i pvs-studio-6.11.20138.1-amd64.deb
RUN rm pvs-studio-6.11.20138.1-amd64.deb
RUN echo Asia/Yekaterinburg >/etc/timezone && ln -sf /usr/share/zoneinfo/Asia/Yekaterinburg /etc/localtime && dpkg-reconfigure -f noninteractive tzdata

Вместо заключения


Казалось бы, Docker используют только web разработчики. Но это не так. Docker можно использовать и для разработки C/C++, в том числе под микроконтроллеры.

Поделиться с друзьями
-->

Комментарии (2)


  1. pftbest
    13.12.2016 19:29
    +5

    apt-get update нужно делать в той же RUN строке в которой apt-get install
    Иначе docker закеширует их по отдельности и могут вылезти проблемы.


    1. timurey
      13.12.2016 20:40
      +1

      Благодарю за внимательность. Подправил Dockerfile.