Skip to content

Commit

Permalink
cmake: fail fast when execute_process() fails (firebase#10566)
Browse files Browse the repository at this point in the history
  • Loading branch information
dconeybe authored Dec 13, 2022
1 parent 67ae955 commit deda107
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 19 deletions.
6 changes: 4 additions & 2 deletions cmake/external_rules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

include("${CMAKE_CURRENT_LIST_DIR}/firebase_utils.cmake")

function(download_external_sources)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/external)

Expand All @@ -37,7 +39,7 @@ function(download_external_sources)
)
endif()

execute_process(
firebase_execute_process(
COMMAND
${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
-DFIREBASE_DOWNLOAD_DIR=${FIREBASE_DOWNLOAD_DIR}
Expand All @@ -56,7 +58,7 @@ function(download_external_sources)
set(cmake_build_args -j)
endif()

execute_process(
firebase_execute_process(
COMMAND ${CMAKE_COMMAND} --build . -- ${cmake_build_args}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/external
)
Expand Down
94 changes: 94 additions & 0 deletions cmake/firebase_utils.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Join all the input arguments together using the <glue> string and store the
# result in the named <output_variable>.
#
# TODO: Delete this function once cmake_minimum_required() is 3.12 or greater,
# in which case the built-in list(JOIN ...) command should be used instead.
# See https://cmake.org/cmake/help/v3.12/command/string.html#join
function(firebase_string_join glue output_variable)
list(LENGTH ARGN ARGN_LENGTH)

if(ARGN_LENGTH EQUAL 0)
set("${output_variable}" "" PARENT_SCOPE)
return()
endif()

list(GET ARGN 0 result_string)
list(REMOVE_AT ARGN 0)

foreach(argv_element ${ARGN})
string(APPEND result_string "${glue}")
string(APPEND result_string "${argv_element}")
endforeach()

set("${output_variable}" "${result_string}" PARENT_SCOPE)
endfunction(firebase_string_join)

# A wrapper around the built-in execute_process() function that adds some
# additional functionality.
#
# In addition to calling the built-in execute_process() function, this function
# also does the following:
# 1. Logs the arguments of the process being executed.
# 2. Fails if the process completes with a non-zero exit code.
function(firebase_execute_process)
cmake_parse_arguments(
"ARG" # prefix
"" # options
"WORKING_DIRECTORY" # one_value_keywords
"COMMAND" # multi_value_keywords
${ARGN}
)

list(LENGTH ARG_COMMAND ARG_COMMAND_LENGTH)
if(ARG_COMMAND_LENGTH EQUAL 0)
message(
FATAL_ERROR
"firebase_execute_process() COMMAND must be given at least one value."
)
endif()

set(execute_process_args "")
list(APPEND execute_process_args "COMMAND" ${ARG_COMMAND})

if("${ARG_WORKING_DIRECTORY}" STREQUAL "")
set(LOG_SUFFIX "")
else()
set(LOG_SUFFIX " (working directory: ${ARG_WORKING_DIRECTORY})")
list(APPEND execute_process_args "WORKING_DIRECTORY" "${ARG_WORKING_DIRECTORY}")
endif()

firebase_string_join(" " ARG_COMMAND_STR ${ARG_COMMAND})
message(
STATUS
"firebase_execute_process(): "
"running command: ${ARG_COMMAND_STR}${LOG_SUFFIX}"
)

execute_process(
${execute_process_args}
RESULT_VARIABLE process_exit_code
)

if(NOT process_exit_code EQUAL 0)
message(
FATAL_ERROR
"firebase_execute_process(): command failed with non-zero exit code "
"${process_exit_code}: ${ARG_COMMAND_STR}${LOG_SUFFIX}"
)
endif()

endfunction(firebase_execute_process)
21 changes: 4 additions & 17 deletions cmake/python_setup.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

include("${CMAKE_CURRENT_LIST_DIR}/firebase_utils.cmake")

# Sets up an isolated Python interpreter, installing required dependencies.
#
# This function does the following:
Expand Down Expand Up @@ -120,20 +122,13 @@ function(FirebaseSetupPythonInterpreter)
"using ${FIREBASE_PYTHON_HOST_EXECUTABLE}"
)
file(REMOVE_RECURSE "${PYVENV_DIRECTORY}")
execute_process(
firebase_execute_process(
COMMAND
"${FIREBASE_PYTHON_HOST_EXECUTABLE}"
-m
venv
"${PYVENV_DIRECTORY}"
RESULT_VARIABLE
FIREBASE_PYVENV_CREATE_RESULT
)
if(NOT FIREBASE_PYVENV_CREATE_RESULT EQUAL 0)
message(FATAL_ERROR
"Failed to create a Python virtualenv in ${PYVENV_DIRECTORY} "
"using ${FIREBASE_PYTHON_HOST_EXECUTABLE}")
endif()

# Find the Python interpreter in the virtualenv.
find_program(
Expand All @@ -157,22 +152,14 @@ function(FirebaseSetupPythonInterpreter)
"${LOG_PREFIX}: Installing Python dependencies into "
"${PYVENV_DIRECTORY}: ${ARG_REQUIREMENTS}"
)
execute_process(
firebase_execute_process(
COMMAND
"${PYTHON_EXECUTABLE}"
-m
pip
install
${ARG_REQUIREMENTS}
RESULT_VARIABLE
PIP_INSTALL_RESULT
)
if(NOT PIP_INSTALL_RESULT EQUAL 0)
message(FATAL_ERROR
"Failed to install Python dependencies into "
"${PYVENV_DIRECTORY}: ${ARG_REQUIREMENTS}"
)
endif()
endif()

# Write the stamp files.
Expand Down

0 comments on commit deda107

Please sign in to comment.