Re: [cmake-developers] Setting up environment using ExternalProject_Add

2015-08-18 Thread Ruslan Baratov via cmake-developers

On 11-Aug-15 07:49, James Johnston wrote:

I have found it annoyingly difficult to set up an environment for a build
when using ExternalProject_Add.


I can confirm that there is an additional mess with the environment 
sometimes and not just about setting it (like vcvarsall.bat for Visual 
Studio) but with *un*setting them too. In short environment variables 
for the ExternalProject_Add are not the same as a user's environment. 
I've found myself some problems with Xcode which add tons of new 
variables but there are even cases for Makefiles (e.g. 
stackoverflow.com/questions/25160405/). I will not say it's an 
annoying thing for me but if there will be some mechanism to control 
it (better globally or even something from the box) 
ExternalProject_Add code can be simplified. I'm personally using next 
patterns:


CONFIGURE_COMMAND
@MSVC_VCVARSALL@@MSVC_ARCH@ # Set Visual Studio environment
COMMAND
... # real configure command (like bootstrap.bat or configure.bat)


BUILD_COMMAND
. /path/to/clear-all.sh  make # run make in a clean environment
   INSTALL_COMMAND
   . /path/to/clear-all.sh  make install # same for make install

include(/path/to/clear-all.cmake)
execute_process(COMMAND make @make_params@ ...) # run make in a 
clean environment


Cheers, Ruslo
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers


Re: [cmake-developers] Setting up environment using ExternalProject_Add

2015-08-13 Thread Brad King
On 08/12/2015 08:06 PM, James Johnston wrote:
  http://www.cmake.org/Bug/view.php?id=15653
 I'll explore that option some more, after the feature you linked to is
 addressed.

Currently no one is looking at addressing it.  If you want to work on
it, take a look at the PERMISSIONS option of the install() command:

 http://www.cmake.org/cmake/help/v3.3/command/install.html

There has also been discussion before about permissions options that
respect umask:

 http://www.cmake.org/Bug/view.php?id=10126#c19488
 http://www.cmake.org/Bug/view.php?id=15163

 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..

I think that is the simplest approach.  It should be easier to use
and also allows us to change how it works underneath in the future if
needed because CMake retains control of the final script generation.

Thanks,
-Brad

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers


Re: [cmake-developers] Setting up environment using ExternalProject_Add

2015-08-12 Thread James Johnston
 -Original Message-
 From: cmake-developers [mailto:cmake-developers-boun...@cmake.org]
 On Behalf Of David Cole via cmake-developers
 Sent: Wednesday, August 12, 2015 15:53
 To: Brad King
 Cc: cmake-developers@cmake.org
 Subject: Re: [cmake-developers] Setting up environment using
 ExternalProject_Add
 
 One thing to consider before embarking on modifying CMake for required
 environment purposes is that it might be just as simple to force (or at
least
 strongly encourage) your project developers to use the proper environment
 for running the whole build.
 
 You could, for example, have an initial external project which all
others
 depend on which verifies the proper environment is set when it is called.
If
 not, it fails with an error, and prevents downstream bits from building.
 
 snip

I think your situation is simpler than mine - i.e. if I'm reading this
right, all your ExternalProjects are built for the same Visual C++ version
and CPU architecture - such that the user can/should run VCVarsAll before
invoking the CMake superbuild?

What I'm trying to do:  A CMake superbuild that expects NO environment set
up, and NO languages configured.  It:
 * Builds Visual C++ 32-bit
 * Builds Visual C++ 64-bit
 * Builds some other non-Visual-C++ compilers/architectures

All within the same superbuild.  This is due to the fact that CMake doesn't
support multiple architectures directly (and probably won't for a long time,
if ever).  So, each ExternalProject_Add needs to have its own unique
environment set up.  I don't think it makes sense to try to run
VCVarsAll.bat before invoking the superbuild - in fact, doing so is
detrimental (i.e. increases risk of building for the wrong CPU architecture
if a particular VCVarsAll.bat invocation silently malfunctions).

Best regards,

James Johnston


-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers


Re: [cmake-developers] Setting up environment using ExternalProject_Add

2015-08-12 Thread James Johnston
 -Original Message-
 From: cmake-developers [mailto:cmake-developers-boun...@cmake.org]
 On Behalf Of Brad King
 Sent: Wednesday, August 12, 2015 14:10
 To: cmake-developers@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


-- 

Powered by www.kitware.com

Please keep messages on-topic

Re: [cmake-developers] Setting up environment using ExternalProject_Add

