Build and Install SystemC and ArchC

Requirements:

  • Unix layout for installed software. [Read it]({{ .Site.BaseURL }}document/unix_layout)
  • Basics of Git. Read the book
  • What is SystemC and ArchC.

Build Setup

First you need choose where you will keep the source and installed files. I like to keep all installed files of all project's softwares in the same prefix, and for organization, keep the prefix in the same directory tree of the project sources.

export SOURCE_PREFIX="/A/B/ac_project"
export PREFIX="${SOURCE_PREFIX}/usr"

You can use you home to store this files. But keep in mind that a network mounted home (as NFS) have advantages and disadvantages.

export SOURCE_PREFIX="/${HOME}/A/B/ac_project"
export PREFIX="${SOURCE_PREFIX}/usr"

Both paths must exists:

mkdir -p "${SOURCE_PREFIX}"
mkdir -p "${PREFIX}"

Now, that you know where you will put the installed files, you can setup your paths to this project:

$ export PATH="${PREFIX}/bin/:${PATH}"
$ export LD_LIBRARY_PATH="${PREFIX}/lib/:${LD_LIBRARY_PATH}"
$ export PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}"

SystemC

SystemC uses the autotools build system. This is a very used build system, maybe you should ever considerate that the software are using this build system or similar one.

Fetch the SystemC, we suggest that you use (our git version)[https://github.com/ArchC/SystemC]. But you can use the (Accellera vanilla code)[http://www.accellera.org/downloads/standards/systemc].

$ git clone https://github.com/ArchC/SystemC.git "${SOURCE_PREFIX}/SystemC"

PS: We are using the commit (a7605fd)[https://github.com/ArchC/SystemC/tree/a7605fd4cd7ada969789d9250f784fc925503d9a].

The SystemC adopts a strange installation layout that you must avoid. In the version 2.3.1 they offer a flag to force use unix layout.

$ cd "${SOURCE_PREFIX}/SystemC"
$ autoreconf -vif
$ ./configure --with-unix-layout --prefix="${PREFIX}"
$ make # Build the source
$ make check # Build and execute the tests
$ make install # Install SystemC in defined $PREFIX

ArchC

Similar to SystemC, the ArchC uses the autotools build system.

Fetch ArchC project:

$ git clone https://github.com/ArchC/ArchC.git "${SOURCE_PREFIX}/ArchC"

PS: We are using the commit (594942b)[https://github.com/ArchC/ArchC/tree/594942bb290f7964b3fff2a05335bcd94bbe480d].

The ArchC will search the SystemC using the pkg-config, remember to use the correct path to help it find your SystemC installation.

$ cd "${SOURCE_PREFIX}/ArchC"
$ autoreconf -vif
$ ./configure --prefix="${PREFIX}"
$ make # Build the source
$ make check # Build and execute the tests
$ make install # Install ArchC in defined $PREFIX

Processors

The ArchC project maintains 4 processor models:

  • MIPS
  • ARM
  • SPARC
  • POWERPC

You can fetch and build them:

mkdir -p "${SOURCE_PREFIX}/ACModels"
for model in mips arm sparc powerpc; do
  git clone "https://github.com/ArchC/${model}.git" "${SOURCE_PREFIX}/ACModels/${model}";
  cd "${SOURCE_PREFIX}/ACModels/${model}";
  acsim ${model}.ac;
  make;
do

Guest Toolchain

You can get the compiled toolchain for each of the maintained models.

Run Guest Binaries

$ cd "${SOURCE_PREFIX}/ACModels/<model name>"
$ ./<model name>.x --load=<full path to binary>

Example:

$ cd "${SOURCE_PREFIX}/ACModels/mips"
$ ./mips.x --load=/tmp/

Debug processor models

Execution flow

You can compare two execution of same binary using the output and the trace. To generate the trace, you must print the list of PC used. Uncomment the debug line at <model>_isa.cpp :

//#define DEBUG_MODEL

Execute your binary:

$ make clean
$ make
$ ./<model name>.x --load=<full path to binary> 2>/tmp/ac_stderr

Get the trace of PC addresses:

$ LINES = 1000
$ grep '^DBG:.* PC=0x[0-9a-f]\+ .*$' /tmp/ac_stderr | head -n ${LINES} | sed 's/^DBG:.* PC=\(0x[0-9a-f]\+\) .*$/\1/g' >/tmp/ac_trace

If your binary was compiled with debug symbols, you can translate the address to source file and line:

$ cat /tmp/ac_trace | xargs <model>-newlib-elf-addr2line -a -f -p -e <full path to binary> >/tmp/ac_hltrace

Unix layout for installed software

The Unix filesystem organization is simple and helps you to know where you should expect find the files. See the root directory: “/". Many of the folders there is one standard to follow. Each software that you will install must follow this standard, but someones are undesirable exceptions.

Unix layout

The basic at this point that you must understand:

  • /bin Executable files that you can run from command line.
  • /etc Configuration files that you can change.
  • /lib Shared and static compiled libraries.
  • /share Non architect/processor dependent files: default configuration, documentations, examples, etc.

Paths

Your shell has some environment variables that defines where search desirable files, as binaries and libraries. You must keep attention in, at least, two one:

  • $PATH Where find binaries.
  • $LD_LIBRARY_PATH Where find libraries.

Both of them are lists of full paths separated with :. If you type ls <enter> in your terminal(gnome-terminal, konsole, xterm, tty, etc.) running your shell (bash, ash, zsh, csh, etc.), your shell will search the binary ls in $PATH and after it can search (or not) in default locations.

Typically, you should prepend the new path to this variables:

$ export PATH="/A/B/bin:${PATH}"
$ export LD_LIBRARY_PATH="/A/B/lib:${LD_LIBRARY_PATH}"

PS: Use export to any child process can read this new values.

The first occorrency is used, and this is very usefull. We can add a path (e.g. /A/B/bin) that contains a binary called gcc:

$ echo ${PATH}
/usr/local/bin:/usr/bin:/bin
$ which gcc
/usr/bin/gcc
$ ls /A/B/bin/
c++ cc  g++ gcc
$ export PATH="/A/B/bin/:${PATH}"
$ which gcc
/A/B/bin/gcc

Now, when a child process of this shell search for gcc, it will use the /A/B/gcc. Similar procedure occur when ld will dynamic search the shared libraries (*.so).

Prefix

Not all software are installed in same place. See in the last example that is common have, at least, three default paths in $PATH: /, /usr, and /usr/local. Each distribution can define their rules to where put the installed software using their package managers.

The common is use / to essential software, as /bin/bash. Use the /usr to all official supported softwares. And they leave the /usr/local to software that you want install manually to the system. Unsupported softwares can use the /opt/<software name>, and should be explicitly included in path variables.

The idea of prefix is define a prefix to your software: /, /usr/, /usr/local/, /A/B/, /opt/A/,… Many build systems accept a parameter of prefix, use it!

If you are the only user of the system, you can install your software in /usr/local/ but keep in mind that you can install non-related softwares there and remove only one of them can be painful.

I suggest that you can have one prefix for each project, install all related builds in this prefix. Remember that you must add all used prefix to paths, specially the $PATH and $LD_LIBRARY_PATH, every time when you want use this software.

$ export PATH="/A/B/bin/:${PATH}"
$ export LD_LIBRARY_PATH="/A/B/lib/:${LD_LIBRARY_PATH}"

pkg-config

To use installed libraries, you should link them to your software. The problem is that you must use the correct link flags, with the correct libraries locations, and sometimes, use third libraries that are required by each dependecy.

pkg-config is a helper tool used when compiling applications and libraries. It helps you insert the correct compiler options on the command line so an application can use gcc -o test test.c $(pkg-config --libs --cflags glib-2.0) for instance, rather than hard-coding values on where to find glib (or other libraries). It is language-agnostic, so it can be used for defining the location of documentation tools, for instance.

pkg-config use software defined files (<library name>.pc) with the installation metadata. This files are find using the $PKG_CONFIG_PATH environment variable, that common contains the $LD_LIBRARY_PATH plus the /pkgconfig. The pkg-config automatic search in default places: /lib/pkgconfig and /usr/lib/pkgconfig.

The software that give their pkg-config description file install it in <prefix>/lib/pkgconfig.

Note that if you want the benefits of pkg-config, you must keep your $PKG_CONFIG_PATH updated together with $PATH and $LD_LIBRARY_PATH.

$ export PKG_CONFIG_PATH="/A/B/lib/pkgconfig:${PKG_CONFIG_PATH}"

Automatic setup

You can setup you environment variables when login or when open your shell. But do it only when you actual understand the paths and pkg-config. If you automatic put this values before understand, you forget how put them in a early future. This is not a one time use knowledge, absorb it!

As said, I like to keep each project installation in one prefix. I only add this project software to my runtime paths only want use them.