View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0005145CMakeCMakepublic2007-06-08 08:252016-06-10 14:30
ReporterJan Engels 
Assigned ToBill Hoffman 
PrioritynormalSeverityfeatureReproducibilityalways
StatusclosedResolutionmoved 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0005145: Set environment variables for ADD_CUSTOM_COMMAND/ADD_CUSTOM_TARGET
DescriptionAs already reported by Anton Deguet it would be very nice if one could set environment variables for running a custom command since I cannot find a way to tell CMake to run a SET( ENV{foo} bar ) before the custom command gets executed.

Thanks
Jan
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0027555)
Andreas Mohr (reporter)
2011-10-07 12:31

Seconded.

It's perhaps not always a good idea to pass script-specific parameters via environment variables rather than doing getopts() stuff, but some people might need to call unmodifiable third-party shell scripts (could be managed by a getopts()-to-environment wrapper script, though).

While configuring environment sorta does "work" (on Linux at least) via
  COMMAND "ENV_VAR1=${foo}" "ENV_VAR2=${bar}" my_cmd.sh
, in the case of foo or bar containing whitespace this will end up being quoted _unfittingly_ (quoting around full assignment expression instead of var content only) by CMake (no matter whether VERBATIM was specified or not), thus at least in the case of whitespace-containing environment settings there's no way to get it passed to a command binary.

Thanks!
(0027559)
Andreas Mohr (reporter)
2011-10-07 17:25

Hrmm, not so fast at jumping to conclusions... turns out that "env" seems exactly be able to be used for this purpose.

Doing a manual terminal test via
env "HELLO=blubb" "TEST1=fasdf sd" sh
and then within that shell executing - err... - "env" will (in addition to HELLO) list TEST1 with proper space-preserved content, _despite_ having done imprecise quoting (entire TEST1 expression rather than content-only).
That did not work as desired when listing the variables only, plus the command binary.

So it seems we do have a workaround for that. Albeit one could say that "env" isn't really truly portable (will need to be restricted to within if(UNIX) or some such).
(0031053)
szx (reporter)
2012-09-18 19:30

I can't set PYTHONPATH without this :(
(0031908)
jbohren (reporter)
2012-12-17 10:09
edited on: 2012-12-17 10:10

There exist cases where the behavior of executables used in custom targets can only be changed via environment variables. For instance, when building LaTeX documents, one can only change the include paths for the pdflatex program by setting the environment variable $TEXINPUTS.

At this time this can only be done by setting the environment variable before running CMake, or with the non-portable "workarounds" mentioned above. Is there anything technically challenging about adding such behavior, or has it not been acted upon because of a design decision?

(0031909)
Andreas Mohr (reporter)
2012-12-17 11:50

I'd like to stress the importance of this feature (as has been said elsewhere - env vars of add_custom_command() is the required base feature of env var support of ExternalProject_Add()), and my suggested workaround above merely is at most that.

[[

I'm currently trying (and failing, for the most part) to extend PATH of a CMake-type ExternalProject_Add() via a somewhat ugly custom env-setting wrapper script handling workaround.
Problem is that I'd like to have this wrapper script adopt the fully authentic
command list as generated by the to-be-replaced EP_Add() step part. And it seems I cannot even get to that information in the first place since (_ep_get_build_command()):

    # Use user-specified arguments instead of default arguments, if any.
    get_property(have_args TARGET ${name} PROPERTY _EP_${step}_ARGS SET)
    if(have_args)
      get_target_property(args ${name} _EP_${step}_ARGS)
    endif()

Prior to calling EP_Add() there obviously simply isn't a target to refer to (I'm now left wondering how this code part ever was intended to be used).

And I cannot modify the EP's build command after EP_Add() since it's already carved in stone via add_custom_command() (only extending might be possible via add_custom_command(...APPEND...), but in the case of a wrapper script I'd have to fully *replace* it.

So currently my only option (for even deciding to resort to creating a working workaround that would want to end up consisting of a manual env-wrapper solution, for crying out loud) seems to be to specify the cmake command line (cmake.exe --build --config $(Configuration)) open-coded, *manually*, i.e. in full disconnect from what more modern EP module implementations might choose to use in future.

]]

And that all is not yet mentioning a general issue of an "impedance mismatch" (see stackoverflow posts) of EP_Add() vs. find_package()).
This could possibly be "workarounded" by doing yet another EP_Add() of a "SuperBuild slave" from a "SuperBuild master", to enable the "child" EP to locate all dependencies prepared in advance by the "master" EP.
I think given how such subsequent tool installations/builds are usually stacked, having to resort to master/slave CMake SuperBuilds would actually be perfectly ok since it exactly reflects that "manual install" pattern (first install base support framework, then adapt env, then continue building child infrastructure via child CMake, etc.) - all these statements however are only valid given the availability of proper env var support!!

So, for SuperBuilds which have a quite justified need to bootstrap their own build environment parts (e.g. MSYS) in a privately controlled build area and have them added to PATH, the current situation can be described as quite dire, thus it would be highly useful to have env capability (this possibly needs to be done with per-system backend support) added to add_custom_command() etc.

That's just to clarify the current status quo and situations where it all breaks down (in multiple facets even, unfortunately).

