0%

How to Cross Compile and Native Build on OpenBMC

Cross Compile

To cross-compile on OpenBMC, follow these steps:

Source the setup script

Start by sourcing the setup script for your target hardware. You can find the script on the OpenBMC GitHub repository. Execute the following command in your terminal:

1
. setup romulus

Build the SDK

Next, build the Software Development Kit (SDK) using the bitbake command. Specify your target as an argument. For example:

1
albertlin@thinkbook:$ bitbake -c populate_sdk obmc-phosphor-image

Install the SDK

Once the SDK is built, you need to install it. Follow these steps:

  1. Create a folder where you want to install the SDK. For instance, let’s use /usr/local/openbmc.

    1
    albertlin@thinkbook:$ sudo mkdir /usr/local/openbmc
  2. Navigate to the directory containing the SDK installation files.

    1
    albertlin@thinkbook:$ cd ./tmp/deploy/sdk/
  3. Run the SDK installation script using the following command:

    1
    2
    3
    albertlin@thinkbook:$ ./oecore-x86_64-armv7ahf-vfpv4d16-toolchain-nodistro.0.sh
    Phosphor OpenBMC (Phosphor OpenBMC Project Reference Distro) SDK installer version nodistro.0
    =============================================================================================
  4. The installation script will prompt you to enter the target directory for the SDK. Specify /usr/local/openbmc when prompted:

    1
    Enter target directory for SDK (default: /usr/local/oecore-x86_64): /usr/local/openbmc
  5. Confirm the installation by typing ‘y’ when asked if you want to proceed:

    1
    2
    3
    4
    5
    You are about to install the SDK to "/usr/local/openbmc". Proceed [Y/n]? y
    Extracting SDK....................................................................................................................................done
    Setting it up...done
    SDK has been successfully set up and is ready to be used.
    Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
  6. The SDK will be extracted and set up in the specified directory.

  7. Verify that the installation was successful by checking the contents of the installation directory:

    1
    albertlin@thinkbook:$ ls -al /usr/local/openbmc/

Using the SDK

Before compiling your code, you need to set up the SDK environment. Execute the following command to source the environment setup script:

1
albertlin@thinkbook:$ . /usr/local/openbmc/environment-setup-armv7ahf-vfpv4d16-openbmc-linux-gnueabi

Compile

Now you’re ready to compile your code. Here’s an example of compiling a simple “hello” program:

  1. Create a directory for your project and navigate into it.

    1
    2
    albertlin@thinkbook:$ mkdir hello
    albertlin@thinkbook:$ cd hello
  2. Create a C source file named hello.c and a Meson build file named meson.build with the following content:

    hello.c:

    1
    2
    3
    4
    5
    6
    #include <stdio.h>

    int main(void) {
    printf("Hello OpenBMC\n");
    return 0;
    }

    meson.build:

    1
    2
    3
    project('hello', 'c')

    executable('hello', 'hello.c')
  3. Generate the build files using Meson:

    1
    albertlin@thinkbook:hello$ meson build
  4. Build the project using Ninja:

    1
    albertlin@thinkbook:hello$ ninja -C build
  5. Once the build is complete, you can find the compiled binary in the build directory. You can copy it to your OpenBMC target for execution using the scp command:

    1
    albertlin@thinkbook:hello$ scp build/hello root@192.168.0.196:/tmp

Run built program in BMC

To execute the binary on your BMC target, follow these steps:

  1. Connect to your BMC target using SSH.

    1
    ssh root@192.168.0.196
  2. Navigate to the directory where you copied the binary.

    1
    root@romulus:/tmp# cd /tmp
  3. Run the binary.

    1
    2
    root@romulus:/tmp# ./hello
    Hello OpenBMC

That’s it! You have successfully cross-compiled and executed a program on OpenBMC.

Native Build

Source the setup script

Start by sourcing the setup script for your target hardware. You can find the script on the OpenBMC GitHub repository. Execute the following command in your terminal:

1
. setup romulus

Environment Setup and Checking

  1. Check if the required packages listed by sdbusplus are installed:
1
2
sudo apt install git meson libtool pkg-config g++ libsystemd-dev \
python3 python3-pip python3-yaml python3-mako python3-inflection
  1. Check the Boost version used by OpenBMC:

    1
    2
    3
    albertlin@thinkbook:$ bitbake-layers show-recipes | grep -i meson -A 1
    boost:
    boost 1.82.0
  2. Ensure that the Boost version matches what OpenBMC currently use.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    albertlin@albertlin:boost$ wget https://boostorg.jfrog.io/artifactory/main/release/1.82.0/source/boost_1_82_0.tar.gz
    --2023-06-17 03:30:56--
    ...
    2023-06-17 03:31:52 (2.52 MB/s) - ‘boost_1_82_0.tar.gz’ saved [142580547/142580547]
    albertlin@albertlin:boost$ ls
    boost_1_82_0.tar.gz

    albertlin@albertlin:boost_1_82_0$ ./bootstrap.sh --prefix=/usr
    Building B2 engine..
    ...
    Further information:

    - Command line help:
    ./b2 --help

    - Getting started guide:
    http://www.boost.org/more/getting_started/unix-variants.html

    - B2 documentation:
    http://www.boost.org/build/

    albertlin@albertlin:boost_1_82_0$ sudo ./b2 --install
    Performing configuration checks
    ...
    The following directory should be added to linker library paths:

    /home/albertlin/hypnoslin/openbmc/boost/boost_1_82_0/stage/lib
    albertlin@albertlin:sdbusplus$ cat /usr/include/boost/version.hpp | grep "BOOST_LIB_VERSION"
    // BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION
    #define BOOST_LIB_VERSION "1_82"

  3. Check the Meson version used by OpenBMC:

