Как Π΄Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ‚Π΅ PVS-Studio Π² Travis CI, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π΅ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ Π½Π° ΠΈΠ³Ρ€ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π½Π° PSP

Как Π΄Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ‚Π΅ PVS-Studio Π² Travis CI, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π΅ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ Π½Π° ΠΈΠ³Ρ€ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π½Π° PSP
Travis CI Π΅ Ρ€Π°Π·ΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° ΡƒΠ΅Π± услуга Π·Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ ΠΈ тСстванС Π½Π° софтуСр, ΠΊΠΎΠΉΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° GitHub ΠΊΠ°Ρ‚ΠΎ хостинг Π½Π° изходния ΠΊΠΎΠ΄. Π’ допълнСниС към Π³ΠΎΡ€Π½ΠΈΡ‚Π΅ Ρ€Π°Π±ΠΎΡ‚Π½ΠΈ сцСнарии ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡ‚Π΅ свои собствСни Π±Π»Π°Π³ΠΎΠ΄Π°Ρ€Π΅Π½ΠΈΠ΅ Π½Π° ΠΎΠ±ΡˆΠΈΡ€Π½ΠΈΡ‚Π΅ ΠΎΠΏΡ†ΠΈΠΈ Π·Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½Π΅. Π’ Ρ‚Π°Π·ΠΈ статия Ρ‰Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°ΠΌΠ΅ Travis CI Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ с PVS-Studio, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ примСрния ΠΊΠΎΠ΄ Π½Π° PPSSPP.

въвСдСниС

Вравис CI Π΅ ΡƒΠ΅Π± услуга Π·Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ ΠΈ тСстванС Π½Π° софтуСр. ОбикновСно сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π°Π΅Π΄Π½ΠΎ с ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ Π·Π° Π½Π΅ΠΏΡ€Π΅ΠΊΡŠΡΠ½Π°Ρ‚Π° интСграция.

PPSSPP - Π•ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ Π½Π° PSP ΠΈΠ³Ρ€ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π°. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π΅ΠΌΡƒΠ»ΠΈΡ€Π° стартиранСто Π½Π° всякакви ΠΈΠ³Ρ€ΠΈ ΠΎΡ‚ дискови изобраТСния, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈ Π·Π° Sony PSP. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π΅ пусната Π½Π° 1 Π½ΠΎΠ΅ΠΌΠ²Ρ€ΠΈ 2012 Π³. PPSSPP Π΅ Π»ΠΈΡ†Π΅Π½Π·ΠΈΡ€Π°Π½ ΠΏΠΎΠ΄ GPL v2. ВсСки ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡ€Π°Π²ΠΈ подобрСния Π½Π° ΠΈΠ·Ρ…ΠΎΠ΄Π΅Π½ ΠΊΠΎΠ΄ Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.

PVS-Π‘Ρ‚ΡƒΠ΄ΠΈΠΎ β€” Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Π½Π° статичСн ΠΊΠΎΠ΄ Π·Π° Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅ Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ ΠΈ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»Π½ΠΈ уязвимости Π² програмния ΠΊΠΎΠ΄. Π’ Ρ‚Π°Π·ΠΈ статия, Π·Π° промяна, Ρ‰Π΅ стартирамС PVS-Studio Π½Π΅ Π»ΠΎΠΊΠ°Π»Π½ΠΎ Π½Π° ΠΌΠ°ΡˆΠΈΠ½Π°Ρ‚Π° Π½Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°, Π° Π² ΠΎΠ±Π»Π°ΠΊΠ° ΠΈ Ρ‰Π΅ Ρ‚ΡŠΡ€ΡΠΈΠΌ Π³Ρ€Π΅ΡˆΠΊΠΈ Π² PPSSPP.

НастройванС Π½Π° Travis CI

Π©Π΅ Π½ΠΈ трябва Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π² GitHub, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ сС Π½Π°ΠΌΠΈΡ€Π° нСобходимият Π½ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ ΠΊΠ»ΡŽΡ‡ Π·Π° PVS-Studio (ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ±Π΅Π½ ΠΊΠ»ΡŽΡ‡ ΠΈΠ»ΠΈ Π±Π΅Π·ΠΏΠ»Π°Ρ‚Π½ΠΎ Π·Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ с ΠΎΡ‚Π²ΠΎΡ€Π΅Π½ ΠΊΠΎΠ΄).

Π”Π° ΠΎΡ‚ΠΈΠ΄Π΅ΠΌ Π½Π° сайта Вравис CI. Π‘Π»Π΅Π΄ ΡƒΠΏΡŠΠ»Π½ΠΎΠΌΠΎΡ‰Π°Π²Π°Π½Π΅ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° вашия Π°ΠΊΠ°ΡƒΠ½Ρ‚ Π² GitHub, Ρ‰Π΅ Π²ΠΈΠ΄ΠΈΠΌ списък с Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°:

Как Π΄Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ‚Π΅ PVS-Studio Π² Travis CI, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π΅ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ Π½Π° ΠΈΠ³Ρ€ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π½Π° PSP
Π—Π° тСста Ρ€Π°Π·ΠΊΠ»ΠΎΠ½ΠΈΡ… PPSSPP.

АктивирамС Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅Ρ‚ΠΎ, ΠΊΠΎΠ΅Ρ‚ΠΎ искамС Π΄Π° ΡΡŠΠ±Π΅Ρ€Π΅ΠΌ:

Как Π΄Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ‚Π΅ PVS-Studio Π² Travis CI, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π΅ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ Π½Π° ΠΈΠ³Ρ€ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π½Π° PSP
Π’ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Travis CI Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·Π³Ρ€Π°Π΄ΠΈ нашия ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, Π·Π°Ρ‰ΠΎΡ‚ΠΎ няма инструкции Π·Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅. Π’Π°ΠΊΠ° Ρ‡Π΅ Π΅ Π²Ρ€Π΅ΠΌΠ΅ Π·Π° конфигурация.