In closing, I'd like to remind all people dealing with this that they should try hard to improve on this situation, e.g. by improving and submitting insufficiently flexible EP module parts or ideally by adding (ideally well-designed) env var support.

Thanks!
(0031911)
jbohren (reporter)
2012-12-18 03:20
edited on: 2012-12-19 12:13

Here's a first stab at support with UNIX Makefiles on a fork of mine on GitHub:
    https://github.com/jbohren-forks/CMake/commit/dc163683e2b010fd4dfb6e8197b83de3dd588216 [^]

You can see an example here:
    https://github.com/jbohren-forks/CMake/blob/master/Tests/CustomCommandEnvVariables/CMakeLists.txt [^]

You can run a corresponding unit test from the main directory by executing:
    ctest -R CustomCommandEnvVariables

Note that there's not a lot of error checking in there, but this is just to get the ball rolling.

(0031919)
Andreas Mohr (reporter)
2012-12-18 08:38

As another complication when resorting to writing custom shell wrappers,
one additionally needs to care about quoting
of space-containing custom command binaries
(which would normally automatically be done by
cmLocalGenerator::EscapeForShellOldStyle() for custom commands).
Yeppers, C:\Program Files\CMake ... prominently featured here...

And yet another complication is the (actually very useful otherwise) CMAKE_CFG_INTDIR special marker which resolves to $(Configuration) - while $(Configuration) is readily available within a project config file's custom command area,
this variable obviously will not be available any more within a wrapper
script's scope, thus necessitating making use of complex configuration
mapping batch commands within that script.
What this particular case shows is that an attempt to add ENV support to
add_custom_command() via a temporary *wrapper script* is doomed since build-side
$(Configuration) etc. variables will fail to get resolved - in other words
environment setting needs to be done inline, *within* the custom command scriptlet in the build config file itself.

Thanks very much to jbohren for providing a substantial implementation of such a
feature - and fortunately it seems this one chose to generate env vars
inline with the custom command rather than writing everything into a
wrapper script.
Given the incredible levels of pain when coding temporary workarounds, I'm afraid I'm very tempted to work on adding MSVS generator support to this patchset...
(0031921)
jbohren (reporter)
2012-12-18 11:22

From what I can see, visual studio deals with external commands via BAT files, so it should be pretty trivial to pull the env vars out for each custom target.

But yeah, the only complicated part is just that CMake is being told the environment variable information at generation time, but it needs to be used at build time, so the build platform, itself, needs to set the information. This requires that the information percolates through the system. I tried to use similar patterns to what I already saw in place there.
(0036770)
trsystran (reporter)
2014-09-10 06:50

This feature would be very useful to improve findFlex.

Indeed flex depends on m4 at runtime, and if the "M4" environment variable is set, it uses this program as m4 instead of searching m4 in $ENV{PATH} as usual.

To force from cmake the usage of a specific m4 path, we have to set an environment variable during compilation time.

The current workaround we use is a shell wrapper around flex to export the environment variable. But this is not portable, nor easily maintainable.

Related issue: http://www.cmake.org/Bug/view.php?id=14795 [^]
(0036775)
Nils Gladitz (developer)
2014-09-10 10:42

0005145:0036770 CMake learned the env external command (in master) which you could use for this.

E.g. ${CMAKE_COMMAND} -E env M4=/foo/bar <actual command>
(0036858)
Robert Knight (reporter)
2014-09-23 10:04

Hi Nils - Which CMake version is '-E env' first available from?
(0036859)
Nils Gladitz (developer)
2014-09-23 10:09

It is currently in "master" which means it should be in the not yet released 3.1.
(0041365)
Kitware Robot (administrator)
2016-06-10 14:27

Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.

 Issue History
Date Modified Username Field Change
2011-10-07 12:31 Andreas Mohr Note Added: 0027555
2011-10-07 17:25 Andreas Mohr Note Added: 0027559
2012-09-18 19:30 szx Note Added: 0031053
2012-12-17 10:09 jbohren Note Added: 0031908
2012-12-17 10:10 jbohren Note Edited: 0031908
2012-12-17 11:50 Andreas Mohr Note Added: 0031909
2012-12-18 03:20 jbohren Note Added: 0031911
2012-12-18 03:21 jbohren Note Edited: 0031911
2012-12-18 08:38 Andreas Mohr Note Added: 0031919
2012-12-18 11:22 jbohren Note Added: 0031921
2012-12-18 13:55 jbohren Note Edited: 0031911
2012-12-18 23:18 jbohren Note Edited: 0031911
2012-12-19 12:13 jbohren Note Edited: 0031911
2014-09-10 06:50 trsystran Note Added: 0036770
2014-09-10 10:42 Nils Gladitz Note Added: 0036775
2014-09-23 10:04 Robert Knight Note Added: 0036858
2014-09-23 10:09 Nils Gladitz Note Added: 0036859
2016-06-10 14:27 Kitware Robot Note Added: 0041365
2016-06-10 14:27 Kitware Robot Status assigned => resolved
2016-06-10 14:27 Kitware Robot Resolution open => moved
2016-06-10 14:30 Kitware Robot Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team