Run PowerShell or Shell script from CMake - cmake

I have a (power)shell script that generates a version file used in other source files in the project.
How can I "register" this script to be used with CMake in build time? Here is what I have tried:
function(version)
set(SRC version.h)
set(VERSION_CMD ${CMAKE_SOURCE_DIR}/fw_lib/version/version.ps1)
ADD_CUSTOM_TARGET(version DEPENDS ${SRC})
ADD_CUSTOM_COMMAND(
OUTPUT ${SRC} COMMAND ${VERSION_CMD}
${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}
)
endfunction(version)
Note that ${CMAKE_SOURCE_DIR} and ${CMAKE_BINARY_DIR} are input arguments to the script.
I get the following error:
process_begin: CreateProcess(....) failed.
make (e=193): Error 193
How can I make this work?

Maybe it is too late, but for future:
# find Powershell executable
find_program(POWERSHELL_PATH NAMES powershell)
add_custom_command(
TARGET "program"
POST_BUILD
COMMAND ${POWERSHELL_PATH} "Some Powershell command")

Related

CMake: dependecies of add_custom_command

Let's say I have a Python script which does something with just built executable. And I want CMake to rebuild that executable if the script was modified (actually it is enough to just re-run the script, but rebuild an executable is fine too).
add_executable(App src/main.cpp)
add_custom_command(
TARGET App
POST_BUILD
COMMAND "${Python3_EXECUTABLE}" ARGS "scripts/do_stuff.py" "$<TARGET_FILE:App>"
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}"
)
How can I achieve that? add_custom_command with TARGET argument doesn't support DEPENDS argument. add_dependency(App "scripts/do_stuff.py") produces an error, because "scripts/do_stuff.py" is not a target, but just a file.
Running the script is very important for correct working of the executable so I don't want define completely separate target via add_custom_command allowing bypass script execution by building just App target.
actually it is enough to just re-run the script
So the executable does not depend on the script. So re-run the script, not the executable.
add_executable(app src/main.cpp)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/did_do_stuff
COMMAND "${Python3_EXECUTABLE}" "scripts/do_stuff.py" "$<TARGET_FILE:app>"
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/did_do_stuff
DEPENDS "$<TARGET_FILE:app>"
"${CMAKE_CURRENT_LIST_DIR}/scripts/do_stuff.py"
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}"
)
add_custom_target(do_stuff
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/did_do_stuff
)
And build target do_stuff (or all) to run it.

CMake: require building of files in addition to building targets

In this simple CMakefile, the first script list.sh outputs a list of 2 generated files file1.proto;file2.proto, instructing CMake that they can be built from source source.xml (using the second script gen.sh).
cmake_minimum_required(VERSION 3.13)
set(source "source.xml")
execute_process(
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/list.sh ${source}
OUTPUT_VARIABLE protos
)
message("${protos}: ${source}")
add_custom_command(
OUTPUT ${protos}
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/gen.sh ${source}
DEPENDS ${source}
)
add_custom_target(my_target DEPENDS ${protos})
Everything works well if I run:
$ cmake ..
file1.proto;file2.proto: source.xml
-- Configuring done
-- Generating done
-- Build files have been written to: /build
$ make my_target
[100%] Generating file1.proto, file2.proto
[100%] Built target my_target
What should I add to be able to also run the code generation with:
$ make file1.proto
[EDIT] autocomplete suggests only the following for command make:
$ make (TAB TAB)
all cmake_force edit_cache/ preinstall
clean default_target help preinstall/
clean/ depend my_target rebuild_cache
cmake_check_build_system edit_cache my_target/ rebuild_cache/
Solution from #KamilCuk :
Adding the following makes it possible to build each proto file individually
(it works, but then cmake complains about circular dependencies!)
foreach(p ${protos})
add_custom_target(${p} DEPENDS {CMAKE_CURRENT_BINARY_DIR}/${p})
endforeach()

Is there a command on CMake to started executable resulted from build?

