How to deal with failing file(MAKE_DIRECTORY

Hi,
I am trying to create a directory using file(MAKE_DIRECTORY …).
I want to handle the failure case: abort the configuration and print a custom error message.

The call to file(MAKE_DIRECTORY …) is somewhere deep in a function call. When it fails it prints its own error message, the execution of the function stops and unwinds all the way to the top-level CMakeLists.txt. From there the execution continues with the next instruction.

This means I cannot handle this error locally but only at the top level. Am i missing something?

A condensed example looks like this:

cmake_minimum_required(VERSION 3.29)

project(demo)

function(this_function_fails)
  file(MAKE_DIRECTORY "/root/test")
  message(STATUS "This line will never be reached")
  if(NOT EXISTS "/root/test")
    message(FATAL_ERROR "Failed to create directory /root/test")
  endif()
endfunction()

this_function_fails()
# Error handling can only happen here?
message(STATUS "The next line that will be executed")

The output of running the script is as follows:

❯ cmake .          
-- The C compiler identification is GNU 12.3.0
-- The CXX compiler identification is GNU 12.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error at CMakeLists.txt:6 (file):
  file failed to create directory:

    /root/test

  because: Permission denied
Call Stack (most recent call first):
  CMakeLists.txt:13 (this_function_fails)


-- The next line that will be executed.
-- Configuring incomplete, errors occurred!

Thanks in advance for your help.

This is something that’s annoyed me too–I wish file(MAKE_DIRECTORY) had an optional RESULT or such that allowed handling error oneself.

This allows the behavior you want:

cmake_minimum_required(VERSION 3.10)

project(demo LANGUAGES NONE)

function(this_function_fails dir)
  # file(MAKE_DIRECTORY ${dir})
  # message(STATUS "This line will never be reached")

  execute_process(
    COMMAND ${CMAKE_COMMAND} -E make_directory ${dir}
    RESULT_VARIABLE result
  )

  if(NOT result EQUAL 0 OR NOT IS_DIRECTORY ${dir})
    message(FATAL_ERROR "Failed to create directory ${dir}")
  endif()
endfunction()

this_function_fails("/test")

message(STATUS "The next line that will be executed")

Indeed. Please file a feature request.

done in https://gitlab.kitware.com/cmake/cmake/-/issues/26041

1 Like