Cartagena de Indias – 10°25′25″N 75°31′31″O

This slideshow requires JavaScript.

Calamari que en el lenguaje indígena significaba cangrejo y que Heredia y sus gentes españolizaron llamándole simplemente Calamar, era el nombre con que los nativos denominaban una aldea situada en el último repliegue de la bahía de Cartagena hacia el norte. Pueblo pajizo con techos que casi llegaban a tierra, rodeado de fuerte empalizada circular y de arboles espinosos coronados de calaveras cuyos habitantes estaban sumidos en secular barbarie, pero también en absoluta libertad.

— descripción de año 1533, año de su fundación por Pedro de Heredia

Panorámica de Cartagena de Indias

 

 

 

Sus calles coloniales, su arquitectura española, el colorido de sus fachadas, el clima tropical junto con la alegría contagiosa de su gente hacen de Cartagena de Indias un lugar único. Un lugar con encanto que aúna en un sólo sitio, en un solo instante, el legado de su historia y la vitalidad de sus gentes.

Sus calles del casco antiguo actúan como máquina del tiempo que te transportan a la antigua Corona española. No en vano, durante tiempo fue ciudad portuaria de las más importantes de América. De Cartagena salían las mayores riquezas de la Corona por rutas marítimas que terminaban en los puertos españoles de Cartagena, Cádiz y Sevilla.

This slideshow requires JavaScript.

También destacan sobre los grabados de sus calles y fachadas los nombres de famosos piratas, corsarios y almirantes. Ingleses como Drake, Vernon, Cote o Hawkins se vinculan estrechamente a la historia de esta ciudad. También, como no podía ser de otra manera, los están los nombres de Blas de Lezo o  Sebastián  Carlos Suillars de Desnaux. Todos ellos figuras destacadas que dejaron su pegada en las calles de Cartagena y que son protagonistas de los hechos y hazañas de las más relevantes de su época. Una época de esplendor que se prolongó por más de 200 años hasta su decadencia finalizando el siglo XIX.

Así pues, fue en el año 1586  cuando el pirata Francis Drake se presentó frente a Cartagena con una gran escuadra de 23 navíos y unos 3000 hombres veteranos. Él mismo,  al frente de su flota, dio asedio y consiguió saquear la ciudad de Cartagena consiguiendo acceso de entrada por la bahía conocida como Boca Grande.

Mapa de Cartagena de indias
Mapa de Cartagena de Indias durante el asedio del inglés Francis Drake

Como consecuencia de este ataque, el rey Felipe II de España ordenó la fortificación del puerto de Cartagena  de Indias, su reconstrucción, y el inicio de la construcción del Castillo de San Felipe de Barajas situado sobre el cerro de San Lázaro. Esta fortificación defendería la ciudad amurallada desde su posición elevada al Norte de la ciudad en años venideros haciendo la plaza de facto inexpugnable.

This slideshow requires JavaScript.

Fue esta construcción defensiva, de hecho,  clave años después, en el año 1740, cuando Blas de Lezo organizó la defensa de la ciudad para repeler el ejército invasor británico comandado por el almirante Vernon. Una flota británica que sumaba 2000 cañones dispuestos en casi 180 barcos, entre navíos de tres puentes, navíos de de línea, fragatas, bombardas y buques de transporte, y que transportaba en torno a 30000 combatientes entre marinos, soldados, milicias norteamericanas y esclavos negros macheteros de Jamaica fue enfrentada y repelida por las defensas de la ciudad de Cartagena a cargo de Lezo y en franca minoria.

Esta acción se conoce como el sitio de Cartagena de Indias de año 1741. Las defensas de Cartagena fueron compuesta, según datos que en algún otro momento  estuvieron a mi alcance, sólo por 3000 hombres entre tropa regular, milicianos, 600 indios, más marinería y tropa de desembarco de los seis navíos de guerra de los que disponía la ciudad : el Galicia, la nave capitana, el San Felipe, el San Carlos, el África, el Dragón y el Conquistador.

