This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

cheribuild - Adding a new target

Hi there,

I am trying to add Mosquitto (MQTT) as a cheribuild target. This is my current Python script:

from .crosscompileproject import CrossCompileCMakeProject, GitRepository
from ...config.compilation_targets import CompilationTargets

class BuildMqtt(CrossCompileCMakeProject):
    target = "mqtt"
    repository = GitRepository("">github.com/.../mosquitto")
    supported_architectures = CompilationTargets.ALL_FREEBSD_AND_CHERIBSD_TARGETS + [CompilationTargets.NATIVE]

When running ./cheribuild mqtt-morello-purecap to build the target, I run into this error message:

CMake Error at man/CMakeLists.txt:29 (message):
xsltproc not found: manpages cannot be built


-- Configuring incomplete, errors occurred!

Looking at the MQTT Git repository here and in the "Building from source" section, I can add the CMake option "WITH_DOCS=no" which disables checking for the optional build dependency xsltproc to generate man pages which I don't need. With these changes my build script now looks like this:

from .crosscompileproject import CrossCompileCMakeProject, GitRepository
from ...config.compilation_targets import CompilationTargets

class BuildMqtt(CrossCompileCMakeProject):
    target = "mqtt"
    repository = GitRepository("">github.com/.../mosquitto")
    supported_architectures = CompilationTargets.ALL_FREEBSD_AND_CHERIBSD_TARGETS + [CompilationTargets.NATIVE]

    def setup(self):
    super().setup()
    self.add_cmake_options(WITH_DOCS=no)

Now when I attempt to run ./cheribuild.py mqtt-morello-purecap again, I am presented with multiple errors:

Traceback (most recent call last):
File "./cheribuild.py", line 42, in <module>
main()
File "/home/ubuntu/cheribuild/pycheribuild/__main__.py", line 258, in main
run_and_kill_children_on_exit(real_main)
File "/home/ubuntu/cheribuild/pycheribuild/processutils.py", line 771, in run_and_kill_children_on_exit
fn()
File "/home/ubuntu/cheribuild/pycheribuild/__main__.py", line 248, in real_main
target_manager.run(cheri_config)
File "/home/ubuntu/cheribuild/pycheribuild/targets.py", line 435, in run
target.execute(config)
File "/home/ubuntu/cheribuild/pycheribuild/targets.py", line 129, in execute
self._do_run(config, msg="Built", func=lambda project: project.process())
File "/home/ubuntu/cheribuild/pycheribuild/targets.py", line 107, in _do_run
project.setup()
File "/home/ubuntu/cheribuild/pycheribuild/projects/cross/mqtt.py", line 11, in setup
self.add_cmake_options(WITH_DOCS=no)
NameError: name 'no' is not defined

Any ideas why this section below in particular is occurring? Or any ideas on how to skip the checking for the xsltproc optional dependency?

File "/home/ubuntu/cheribuild/pycheribuild/projects/cross/mqtt.py", line 11, in setup
self.add_cmake_options(WITH_DOCS=no)
NameError: name 'no' is not defined

Thanks!

  • Hi,

    In your code `no` is a python variable, which isn't defined. What you want to be using is either self.add_cmake_options(WITH_DOCS=False) if the project expects a CMake boolean (i.e. ON/OFF/TRUE/FALSE) or self.add_cmake_options(WITH_DOCS="no") if the project does a string comparison.

  • Hi there,

    Thanks for your response. The project is expecting a string comparison so I've added self.add_cmake_options(WITH_DOCS="no")

    The build is still erroring out because it can't find xsltproc to generate the man pages, even though I've told it to skip that step:

    CMake Error at man/CMakeLists.txt:29 (message):
        xsltproc not found: manpages cannot be built

    -- Configuring incomplete, errors occurred!

    Any ideas on how best to resolve this?

  • I don't see WITH_DOCS mentioned anywhere in the CMakeLists.txt there. However, there is a 

    option(DOCUMENTATION "Build documentation?" ON)

    so you should be able to use self.add_cmake_options(DOCUMENTATION=False).

    I'd recommend opening an issue with the project and tell them that their documentation is out-of-date.

  • It's always been that https://github.com/eclipse/mosquitto/commit/3163cf2d709e7b021867aec2e811331991ad097a. Someone just put the wrong thing in the README, presumably wasn't thinking and assumed it followed the same pattern as all the other options which do use WITH_FOO.

  • Ah. It's WITH_DOCS for the Makefile, and the README talks about make. For CMake it just says "Equivalent options for enabling/disabling features are available when using the CMake build".

  • Thanks for the clarification Jessica :) It seems to build perfectly now

  • Another quick question on this. Do I have to use an upstream Git repository as I have with this Python script, or can I use another method such as referencing a local directory if I have already downloaded the source manually? Or maybe another method? Thanks

  • I have ran into another error when trying to cross-compile tcpdump. I have tried create a Python script to add it as a cheribuild target, and also cross-compiling manually with:

    CC="$HOME/cheri/output/morello-sdk/bin/clang --target=aarch64-unknown-freebsd13 --sysroot=$HOME/cheri/output/rootfs-morello-purecap" CFLAGS="-march=morello+c64 -mabi=purecap -femulated-tls" LDFLAGS="-fuse-ld=lld" PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR= ./configure --host=aarch64-unknown-freebsd13

    ...but I keep getting the same error and the build stops:

    checking whether printf(3) supports the z length modifier... configure: error: in `/home/ubuntu/tcpdump':
    configure: error: cannot run test program while cross compiling
    See `config.log' for more details

    The "tests" folder in the source directory is the last thing accessed by the configure script but keeps erroring out. Looking at the config.log, this is what is displayed with relation to that error:

    conftest.c:66:6: note: 'snprintf' is a builtin with type 'int (char *, unsigned long, const char *, ...)'1 warning generated.
    configure:4963: $? = 0
    configure:4963: result: yes
    configure:4975: checking whether printf(3) supports the z length modifier
    configure:4978: error: in `/home/ubuntu/tcpdump':
    configure:4980: error: cannot run test program while cross compiling
    See `config.log' for more details

  • Another quick question on this. Do I have to use an upstream Git repository as I have with this Python script, or can I use another method such as referencing a local directory if I have already downloaded the source manually? Or maybe another method? Thanks

    If you have a local directory with sources you can use 

    repository = ExternallyManagedSourceRepository()

    to skip the update step for cheribuild. You will have to ensure the sources are in the expected directory or manually set the "<project>/source-directory" config option.

    checking whether printf(3) supports the z length modifier... configure: error: in `/home/ubuntu/tcpdump':
    configure: error: cannot run test program while cross compiling
    See `config.log' for more details

    Autotools is a terrible "build system" so often requires various workarounds when cross-compiling. The same issue happened with PostgreSQL and there the workaround is:

                # tell postgres configure that %zu works in printf()
                self.add_configure_and_make_env_arg("PRINTF_SIZE_T_SUPPORT", "yes")

    However, since autotools build scripts are essentially just shell scripts that use arbitrary variable naming conventions, tcpdump may well be using a different environment variable for this. You'll have to look at the generated configure script to find out which variable they decided to use.

  • to skip the update step for cheribuild. You will have to ensure the sources are in the expected directory or manually set the "<project>/source-directory" config option.

    I'm not sure what you mean by this above.

    Also, what is the CheriConfig module imported in the postgres.py script and what is the purpose of this?

    And looking at the configure script, the portion of the script that is erroring out is this:

    #
    # Define HAVE_NO_PRINTF_Z to make it possible to disable test cases that
    # depend on %zu.
    #
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether printf(3) supports the z length modifier" >&5
    $as_echo_n "checking whether printf(3) supports the z length modifier... " >&6; }
    if test "$cross_compiling" = yes; then :
    { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
    as_fn_error $? "cannot run test program while cross compiling
    See \`config.log' for more details" "$LINENO" 5; }
    else
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h. */

    However, I'm not sure which environment variable I have to manipulate to bypass these checks. I am guessing it is HAVE_NO_PRINTF_Z but I am not sure if that is even an environment variable, or how to define that in the Python build script. In the configure.ac file, the following is defined:

    AC_DEFINE(HAVE_NO_PRINTF_Z, 1,
    [Define to 1 if printf(3) does not support the z length modifier.])

    So my question is how do I manipulate the configure.ac file through the Python build scripts for my project?

  • After researching further into this, it seems to not be a problem at all with printf() supporting the z length modifier, but instead, the configure script is erroring out because it is trying to run tests, which it cannot do because the target binary is being cross-compiled and doesn't understand it. Output from the configure script:

    if test "$cross_compiling" = yes; then :
    { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
    as_fn_error $? "cannot run test program while cross compiling
    See \`config.log' for more details" "$LINENO" 5; }
    else
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    /* end confdefs.h. */

    Is there a way I can amend the Python build script to include a Site Default which includes: cross_compiling=no to skip this test?

    cross_compiling is being set to yes at this portion of the configure script when checking if the build machine is the same as the target machine:

    elif test "x$build_alias" != "x$host_alias"; then
    cross_compiling=yes

  • So I managed to disable this from happening manually by editing out....

    as_fn_error

    from the configure script to stop it erroring and cancelling the build. It now builds just fine. I am still unsure how this would equate to amendments to a Python build script.

  • That is far from a fix, and may be causing subtle mis-compiles. The correct thing to do is to find out what the test is doing, find out what variable it's using for the test result and manually specify the value for the variable so the test is skipped, normally via something like self.add_configure_vars(ac_cv_foo="bar") in your target's setup function.