По Π²Ρ€Π΅ΠΌΠ΅ Π½Π° Π°Π½Π°Π»ΠΈΠ·Π° някои ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Ρ‰Π΅ Π½ΠΈ Π±ΡŠΠ΄Π°Ρ‚ ΠΏΠΎΠ»Π΅Π·Π½ΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ»ΡŽΡ‡ΡŠΡ‚ Π·Π° PVS-Studio, ΠΊΠΎΠΉΡ‚ΠΎ Π±ΠΈ Π±ΠΈΠ»ΠΎ Π½Π΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»Π½ΠΎ Π΄Π° сС посочи Π² конфигурационния Ρ„Π°ΠΉΠ». Π’Π°ΠΊΠ° Ρ‡Π΅ Π½Π΅ΠΊΠ° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° срСдата, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ настройкитС Π·Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ Π² Travis CI:

Как Π΄Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ‚Π΅ PVS-Studio Π² Travis CI, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π΅ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ Π½Π° ΠΈΠ³Ρ€ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π½Π° PSP
ИмамС Π½ΡƒΠΆΠ΄Π° ΠΎΡ‚:

  • PVS_USERNAME - потрСбитСлско ΠΈΠΌΠ΅
  • PVS_KEY - ΠΊΠ»ΡŽΡ‡
  • MAIL_USER - ΠΈΠΌΠ΅ΠΉΠ», ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ Π½Π° ΠΎΡ‚Ρ‡Π΅Ρ‚Π°
  • MAIL_PASSWORD - ΠΈΠΌΠ΅ΠΉΠ» ΠΏΠ°Ρ€ΠΎΠ»Π°

ΠŸΠΎΡΠ»Π΅Π΄Π½ΠΈΡ‚Π΅ Π΄Π²Π΅ Π½Π΅ са Π·Π°Π΄ΡŠΠ»ΠΆΠΈΡ‚Π΅Π»Π½ΠΈ. Π’Π΅ Ρ‰Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π·Π° ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ Π½Π° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈΡ‚Π΅ ΠΏΠΎ ΠΏΠΎΡ‰Π°Ρ‚Π°. Ако искатС Π΄Π° разпространитС Π΄ΠΎΠΊΠ»Π°Π΄Π° ΠΏΠΎ Π΄Ρ€ΡƒΠ³ Π½Π°Ρ‡ΠΈΠ½, Π½Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° Π³ΠΈ посочватС.

И Ρ‚Π°ΠΊΠ°, Π΄ΠΎΠ±Π°Π²ΠΈΡ…ΠΌΠ΅ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈΡ‚Π΅ Π½Π° срСдата, ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ сС Π½ΡƒΠΆΠ΄Π°Π΅ΠΌ:

Как Π΄Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ‚Π΅ PVS-Studio Π² Travis CI, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π΅ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ Π½Π° ΠΈΠ³Ρ€ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π½Π° PSP
Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° създадСм Ρ„Π°ΠΉΠ» .travis.yml ΠΈ Π³ΠΎ поставСтС Π² ΠΊΠΎΡ€Π΅Π½Π° Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. PPSSPP Π²Π΅Ρ‡Π΅ имашС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π΅Π½ Ρ„Π°ΠΉΠ» Π·Π° Travis CI, Π½ΠΎ Ρ‚ΠΎΠΉ бСшС Ρ‚Π²ΡŠΡ€Π΄Π΅ голям ΠΈ напълно нСподходящ Π·Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Ρ‚Ρ€ΡΠ±Π²Π°ΡˆΠ΅ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Π΄Π° Π³ΠΎ опростим ΠΈ Π΄Π° оставим само основнитС Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈ.

ΠŸΡŠΡ€Π²ΠΎ, Π½Π΅ΠΊΠ° посочим Π΅Π·ΠΈΠΊΠ°, вСрсията Π½Π° Ubuntu Linux, която искамС Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ във Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π°Ρ‚Π° машина, ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈΡ‚Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π·Π° компилацията:

language: cpp
dist: xenial

addons:
  apt:
    update: true
    packages:
      - ant
      - aria2
      - build-essential
      - cmake
      - libgl1-mesa-dev
      - libglu1-mesa-dev
      - libsdl2-dev
      - pv
      - sendemail
      - software-properties-common
    sources:
      - sourceline: 'ppa:ubuntu-toolchain-r/test'
      - sourceline: 'ppa:ubuntu-sdk-team/ppa'

Всички ΠΈΠ·Π±Ρ€ΠΎΠ΅Π½ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ са Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ ΠΈΠ·ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Π·Π° PPSSPP.

Π‘Π΅Π³Π° посочвамС ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°Ρ‚Π° Π½Π° сглобяванС:

matrix:
  include:
    - os: linux
      compiler: "gcc"
      env: PPSSPP_BUILD_TYPE=Linux PVS_ANALYZE=Yes
    - os: linux
      compiler: "clang"
      env: PPSSPP_BUILD_TYPE=Linux

ΠžΡ‰Π΅ ΠΌΠ°Π»ΠΊΠΎ Π·Π° сСкцията ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°. Π’ Travis CI ΠΈΠΌΠ° Π΄Π²Π° Π½Π°Ρ‡ΠΈΠ½Π° Π·Π° създаванС Π½Π° ΠΎΠΏΡ†ΠΈΠΈ Π·Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅: ΠΏΡŠΡ€Π²ΠΈΡΡ‚ Π΅ Π΄Π° сС посочи списък с ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€ΠΈ, Ρ‚ΠΈΠΏΠΎΠ²Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΈ систСми, ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° срСдата ΠΈ Ρ‚.Π½., слСд ΠΊΠΎΠ΅Ρ‚ΠΎ сС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° ΠΎΡ‚ всички възмоТни ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΈ; Π²Ρ‚ΠΎΡ€ΠΎΡ‚ΠΎ Π΅ ΠΈΠ·Ρ€ΠΈΡ‡Π½ΠΎ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π½Π° ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°Ρ‚Π°. Π Π°Π·Π±ΠΈΡ€Π° сС, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€Π°Ρ‚Π΅ Ρ‚Π΅Π·ΠΈ Π΄Π²Π° ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° ΠΈ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡ‚Π΅ ΡƒΠ½ΠΈΠΊΠ°Π»Π΅Π½ случай ΠΈΠ»ΠΈ, Π½Π°ΠΏΡ€ΠΎΡ‚ΠΈΠ², Π΄Π° Π³ΠΎ ΠΈΠ·ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ сСкцията ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π²Π°ΠΌ. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅Ρ‚Π΅ ΠΏΠΎΠ²Π΅Ρ‡Π΅ Π·Π° Ρ‚ΠΎΠ²Π° Π² Travis CI докумСнтация.

