Search code examples
pythoncmake

CMake Python execv-based wrapper fails with `CMake Error: Could not find CMAKE_ROOT !!!`


I want to write a Python wrapper for CMake, but even the simplest of wrappings fails:

#!/usr/bin/env python
import os
import sys
os.execvp("cmake", sys.argv) # or 'sys.argv[1:]', both fail

Running this Python script with e.g. ./pycmake . in a directory containing a CMakeLists.txt fails with:

CMake Error: Could not find CMAKE_ROOT !!!
CMake has most likely not been installed correctly.
Modules directory not found in

CMake Error: Error executing cmake::LoadCache(). Aborting.

Running cmake . on the same directory works without issues.

Am I forgetting something when doing the os.execvp call? Or is CMake using some mechanism that fails when wrapped by Python?


Solution

  • As the documentation says:

    In either case, the arguments to the child process should start with the name of the command being run, but this is not enforced.

    cmake, as well as some other programs, requires that the first argument must be its name or the path to the executable. It's doing some work with that argument under the hood, mostly initialization, that's because it yells about missing CMAKE_ROOT, when it gets something else. Thus, the solution should look like this:

    #!/usr/bin/env python
    
    import os
    import sys
    
    os.execvp("cmake", ["cmake"] + sys.argv[1:])