1
2
3
albertlin@thinkbook:$ bitbake-layers show-recipes | grep -i meson -A 1
meson:
meta 1.0.1
  1. Ensure that the Meson version matches what OpenBMC currently uses. It’s recommended to have an upgraded version:
1
2
3
4
5
6
7
8
9
10
11
12
13
albertlin@albertlin:sdbusplus$ meson -v
0.61.2
albertlin@albertlin:sdbusplus$ python --version
Python 3.10.6
albertlin@albertlin:sdbusplus$ python -m pip install meson
Defaulting to user installation because normal site-packages is not writeable
Collecting meson
Downloading meson-1.1.1-py3-none-any.whl (918 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 918.4/918.4 KB 2.9 MB/s eta 0:00:00
Installing collected packages: meson
Successfully installed meson-1.1.1
albertlin@thinkbook:~$ meson -v
1.1.1
  1. If there are missing packages reported by Meson while building, install them:
1
sudo apt-get install -y libi2c-dev libarchive-dev libfmt-dev libsystemd-dev
  1. Verify that the GCC/G++ version matches what OpenBMC currently uses.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    albertlin@thinkbook:$ bitbake-layers show-recipes | grep gcc -A 1
    gcc:
    meta 12.2.0
    gcc-cross-arm:
    meta 12.2.0
    gcc-cross-canadian-arm:
    meta 12.2.0
    gcc-crosssdk-x86_64-oesdk-linux:
    meta 12.2.0
    gcc-runtime:
    meta 12.2.0
    gcc-sanitizers:
    meta 12.2.0
    gcc-source-12.2.0:
    meta 12.2.0

    libgcc:
    meta 12.2.0
    libgcc-initial:
    meta 12.2.0
    1
    2
    3
    4
    5
    albertlin@thinkbook:$ gcc -v
    Using built-in specs.
    COLLECT_GCC=gcc
    ...
    gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04.1)
  2. Ensure that the g++ version matches what OpenBMC currently uses.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    albertlin@albertlin:~$ g++ -v
    Using built-in specs.
    COLLECT_GCC=g++
    ...
    gcc version 9.5.0 (Ubuntu 9.5.0-1ubuntu1~22.04)
    albertlin@albertlin:~$ sudo apt install g++-12
    Reading package lists... Done
    ...
    Processing triggers for man-db (2.10.2-1) ...
    albertlin@albertlin:~$ ls -al /usr/bin/g++
    lrwxrwxrwx 1 root root 5 Mar 20 2020 /usr/bin/g++ -> g++-9
    albertlin@albertlin:~$ sudo rm /usr/bin/g++
    albertlin@albertlin:~$ sudo ln /usr/bin/g++-12 /usr/bin/g++
    albertlin@albertlin:~$ g++ -v
    Using built-in specs.
    COLLECT_GCC=g++
    ...
    gcc version 12.1.0 (Ubuntu 12.1.0-2ubuntu1~22.04)

Building and Executing

  1. Clone the sdbusplus repository. Run the following command:

    1
    2
    git clone https://github.com/openbmc/sdbusplus.git
    cd sdbusplus
  2. Configure the build using Meson. Run the following command:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    albertlin@albertlin:sdbusplus$ meson build -Dtests=disabled -Dexamples=disabled
    The Meson build system
    Version: 1.1.1
    Source dir: /home/albertlin/hypnoslin/openbmc/sdbusplus
    Build dir: /home/albertlin/hypnoslin/openbmc/sdbusplus/build
    Build type: native build
    Project name: sdbusplus
    Project version: 1.0.0
    C compiler for the host machine: cc (gcc 11.3.0 "cc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0")
    C linker for the host machine: cc ld.bfd 2.38
    C++ compiler for the host machine: c++ (gcc 12.1.0 "c++ (Ubuntu 12.1.0-2ubuntu1~22.04) 12.1.0")
    C++ linker for the host machine: c++ ld.bfd 2.38
    Host machine cpu family: x86_64
    Host machine cpu: x86_64
    Found pkg-config: /usr/bin/pkg-config (0.29.2)
    Run-time dependency libsystemd found: YES 249
    Program python3 (inflection, yaml, mako) found: YES (/usr/bin/python3) modules: inflection, yaml, mako
    Run-time dependency Boost found: YES 1.82.0 (/usr/include)
    Program sdbus++ found: YES (/home/albertlin/hypnoslin/openbmc/sdbusplus/tools/sdbus++)
    Program sdbus++ found: YES (overridden)
    Program sdbus++-gen-meson found: YES (/home/albertlin/hypnoslin/openbmc/sdbusplus/tools/sdbus++-gen-meson)
    Program sdbus++-gen-meson found: YES (overridden)
    Build targets in project: 1

    sdbusplus 1.0.0

    User defined options
    examples: disabled
    tests : disabled

    Found ninja-1.10.1 at /usr/bin/ninja
    WARNING: Running the setup command as `meson [options]` instead of `meson setup [options]` is ambiguous and deprecated.
  3. Build the project using Ninja. Run the following command:

    1
    2
    3
    albertlin@albertlin:sdbusplus$ ninja -C build
    ninja: Entering directory `build'
    [11/11] Linking target libsdbusplus.so.1.0.0