Всичко, ΠΊΠΎΠ΅Ρ‚ΠΎ остава, Π΅ Π΄Π° прСдоставитС спСцифични Π·Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° инструкции Π·Π° сглобяванС:

before_install:
  - travis_retry bash .travis.sh travis_before_install

install:
  - travis_retry bash .travis.sh travis_install

script:
  - bash .travis.sh travis_script

after_success:
  - bash .travis.sh travis_after_success

Travis CI Π²ΠΈ позволява Π΄Π° добавятС свои собствСни ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Π΅Ρ‚Π°ΠΏΠΈ ΠΎΡ‚ ΠΆΠΈΠ²ΠΎΡ‚Π° Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° машина. Π Π°Π·Π΄Π΅Π» ΠΏΡ€Π΅Π΄ΠΈ_инсталиранС сС изпълнява ΠΏΡ€Π΅Π΄ΠΈ инсталиранС Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ. Π’ΠΎΠ³Π°Π²Π° инсталирам, ΠΊΠΎΠ΅Ρ‚ΠΎ слСдва инсталиранСто Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ ΠΎΡ‚ списъка addons.aptΠΊΠΎΠΈΡ‚ΠΎ посочихмС ΠΏΠΎ-Π³ΠΎΡ€Π΅. Π‘Π°ΠΌΠΎΡ‚ΠΎ сглобяванС сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° Π² писмСност. Ако всичко Π΅ ΠΌΠΈΠ½Π°Π»ΠΎ Π΄ΠΎΠ±Ρ€Π΅, Π·Π½Π°Ρ‡ΠΈ Ρ‰Π΅ сС ΠΎΠ·ΠΎΠ²Π΅ΠΌ слСд_успСх (ΠΈΠΌΠ΅Π½Π½ΠΎ Π² Ρ‚ΠΎΠ·ΠΈ Ρ€Π°Π·Π΄Π΅Π» Ρ‰Π΅ ΠΏΡ€ΠΎΠ²Π΅Π΄Π΅ΠΌ статичСн Π°Π½Π°Π»ΠΈΠ·). Π’ΠΎΠ²Π° Π½Π΅ са всички ΡΡ‚ΡŠΠΏΠΊΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Π½ΠΈ, Π°ΠΊΠΎ ΠΈΠΌΠ°Ρ‚Π΅ Π½ΡƒΠΆΠ΄Π° ΠΎΡ‚ ΠΏΠΎΠ²Π΅Ρ‡Π΅, Ρ‚ΠΎΠ³Π°Π²Π° трябва Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°Ρ‚Π΅ Travis CI докумСнтация.

Π—Π° ΠΏΠΎ-лСсно Ρ‡Π΅Ρ‚Π΅Π½Π΅ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡ‚Π΅ бяха поставСни Π² ΠΎΡ‚Π΄Π΅Π»Π΅Π½ скрипт .travis.sh, ΠΊΠΎΠΉΡ‚ΠΎ сС поставя Π² основата Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.

Π’Π°ΠΊΠ° Ρ‡Π΅ ΠΈΠΌΠ°ΠΌΠ΅ слСдния Ρ„Π°ΠΉΠ» .travis.yml:

language: cpp
dist: xenial

addons:
  apt:
    update: true
    packages:
      - ant
      - aria2
      - build-essential
      - cmake
      - libgl1-mesa-dev
      - libglu1-mesa-dev
      - libsdl2-dev
      - pv
      - sendemail
      - software-properties-common
    sources:
      - sourceline: 'ppa:ubuntu-toolchain-r/test'
      - sourceline: 'ppa:ubuntu-sdk-team/ppa'

matrix:
  include:
    - os: linux
      compiler: "gcc"
      env: PVS_ANALYZE=Yes
    - os: linux
      compiler: "clang"

before_install:
  - travis_retry bash .travis.sh travis_before_install

install:
  - travis_retry bash .travis.sh travis_install

script:
  - bash .travis.sh travis_script

after_success:
  - bash .travis.sh travis_after_success

ΠŸΡ€Π΅Π΄ΠΈ Π΄Π° инсталирамС ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈΡ‚Π΅, Ρ‰Π΅ Π°ΠΊΡ‚ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€Π°ΠΌΠ΅ ΠΏΠΎΠ΄ΠΌΠΎΠ΄ΡƒΠ»ΠΈΡ‚Π΅. Π’ΠΎΠ²Π° Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ Π½Π° PPSSPP. НСка Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΡŠΡ€Π²Π°Ρ‚Π° функция към .travis.sh (ΠΎΠ±ΡŠΡ€Π½Π΅Ρ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΠ΅Ρ‚ΠΎ):

travis_before_install() {
  git submodule update --init --recursive
}

Π‘Π΅Π³Π° стигамС Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ Π΄ΠΎ настройката Π½Π° Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎΡ‚ΠΎ стартиранС Π½Π° PVS-Studio Π² Travis CI. ΠŸΡŠΡ€Π²ΠΎ трябва Π΄Π° инсталирамС ΠΏΠ°ΠΊΠ΅Ρ‚Π° PVS-Studio Π² систСмата:

travis_install() {
  if [ "$CXX" = "g++" ]; then
    sudo apt-get install -qq g++-4.8
  fi
  
  if [ "$PVS_ANALYZE" = "Yes" ]; then
    wget -q -O - https://files.viva64.com/etc/pubkey.txt 
      | sudo apt-key add -
    sudo wget -O /etc/apt/sources.list.d/viva64.list 
      https://files.viva64.com/etc/viva64.list  
    
    sudo apt-get update -qq
    sudo apt-get install -qq pvs-studio 
                             libio-socket-ssl-perl 
                             libnet-ssleay-perl
  fi
    
  download_extract 
    "https://cmake.org/files/v3.6/cmake-3.6.2-Linux-x86_64.tar.gz" 
    cmake-3.6.2-Linux-x86_64.tar.gz
}

