Search code examples
yoctobitbakeopenembedded

Handling failed task in Yocto recipe


I need some advice on how to handle errors in recipe tasks. Consider the following snippet for a Yocto recipe recipe:

do_compile_custom() {
    oe_runmake  // oe_runmake command fails 
}
addtask compile_custom after do_compile before do_install

When oe_runmake fails, i want to execute some custom command and to continue with the build so i thought that this should work.

do_compile_custom() {
    oe_runmake || true // oe_runmake command fails 
    if [ $? -ne 0 ]; then
        bberror "MAKE FAILED"
    fi
}
addtask compile_custom after do_compile before do_install

But when oe_runmake fails, it exits the task and the rest of the task is not executed. I don't see

MAKE FAILED

in my build log.

I started to investigate bitbake Events so the next thing i did was to add an event handler in my recipe, without any event filters at first to see all the events received.

do_compile_custom() {
    oe_runmake  // oe_runmake command fails 
}
addtask compile_custom after do_compile before do_install

addhandler failure_eventhandler
python failure_eventhandler() {
    from bb.event import getName
    print("strtogrep The name of the Event is %s" % getName(e))
}

With this implementation of the recipe, from the handler i am only able to see 3 events printed:

| The name of the Event is RecipePreFinalise
| The name of the Event is RecipeTaskPreProcess
| The name of the Event is RecipeParsed

From all the events defined in bitbake, i was expecting to get TaskFailed Event after the task fails but this is never received. Does anyone have some suggestions on how to handle this?


Solution

  • The reason why You can't occur MAKE FAILES log message is the consequence of oe_runmake function.

    As You can see implementation of oe_runmake (from meta/classes/base.bbclass file), runs die() logging function in case of any failures:

    58 oe_runmake() {                                     
    59     oe_runmake_call "$@" || die "oe_runmake failed"
    60 }
    

    Lately on die() function use bbfatal_log() function (from meta/classes/logging.bbclass file), which finally end's with exit 1:

    66 bbfatal_log() {
    67     if [ -p ${LOGFIFO} ] ; then
    68         printf "%b\0" "bbfatal_log $*" > ${LOGFIFO}
    69     else
    70         echo "ERROR: $*"
    71     fi
    72     exit 1
    73 }
    

    I think easiest way for You to archive Your goal, is to give up with using default do_compile implementation task in order that have a custom compile task, with error handling:

    # disable do_compile task
    do_compile[noexec] = "1"
    
    do_compile_custom() {
        oe_runmake_custom_call() {                    
            bbnote ${MAKE} ${EXTRA_OEMAKE} "$@"
            ${MAKE} ${EXTRA_OEMAKE} "$@"       
        }                                      
    
        oe_runmake_custom_call || bbwarn "oe_runmake_custom failed"
        if [ $? -ne 0 ]; then
            bberror "MAKE FAILED"
        fi
    }
    addtask compile_custom before do_install