Ostatnio pisałem o walce z konfiguracją Travis-CI. Po kolejnych 30 próbach w końcu udało mi się go skonfigurować tak jak chciałem. Przy okazji musiałem pokonać kilka problemów, które opiszę w tym poście.

Środowisko builda

W poprzednim wpisie już poruszałem ten temat. Wtedy myślałem, że muszę użyć ustawień:

sudo: required
dist: trusty

Jednak się myliłem. Okazuje się, że przy ustawieniu sudo: required maszyna działa wolniej. Skutek był taki, że build toolchaina nie wyrabiał się w 50 minut. Taki sam efekt był na dystrybucji Trusty i Precise. Ustawienie:

sudo: false
dist: trusty

Odrzuciłem już poprzednio ze względu na ograniczenie do 500MB RAM. Zostało więc domyślne ustawienie sudo: false z domyślną dystrybucją Precise. W tym wypadku problemem była stara wersja gcc nie wspierająca standardu C++11.

Aktualizacja gcc

Domyślna wersja gcc na Ubuntu Precise to 4.6, która nie wspiera nowszych standardów C++. Pierwszym sposobem na rozwiązanie tego problemu było doinstalowanie nowszych wersji za pomocą apt-get. W tym celu do pliku .travis.yml dodałem linie:

addons:
  apt:
    packages:
      - gcc-4.8
      - g++-4.8

Niestety nie jest to wystarczające. Nowsze gcc się nie instaluje. Aby to naprawić należało jeszcze dodać repozytorium, z którego apt-get miał wziąć nowe wersje gcc:

addons:
  apt:
    sources:
      - ubuntu-toolchain-r-test
    packages:
      - gcc-4.8
      - g++-4.8

Dzięki temu udało się zainstalować nowszą wersję gcc, jednak system dalej używa starej wersji jako domyślnej. Aby mu podmienić wersje należy użyć komendy update-alternatives, która wymaga uprawnień sudo, które z kolei nie mogą być włączone aby przechodził build toolchaina. Mamy więc deadlocka.

Aby obejść ten problem wykorzystałem zmienną środowiskową TRAVIS=true ustawianą w travisowym buildzie. W makefile dodałem więc linie:

ifeq ($(TRAVIS), true)
CC := gcc-4.8
CPP := g++-4.8
AR := ar
else
CC := gcc
CPP := g++
AR := ar
endif

Dzięki temu lokalnie wykorzystywane jest standardowe gcc, a w Travisie gcc-4.8.

Zmienne środowiskowe

Travis udostępnia zestaw zmiennych środowiskowych, których pełny spis jest dostępny pod linkiem. Te zmienne były rozwiązaniem problemu jaki miałem z wersjami gcc, ale oczywiście były także źródłem innych problemów.

W Travisie zmienne środowiskowe nie są zapamiętywane pomiędzy wywołaniami skryptu. Oznacza to, że jeśli w skrypcie instalującym toolchaina dodałem go do zmiennej PATH, wywołany jako następny make już ich nie widzi. Na szczęście komendy wywołane bezpośrednio z pliku .travis.yml modyfikują zmienne środowiskowe tak, żeby były widoczne w skryptach. Rozwiązaniem tego problemu było dodanie do pliku konfiguracyjnego linii:

script:
script:
  - chmod +x scripts/install_bleeding_edge_toolchain.sh
  - ./scripts/install_bleeding_edge_toolchain.sh
  - cd ${HOME}/toolchains/arm-none-eabi-gcc-6.3.0-*/bin; export PATH=$PATH:$(pwd); echo $PATH; cd ${TRAVIS_BUILD_DIR}
  - make

Ważne tutaj jest, aby nie polegać na konkretnym numerze wersji gcc, bo po każdej zmianie będzie trzeba modyfikować skrypt. Dlatego używam zapisu gcc-6.3.0-*. Ścieżkę toolchaina dodaje do zmiennej środowiskowej PATH przy pomocy komendy pwd. W tym celu najpierw zmieniam aktualną ścieżkę na folder binarek kompilatora. Po operacji muszę wrócić do ścieżki, gdzie wykonywany jest build, żeby móc wywołać make. W tym celu używam zmiennej środowiskowej TRAVIS_BUILD_DIR.

Notyfikacje mailowe

Po tych wszystkich zabawach z Travisem otworzyłem skrzynkę mailową i znalazłem solidną porcję spamu. Przy każdym buildzie szedł oddzielny mail. Żeby wyłączyć powiadomienia mailowe, do pliku konfiguracyjnego należy dodać linie:

notifications:
  email: false

Podsumowanie

Travis-CI jest prosty do konfiguracji, jeśli chcemy używać standardowego setupu. Jeżeli jednak ktoś chce postawić coś rzadko spotykanego – sprawy mocno się komplikują. Jak widać konfiguracja kompilacji gcc na PC i ARM w jednym buildzie nie jest niemożliwa, ale na pewno nie jest też prosta. Prostszym wyjściem było by pewnie użycie domyślnego kompilatora arm na linuxa zamiast Bleeding Edge Toolchain. Przechodząc tą konfigurację kilkukrotnie byłem bliski rezygnacji, ponieważ poprawienie jednego problemu zawsze powodowało kolejne problemy. Jednak w końcu się udało. Mam nadzieję, że teraz to będzie działać i nie będę musiał już za dużo grzebać przy Travisie.