Π’ Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° функцията travis_install Π½ΠΈΠ΅ инсталирамС ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€ΠΈΡ‚Π΅, ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ сС Π½ΡƒΠΆΠ΄Π°Π΅ΠΌ, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° срСдата. Π’ΠΎΠ³Π°Π²Π°, Π°ΠΊΠΎ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°Ρ‚Π° $PVS_ANALYZE ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° стойност Π”Π° (посочили смС Π³ΠΎ Π² Ρ€Π°Π·Π΄Π΅Π»Π° Околна срСда ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° конфигурацията Π½Π° ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°Ρ‚Π° Π·Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅), инсталирамС ΠΏΠ°ΠΊΠ΅Ρ‚Π° pvs-студио. Π’ допълнСниС към Ρ‚ΠΎΠ²Π° са посочСни ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ libio-socket-ssl-perl ΠΈ libnet-ssleay-perl, ΠΎΠ±Π°Ρ‡Π΅, Ρ‚Π΅ са Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ Π½Π° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈΡ‚Π΅ ΠΏΠΎ ΠΏΠΎΡ‰Π°Ρ‚Π°, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π½Π΅ са Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ, Π°ΠΊΠΎ стС ΠΈΠ·Π±Ρ€Π°Π»ΠΈ Π΄Ρ€ΡƒΠ³ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π·Π° доставянС Π½Π° вашия ΠΎΡ‚Ρ‡Π΅Ρ‚.

Ѐункция изтСглянС_Скстракт изтСгля ΠΈ Ρ€Π°Π·ΠΎΠΏΠ°ΠΊΠΎΠ²Π° посочСния Π°Ρ€Ρ…ΠΈΠ²:

download_extract() {
  aria2c -x 16 $1 -o $2
  tar -xf $2
}

Π’Ρ€Π΅ΠΌΠ΅ Π΅ Π΄Π° сглобим ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. Π’ΠΎΠ²Π° сС случва Π² сСкцията писмСност:

travis_script() {
  if [ -d cmake-3.6.2-Linux-x86_64 ]; then
    export PATH=$(pwd)/cmake-3.6.2-Linux-x86_64/bin:$PATH
  fi
  
  CMAKE_ARGS="-DHEADLESS=ON ${CMAKE_ARGS}"
  if [ "$PVS_ANALYZE" = "Yes" ]; then
    CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
  fi
  cmake $CMAKE_ARGS CMakeLists.txt
  make
}

Π’ΡΡŠΡ‰Π½ΠΎΡΡ‚ Ρ‚ΠΎΠ²Π° Π΅ опростСна ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½Π° конфигурация, с ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π½Π° Ρ‚Π΅Π·ΠΈ Ρ€Π΅Π΄ΠΎΠ²Π΅:

if [ "$PVS_ANALYZE" = "Yes" ]; then
  CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi

Π’ Ρ‚ΠΎΠ·ΠΈ Ρ€Π°Π·Π΄Π΅Π» ΠΎΡ‚ ΠΊΠΎΠ΄Π°, ΠΊΠΎΠΉΡ‚ΠΎ смС Π·Π°Π΄Π°Π»ΠΈ Π·Π° cmake Ρ„Π»Π°Π³ Π·Π° СкспортиранС Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° компилация. Π’ΠΎΠ²Π° Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π° Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Π½Π° статичСн ΠΊΠΎΠ΄. ΠŸΠΎΠ²Π΅Ρ‡Π΅ Π·Π° Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅Ρ‚Π΅ Π² статията β€œΠšΠ°ΠΊ Π΄Π° стартиратС PVS-Studio Π½Π° Linux ΠΈ macOS".

Ако сглобяванСто Π΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Ρ‚ΠΎΠ³Π°Π²Π° стигамС Π΄ΠΎ слСд_успСх, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°ΠΌΠ΅ статичСн Π°Π½Π°Π»ΠΈΠ·:

travis_after_success() {
  if [ "$PVS_ANALYZE" = "Yes" ]; then
    pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
    pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic 
                                    -o PVS-Studio-${CC}.log 
                                    --disableLicenseExpirationCheck
    
    plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html
    sendemail -t [email protected] 
              -u "PVS-Studio $CC report, commit:$TRAVIS_COMMIT" 
              -m "PVS-Studio $CC report, commit:$TRAVIS_COMMIT" 
              -s smtp.gmail.com:587 
              -xu $MAIL_USER 
              -xp $MAIL_PASSWORD 
              -o tls=yes 
              -f $MAIL_USER 
              -a PVS-Studio-${CC}.log PVS-Studio-${CC}.html
  fi
}

НСка Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠΎ-ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ слСднитС Ρ€Π΅Π΄ΠΎΠ²Π΅:

pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic 
                                -o PVS-Studio-${CC}.log 
                                --disableLicenseExpirationCheck
plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html

ΠŸΡŠΡ€Π²ΠΈΡΡ‚ Ρ€Π΅Π΄ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° Ρ„Π°ΠΉΠ» с Π»ΠΈΡ†Π΅Π½Π· ΠΎΡ‚ потрСбитСлското ΠΈΠΌΠ΅ ΠΈ ΠΊΠ»ΡŽΡ‡Π°, ΠΊΠΎΠΈΡ‚ΠΎ посочихмС Π² самото Π½Π°Ρ‡Π°Π»ΠΎ ΠΏΡ€ΠΈ настройванСто Π½Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈΡ‚Π΅ Π½Π° срСдата Travis CI.

Вторият Ρ€Π΅Π΄ стартира Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ Π°Π½Π°Π»ΠΈΠ·Π°. Π€Π»Π°Π³ -j Π·Π°Π΄Π°Π²Π° броя Π½Π° Π½ΠΈΡˆΠΊΠΈΡ‚Π΅ Π·Π° Π°Π½Π°Π»ΠΈΠ·, Ρ„Π»Π°Π³ -Π» ΠΏΠΎΠΊΠ°Π·Π²Π° Π»ΠΈΡ†Π΅Π½Π·, Ρ„Π»Π°Π³ -ΠΎ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π° Ρ„Π°ΠΉΠ»Π° Π·Π° ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° рСгистрационни Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅ ΠΈ Ρ„Π»Π°Π³Π° -disableLicenseExpirationCheck изисква сС Π·Π° ΠΏΡ€ΠΎΠ±Π½ΠΈ вСрсии, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ pvs-studio-Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Ρ‰Π΅ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅Π΄ΠΈ потрСбитСля, Ρ‡Π΅ Π»ΠΈΡ†Π΅Π½Π·ΡŠΡ‚ Π΅ Π½Π° ΠΏΡŠΡ‚ Π΄Π° ΠΈΠ·Ρ‚Π΅Ρ‡Π΅. Π—Π° Π΄Π° ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Ρ‚ΠΎΠ²Π° Π΄Π° сС случи, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° посочитС Ρ‚ΠΎΠ·ΠΈ Ρ„Π»Π°Π³.