La contienda fue dura y la estrategia de Blas de Lezo se basó en contener al enemigo el mayor tiempo posible, desgastando al enemigo a sabiendas de que el tiempo y la logística contaban a su favor.  El desenlace se produjo precisamente en el fracaso de la toma del castillo de San Felipe de Barajas por parte de las tropas de Vernon que, tras tomar algunas de las defensas de la ciudad, el fallaron en el asalto al castillo San Felipe, el último baluarte importante que la defendía. Como resultado, el ejército británico, con gran parte de la tropa enferma, grandes bajas sufridas en los combates y la llegada de la época de lluvias, optó por destruir las defensas a su alcance y desistir del asedio.

Pero es también Cartagena un paraíso natural. Zona privilegiada del Mar Caribe, es su costa está continuamente salpicada de islas, cayos y pequeños paraísos. Su costa es, además, respetada por los huracanes tropicales siendo visitable durante los 365 del año.

This slideshow requires JavaScript.

 

Building Chromium in MacOS with a Linux icecc cluster

Many times, during these last months, I thought to keep updated my blog writing a new post. Unfortunately, for one or another reason I always found an excuse to not do so. Well, I think that time is over because finally I found something useful and worthy the time spent time on the writing.

– That is OK but … what are you talking about?.
– Be patient Pablo, if you didn’t skip the headline of the post you already know about what I’m talking, probably :-).

Yes, I’m talking about how to setup a MacPro computer into a icecc cluster based on Linux hosts to take advantage of those to get more CPU power to build heavy software projects, like Chromium,  faster. The idea besides this is to distribute all the computational work over Linux nodes (fairly cheaper than any Mac) requested for cross-compiling tasks from the Mac host.

I’ve been working as a sysadmin at Igalia for the last couple of years. One of my duties here is to support and improve the developers building infrastructures. Recently we’ve faced long building times for heavy software projects like, for instance, Chromium. In this context, one of the main  issues that I had to solve is  how to build Chromium for MacOS in a reasonable time and avoiding to spend a lot of money in expensive bleeding edge Apple’s hardware to get CPU power.

This is what this post is about. This is an explanation about how to configure a Mac Pro to use a Linux based icecc cluster to boost the building times using cross-compilation. For simplicity, the explanation is focused in the singular case of just one single Linux host as icecc node and just one MacOS host requesting for compiling tasks but, in any case, you can extrapolate the instructions provided here to have many nodes as you need.

So let’s go with the the explanation but, first of all, a summary for those who want to go directly to the minimal and essential information …

TL;DR

On the Linux host:

# Configure the iceccd
$ sudo apt install icecc
$ sudo systemctl enable icecc-scheduler
$ edit /etc/icecc/icecc.conf
ICECC_MAX_JOBS="32"
ICECC_ALLOW_REMOTE="yes"
ICECC_SCHEDULER_HOST="192.168.1.10"
$ sudo systemctl restart icecc

# Generate the clang cross-compiling toolchain
$ sudo apt install build-essential icecc
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git ~/depot_tools
$ export PATH=$PATH:~/depot_tools
$ git clone https://github.com/psaavedra/chromium_clang_darwin_on_linux ~/chromium_clang_darwin_on_linux
$ cd ~/chromium_clang_darwin_on_linux
$ export CLANG_REVISION=332838  # or CLANG_REVISION=$(./get-chromium-clang-revision)
$ ./icecc-create-darwin-env
# copy the clang_darwin_on_linux_332838.tar.gz to your MacOS host

On the Mac:

# Configure the iceccd
$ git clone https://github.com/darktears/icecream-mac.git ~/icecream-mac/
$ sudo ~/icecream-mac/install.sh 192.168.1.10
$ launchctl load /Library/LaunchDaemons/org.icecream.iceccd.plist
$ launchctl start /Library/LaunchDaemons/org.icecream.iceccd.plist

