Sunday 29 June 2014

bjam / boost.build

Boost.Build
Common signature:

rule rule-name
    (
        target-name :
        sources + :
        requirements * :
        default-build * :
        usage-requirements *
    )

target-name is the name used to request the target
sources is the list of source files or other targets
requirements is the list of properties that must always be present when building this target
default-build is the list of properties that will be used unless some other value is already specified (eg: on cmd line or propagation from a dependent target)
usage-requirements is the properties that will be propagated to all targets that use this one

Helper commands:
glob - takes a list shell pattern and returns the list of files in the project's source directory that match the pattern. optional second argument is a list of exclude patterns
lib tools : [ glob *.cpp : exclude.cpp ] ;

glob-tree - recursive glob
lib tools : [ glob-tree *.cpp : .svn ] ;

constant - project wide constant
constant VERSION : 1.34.0 ;

Project:

project project-name
    : requirements <feature>value <feature>value
    ;

Programs:

exe app-name
    : app.cpp some_library.lib ../project//library
    : <threading>multi
    ;

sources is one cpp file (app.cpp), a library in the same directory (some_library.lib) and a Jamfile target (library) specified in the Jamfile found in the path ../project
requirements is that threading is multi

Libraries:
Library targets can represent:

Libraries that should be built from source


lib lib-name
    : lib.cpp
    ;

sources is one cpp file (lib.cpp)