РСгистрационният Ρ„Π°ΠΉΠ» ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° Π½Π΅ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π΅Π½ ΠΈΠ·Ρ…ΠΎΠ΄, ΠΊΠΎΠΉΡ‚ΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅Π½ Π±Π΅Π· ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°Π½Π΅, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ ΠΏΡŠΡ€Π²ΠΎ трябва Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ Ρ„Π°ΠΉΠ»Π° Ρ‡Π΅Ρ‚ΠΈΠΌ. НСка ΠΏΡ€Π΅ΠΊΠ°Ρ€Π°ΠΌΠ΅ Ρ‚Ρ€ΡƒΠΏΠΈΡ‚Π΅ plog-ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΎΡ€, Π° ΠΈΠ·Ρ…ΠΎΠ΄ΡŠΡ‚ Π΅ html Ρ„Π°ΠΉΠ».

Π’ Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π΅ΡˆΠΈΡ… Π΄Π° ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°ΠΌ ΠΎΡ‚Ρ‡Π΅Ρ‚ΠΈ ΠΏΠΎ ΠΏΠΎΡ‰Π°Ρ‚Π° с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° Π˜Π·ΠΏΡ€Π°Ρ‚Π΅Ρ‚Π΅ ΠΈΠΌΠ΅ΠΉΠ».

Π’ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Π½Π° Ρ‚ΠΎΠ²Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ…ΠΌΠ΅ слСдния Ρ„Π°ΠΉΠ» .travis.sh:

#/bin/bash

travis_before_install() {
  git submodule update --init --recursive
}

download_extract() {
  aria2c -x 16 $1 -o $2
  tar -xf $2
}

travis_install() {
  if [ "$CXX" = "g++" ]; then
    sudo apt-get install -qq g++-4.8
  fi
  
  if [ "$PVS_ANALYZE" = "Yes" ]; then
    wget -q -O - https://files.viva64.com/etc/pubkey.txt 
      | sudo apt-key add -
    sudo wget -O /etc/apt/sources.list.d/viva64.list 
      https://files.viva64.com/etc/viva64.list  
    
    sudo apt-get update -qq
    sudo apt-get install -qq pvs-studio 
                             libio-socket-ssl-perl 
                             libnet-ssleay-perl
  fi
    
  download_extract 
    "https://cmake.org/files/v3.6/cmake-3.6.2-Linux-x86_64.tar.gz" 
    cmake-3.6.2-Linux-x86_64.tar.gz
}
travis_script() {
  if [ -d cmake-3.6.2-Linux-x86_64 ]; then
    export PATH=$(pwd)/cmake-3.6.2-Linux-x86_64/bin:$PATH
  fi
  
  CMAKE_ARGS="-DHEADLESS=ON ${CMAKE_ARGS}"
  if [ "$PVS_ANALYZE" = "Yes" ]; then
    CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
  fi
  cmake $CMAKE_ARGS CMakeLists.txt
  make
}
travis_after_success() {
  if [ "$PVS_ANALYZE" = "Yes" ]; then
    pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
    pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic 
                                    -o PVS-Studio-${CC}.log 
                                    --disableLicenseExpirationCheck
    
    plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html
    sendemail -t [email protected] 
              -u "PVS-Studio $CC report, commit:$TRAVIS_COMMIT" 
              -m "PVS-Studio $CC report, commit:$TRAVIS_COMMIT" 
              -s smtp.gmail.com:587 
              -xu $MAIL_USER 
              -xp $MAIL_PASSWORD 
              -o tls=yes 
              -f $MAIL_USER 
              -a PVS-Studio-${CC}.log PVS-Studio-${CC}.html
  fi
}
set -e
set -x

$1;

Π‘Π΅Π³Π° Π΅ Π²Ρ€Π΅ΠΌΠ΅ Π΄Π° ΠΈΠ·ΠΏΡ€Π°Ρ‚ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ‚Π΅ Π² git Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅Ρ‚ΠΎ, слСд ΠΊΠΎΠ΅Ρ‚ΠΎ Travis CI Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ Ρ‰Π΅ стартира компилацията. Π©Ρ€Π°ΠΊΠ½Π΅Ρ‚Π΅ Π²ΡŠΡ€Ρ…Ρƒ β€žppssppβ€œ, Π·Π° Π΄Π° ΠΎΡ‚ΠΈΠ΄Π΅Ρ‚Π΅ Π½Π° ΠΎΡ‚Ρ‡Π΅Ρ‚ΠΈΡ‚Π΅ Π·Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅:

Как Π΄Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ‚Π΅ PVS-Studio Π² Travis CI, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π΅ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ Π½Π° ΠΈΠ³Ρ€ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π½Π° PSP
Π©Π΅ Π²ΠΈΠ΄ΠΈΠΌ ΠΏΡ€Π΅Π³Π»Π΅Π΄ Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° компилация:

Как Π΄Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ‚Π΅ PVS-Studio Π² Travis CI, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π΅ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ Π½Π° ΠΈΠ³Ρ€ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π½Π° PSP
Ако ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΠΈΠΌΠ΅ΠΉΠ» с Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈΡ‚Π΅ ΠΎΡ‚ статичния Π°Π½Π°Π»ΠΈΠ·. Π Π°Π·Π±ΠΈΡ€Π° сС, ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅Ρ‚ΠΎ ΠΏΠΎ ΠΏΠΎΡ‰Π°Ρ‚Π° Π½Π΅ Π΅ СдинствСният Π½Π°Ρ‡ΠΈΠ½ Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΎΡ‚Ρ‡Π΅Ρ‚. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΈΠ·Π±Π΅Ρ€Π΅Ρ‚Π΅ всСки ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π° изпълнСниС. Но Π΅ Π²Π°ΠΆΠ½ΠΎ Π΄Π° Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Π΅ слСд ΠΊΠ°Ρ‚ΠΎ компилацията ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡ΠΈ, няма Π΄Π° Π΅ възмоТСн Π΄ΠΎΡΡ‚ΡŠΠΏ Π΄ΠΎ Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅Ρ‚Π΅ Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π°Ρ‚Π° машина.

