[cmake-developers] Setting up environment using ExternalProject_Add

James Johnston johnstonj.public at codenest.com
Wed Aug 12 20:06:14 EDT 2015


> -----Original Message-----
> From: cmake-developers [mailto:cmake-developers-bounces at cmake.org]
> On Behalf Of Brad King
> Sent: Wednesday, August 12, 2015 14:10
> To: cmake-developers at cmake.org
> Subject: Re: [cmake-developers] Setting up environment using
> ExternalProject_Add
> 
> On 08/11/2015 10:41 AM, James Johnston wrote:
> > 1.  CMake creates a temporary shell script / batch file (the shell
> > chosen based on the platform CMake compiled for - cmd.exe on Windows,
> sh on POSIX).
> 
> I don't think CMake needs to be the one to generate this.  The complexity
of
> the file-based or command-line-based interfaces you discussed shows that
it
> would be tricky to have CMake generate it.
>
> <snip>

OK...

> > enhancing e.g. add_custom_command as I proposed might make it easier,
> > as this command could be aware of compiled EXE targets.
> 
> With file(GENERATE) the project code can easily create scripts that
reference
> executable targets and such.  One would just need to tackle this feature
> request first to get file permissions right:
> 
>  http://www.cmake.org/Bug/view.php?id=15653

Indeed; that looks like a useful feature to have to begin with, and a
requirement if ExternalProject is to generate its own script...

> 
> Therefore I do not think add_custom_command needs any hook for this.
> One would simply give the script as the COMMAND.

Right, obviously not needed if no "cmake -E" option is added/enhanced and if
we want ExternalProject_Add (and anyone else needing custom targets) to make
their own script...

> 
> > we'd want to add features to ExternalProject that use the new CMake
> > functionality to finally solve the original problem.
> 
> Yes, this part certainly needs an update to ExternalProject.  Currently
when
> one specifies an individual <step>_COMMAND like CONFIGURE_COMMAND,
> then one could simply give it the environment-set-and-launch script
directly.
> What ExternalProject needs is an interface to specify the environment-
> setting script for use around otherwise default-generated commands for
> each step.  For example, a <step>_ENVIRONMENT setting (which is perhaps
> not allowed in combination with <step>_COMMAND).
> This approach is similar to your original alternative (3).

I'll explore that option some more, after the feature you linked to is
addressed.  " one could simply give it the environment-set-and-launch script
directly" ... This script is obviously platform-specific, yet still needs
knowledge of the command that ExternalProject will generate to launch the
sub-CMake - which the user of ExternalProject obviously does not know.  I am
not sure that introducing some shell-specific knowledge to ExternalProject
can be avoided in this case, so hopefully it will not be a problem to do
this.

There are two ways I immediately think of - trying to clarify what I think
you are suggesting:

1.  The new <step>_ENVIRONMENT setting points to a "environment-set" script
that does not try to do any launching (e.g. you could pass VCVarsAll.bat
directly as the <step>_ENVIRONMENT).  ExternalProject determines which shell
to generate for, and generates the "environment-set-and-launch script"
itself from scratch (like how I originally proposed with the "cmake -E"
enhancement).

In other words, ExternalProject(<snip> CONFIGURE_ENVIRONMENT
$ENV{VS100COMNTOOLS}/../../VC/vcvarsall.bat x86 CMAKE_GENERATOR Ninja
CMAKE_CACHE_ARGS <snip>) and away the user goes..

2.  The new <step>_ENVIRONMENT setting points to an
"environment-set-and-launch" script that is expected to be configured with
configure_file by ExternalProject.  So e.g. the user provides a batch file
that calls VCVarsAll.bat, and then there is a magical
${EXTERNAL_PROJECT_COMMAND} or whatever that the user is expected to provide
at the end of the template batch file that they give to ExternalProject.  I
suspect this will simplify ExternalProject a little bit at the cost of more
boiler-plate code that the user has to provide (e.g. can't directly call
VCVarsAll.bat in the common case, must manage their own scripts).  And gives
the user opportunity to really mess up ExternalProject operation (e.g.
forgetting to include ${EXTERNAL_PROJECT_COMMAND}, or forgetting to check
ERROR_LEVEL in a shell-specific way after calling EXTERNAL_PROJECT_COMMAND,
etc.).  I think this would not be as user friendly, but perhaps slightly
easier for ExternalProject to handle.  But at the end, the configure_file
substitution for ${EXTERNAL_PROJECT_COMMAND} is still potentially
shell-specific....

In other words, ExternalProject(<snip> CONFIGURE_ENVIRONMENT
ProjectEnvironment.bat.in CMAKE_GENERATOR Ninja CMAKE_CACHE_ARGS <snip>)

And ProjectEnvironment.bat.in:

@echo off
call "%VS100COMNTOOLS%/../../VC/vcvarsall.bat"
rem Users better not forget this next line...
rem ExternalProject would configure_file this.
${EXTERNAL_PROJECT_COMMAND}
rem If a user adds more commands to the end of the batch file, they'd need
this:
if ERRORLEVEL 1 exit /b %ERRORLEVEL%

Best regards,

James Johnston




More information about the cmake-developers mailing list