I have this snippet in my CMakeLists.txt
of my raspberrypi/pico-sdk project, where I conditionally call the pico_sdk_init()
function (that is, macro):
# ...
if(myCONDITION STREQUAL "Something")
message("*** BEFORE pico_sdk_init() ***")
pico_sdk_init()
message("*** BEFORE return() ***")
return() # exit for debug
# other CMake conditional code commands continue here ...
endif() # myCONDITION STREQUAL "Something"
# ...
So, I do mkdir build && cd build
in the project directory where the CMakeLists.txt
is, and then I run cmake
- in this case, I get output like this:
$ cmake ../ -DCMAKE_BUILD_TYPE=Debug -G "MSYS Makefiles"
...
*** BEFORE pico_sdk_init() ***
Build type is Debug
...
Using PICO_EXAMPLES_PATH from environment ...
*** BEFORE return() ***
-- Configuring done
-- Generating done
-- Build files have been written to: C:/path/to/myproject/build
After this, if I check from the ./build
subfolder, I have a Makefile
there (and in a whole bunch of other locations):
$ find . -name Makefile
./Makefile
./pico-sdk/docs/Makefile
./pico-sdk/Makefile
./pico-sdk/src/common/boot_picobin_headers/Makefile
...
./pico-sdk/src/rp2_common/tinyusb/Makefile
./pico-sdk/tools/Makefile
... and for the Makefile
in the ./build
subfolder, I have the following targets:
$ make #press [TAB] here
all default_target
bs2_default/fast depend
bs2_default_bin/fast edit_cache/fast
bs2_default_library/fast help
clean/fast pioasmBuild/fast
cmake_check_build_system preinstall/fast
cmake_force rebuild_cache/fast
cyw43_driver_picow_cyw43_bus_pio_spi_pio_h/fast
So, I can run, say, make pioasmBuild
at this point, and it will build fine:
$ make pioasmBuild
Scanning dependencies of target pioasmBuild
[ 12%] Creating directories for 'pioasmBuild'
[ 25%] No download step for 'pioasmBuild'
...
Scanning dependencies of target pioasm
[100%] Built target pioasm
[ 87%] Performing install step for 'pioasmBuild'
[100%] Built target pioasm
Install the project...
-- Install configuration: "Release"
[100%] Completed 'pioasmBuild'
[100%] Built target pioasmBuild
$ find . -name pioasm.exe
./pioasm/pioasm.exe
./pioasm-install/pioasm/pioasm.exe
Great.
Now, let's say, I do not want to exit for debug with return()
- but instead, at that point, I want to run the equivalent of make pioasmBuild
: so from that point on, pioasm.exe
is available for the "other CMake conditional code commands"; for that, I rewrite my snippet as:
# ...
if(myCONDITION STREQUAL "Something")
message("*** BEFORE pico_sdk_init() ***")
pico_sdk_init()
execute_process(
# this command, the equivalent of `make pioasmBuild`, fails with "Error: could not load cache"
COMMAND ${CMAKE_COMMAND} --build . --target pioasmBuild
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
message("*** NOT anymore BEFORE return() ***")
#return() # exit for debug
# other CMake conditional code commands continue here ...
endif() # myCONDITION STREQUAL "Something"
# ...
As the comment already hints, the equivalent of make pioasmBuild
at this point fails - after cleaning with rm -rf *
in the ./build
subdirectory, this is what I get in the cmake
output:
$ cmake ../ -DCMAKE_BUILD_TYPE=Debug -G "MSYS Makefiles"
...
*** BEFORE pico_sdk_init() ***
Build type is Debug
...
Using PICO_EXAMPLES_PATH from environment ...
Error: could not load cache
*** NOT anymore BEFORE return() ***
... other CMake conditional code commands continue here ...
So, as far as I can see, this Error: could not load cache
happens because at that point, the Makefile
in the ./build
subfolder has not been created yet!
In fact, as I understand the process at this time: the creation of that Makefile
in ./build
, in the previous case, was triggered by the return()
early exit itself!
So my question is - is there a canonical way for us to force CMake to have configuring, generating and writing of build files to be completed at this (or arbitrary) point in the CMakeLists.txt
file (using whatever data is available at that point; and at least in this case, as shown earlier, there is enough data at that point to generate a functioning Makefile
) - without forcing the cmake
process to exit at that point in CMakeLists.txt
, but instead proceed with the remaining commands (including possibly building a target in that previously/early generated Makefile
, directly from CMake)?
(Of course, in such a case of "early generation", when the CMakeLists.txt
reaches its otherwise "natural" end, then all Makefile
s and related build files would simply be overwritten, possibly with e.g. more targets, resulting from more data due to the execution of the remainder of the file)
I have this snippet in my CMakeLists.txt
of my raspberrypi/pico-sdk project, where I conditionally call the pico_sdk_init()
function (that is, macro):
# ...
if(myCONDITION STREQUAL "Something")
message("*** BEFORE pico_sdk_init() ***")
pico_sdk_init()
message("*** BEFORE return() ***")
return() # exit for debug
# other CMake conditional code commands continue here ...
endif() # myCONDITION STREQUAL "Something"
# ...
So, I do mkdir build && cd build
in the project directory where the CMakeLists.txt
is, and then I run cmake
- in this case, I get output like this:
$ cmake ../ -DCMAKE_BUILD_TYPE=Debug -G "MSYS Makefiles"
...
*** BEFORE pico_sdk_init() ***
Build type is Debug
...
Using PICO_EXAMPLES_PATH from environment ...
*** BEFORE return() ***
-- Configuring done
-- Generating done
-- Build files have been written to: C:/path/to/myproject/build
After this, if I check from the ./build
subfolder, I have a Makefile
there (and in a whole bunch of other locations):
$ find . -name Makefile
./Makefile
./pico-sdk/docs/Makefile
./pico-sdk/Makefile
./pico-sdk/src/common/boot_picobin_headers/Makefile
...
./pico-sdk/src/rp2_common/tinyusb/Makefile
./pico-sdk/tools/Makefile
... and for the Makefile
in the ./build
subfolder, I have the following targets:
$ make #press [TAB] here
all default_target
bs2_default/fast depend
bs2_default_bin/fast edit_cache/fast
bs2_default_library/fast help
clean/fast pioasmBuild/fast
cmake_check_build_system preinstall/fast
cmake_force rebuild_cache/fast
cyw43_driver_picow_cyw43_bus_pio_spi_pio_h/fast
So, I can run, say, make pioasmBuild
at this point, and it will build fine:
$ make pioasmBuild
Scanning dependencies of target pioasmBuild
[ 12%] Creating directories for 'pioasmBuild'
[ 25%] No download step for 'pioasmBuild'
...
Scanning dependencies of target pioasm
[100%] Built target pioasm
[ 87%] Performing install step for 'pioasmBuild'
[100%] Built target pioasm
Install the project...
-- Install configuration: "Release"
[100%] Completed 'pioasmBuild'
[100%] Built target pioasmBuild
$ find . -name pioasm.exe
./pioasm/pioasm.exe
./pioasm-install/pioasm/pioasm.exe
Great.
Now, let's say, I do not want to exit for debug with return()
- but instead, at that point, I want to run the equivalent of make pioasmBuild
: so from that point on, pioasm.exe
is available for the "other CMake conditional code commands"; for that, I rewrite my snippet as:
# ...
if(myCONDITION STREQUAL "Something")
message("*** BEFORE pico_sdk_init() ***")
pico_sdk_init()
execute_process(
# this command, the equivalent of `make pioasmBuild`, fails with "Error: could not load cache"
COMMAND ${CMAKE_COMMAND} --build . --target pioasmBuild
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
message("*** NOT anymore BEFORE return() ***")
#return() # exit for debug
# other CMake conditional code commands continue here ...
endif() # myCONDITION STREQUAL "Something"
# ...
As the comment already hints, the equivalent of make pioasmBuild
at this point fails - after cleaning with rm -rf *
in the ./build
subdirectory, this is what I get in the cmake
output:
$ cmake ../ -DCMAKE_BUILD_TYPE=Debug -G "MSYS Makefiles"
...
*** BEFORE pico_sdk_init() ***
Build type is Debug
...
Using PICO_EXAMPLES_PATH from environment ...
Error: could not load cache
*** NOT anymore BEFORE return() ***
... other CMake conditional code commands continue here ...
So, as far as I can see, this Error: could not load cache
happens because at that point, the Makefile
in the ./build
subfolder has not been created yet!
In fact, as I understand the process at this time: the creation of that Makefile
in ./build
, in the previous case, was triggered by the return()
early exit itself!
So my question is - is there a canonical way for us to force CMake to have configuring, generating and writing of build files to be completed at this (or arbitrary) point in the CMakeLists.txt
file (using whatever data is available at that point; and at least in this case, as shown earlier, there is enough data at that point to generate a functioning Makefile
) - without forcing the cmake
process to exit at that point in CMakeLists.txt
, but instead proceed with the remaining commands (including possibly building a target in that previously/early generated Makefile
, directly from CMake)?
(Of course, in such a case of "early generation", when the CMakeLists.txt
reaches its otherwise "natural" end, then all Makefile
s and related build files would simply be overwritten, possibly with e.g. more targets, resulting from more data due to the execution of the remainder of the file)
1 Answer
Reset to default 1There's no way to do this, since there may be other information about the targets that comes later in the CMakeLists.txt
files. What you want to do instead is add a dependency on pioasmBuild
anywhere that needs it, since that set up your actual build dependencies properly.
add_dependencies(my_target pioasmBuild)
However, I'd recommend building pioasmBuild
separately and using find_executable
instead. If you're cross-compiling, you'd build targets using the cross-compiler and thus can't use them on your native machine.