View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0014999CMakeCMakepublic2014-07-01 07:472016-06-10 14:31
ReporterRam Singh 
Assigned ToKitware Robot 
PriorityhighSeverityfeatureReproducibilityalways
StatusclosedResolutionmoved 
PlatformOSOS Version
Product VersionCMake 2.8.9 
Target VersionFixed in Version 
Summary0014999: Changing Intermediate Directory of Visual Studio 2012
DescriptionWe want to change the Intermediate Directory of CMake build so that our object files, executables and libraries can be build outside of CMake built files.
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0036293)
Brad King (manager)
2014-07-01 08:27

The CMAKE_RUNTIME_OUTPUT_DIRECTORY, CMAKE_LIBRARY_OUTPUT_DIRECTORY, and CMAKE_ARCHIVE_OUTPUT_DIRECTORY variables and the target properties they initialize already allow executable and library locations to be specified.

Visual Studio itself treats object files as second-class entities (hence the name "intermediate"). Why do you need to control where they go?
(0036502)
sigiesec (reporter)
2014-07-30 12:51

We would also like to change the intermediate directory. In our case, the reason is that the full path name of the intermediate directory is too long in many contexts. Our target names are quite long, and the path of the intermediate directory contains the target name. This appears to be unnecessary, since the intermediate directory is local to the build directory of the corresponding target. In some cases, we can solve the problem by specifying a shorter build directory name, but in other cases this is not sufficient.
(0036503)
Brad King (manager)
2014-07-30 13:12

Re 0014999:0036502: CMake puts the target name in the path to the intermediate directory because multiple targets in the same directory could compile the same source file with different flags so each needs its own unique object file.

CMake already has a lot of logic to try to keep the path to object files under 250-ish characters on Windows, at least for the Makefile and Ninja generators. We even do things like replace a lengthy directory path with the md5 hash of itself to get a shorter path. It looks like something like this may be needed to shorten the path to the intermediate files directory for VS.
(0036659)
Timur (reporter)
2014-08-21 15:35
edited on: 2014-08-21 15:39

Indeed an important feature, I implemented it for my custom version by introducing a new target property in a similar way to RUNTIME_OUTPUT_DIRECTORY

VS_INTERMEDIATE_DIRECTORY_${CONFIG}

used like this:
set_target_properties( Target PROPERTIES VS_INTERMEDIATE_DIRECTORY_DEBUG "c:\temp\debug")

set_target_properties( Target PROPERTIES VS_INTERMEDIATE_DIRECTORY_RELEASE "c:\temp\release")

I can provide a patch for change


It is important to control where they go since we work with multiple windows based platforms, and every platform can generate a huge intermediate directory, for organizational reasons we want to keep it in one central place to control disk size (gets important when you develop on SSD).

(0036660)
Timur (reporter)
2014-08-21 18:41

Subject: [PATCH] VS: change intermediate directory in .vcxproj
 (VS_INTERMEDIATE_DIRECTORY_)

---
 Source/cmVisualStudio10TargetGenerator.cxx | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index ef343b6..82e6b2b 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1422,6 +1422,15 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
       intermediateDir += "/";
       intermediateDir += *config;
       intermediateDir += "/";
+
+ // Override intermediate directory of the optional VS_INTERMEDIATE_DIRECTORY_${CONFIG} property (VS_INTERMEDIATE_DIRECTORY_DEBUG,VS_INTERMEDIATE_DIRECTORY_RELEASE)
+ std::string vsIntDirProp = std::string("VS_INTERMEDIATE_DIRECTORY_") + cmSystemTools::UpperCase(*config);
+ const char* vsIntermediateDir = this->Target->GetProperty( vsIntDirProp.c_str() );
+ if (vsIntermediateDir)
+ {
+ intermediateDir = vsIntermediateDir;
+ }
+
       std::string outDir;
       std::string targetNameFull;
       if(ttype == cmTarget::OBJECT_LIBRARY)
--
1.8.3.msysgit.0
(0036663)
Brad King (manager)
2014-08-22 08:56

Re 0014999:0036659: The disk size use case is interesting.

Thanks for working on a patch. However, changing the intermediate directory is a bit more complicated than just updating what is written to the .vcxproj files. As explained in 0014999:0036503 there needs to be a per-target intermediate directory. Also the implementation of OBJECT libraries needs to know exactly where the objects will go. Anything allowing the location of object files to be changed needs to address all of this.

Meanwhile perhaps you can place the whole build tree on one disk and set all the other output paths for the binaries to go on the other disk.
(0036665)
Timur (reporter)
2014-08-22 09:43
edited on: 2014-08-22 09:44

