views:

1910

answers:

2

[NOTE: This questions is similar to but not the same as this one.]

Visual Studio defines several dozen "Macros" which are sort of simulated environment variables (completely unrelated to C++ macros) which contain information about the build in progress. Examples:

    ConfigurationName  Release
    TargetPath         D:\work\foo\win\Release\foo.exe
    VCInstallDir       C:\ProgramFiles\Microsoft Visual Studio 9.0\VC\

Here is the complete set of 43 built-in Macros that I see (yours may differ depending on which version of VS you use and which tools you have enabled):

    ConfigurationName  IntDir           RootNamespace      TargetFileName
    DevEnvDir          OutDir           SafeInputName      TargetFramework
    FrameworkDir       ParentName       SafeParentName     TargetName
    FrameworkSDKDir    PlatformName     SafeRootNamespace  TargetPath
    FrameworkVersion   ProjectDir       SolutionDir        VCInstallDir
    FxCopDir           ProjectExt       SolutionExt        VSInstallDir
    InputDir           ProjectFileName  SolutionFileName   WebDeployPath
    InputExt           ProjectName      SolutionName       WebDeployRoot
    InputFileName      ProjectPath      SolutionPath       WindowsSdkDir
    InputName          References       TargetDir          WindowsSdkDirIA64
    InputPath          RemoteMachine    TargetExt             

Of these, only four (FrameworkDir, FrameworkSDKDir, VCInstallDir and VSInstallDir) are set in the environment used for build-events.

As Brian mentions, user-defined Macros can be defined such as to be set in the environment in which build tasks execute. My problem is with the built-in Macros.

I use a Visual Studio Post-Build Event to run a python script as part of my build process. I'd like to pass the entire set of Macros (built-in and user-defined) to my script in the environment but I don't know how. Within my script I can access regular environment variables (e.g., Path, SystemRoot) but NOT these "Macros". All I can do now is pass them on-by-one as named options which I then process within my script. For example, this is what my Post-Build Event command line looks like:

    postbuild.py --t="$(TargetPath)" --c="$(ConfigurationName)"

Besides being a pain in the neck, there is a limit on the size of Post-Build Event command line so I can't pass dozens Macros using this method even if I wanted to because the command line is truncated.

Does anyone know if there is a way to pass the entire set of Macro names and values to a command that does NOT require switching to MSBuild (which I believe is not available for native VC++) or some other make-like build tool?

A: 

This is a bit hacky, but it could work.

Why not call multiple .py scripts in a row?

Each scripts can pass in a small subset of the parameters, and the values to a temp text file. The final script will read and work off of the temp text file.

I agree that this method is filled with danger and WTF's, but sometimes you have to just hack stuff together.

TonyOssa
Good idea but there is a limit to the length of a command line callable from a VisualStudio build event. It's something like 128 or 256 characters. Way too short to call N scripts where N = #macros (about 43 builtins plus any defined by the user.)
jwfearn
+2  A: 

You might want to look into PropertySheets. These are files containing Visual C++ settings, including user macros. The sheets can inherit from other sheets and are attached to VC++ projects using the PropertyManager View in Visual Studio. When you create one of these sheets, there is an interface for creating user macros. When you add a macro using this mechanism, there is a checkbox for setting the user macro as an environment variable. We use this type of mechanism in our build system to rapidly set up projects to perform out-of-place builds. Our various build directories are all defined as user macros. I have not actually verified that the environment variables are set in an external script called from post-build. I tend to use these macros as command line arguments to my post-build scripts - but I would expect accessing them as environment variables should work for you.

Brian Stewart
I'm not the original question-poster. But I want to say THANK YOU for this. I never new such sheets existed, and I have an immediate use for them.
que que
I do use .vsprops files in the same way as you do, for build directories. User-defined variables are passed OK (as long as PerformEnvironmentSet="true") but for some reason almost all of the built-in vars are not.
jwfearn