This example aims to show colcon's behavior when following dependencies from an <exec_depend> to a <build_export_depend>. What is described here isn't necessarily wrong, but an attempt to explain the behavior.
There are 3 pure-CMake packages in this repository:
pkg_c - no dependencies pkg_b - <build_export_depend> on pkg_c pkg_a - <exec_depend> on pkg_b
The packages themselves do nothing other than install a single file.
When building pkg_c, it doesn't access any of the paths from the other packages; it has no dependencies.
When building pkg_b, it pulls in the paths and other things from package_c, since it has a <build_export_depend> on it.
When building pkg_a, it doesn't pull in anything; there is only an <exec_depend> between pkg_a and pkg_b, and, in theory, that shouldn't be necessary at build time.
rm -rf build/ install/ log example.* # Remove old artifacts
colcon build --event-handlers console_direct+ # build everything once
rm -rf build/pkg_a install/pkg_a # Remove the artifacts from pkg_a
strace -o example -tt -s 1024 -ff colcon build --event-handlers console_direct+ --packages-select pkg_a # Build pkg_a, tracing all accesses
strace-log-merge example > example.out # Merge together the strace output
grep "pkg_c/package.sh" example.out # Look for accesses to pkg_c from pkg_a
When running the above, what we actually see is that the build for pkg_a does actually pull in pkg_c, in particular it opens up pkg_c/package.sh for reading. Whether that is actually correct is somewhat open for interpretation.