РСзюмС Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈΡ‚Π΅

УспСшно Π·Π°Π²ΡŠΡ€ΡˆΠΈΡ…ΠΌΠ΅ Π½Π°ΠΉ-Ρ‚Ρ€ΡƒΠ΄Π½Π°Ρ‚Π° част. Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° сС ΡƒΠ²Π΅Ρ€ΠΈΠΌ, Ρ‡Π΅ всичкитС Π½ΠΈ усилия си заслуТават. НСка Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ някои интСрСсни Ρ‚ΠΎΡ‡ΠΊΠΈ ΠΎΡ‚ Π΄ΠΎΠΊΠ»Π°Π΄Π° Π·Π° статичСн Π°Π½Π°Π»ΠΈΠ·, ΠΊΠΎΠΉΡ‚ΠΎ ΠΌΠΈ Π΄ΠΎΠΉΠ΄Π΅ ΠΏΠΎ ΠΏΠΎΡ‰Π°Ρ‚Π° (Π½Π΅ Π½Π°ΠΏΡ€Π°Π·Π½ΠΎ Π³ΠΎ посочих).

Опасна оптимизация

void sha1( unsigned char *input, int ilen, unsigned char output[20] )
{
  sha1_context ctx;

  sha1_starts( &ctx );
  sha1_update( &ctx, input, ilen );
  sha1_finish( &ctx, output );

  memset( &ctx, 0, sizeof( sha1_context ) );
}

PVS-Studio ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅: V597 ΠšΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€ΡŠΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·Ρ‚Ρ€ΠΈΠ΅ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° функцията 'memset', ΠΊΠΎΠ΅Ρ‚ΠΎ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° изчистванС Π½Π° Π±ΡƒΡ„Π΅Ρ€Π° 'sum'. Ѐункцията RtlSecureZeroMemory() трябва Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΠΈΠ·Ρ‚Ρ€ΠΈΠ²Π°Π½Π΅ Π½Π° Π»ΠΈΡ‡Π½ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ. sha1.cpp 325

Π’Π°Π·ΠΈ част ΠΎΡ‚ ΠΊΠΎΠ΄Π° сС Π½Π°ΠΌΠΈΡ€Π° Π² ΠΌΠΎΠ΄ΡƒΠ»Π° Π·Π° Π·Π°Ρ‰ΠΈΡ‚Π΅Π½ΠΎ Ρ…Π΅ΡˆΠΈΡ€Π°Π½Π΅, Π½ΠΎ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° сСриозСн пропуск Π² сигурността (CWE-14). НСка Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ списъка с асСмблиранС, ΠΊΠΎΠΉΡ‚ΠΎ сС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° ΠΏΡ€ΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° вСрсията Π·Π° отстраняванС Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ:

; Line 355
  mov r8d, 20
  xor edx, edx
  lea rcx, QWORD PTR sum$[rsp]
  call memset
; Line 356

Всичко Π΅ изрядно ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π° мСмСсСт сС изпълнява, ΠΊΠ°Ρ‚ΠΎ ΠΏΠΎ Ρ‚ΠΎΠ·ΠΈ Π½Π°Ρ‡ΠΈΠ½ прСзаписва Π²Π°ΠΆΠ½ΠΈ Π΄Π°Π½Π½ΠΈ Π² RAM, Π½ΠΎ всС ΠΎΡ‰Π΅ Π½Π΅ сС Ρ€Π°Π΄Π²Π°ΠΉΡ‚Π΅. НСка Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ списъка Π·Π° сглобяванС Π½Π° вСрсията Release с оптимизация:

; 354  :
; 355  :  memset( sum, 0, sizeof( sum ) );
; 356  :}

ΠšΠ°ΠΊΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π²ΠΈΠ΄ΠΈ ΠΎΡ‚ листинга, ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€ΡŠΡ‚ Π΅ ΠΏΡ€Π΅Π½Π΅Π±Ρ€Π΅Π³Π½Π°Π» ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ мСмСсСт. Π’ΠΎΠ²Π° сС дълТи Π½Π° Ρ„Π°ΠΊΡ‚Π°, Ρ‡Π΅ във функцията sha1 слСд ΠΎΠ±Π°ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ мСмСсСт няма ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΏΡ€Π΅ΠΏΡ€Π°Ρ‚ΠΊΠΈ към структурата ctx. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»Π½ΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€ΡŠΡ‚ Π½Π΅ Π²ΠΈΠΆΠ΄Π° смисъл Π΄Π° Π³ΡƒΠ±ΠΈ процСсорно Π²Ρ€Π΅ΠΌΠ΅ Π·Π° прСзаписванС Π½Π° ΠΏΠ°ΠΌΠ΅Ρ‚, която Π½Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π² Π±ΡŠΠ΄Π΅Ρ‰Π΅. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΊΠΎΡ€ΠΈΠ³ΠΈΡ€Π°Ρ‚Π΅ Ρ‚ΠΎΠ²Π°, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ функцията RtlSecureZeroMemory ΠΈΠ»ΠΈ сходна Π½Π° нСя.

вярна:

void sha1( unsigned char *input, int ilen, unsigned char output[20] )
{
  sha1_context ctx;

  sha1_starts( &ctx );
  sha1_update( &ctx, input, ilen );
  sha1_finish( &ctx, output );

  RtlSecureZeroMemory(&ctx, sizeof( sha1_context ) );
} 

Излишно сравнСниС

static u32 sceAudioOutputPannedBlocking
             (u32 chan, int leftvol, int rightvol, u32 samplePtr) {
  int result = 0;
  // For some reason, this is the only one that checks for negative.
  if (leftvol > 0xFFFF || rightvol > 0xFFFF || leftvol < 0 || rightvol < 0) {
    ....
  } else {
    if (leftvol >= 0) {
      chans[chan].leftVolume = leftvol;
    }
    if (rightvol >= 0) {
      chans[chan].rightVolume = rightvol;
    }
    chans[chan].sampleAddress = samplePtr;
    result = __AudioEnqueue(chans[chan], chan, true);
  }
}