Prebuilt libraries which already exist on the system
Such libraries can be searched for by the tools using them (typically with the linker's -l option), or their paths can be known in advance by the build system.

lib z
    :
    : <name>z <search>../3rd/libz
    ;

lib compress
    :
    : <file>/opt/libs/libcompress.a
    ;

<name> specifies the name of the library without the standard prefixes and suffixes.
In the above example, z could refer to z.so, libz.a, z.lib etc
<search> specifies paths in which to search for the library (in addition to the default compiler paths)
<search> can be specified multiple times, or omitted (meaning only the default compiler paths will be searched)
Note that <search> paths are added to the linker search path (-L) for all libraries being linked in the target, which can potentially lead to libraries from another path being picked up first

Convenience helper syntax for prebuilt libraries

lib z ;
lib gui db aux ;

is the same as

lib z : : <name>z ;
lib gui : : <name>gui ;
lib db : : <name>db ;
lib aux : : <name>aux ;

Prebuilt libraries for different build variants

lib foo
    :
    : <file>libfoo_release.a <variant>release
    ;

lib foo
    :
    : <file>libfoo_debug.a <variant>debug

    ;

Referencing other libraries
When a library references another library, that library should be listed in its list of sources.
Specify library dependencies even for searched and prebuilt libraries

lib z ;
lib png : z : <name>png ;

How Boost.Build includes library dependencies
When a library has a shared library as a source, or a static library has another static library as a source, then an target linking to the first library will also automatically link to the source library

However, when a shared library has a static library as a source, then the shared library will be built such that it completely includes the static library (--whole-archive)
If you don't want this behaviour, you need to use the following:

lib a : a.cpp : <use>b : : <library>b ;

This says that library uses library b, and causes executables that link to a to also link to b, instead of a referring to b

Automatically add a library's header location to any upstream target's include path
When a library's interface is in a header file, you can set usage-requirements for the library to include the path where the header file is, so that any target using the library target will automatically get the path to its header added to its include search path

lib foo : foo.cpp : : : <include>. ;

Control library linking order
If library a "uses" library b, then library a will appear before library b.
Library a is considered to use library b is b is present either in library a's sources or its usage is listed in its requirements
The <use> feature can also be used to explicitly express a relationship.

lib z ;
lib png : : <use>z ;
exe viewer : viewer png z ;

z will be linked before png

Special helper for zlib.
zlib can be configured either to use precompiled binaries or to build the library from source.

Find zlib in the default system location
using zlib ;
Build zlib from source
using zlib : 1.2.7 : <source>/home/steven/zlib-1.2.7 ;
Find zlib in /usr/local
using zlib : 1.2.7 : <include>/usr/local/include <search>/usr/local/lib ;
Build zlib from source for msvc and find prebuilt binaries for gcc.
using zlib : 1.2.7 : <source>C:/Devel/src/zlib-1.2.7 : <toolset>msvc ;
using zlib : 1.2.7 : : <toolset>gcc ;

Builtin features:
variant - build variant. Default configuration values: debug, release, profile.
link - library linking. values: shared, static
runtime-link - binary linking. values: shared, static
threading - link additional threading libraries. values: single, multi
source - useful for adding the same source to all targets in the project (put <source> in requirements), or to conditionally include a source
library - useful for linking to the same libraries for all targets in the project
dependency - introduces a dependency on the target named by the value. If the declared target is built, the dependent target will be too
implicit-dependency - indicates the target named by the value may produce files which the declared target uses.
use - introduces a dependency on the target named by the value, and adds its usage requirements to the build properties of the target being declared. The dependency is not used in any other way.
dll-path - add a shared library search path.
hardcode-dll-path - hardcode the dll-path entries. Values: true, false.
cflags, cxxflags, linkflags - passed on to the corresponding tools.
include - add an include search path.
define - define a preprocessor symbol. A value can be specified: <define>symbol=value
warnings - control the warning level of the compiler. Values: off, on, all.
warnings-as-errors - turn on to have builds fail when a warning is emitted.
build - skips building the target. Useful to conditionally set the value. Values: no.
tag - customize the name of generated files. Value: @rulename, where rulename is the name of a rule with the signature: rule tag ( name : type ? : property-set ). The rule will be called for each target with the default name of the target, the type of the target, and property set. Return an empty string to use the default target name, or a non empty string to be used for the name of the target. Useful for encoding library version nos etc.
debug-symbols - Include debug symbols in the object files etc. Values: on, off.

Objects:
Change behaviour for only a single object file

obj foo : foo.cpp : <optimizarion>off ;
exe bar : bar.cpp foo ;

foo will be built with the special flags, and then van be pulled into other targets

Alias:
Alternative name for a group of targets

alias core : foo bar baz ;

Using core in the source list of any other target or on the command line will translate to the aliased group of targets

Change build properties

alias my_bar : ../foo//bar : <link>static ;

my_bar now refers to the bar target in the foo Jamfile, but has the requirement that it be linked statically

Specify a header only library

alias hdr_only_lib : : : : <include>/path/to/headers ;

Using hdr_only_lib will just add an include path to any targets

Propagation of usage-requirements
When an alias has sources, the usage-requirements of those sources are propagated as well.

lib lib1 : lib1src.cpp : : : <include>/path/to/lib1.hpp ;
lib lib2 : lib2src.cpp : : : <include>/path/to/lib2.hpp ;
alias static_libs : lib1 lib2 : <link>static ;
exe main : main.cpp static_libs ;

Compile main with lib1 and lib2 as static libraries, and their paths are added to the include search path

Installing:
Installing a built target to a relative path

install dist : foo bar ;

foo and bar will be moved to the dist folder, relative to the Jamfile's directory

Installing a built target to specific location

install dist : foo bar : <location>/install/path/location

foo and bar will be moved to /install/path/location

Installing a built target to a path based on a conditional expression
(see conditional expressions below)

install dist 
    : foo bar 
    : <variant>release:<location>dist/release
      <variant>debug:<location>dist/debug ;

foo and bar will be installed to relative path dist/<build-variant>

Installing a built target to a path based on an environment variable
(see accessing environment variables below)

install dist : foo bar : <location>$(DIST) ;

Automatically install all dependencies

install dist 
    : foo
    : <install-dependencies>on
      <install-type>EXE
      <install-type>LIB
    ;

will find all targets foo depends on, and install those which are either executables or libraries.

Preserve directory hierarchy

install headers 
    : a/b/c.h
    : <location>/tmp
      <install-source-root>a
    ;

/tmp/b/c.h will be installed

Install into several directories
use an alias rule to install to several directories

alias install : install-bin install-lib ;
install install-bin : apps : <location>/usr/bin ;
install install-lib : libs : <location>/usr/lib ;

set the RPATH

install installed : application : <dll-path>/usr/lib/snake
                                  <location>/usr/bin ;

will allow the application to find libraries placed in the /usr/lib/snake directory.

Testing:
unit-testing

unit-test foo_test : test.cpp foo ;

behaves just like exe rule, but the test is automatically run after building

testing through another application

unit-test foo_test : test.cpp foo : <testing.launcher>valgrind ;

runs the test through the launcher, eg: valgrind build/path/foo_test

Environment variables:
local foo = [ SHELL "bar" ] ;

Executing external programs:
import os ;
local SOME_PATH = [ os.environ SOME_PATH ] ;
exe foo : foo.cpp : <include>$(SOME_PATH) ;

Conditional expressions:
syntax

property ( "," property ) * ":" property

multiple properties can be combined

exe hello : hello.cpp : <os>NT,<toolset>gcc:<link>static ;

will link hello statically only when compiling with gcc on NT

Command reference:
http://www.boost.org/doc/libs/1_55_0/doc/html/bbv2/reference.html





Thursday 19 June 2014

Eclipse configuration

Install from eclipse site, not apt-get:

http://www.eclipse.org/downloads/

I decompressed it into /opt/eclipse, and installed a symlink in /usr/bin

$ sudo ln -s /opt/eclipse/eclipse /usr/bin

Increase heap memory available to eclipse (prevents crashing):

$ vim /opt/eclipse/eclipse.ini

-vmargs
-Dosgi.requiredJavaVersion=1.6
-XX:MaxPermSize=1G
-Xms1G
-Xmx2G

Add support for C++11 features for the code inspection

Window -> Preferences -> C/C++ -> Build -> Settings -> Discovery (tab) -> CDT GCC Built-in Compiler Settings. There is "Command to get compiler specs", add "-std=c++11" in there.

Syntax Highlighting theme:

Add the eclipse-color-theme repo to Eclipse marketplace

Help -> Install New Software -> Add -> Location: http://eclipse-color-theme.github.com/update

Select color theme:

Window -> Preferences -> General -> Appereance -> Color Theme : select Monkai or Obsidian or RecognEyes

Editor line highlight colors, etc:

Window -> Preferences -> General -> Editors -> Text Editors

Annotations:

Window -> Preferences -> General -> Editors -> Text Editors -> Annotations

C/C++ Indexer Markers -> Uncheck all
C/C++ Occurrences -> Uncheck Text as Squiggly Line
Codan Errors -> Uncheck all
Codan Warnings -> Uncheck all

Change default Build Action:

Window -> Preferences -> General -> Keys

Filter on "Build"

Remove Ctrl-B from Build All, and add it to Build Project

C++ build console:

Window -> Preferences -> C++ -> Build -> Console

Increase the number of lines
Set colors

Source hover popup:

Window -> Preferences -> C++ -> Editor

Source Hover Background

Automatically close:

Window -> Preferences -> C++ -> Editor -> Typing

Uncheck all auto-close

Editor mark occurrences:

Window -> Preferences -> C++ -> Editor -> Mark Occurrences

Uncheck "Keep marks when the selection changes"

Now restart eclipse to make sure your settings are saved.

Change scalability settings

Window -> Preferences -> C++ -> Editor -> Scalability

Increase number of lines to something larger

Unused:

Color theme:

http://marketplace.eclipse.org/content/eclipse-moonrise-ui-theme

Window -> Preferences -> General -> Appearance : select Dark or MoonRise

Remote System Explorer:

Help -> Install New Software

Search for Remote, I

New connection -> SSH Only

Connect

Sftp files -> navigate to src directory -> Rt click -> Create Remote Project

Project indexer search paths 

Project -> Properties -> C++ General -> Paths & Symbols

Includes
Library Paths

eg:

Includes:
    ${QTDIR}/include
    ${QTDIR}/include/QtCore
    ${QTDIR}/include/QtWidgets
    ${QTDIR}/include/QtGui

Library paths
    ${QTDIR}/include
    ${QTDIR}/include/QtCore
    ${QTDIR}/include/QtWidgets
    ${QTDIR}/include/QtGui

Wednesday 4 June 2014

Setting up an ubuntu vagrant instance

Install vagrant

Download the latest deb from http://www.vagrantup.com/downloads.html

Install vagrant from downloaded deb

$ sudo dpkg -i ./vagrant.deb

Install virtualbox

Add the appropriate deb source to your apt sources

$ echo "deb http://download.virtualbox.org/virtualbox/debian trusty contrib" | sudo tee -a /etc/apt/sources.list

Add the oracle public key

$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -

Update the apt cache

$ sudo apt-get update

Install virtualbox

$ sudo apt-get install virtualbox-4.3

Initialise a vagrant instance

Note that if you're loading a 64 bit vm you need to have hardware virtualisation enabled in your bios (and your processor needs to support it!)

$ vagrant init ubuntu/trusty64
$ vagrant up

ssh into vm

$ vagrant ssh

halt/suspend/destroy vm

$ vagrant suspend saves current state of vm and stops it - fast to resume, uses more space
$ vagrant halt    saves current state of vm and shuts down - slower to resume, less space
$ vagrant destroy destroys all traces of the vm - no space used

Enable remote ssh access

By default vagrant will only create a private network between the host and vm. By changing to a public network, the vm will be allocated an ip address from your LAN and you will be able to ssh in from a remote machine

In the Vagranfile:

config.vm.network "public_network", bridge: 'eth0'

Reload Vagrantfile:

$ vagrant reload

You can ssh into the vm (vagrant ssh) and find out the ip address (ifconfig), allowing you to now ssh directly into the machine

$ ssh vagrant@192.168.1.xxx

Enable provisioning of the vm with ansible

Requires ansible to be installed
In the Vagrantfile

config.vm.provision :ansible do |ansible|
    ansible.playbook = "ansible/provision.yml"
    ansible.inventory_path = "ansible/hosts"
    ansible.limit = "all"
end


Create a file called ansible/hosts which has the vagrant vm listed in it

[vagrant]
192.168.1.xxx


Create a file called ansible/provision.yml which will be our playbook

---
- hosts: vagrant
tasks:
    - name: test vm is up
      ping:


Provision the vm
 
$ vagrant provision