blob: bd790c96c0e2d18a611192e0088a8b7b873dbf71 [file] [log] [blame] [edit]
#!/usr/bin/env -S cmake -P
#
# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
#
# SPDX-License-Identifier: BSD-2-Clause
#
message("CMake REPL: Execute cmake commands interactively. (Ctrl-D to exit)")
# If this file was included somewhere else then CMAKE_PARENT_LIST_FILE will be set
if(NOT "${CMAKE_PARENT_LIST_FILE}" STREQUAL "")
message(" Currently included in file: ${CMAKE_PARENT_LIST_FILE}")
set(state_dir ${CMAKE_BINARY_DIR}/.repl/)
set(history_file ${CMAKE_BINARY_DIR}/.repl/history)
else()
# If not included by anywhere else, then spew data into the user's home directory
# Calculate a thread id to allow running multiple instances
file(GLOB tids /proc/self/task/*)
list(GET tids 0 tid_path)
get_filename_component(tid ${tid_path} NAME)
set(state_dir "$ENV{HOME}/.cmakerepl/tid/")
set(history_file $ENV{HOME}/.cmakerepl/history)
endif()
file(MAKE_DIRECTORY ${state_dir})
file(TOUCH ${history_file})
set(prompt "> ")
# Write a python read script out to disk. We use this to for obtaining user input
# it uses readline to provide history and line editing. Unfortunately it isn't
# featured enough to support multiline input.
file(WRITE ${state_dir}/read.py "from __future__ import print_function
import readline
f = open(\"${state_dir}/test\", 'w')
readline.read_history_file(\"${history_file}\")
try:
s = raw_input(\"${prompt}\")
print(s, file=f)
readline.write_history_file(\"${history_file}\")
except EOFError:
print(\"set(forever OFF)\", file=f)
")
# Declare a short hand run function for executing something on the shell
# if this starts name colliding with existing functions in scope it can just be deleted
function(run)
execute_process(
COMMAND ${ARGV}
INPUT_FILE /dev/stdin
OUTPUT_FILE /dev/stdout
ERROR_FILE /dev/stderr
)
endfunction()
# Start REPL.
# This calls the python script that prompts the user for input.
# The input is then written out to a file which cmake includes into itself
# Including the file results in its execution.
# Then we loop back again.
# Exiting is implemented by setting the loop variable to false when an EOF exception
# is caught in the python script.
set(forever ON)
while(forever)
execute_process(
COMMAND python ${state_dir}/read.py
INPUT_FILE /dev/stdin
OUTPUT_FILE /dev/stdout
ERROR_FILE /dev/stderr
)
include(${state_dir}/test)
endwhile()