PVS-Studio ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅: V547 Π˜Π·Ρ€Π°Π·ΡŠΡ‚ β€žleftvol >= 0β€œ Π²ΠΈΠ½Π°Π³ΠΈ Π΅ Π²Π΅Ρ€Π΅Π½. sceAudio.cpp 120

ΠžΠ±ΡŠΡ€Π½Π΅Ρ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΊΠ»ΠΎΠ½Π° else Π·Π° ΠΏΡŠΡ€Π²ΠΈΡ if. ΠšΠΎΠ΄ΡŠΡ‚ Ρ‰Π΅ бъдС изпълнСн само Π°ΠΊΠΎ са изпълнСни всички условия leftvol > 0xFFFF || ΠΏΡ€Π°Π² Π·Π²ΡƒΠΊ > 0xFFFF || ляв ΠΎΠ±Π΅ΠΌ < 0 || ΠΏΡ€Π°Π² ΠΎΠ±Π΅ΠΌ < 0 Ρ‰Π΅ сС ΠΎΠΊΠ°ΠΆΠ΅ нСвярно. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»Π½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ слСднитС Ρ‚Π²ΡŠΡ€Π΄Π΅Π½ΠΈΡ, ΠΊΠΎΠΈΡ‚ΠΎ Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ Π²Π΅Ρ€Π½ΠΈ Π·Π° ΠΊΠ»ΠΎΠ½ else: ляв ΠΎΠ±Π΅ΠΌ <= 0xFFFF, ΠΏΡ€Π°Π² ΠΎΠ±Π΅ΠΌ <= 0xFFFF, ляв ΠΎΠ±Π΅ΠΌ >= 0 ΠΈ ΠΏΡ€Π°Π² ΠΎΠ±Π΅ΠΌ >= 0. ΠžΠ±ΡŠΡ€Π½Π΅Ρ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° послСднитС Π΄Π²Π΅ Ρ‚Π²ΡŠΡ€Π΄Π΅Π½ΠΈΡ. Има Π»ΠΈ смисъл Π΄Π° сС провСрява ΠΊΠΎΠ΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡ‚ΠΎ условиС Π·Π° ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Ρ‚ΠΎΠ·ΠΈ ΠΊΠΎΠ΄?

Π’Π°ΠΊΠ° Ρ‡Π΅ ΠΌΠΎΠΆΠ΅ΠΌ бСзопасно Π΄Π° ΠΏΡ€Π΅ΠΌΠ°Ρ…Π½Π΅ΠΌ Ρ‚Π΅Π·ΠΈ условни ΠΈΠ·Ρ€Π°Π·ΠΈ:

static u32 sceAudioOutputPannedBlocking
(u32 chan, int leftvol, int rightvol, u32 samplePtr) {
  int result = 0;
  // For some reason, this is the only one that checks for negative.
  if (leftvol > 0xFFFF || rightvol > 0xFFFF || leftvol < 0 || rightvol < 0) {
    ....
  } else {
    chans[chan].leftVolume = leftvol;
    chans[chan].rightVolume = rightvol;

    chans[chan].sampleAddress = samplePtr;
    result = __AudioEnqueue(chans[chan], chan, true);
  }
}

Π”Ρ€ΡƒΠ³ сцСнарий. Има някакъв Π²ΠΈΠ΄ Π³Ρ€Π΅ΡˆΠΊΠ°, скрита Π·Π°Π΄ Ρ‚Π΅Π·ΠΈ излишни условия. МоТС Π±ΠΈ Π½Π΅ са ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠ»ΠΈ Ρ‚ΠΎΠ²Π°, ΠΊΠΎΠ΅Ρ‚ΠΎ сС изисква.

Ctrl+C Ctrl+V ΠΎΡ‚Π²Ρ€ΡŠΡ‰Π° Π½Π° ΡƒΠ΄Π°Ρ€Π°

static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
  if (!Memory::IsValidAddress(psmfData) ||
      !Memory::IsValidAddress(psmfData)) {
    return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
  }
  ....
}

V501 Има ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½ΠΈ ΠΏΠΎΠ΄ΠΈΠ·Ρ€Π°Π·ΠΈ '!Memory::IsValidAddress(psmfData)' отляво ΠΈ отдясно Π½Π° '||' ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€. scePsmf.cpp 703

ΠžΠ±ΡŠΡ€Π½Π΅Ρ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Ρ‡Π΅ΠΊΠ° Π²ΡŠΡ‚Ρ€Π΅ if. НС мислитС Π»ΠΈ, Ρ‡Π΅ Π΅ странно, Ρ‡Π΅ провСрявамС Π΄Π°Π»ΠΈ адрСса Π΅ Π²Π°Π»ΠΈΠ΄Π΅Π½? psmfData, Π΄Π²ΠΎΠΉΠ½ΠΎ ΠΏΠΎΠ²Π΅Ρ‡Π΅? Π’Π°ΠΊΠ° Ρ‡Π΅ Ρ‚ΠΎΠ²Π° ΠΌΠΈ сС струва странно... Π’ΡΡŠΡ‰Π½ΠΎΡΡ‚ Ρ‚ΠΎΠ²Π°, Ρ€Π°Π·Π±ΠΈΡ€Π° сС, Π΅ ΠΏΠ΅Ρ‡Π°Ρ‚Π½Π° Π³Ρ€Π΅ΡˆΠΊΠ° ΠΈ идСята бСшС Π΄Π° сС провСрят ΠΈ Π΄Π²Π°Ρ‚Π° Π²Ρ…ΠΎΠ΄Π½ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€Π°.

ΠŸΡ€Π°Π²ΠΈΠ»Π΅Π½ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚:

static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
  if (!Memory::IsValidAddress(psmfStruct) ||
      !Memory::IsValidAddress(psmfData)) {
    return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
  }
  ....
}

Π—Π°Π±Ρ€Π°Π²Π΅Π½Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°

