Tenho este trecho no CMakeLists.txt
meu projeto raspberrypi/pico-sdk , onde chamo condicionalmente a pico_sdk_init()
função (ou seja, 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"
# ...
Então, eu faço isso mkdir build && cd build
no diretório do projeto onde ele CMakeLists.txt
está e então executo cmake
- neste caso, obtenho uma saída como esta:
$ 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
Depois disso, se eu verificar na ./build
subpasta, tenho um Makefile
lá (e em vários outros locais):
$ 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
... e para a Makefile
subpasta ./build
, tenho os seguintes alvos:
$ 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
Então, eu posso executar, digamos, make pioasmBuild
neste ponto, e ele será construído corretamente:
$ 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
Ótimo.
Agora, digamos que eu não queira sair para depuração com return()
- mas, em vez disso, naquele ponto, eu queira executar o equivalente a make pioasmBuild
: então, daquele ponto em diante, pioasm.exe
está disponível para os "outros comandos de código condicional do CMake"; para isso, eu reescrevo meu snippet como:
# ...
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"
# ...
Como o comentário já sugere, o equivalente a make pioasmBuild
neste ponto falha - depois de limpar rm -rf *
no ./build
subdiretório, isto é o que obtenho na cmake
saída:
$ 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 ...
Então, até onde posso ver, isso Error: could not load cache
acontece porque, naquele ponto, a Makefile
subpasta ainda não ./build
foi criada !
Na verdade, pelo que entendi do processo neste momento: a criação disso Makefile
em ./build
, no caso anterior, foi desencadeada pela return()
própria saída antecipada!
Então, minha pergunta é: existe uma maneira canônica de forçar o CMake a ter a configuração, geração e gravação de arquivos de compilação a serem concluídos neste (ou arbitrário) ponto do CMakeLists.txt
arquivo (usando quaisquer dados disponíveis naquele ponto; e pelo menos neste caso, como mostrado anteriormente, há dados suficientes naquele ponto para gerar um Makefile
) funcional - sem forçar o cmake
processo a sair naquele ponto em CMakeLists.txt
, mas em vez disso prosseguir com os comandos restantes (incluindo possivelmente a compilação de um destino naquele gerado anteriormente/antecipadamente Makefile
, diretamente do CMake)?
(É claro que, em tal caso de "geração inicial", quando o CMakeLists.txt
atinge seu fim "natural", todos os Makefile
s e arquivos de compilação relacionados seriam simplesmente substituídos, possivelmente com, por exemplo, mais alvos, resultando em mais dados devido à execução do restante do arquivo)
Não há como fazer isso, pois pode haver outras informações sobre os alvos que vêm depois nos
CMakeLists.txt
arquivos. O que você quer fazer em vez disso é adicionar uma dependência empioasmBuild
qualquer lugar que precise dela, pois isso configura suas dependências de build reais corretamente.No entanto, eu recomendaria compilar
pioasmBuild
separadamente e usarfind_executable
em vez disso. Se você estiver compilando de forma cruzada, você compilaria alvos usando o compilador cruzado e, portanto, não poderá usá-los em sua máquina nativa.