This intermediate directory issue really only applies to the Visual Studio generated projects (this is why I also used VS_ named property)
Since it is convenient to keep the solution/projects directory separate from temporaries directory.
In our case it is organized like:

project_root/
  BinTemp/
  Code/
  Sln_VS11_Win32/
  Sln_VS11_Win64/
  Sln_VS12_Win32/
  Sln_VS12_Win64/
  Sln_VS11_Console1/
  Sln_VS11_Console2/
   
So projects are generated into the Sln_* folders
While all intermediate files from all solutions go to under BinTemp
Intermediate directory for VS can also be customized with Visual Studio internal macros:

I basically use it like this:

# Assign Intermediate Directory to Visual Studio Project per configuration
if(INTERMEDIATE_DIRECTORY)
  # Iterate Debug/Release configs and adds _DEBUG or _RELEASE
  foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
    string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG_UPPER )
    set_target_properties(${TargetProject} PROPERTIES VS_INTERMEDIATE_DIRECTORY_${OUTPUTCONFIG_UPPER} "${INTERMEDIATE_DIRECTORY}/$(Platform)/$(Configuration)/$(ProjectName)/")
  endforeach()
endif()

As for OBJECT libraries, it looks like Visual Studio finds them correctly, I didnt run into a problem with this, or maybe I misunderstood what you mean.

(0036667)
Brad King (manager)
2014-08-22 10:30

Re 0014999:0036665: See ComputeTargetObjectDirectory:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmGlobalVisualStudioGenerator.cxx;hb=4517d6b7#l120 [^]

I suggest making the property be a root directory under which CMake takes care of adding the per-target subdirectories. Also rather than requiring a project to set this property on every target, perhaps it is simpler to have a variable to activate this: CMAKE_VS_INTERMEDIATE_DIRECTORY[_<CONFIG>]. One could still also have a VS_INTERMEDIATE_DIRECTORY[_<CONFIG>] target property that is initialized by the variable (see calls to SetPropertyDefault in cmTarget.cxx for handling of other output directories like this).
(0038972)
Neil Gatenby (reporter)
2015-06-25 07:28

I'm looking at making at patch for this, extending what 0014999:0036660 says. I'd like to clarify a few things before submitting, if you've a minute?

There seems to a slight clash here in what comes first, in the directory (the per-target part, or the per-config part) ... CMake currently outputs to
   ${CMAKE_CURRENT_BINARY_DIR}/<target-name>.dir/<config-name>/
Whereas Timur would like to output to
   <yada yada>/<config-name>/<target-name>/
And I'd be happy with either that or
   <yada yada>/<target-name>/<config-name>/

Timur suggests a per-target and per-config property
   VS_INTERMEDIATE_DIRECTORY_CONFIG

Brad points out that cmGlobalVisualStudioGenerator::ComputeTargetObjectDirectory is where we'd grab a (per-config) root directory under which CMake adds subdirs like <target-name>.dir (presumably if the user has NOT specified a target-property for that config?).

I believe the following is being suggested???

 property VS_INTERMEDIATE_DIRECTORY_CONFIG
   - per target
   - per config
   - variable CMAKE_VS_INTERMEDIATE_DIRECTORY_CONFIG initialises this (per config) for all targets
 property VS_INTERMEDIATE_DIRECTORY
   - per target
   - this initialises all VS_INTERMEDIATE_DIRECTORY_CONFIG properties for this target
   - variable CMAKE_VS_INTERMEDIATE_DIRECTORY initialises this for all targets

So one gets
   <yada yada>/<target-name>.dir/<config-name>/
using
   set(CMAKE_VS_INTERMEDIATE_DIRECTORY <yada yada>)

One gets
   <yada yada>/<target-name>/<config-name>/
using
   foreach ( target ${TARGETS_I_CARE_ABOUT} )
     set_target_properties(${target} PROPERTIES VS_INTERMEDIATE_DIRECTORY <yada yada>/${target}/)
   endforeach( target )

One gets
   <yada yada>/<config-name>/<target-name>/
using
   foreach ( target ${TARGETS_I_CARE_ABOUT} )
     foreach ( config ${CONFIGS_I_CARE_ABOUT} )
       set_target_properties(${target} PROPERTIES VS_INTERMEDIATE_DIRECTORY_CONFIG <yada yada>/${config}/${target}/)
     endforeach( config )
   endforeach( target )

Or, one gets
   <yada yada>/<config-name>/<target-name>.dir/