# Set the ICECC env vars
$ export ICECC_CLANG_REMOTE_CPP=1
$ export ICECC_VERSION=x86_64:~/clang_darwin_on_linux_332838.tar.gz
$ export PATH=~/icecream-mac/bin/icecc/:$PATH

# Get the depot_tools
$ cd ~
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
$ export PATH=$PATH:~/depot_tools

# Download and build the Chromium sources
$ cd chromium && fetch chromium && cd src
$ gn gen out/Default --args='cc_wrapper="icecc" \
  treat_warnings_as_errors=false \
  clang_use_chrome_plugins=false \
  use_debug_fission=false \
  linux_use_bundled_binutils=false \
  use_lld=false \
  use_jumbo_build=true'
$ ninja -j 32 -C out/Default chrome

… and now the detailed explanation

Installation and setup of icecream on Linux hosts

The installation of icecream on a  Debian based Linux host is pretty simple. The latest version (1.1) for icecc is available in Debian testing and sid for a while so everything that you must to do is install it from the APT repositories. For case of stretch, there is a backport available  in the apt.igalia.com repository publically available:

sudo apt install icecc

The second important part of a icecc cluster is the icecc-scheduler. This daemon is in charge to route the requests from the icecc nodes which requiring available CPUs  for compiling to the nodes of the icecc cluster allowed to run remote build jobs.

In this setup we will activate the scheduler in the Linux node (192.168.1.10). The key here is that only one scheduler should be up at the same time in the same network to avoid errors in the cluster.

sudo systemctl enable icecc-scheduler

Once the scheduler is configured and up, it is time to add icecc hosts to the cluster. We will start adding the Linux hosts following this idea:

  • The IP of the icecc scheduler is 192.168.1.10
  • The Linux host is allowed to run remote jobs
  • The Linux host is allowed to run up to 32 concurrent jobs (this is arbitrary decision and can be adjusted per each particular host)
    # edit /etc/icecc/icecc.conf
    ICECC_NICE_LEVEL="5"
    ICECC_LOG_FILE="/var/log/iceccd.log"
    ICECC_NETNAME=""
    ICECC_MAX_JOBS="32"
    ICECC_ALLOW_REMOTE="yes"
    ICECC_BASEDIR="/var/cache/icecc"
    ICECC_SCHEDULER_LOG_FILE="/var/log/icecc_scheduler.log"
    ICECC_SCHEDULER_HOST="192.168.1.10"

We will need to restart the service to apply those changes:

sudo systemctl restart icecc

Installing and setup of icecream on MacOS hosts

The next step is to install and configure the icecc service on our Mac.  The easy way to get icecc available on Mac is icecream-mac project from darktears. We will do the installation assuming the following facts:

  • The local user account in Mac is psaavedra
  • The IP of the icecc scheduler is 192.168.1.10
  • The Mac is not allowed to accept remote jobs
  • We don’t want run use the Mac as worker.

To get the icecream-mac software we will make a git-clone of the project on Github:

git clone https://github.com/darktears/icecream-mac.git /Users/psaavedra/icecream-mac/
sudo /Users/psaavedra/icecream-mac/install.sh 192.168.1.10

We will edit a bit the /Library/LaunchDaemons/org.icecream.iceccd.plist daemon definition as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>org.icecream.iceccd</string>
    <key>ProgramArguments</key>
    <array>
      <string>/Users/psaavedra/icecream-mac/bin/icecc/iceccd</string>
      <string>-s</string>
      <string>192.168.1.10</string>
      <string>-m</string>
      <string>2</string>
      <string>--no-remote</string>
    </array>
    <key>KeepAlive</key>
    <true/>
    <key>UserName</key>
    <string>root</string>
  </dict>
</plist>

