I’m trying to use cmake for cross-compiling. My project also needs a home-made tool to compile target code. So building target code depends on the external tool.
I know we can use “export” command to generate a file for my cross-compiling project to include. But can cmake automatically generate a dependency relationship between my cross-compiling project and the external project that is used to build the home-made tool? So that, we I make my cross-compiling target, if the tool is outdated, cmake can automatically invoke another cmake instance to make the external tool first?
You can manage external projects by using module ExternalProject or FetchContent.
I tried ExternalProject. It works, but it seems that BUILD_ALWAYS has to been used, which is not preferred:
Enabling this option forces the build step to always be run. This can be the easiest way to robustly ensure that the external project’s own build dependencies are evaluated rather than relying on the default success timestamp-based method. This option is not normally needed unless developers are expected to modify something the external project’s build depends on in a way that is not detectable via the step target dependencies (e.g.
SOURCE_DIR is used without a download method and developers might modify the sources in
I tried by changing a source file in my external project, and then built from the main project, but the external project didn’t rebuild for the changed file.
If you need to work with two different compilers/platforms in the same build, using ExternalProject is pretty much unavoidable. As you’ve discovered, you need to use BUILD_ALWAYS if you are going to be making changes in the project that you bring in via ExternalProject_Add(). This is because ExternalProject is based around timestamps. Once a step has completed successfully, the only ways to get it to re-execute that step is if the download details change or if you explicitly ask it to always do the build step with BUILD_ALWAYS set to true (i.e. ignore the timestamp for the build step).
An alternative is to use a more traditional super build setup and have a top level project call ExternalProject_Add() twice - once for the home made tool/compiler and once for the cross-compiled code. You can run that super build once to get everything set up, then if you need to work on the cross-compiled code, you can build just that subproject as though it was standalone and likewise for the home made tool/compiler. You would only need to re-execute the top level super build project if something changed about the way the two sub-projects interacted. Just be aware that you need to exercise care to prevent the top level super build from discarding any uncommitted changes in the sub-projects.