I'm trying to write generic way to run executable resulted after build using CMake's way.
git clone git#github.com:gargamel/ihatesmurfs.git
cmake -E make_directory build
cmake -Sihatesmurfs -Bbuild
cmake --build build
cmake -E chdir build
Now I want to start executable but on *nix, it's like:
./output
and on Windows:
output.exe
Is there a way to escape this with any possible CMake command?
Expanding on my comment a bit, you can modify the CMakeLists.txt file of the project to include add_custom_command. If your CMake creates an executable named HateSmurfs, you can add the custom command to run the executable after compilation completes:
add_executable(HateSmurfs smurfs.cpp)
# Add this piece of code to run the executable after it is built.
add_custom_command(
TARGET HateSmurfs
POST_BUILD
COMMAND HateSmurfs
)
According to add_custom_command documentation:
COMMAND
If COMMAND specifies an executable target name (created by the add_executable() command) it will automatically be replaced by the location of the executable created at build time.

Random executable output with CMake

Can I have a random name for the executable file of each build?
Or, in another words, a different name for the executable of each build action?
I wonder if a random-variable could be inserted into the build-tool-chain.
The reason of such a name is that my company's virus-checking is quite slow -- it took a long long time checking each executable, even longer then the build.
I'm using CLion 2016.2 on Win7, tool-chain is MinGW_w64_5.0, bundled CMake 3.5.2
You could always define POST_BUILD steps that call another CMake script. The only downside in the following approach would be that you can't - since it's random - reuse the executable's output name in CMake itself:
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(RandomExeName)
file(WRITE main.cpp "int main() { return 0; }")
add_executable(${PROJECT_NAME} main.cpp)
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -D _file:PATH="$<TARGET_FILE:${PROJECT_NAME}>"
-P ${CMAKE_SOURCE_DIR}/CopyToRandom.cmake
)
set_property(TARGET ${PROJECT_NAME} PROPERTY SUFFIX ".temp")
CopyToRandom.cmake
string(RANDOM _random)
file(GLOB _old_files RELATIVE "${CMAKE_BINARY_DIR}" "*.exe")
execute_process(
COMMAND "${CMAKE_COMMAND}" -E remove ${_old_files}
COMMAND "${CMAKE_COMMAND}" -E copy "${_file}" "${_random}.exe"
)
# generate shortcut
get_filename_component(_name "${_file}" NAME_WE)
file(
WRITE "${_name}.sh"
"#!/bin/bash\n"
"${_random}.exe"
)
No you can't. Or you have to reconfigure for every build.
Regarding your actual problem: Advice the virus checker to exclude your build directories.

Using cmake with a custom file generator

I'd like to use CMake to generate obfuscated lua files for delivery. For the life of me I cannot get add_custom_command + add_custom_target to build these files for me. There's something I'm missing.
ADD_CUSTOM_TARGET(LUABIND_COMPILED_FILES ALL)
FOREACH(F ${LUA_SCRIPT_FILES})
ADD_CUSTOM_COMMAND(
OUTPUT ${LUA_COMPILED_SCRIPTS}/${F}
COMMAND ${LUAC} -o ${LUA_COMPILED_SCRIPTS}/${F}
COMMENT "Compiling ${F} to binary"
ADD_DEPENDENCIES(LUABIND_COMPILED_FILES ${LUA_COMPILED_SCRIPTS}/${F})
ENDFOREACH()
For some reason when I run cmake + make the output tells me there's nothing to be done for target LUABIND_COMPILED_FILES. Am I missing something here? Thanks in advance.
The ADD_DEPENDENCIES command can only be used to add dependencies between top-level targets. The ADD_CUSTOM_COMMAND command however generates output files, but does not add new targets.
To make a custom target depend on generated files, use the DEPENDS options of the add_custom_target command:
set (LUA_COMPILED_FILES "")
foreach(F ${LUA_SCRIPT_FILES})
add_custom_command(
OUTPUT "${LUA_COMPILED_SCRIPTS}/${F}"
COMMAND ${LUAC} -o "${LUA_COMPILED_SCRIPTS}/${F}"
COMMENT "Compiling ${F} to binary")
list (APPEND LUA_COMPILED_FILES "${LUA_COMPILED_SCRIPTS}/${F}")
endforeach()
add_custom_target(LUABIND ALL DEPENDS ${LUA_COMPILED_FILES})