2015-08-11 Thread James Johnston
 -Original Message-
 From: Brad King [mailto:brad.k...@kitware.com]
 Sent: Tuesday, August 11, 2015 13:35
 To: James Johnston
 Cc: cmake-developers@cmake.org
 Subject: Re: [cmake-developers] Setting up environment using
 ExternalProject_Add
 
 On 08/11/2015 12:49 AM, James Johnston wrote:
  CONFIGURE_ENVIRONMENT_COMMAND path to VCVarsAll.bat
 [snip]
  add_custom_command(snip ENVIRONMENT_COMMAND path to
 vcvarsall.bat
  COMMAND ${CMAKE_PROGRAM} -GNinja snip)
 
 A problem with both of these approaches is that on UNIX and in Make the
 environment does not persist after the command exits.

Exactly right, I'm aware... and also it seems there is no
good/easy/non-hackish way to capture the environment from a child process
after it terminates, either - that I'm aware of.  (It would be nice if we
could run a process, then capture its environment after it exits, but I
don't think it can be done.)

 Whatever wrapper
 tool is used must set the environment and also launch the real command to
 be run under that environment.  This is what the env tool (and recently
 cmake -E env) does.

Right, but the problem with cmake -E env is it assumes you know what
variables you want to set - we don't.  Only a shell script / batch file
knows in the case of VCVarsAll.bat...

I think I mentioned this solution in the original e-mail but in more detail,
what I'm proposing with the proposed cmake -E run_commands or whatever we
want to call it would be the following.  In fact upon further thought, it
might be better to see about enhancing the cmake -E env command but I am
not sure if this is possible due to the syntax of cmake -E env.  Anyhow
the basic idea is this: 

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).
2.  CMake calls one or more environment setup commands.  These are pulled
in using call / source.  Users would be required to provide scripts for
environment setup in the format of the native shell (e.g. you can't call a
bash script from a Windows .bat file).  For example:

@echo off
rem User script provided to CMake, including some arguments to the
script
call dir\VCVarsAll.bat x86
rem An additional environment variable explicitly specified by the user
set MyVar=Value
cmake -GNinja .

Or:

#!/bin/sh
source setMyEnv.sh
cmake -GNinja .

Error handling has been cut for brevity, but we would want the script to
check for ERRORLEVEL / $? after each line above.  As you can see, the
problem of environment not being retained has been solved by using call
and source.

3.  Then CMake runs the above script as normal and checks the exit code as
normal.

It's basically a close cousin of what cmake -E env does in that we: (1) do
some things to set up the environment, (2) run the specified EXE.  Ideally
cmake -E env could be enhanced with the new functionality, but since we now
want to pass an arbitrary list of commands, each with potentially unlimited
parameters of any format, I'm not sure how that should look in practice.  It
might be easier to make a new command cmake -E env2 or whatever (need to
find a better name):
  * It could be passed a file.  The file contents would have a series of
lines, either SET / UNSET name=[value], SOURCE VCVarsAll.bat x86, or
COMMAND cmake.exe snip.  Newlines delimit commands.
  * It could be passed all the commands directly on the command line.  A
recognized -- switch delimits commands.  E.g. cmake -E env2 --unset NAME
--set NAME=VALUE --source VCVarsAll.bat x86 --command cmake.exe snip
--source moreSetup.bat --command somethingelse.exe
Downsides with first method: file adds complexity.  Downsides with second
method:  subject to command line length limits, though probably not an issue
in practice.  Also, what if user wants to pass --unset or --set
parameter to their command as an argument?  Without a means of escaping,
CMake will think the command is ended and the user is trying to do something
new.

That's the first and most important step.  The above functionality would
still be inconvenient to use (e.g. cmake -E will not be aware of any
compiled EXE target output paths).  So, enhancing e.g. add_custom_command as
I proposed might make it easier, as this command could be aware of compiled
EXE targets.  Finally, we'd want to add features to ExternalProject that use
the new CMake functionality to finally solve the original problem.

The alternative ideas in my e-mail are just a question of who generates
the above temporary script that sources/calls a user script.  E.g. in
option 3, we leave C++ portion of CMake alone, and ExternalProject would
then have to auto-generate the above temporary script instead.

Best regards,

James Johnston


-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community

Re: [cmake-developers] Setting up environment using ExternalProject_Add

2015-08-11 Thread Brad King
On 08/11/2015 12:49 AM, James Johnston wrote:
 CONFIGURE_ENVIRONMENT_COMMAND path to VCVarsAll.bat
[snip]
 add_custom_command(snip ENVIRONMENT_COMMAND path to vcvarsall.bat
 COMMAND ${CMAKE_PROGRAM} -GNinja snip)

A problem with both of these approaches is that on UNIX and in Make
the environment does not persist after the command exits.  Whatever
wrapper tool is used must set the environment and also launch the
real command to be run under that environment.  This is what the
env tool (and recently cmake -E env) does.  Of course on Windows
we need to run the .bat file to set the environment because we do
not know what variables it will set.

So, in order to do something like this we first need to identify a
proper abstraction to capture both cases.