using
   foreach ( config ${CONFIGS_I_CARE_ABOUT} )
     set(CMAKE_VS_INTERMEDIATE_DIRECTORY_CONFIG <yada yada>/${config})
   endforeach( config )


Is that the behaviour we're looking for, in my patch?

Thanks in advance,
Neil
(0038973)
Brad King (manager)
2015-06-25 08:32

Re 0014999:0038972: Thanks for looking into this.

We could also consider having some kind of explicit placeholders allowed/required in the VS_INTERMEDIATE_DIRECTORY values to specify where the target name and config names should be substituted. That would allow any order of the directories that one desires.

As for [CMAKE_]VS_INTERMEDIATE_DIRECTORY[_<CONFIG>], the per-config value can simply override the generic value if set but otherwise does not have to always be set/initialized.
(0038978)
Neil Gatenby (reporter)
2015-06-25 09:50

Thanks for the prompt feedback

How might those placeholders appear, in the CMakeLists.txt? Grepping in CMake I suspect maybe
  @config, @target
or
  %(config), %(target)
or
  (c) something else?
??

So one gets
   c:/Neil/TempBin/<target-name>.dir/<config-name>/
using
   set(CMAKE_VS_INTERMEDIATE_DIRECTORY "c:/Neil/TempBin/@target/@config/")

Or one gets
   c:/Neil/TempBin/<config-name>/<target-name>.dir/
using
   set(CMAKE_VS_INTERMEDIATE_DIRECTORY "c:/Neil/TempBin/@config/@target/")

I'm assuming that CMake will continue to use
   <target-name>.dir
when it is left to come up with this directory, from the target name - I plan to override that, for my use, but leave it that way for others.

As for (0014999:0038973) "the per-config value can simply override the generic value if set but otherwise does not have to always be set/initialized" ... yes, that's my plan/thinking

Cheers
Neil
(0038982)
Brad King (manager)
2015-06-25 10:32

Re 0014999:0038978: The %(var) style is used in ExternalData. The @var@ style is used for configure_file input content. The <VAR> style is used in Makefile/Ninja generator rules like CMAKE_C_COMPILE_OBJECT. Since the VS_INTERMEDIATE_DIRECTORY case is for generators, I think <CONFIG> and <TARGET_NAME> will be reasonable placeholders.
(0038988)
Neil Gatenby (reporter)
2015-06-25 17:51

Great. More from me when I've got something that fits the spec
(0039330)
Carl Poirier (reporter)
2015-08-26 10:48
edited on: 2015-08-26 10:50

Hi Neil,

Do you have any update on the matter?

Regards,

Carl

(0042575)
Kitware Robot (administrator)
2016-06-10 14:29

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
2014-07-01 07:47 Ram Singh New Issue
2014-07-01 08:27 Brad King Note Added: 0036293
2014-07-01 08:27 Brad King Severity major => feature
2014-07-01 08:27 Brad King Status new => backlog
2014-07-30 12:51 sigiesec Note Added: 0036502
2014-07-30 13:12 Brad King Note Added: 0036503
2014-08-21 15:35 Timur Note Added: 0036659
2014-08-21 15:35 Timur Note Edited: 0036659
2014-08-21 15:36 Timur Note Edited: 0036659
2014-08-21 15:39 Timur Note Edited: 0036659
2014-08-21 18:41 Timur Note Added: 0036660
2014-08-22 08:56 Brad King Note Added: 0036663
2014-08-22 09:43 Timur Note Added: 0036665
2014-08-22 09:44 Timur Note Edited: 0036665
2014-08-22 10:30 Brad King Note Added: 0036667
2015-06-25 07:28 Neil Gatenby Note Added: 0038972
2015-06-25 08:32 Brad King Note Added: 0038973
2015-06-25 09:50 Neil Gatenby Note Added: 0038978
2015-06-25 10:32 Brad King Note Added: 0038982
2015-06-25 17:51 Neil Gatenby Note Added: 0038988
2015-08-26 10:48 Carl Poirier Note Added: 0039330
2015-08-26 10:49 Carl Poirier Note Edited: 0039330
2015-08-26 10:50 Carl Poirier Note Edited: 0039330
2016-06-10 14:29 Kitware Robot Note Added: 0042575
2016-06-10 14:29 Kitware Robot Status backlog => resolved
2016-06-10 14:29 Kitware Robot Resolution open => moved
2016-06-10 14:29 Kitware Robot Assigned To => Kitware Robot
2016-06-10 14:31 Kitware Robot Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team