nRF Connect SDK: add_child_image() does not work for out-of-tree sources

I have several out-of-tree applications targeting the nRF9160 that all build correctly when built individually. One of these applications, named "secure_partition", is a customized clone of the Secure Partition Manager  (SPM) sample provided in the SDK. This image targets a "secure board" while the others target "nonsecure" boards.

For the non-secure applications, I would like to also build my "secure_partition" application as a child image. However, I have discovered multiple defects in the "Multi-image build" support offered by the NCS that prevent this from being possible.

The first defect I discovered is that it's not enough to simply add a call to `add_child_image(....)` in the `CMakeLists.txt` for the non-secure application. This is because the `partition_manager.cmake` script needs to run *after* the last call to `add_child_image(....)`. Currently Zephyr's build system assumes (incorrectly) that child images are only added by in-tree code, and thus Zephyr's build system includes `partition_manager.cmake` in the `app/boilerplate.cmake` file. 

The work-around for the first defect is to manually include `partition_manager.cmake` again after calling `add_child_image(...)` in the `CMakeLists.txt` for the non-secure application. It would be a much better API if the NCS just handled running the `partition_manager.cmake` script anytime a child image was added.

The second defect I discovered is that the `partition_manager.cmake` script makes an incorrect assumption about the location of the hex file for the 'app' image. The `partition_manager.cmake` script assumes that the 'app' image hex file is located at "${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME}". This assumption is only true when the active CMake project is the 'Zephyr-Kernel' project. If the active CMake project is the application project (aka the application `CMakeLists.txt` calls `project(....)`), then the value of `${PROJECT_BINARY_DIR}` will no longer correspond to the directory containing the Zephyr kernel build artifacts.

The `partition_manager.cmake` script should not assume that `${PROJECT_BINARY_DIR}` refers to the binary directory for the Zephyr kernel, as that variable is automatically changed by CMake anytime the `project(...)` function is called. Instead, the `partition_manager.cmake` script should determine the correct location of the `${KERNEL_HEX_NAME}` file via other means. It does not appear that Zephyr defines a variable such as ${ZEPHYR_BINARY_DIR}, though if would certainly be helpful if such a variable existed.

The work-around for the second defect is to set the location for the 'app' image hex file to `${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME}`. This work-around also relies on a sometimes-untrue assumption, namely that the binary directory for the application is the same as the root binary directory. In my immediate situation this assumption holds, but nothing guarantees it. A better permanent solution is necessary.

Related