extern void ud_translate_att(
  int size = 0;
  ....
  if (size == 8) {
    ud_asmprintf(u, "b");
  } else if (size == 16) {
    ud_asmprintf(u, "w");
  } else if (size == 64) {
    ud_asmprintf(u, "q");
  }
  ....
}

PVS-Studio ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅: V547 Π˜Π·Ρ€Π°Π·ΡŠΡ‚ 'size == 8' Π²ΠΈΠ½Π°Π³ΠΈ Π΅ false. syn-att.c 195

Π’Π°Π·ΠΈ Π³Ρ€Π΅ΡˆΠΊΠ° сС Π½Π°ΠΌΠΈΡ€Π° Π² ΠΏΠ°ΠΏΠΊΠ°Ρ‚Π° Π²ΡŠΡ‚Ρ€, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ подходящо Π·Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, Π½ΠΎ Π³Ρ€Π΅ΡˆΠΊΠ°Ρ‚Π° бСшС ΠΎΡ‚ΠΊΡ€ΠΈΡ‚Π° ΠΏΡ€Π΅Π΄ΠΈ Π΄Π° я Π·Π°Π±Π΅Π»Π΅ΠΆΠ°, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Ρ€Π΅ΡˆΠΈΡ… Π΄Π° я оставя. Π’ ΠΊΡ€Π°ΠΉΠ½Π° смСтка Ρ‚Π°Π·ΠΈ статия Π½Π΅ Π΅ Π·Π° ΠΏΡ€Π΅Π³Π»Π΅Π΄ Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ, Π° Π·Π° интСграция с Travis CI ΠΈ Π½Π΅ Π΅ ΠΈΠ·Π²ΡŠΡ€ΡˆΠ΅Π½Π° конфигурация Π½Π° Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°.

ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ² Ρ€Π°Π·ΠΌΠ΅Ρ€ сС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π° ΠΎΡ‚ константа, Π½ΠΎ ΠΈΠ·ΠΎΠ±Ρ‰ΠΎ Π½Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π² ΠΊΠΎΠ΄Π°, Ρ‡Π°ΠΊ Π΄ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° if, ΠΊΠΎΠ΅Ρ‚ΠΎ, Ρ€Π°Π·Π±ΠΈΡ€Π° сС, Π΄Π°Π²Π° Ρ„Π°Π»ΡˆΠΈΠ² Π΄ΠΎΠΊΠ°Ρ‚ΠΎ провСрявамС условията, Π·Π°Ρ‰ΠΎΡ‚ΠΎ, ΠΊΠ°ΠΊΡ‚ΠΎ си спомнямС, Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ€Π°Π²Π½ΠΎ Π½Π° Π½ΡƒΠ»Π°. ΠŸΠΎΡΠ»Π΅Π΄Π²Π°Ρ‰ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡΡŠΡ‰ΠΎ нямат смисъл.

ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ Π°Π²Ρ‚ΠΎΡ€ΡŠΡ‚ Π½Π° кодовия Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ Π΅ Π·Π°Π±Ρ€Π°Π²ΠΈΠ» Π΄Π° ΠΏΡ€Π΅Π·Π°ΠΏΠΈΡˆΠ΅ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°Ρ‚Π° Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡ€Π΅Π΄ΠΈ Ρ‚ΠΎΠ²Π°.

Π‘ΠΏΠΈΡ€Π°Π½Π΅

ВСроятно Ρ‚ΡƒΠΊ Ρ‰Π΅ ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡ΠΈΠΌ с Π³Ρ€Π΅ΡˆΠΊΠΈΡ‚Π΅. Π¦Π΅Π»Ρ‚Π° Π½Π° Ρ‚Π°Π·ΠΈ статия Π΅ Π΄Π° дСмонстрира Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° Π½Π° PVS-Studio ΡΡŠΠ²ΠΌΠ΅ΡΡ‚Π½ΠΎ с Travis CI, Π° Π½Π΅ Π΄Π° Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° възмоТно Π½Π°ΠΉ-Π·Π°Π΄ΡŠΠ»Π±ΠΎΡ‡Π΅Π½ΠΎ. Ако искатС ΠΏΠΎ-Π³ΠΎΠ»Π΅ΠΌΠΈ ΠΈ ΠΏΠΎ-красиви Π³Ρ€Π΅ΡˆΠΊΠΈ, Π²ΠΈΠ½Π°Π³ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΈΠΌ сС Π²ΡŠΠ·Ρ…ΠΈΡ‰Π°Π²Π°Ρ‚Π΅ Ρ‚ΡƒΠΊ :).

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π˜Π·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΡƒΠ΅Π± услуги Π·Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ Π·Π°Π΅Π΄Π½ΠΎ с ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°Ρ‚Π° Π½Π° ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π°Π»Π΅Π½ Π°Π½Π°Π»ΠΈΠ· Π²ΠΈ позволява Π΄Π° ΠΎΡ‚ΠΊΡ€ΠΈΠ΅Ρ‚Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ Π²Π΅Π΄Π½Π°Π³Π° слСд сливанСто Π½Π° ΠΊΠΎΠ΄. Π•Π΄Π½Π° компилация ΠΎΠ±Π°Ρ‡Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π΅ Π΅ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½Π°, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ настройката Π½Π° тСстванС Π·Π°Π΅Π΄Π½ΠΎ със статичСн Π°Π½Π°Π»ΠΈΠ· Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Ρ‰Π΅ ΠΏΠΎΠ΄ΠΎΠ±Ρ€ΠΈ качСството Π½Π° ΠΊΠΎΠ΄Π°.

ПолСзни Π²Ρ€ΡŠΠ·ΠΊΠΈ

Как Π΄Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Ρ‚Π΅ PVS-Studio Π² Travis CI, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π΅ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ Π½Π° ΠΈΠ³Ρ€ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π½Π° PSP

Ако искатС Π΄Π° сподСлитС Ρ‚Π°Π·ΠΈ статия с англоговоряща аудитория, моля, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅ Π²Ρ€ΡŠΠ·ΠΊΠ°Ρ‚Π° Π·Π° ΠΏΡ€Π΅Π²ΠΎΠ΄: Максим ЗвягинцСв. Как Π΄Π° настроитС PVS-Studio Π² Travis CI, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Π΅ΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€Π° Π½Π° ΠΈΠ³Ρ€ΠΎΠ²Π°Ρ‚Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π½Π° PSP.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€