Thanks,
-Brad

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers


[cmake-developers] Setting up environment using ExternalProject_Add

2015-08-10 Thread James Johnston
Hi,

(Pardon the length; skip to end to see what I am proposing to change.  Below
is justification why.)

I have found it annoyingly difficult to set up an environment for a build
when using ExternalProject_Add.  This seems to be needed when creating a
superbuild that uses several different compilers.  The common workaround
seems to be to use a batch file that kicks off the build, as suggested by
multiple posts I have seen on these mailing lists, StackOverflow, etc.  An
example of a nice  neat usage that doesn't need an environment set up.

# For this discussion, suppose this is called from a
# superbuild that has no languages set up, and no build
# environment.
ExternalProject_Add(
snip
# Conveniently, VS2010 generator doesn't need VCVarsAll.bat
CMAKE_GENERATOR Visual Studio 10 2010
CMAKE_CACHE_ARGS long list of args)

But let's say I want to use Ninja to build both VS2010 32-bit/64-bit.  Now
things get really messy, especially if I want my logic in a reusable piece
of code (effectively acting as a wrapper around ExternalProject_Add):

# ${setEnv} must be path to a batch file that does this.
# 1.  Call VCVarsAll for desired VC version.
# 2.  Run command passed via arguments.
snip code to configure_file and write ${setEnv}

# ${someScriptFile} has to be made via file(GENERATE).
# Essentially we have to reimplement the CMAKE_CACHE_ARGS option.
# That is made difficult because _ep_command_line_to_initial_cache
# is a private implementation detail of ExternalProject.cmake.
snip code to file(GENERATE) ${someScriptFile}

ExternalProject_Add(
snip
CONFIGURE_COMMAND ${setEnv} ${CMAKE_COMMAND}
-GNinja -C${someScriptFile})

Basically I find myself copy/pasting _ep_command_line_to_initial_cache into
my own project, amongst other annoyances.  :(

What would be nice is if I could directly pass VCVarsAll.bat to
ExternalProject_Add and still be able to use CMAKE_GENERATOR and
CMAKE_CACHE_ARGS.  It would also be nice if this mechanism did not interfere
with option CONFIGURE_COMMAND in case the external project is not
CMake-based.

Something like this might be perfect:

ExternalProject_Add(
snip
CONFIGURE_ENVIRONMENT_COMMAND path to VCVarsAll.bat
CMAKE_GENERATOR Ninja
CMAKE_CACHE_ARGS long list of args)
# Offer similar capability for other steps like building.

This is made somewhat difficult by the fact that CMake currently provides no
mechanism for a custom command to do this that I know of, and thus nothing
for ExternalProject_Add to easily build off of.  Therefore, I propose
several possible options, and I'd like to know which one(s) I should think
about pursuing:

1.  add_custom_command (and friends) could be extended with a new keyword
indicating that command is environment preparation for the next command.
For example:

add_custom_command(snip ENVIRONMENT_COMMAND path to vcvarsall.bat
COMMAND ${CMAKE_PROGRAM} -GNinja snip)

In this case, add_custom_command will run the ENVIRONMENT_COMMAND and
COMMAND in the same shell.  The ENVIRONMENT_COMMAND would have to be
source'd / call'd as needed, depending on the shell.

Implementation of #1:
a.  A new cmake -E run_commands command list file option could be
added that runs each command on each line of the input file in a shared
environment (source'ing and call'ing as needed depending on shell).  E.g. by
translating the list of input commands to a temporary batch/shell script and
running it.  Behind the scenes, add_custom_command and friends would
assemble things into a cmake -E invocation that can be passed to the
generators - handling EXE targets as needed.
b.  OR:  Each CMake generator handles this directly without any special
cmake -E option.  (This sounds like more work?)

2.  Instead of altering add_custom_command, just add the proposed cmake -E
run_commands option as described above.  ExternalProject_Add could then be
modified to use this new cmake -E option directly.  (Need to think about
if the command is an EXE target...)

3.  Instead of altering any C++ CMake code at all, modify
ExternalProject_Add to implement my original workaround outlined at the top
of this e-mail of generating a wrapper script.  Downside: now
ExternalProject.cmake has to learn platform-specific knowledge of the shell.
Also need to think about if target is EXE target...

4.  Do nothing; this is too complicated and so are not desired changes to
make to CMake.  Or: something else?

The one possible wrench in the works would be if you used a Cygwin version
of CMake (i.e. CMake expects /bin/sh shell) and wanted to prepare to use
Visual C++ and run VCVarsAll.bat (i.e. but you need cmd.exe shell).  That
wouldn't work without a special option allowing you to explicitly set the
shell.  That's a rare enough case it's probably not worth worrying about in
this initial version, I think.

My personal preference would be option 1, and