Note that we are setting 2 workers in the Mac. Those workers are needed to execute threads in the host client host for things like linking … We will reload the service with this configuration:

launchctl load /Library/LaunchDaemons/org.icecream.iceccd.plist
launchctl start /Library/LaunchDaemons/org.icecream.iceccd.plist

Getting the cross-compilation toolchain for the icecream-mac

We already have the icecc cluster configured but, before to start to build Chromium on MacOS using icecc, there is still something before to do. We still need a cross-compiled clang for Darwin on Linux and, to avoid incompatibilities between versions, we need a clang based on the very same version that your Chromium code to be compiled.

You can check and get the cross-compilation clang revision that you need as follows:

cd src
CLANG_REVISION=$(cat tools/clang/scripts/update.py | grep CLANG_REVISION | head -n 1 | cut -d "'" -f 2)
echo $CLANG_REVISION
332838

In order to simplify this step.  I made some scripts which make it easy the generation of this clang cross-compiled toolchain. On a Linux host:

  • Install build depends:
    sudo apt install build-essential icecc
  • Get the Chromium project depot tools
    git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git ~/depot_tools  
    export PATH=$PATH:~/depot_tools
  • Download the psaavedra’s scripts (yes, my scripts):
    git clone https://github.com/psaavedra/chromium_clang_darwin_on_linux ~/chromium_clang_darwin_on_linux
    cd ~/chromium_clang_darwin_on_linux
  • You can use the get-chromium-clang-revision script to get the latest clang revision using in Chromium master:
    ./get-chromium-clang-revision
  • and then, to build the cross-compiled toolchain:
    ./icecc-create-darwin-env

    ; this script encapsulates the download, configure and build of the clang software.

  • A clang_darwin_on_linux_999999.tar.gz file will be generated.

Setup the icecc environment variables

Once you have the /Users/psaavedra/clang_darwin_on_linux_332838.tar.gz generated in your MacOS. You are ready to set the icecc environments variables.

export ICECC_CLANG_REMOTE_CPP=1
export ICECC_VERSION=x86_64:/Users/psaavedra/clang_darwin_on_linux_332838.tar.gz

The first variable enables the usage of the remote clang for C++. The second one establish toolchain to use by the x86_64 (Linux nodes) to build the code sent from the Mac.

Finally, remember to add the icecc binaries to the $PATH:

export PATH=/Users/psaavedra/icecream-mac/bin/icecc/:$PATH

You can check and get the cross-compiled clang revision that you need as follows:

cd src
CLANG_REVISION=$(cat tools/clang/scripts/update.py | grep CLANG_REVISION | head -n 1 | cut -d "'" -f 2)
echo $CLANG_REVISION
332838

… and building Chromium, at last

Reached this point, it’s time to build a Chromium using the icecc cluster and the cross-compiled clang toolchain previously created. These steps follows the official Chromium build procedure and only adapted to setup the icecc wrapper.

Ensure depot_tools is the path:

cd ~git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$PATH:~/depot_tools
ninja --version
# 1.8.2

Get the code:

git config --global core.precomposeUnicode truemkdir chromium
cd chromium
fetch chromium

Configure the build:

cd src
gn gen out/Default --args='cc_wrapper="icecc" treat_warnings_as_errors=false clang_use_chrome_plugins=false linux_use_bundled_binutils=false use_jumbo_build=true'
# or with ccache
export CCACHE_PREFIX=icecc
gn gen out/Default --args='cc_wrapper="ccache" treat_warnings_as_errors=false clang_use_chrome_plugins=false linux_use_bundled_binutils=false use_jumbo_build=true'

And build, at last:

ninja -j 32 -C out/Default chrome

icemon allows you to graphically monitoring the icecc cluster. Run it in remote from your Linux host if you don’t want install it in the MacOS:

ssh -X user@yourlinuxbox icemon

; with icemon you should see how each build task is distributed across the icecc cluster.

icemon