MantisBT - CMake
View Issue Details
0008243CMakeCMakepublic2008-12-05 15:482009-10-28 16:23
David Karr 
David Cole 
normalfeaturealways
closedduplicate 
CMake-2-6 
 
0008243: Users cannot adequately control where Visual Studio writes its output files
When CMake generates a "solution" for Visual Studio 7.0 or later, the paths of the output files of the "projects" in that solution contain the selected Visual Studio configuration. For example, if the a project is supposed to write a file named "myprogram.exe", and you build your "solution" in the Debug configuration, you get a file named ${somepath}/Debug/myprogram.exe.

This is incompatible with some users' environments, in which there are procedures (sometimes automated) that expect to find a file named ${somepath}/myprogram.exe at the end of the build, where the string "Debug" does NOT appear anywhere in ${somepath}.

There are other ways, to many to detail, in which CMake's choice of output directories for VS 7.0+ projects can degrade or break users' other procedures.

It would be highly desirable for the user to be able to achieve the same result in VS 7.0+ that can be achieved in VS 6.0 by adding flags such as "/out:${somepath}/myprogram.exe" or "/implib:${someotherpath}/mylibrary.lib". There are several different features involved here, including the ability to control the destination of each type of output file (exe, dll, lib, pdb, obj) independently of the other types of output, the ability to eliminate the configuration name (e.g. Debug or Release) from the path of output files of one type, and the ability to eliminate the component ${projectname}.dir from the paths of some of the output files.

It's unlikely that all these features are critical for any one user; there may be features in the list that everyone can live without; but just about any well-designed mechanism to let the CMake user control the critical features from this list should easily be extensible to cover all of them.
No tags attached.
duplicate of 0009163closed Brad King A way to set different output paths for MSVC Debug/Release configurations 
has duplicate 0008555closed  Ability to generate targets outside of Visual Studio's "Release" or "Debug" folders 
cxx cmLocalVisualStudio7Generator.cxx (85,453) 2009-03-09 11:31
https://public.kitware.com/Bug/file/2110/cmLocalVisualStudio7Generator.cxx
? cmLocalVisualStudio7Generator.h (8,142) 2009-03-09 11:36
https://public.kitware.com/Bug/file/2111/cmLocalVisualStudio7Generator.h
cxx cmTarget.cxx (136,652) 2009-03-09 11:43
https://public.kitware.com/Bug/file/2112/cmTarget.cxx
? cmTarget.h (23,274) 2009-03-09 11:44
https://public.kitware.com/Bug/file/2113/cmTarget.h
Issue History
2008-12-05 15:48David KarrNew Issue
2008-12-05 16:05David KarrNote Added: 0014303
2008-12-15 10:39Bill HoffmanStatusnew => assigned
2008-12-15 10:39Bill HoffmanAssigned To => David Cole
2008-12-15 11:26David KarrNote Added: 0014341
2008-12-18 06:25Thorsten KösterNote Added: 0014393
2009-02-03 21:30Philip LowmanNote Added: 0014773
2009-02-18 08:11Philip LowmanNote Added: 0015127
2009-02-18 08:13Philip LowmanRelationship addedhas duplicate 0008555
2009-02-19 14:26David ColeNote Added: 0015224
2009-02-19 14:26David ColeSeveritymajor => feature
2009-02-23 12:01David KarrNote Added: 0015293
2009-02-23 21:29Philip LowmanNote Added: 0015299
2009-03-07 08:20Pau Garcia i QuilesNote Added: 0015596
2009-03-09 11:31David KarrFile Added: cmLocalVisualStudio7Generator.cxx
2009-03-09 11:36David KarrFile Added: cmLocalVisualStudio7Generator.h
2009-03-09 11:43David KarrFile Added: cmTarget.cxx
2009-03-09 11:44David KarrFile Added: cmTarget.h
2009-03-09 12:22David KarrNote Added: 0015607
2009-04-06 18:36Alexey StukalovNote Added: 0015939
2009-10-28 14:19David ColeRelationship addedduplicate of 0009163
2009-10-28 14:24Brad KingNote Added: 0018258
2009-10-28 14:24Brad KingStatusassigned => closed
2009-10-28 14:25Brad KingResolutionopen => duplicate
2009-10-28 16:05David KarrNote Added: 0018261
2009-10-28 16:05David KarrStatusclosed => feedback
2009-10-28 16:05David KarrResolutionduplicate => reopened
2009-10-28 16:23Brad KingNote Added: 0018262
2009-10-28 16:23Brad KingStatusfeedback => closed
2009-10-28 16:23Brad KingResolutionreopened => duplicate

Notes
(0014303)
David Karr   
2008-12-05 16:05   
Additional details of some aspects of this problem are described here: http://www.cmake.org/pipermail/cmake/2008-November/025615.html [^]

Also here: http://www.cmake.org/pipermail/cmake/2008-December/025860.html [^]
(0014341)
David Karr   
2008-12-15 11:26   
By adding a few lines of code, I'm able to get the effect I want, but at the cost of adding a few more configuration variables to the already long list of variables that can be read by CMake. (But at least you can simply not define these variables in your CMakeLists.txt, in which case CMake behaves the same as it did before.)

Illustrating the lack of power of this approach, I now have a project where I'm being asked to force the VC9 project files to put their objects in a subdirectory named Debug9 rather than Debug. And yet another variable would have to be defined if this option is to be supported.

It occurs to me that my real difficulty is the extent to which so many details of the directory names of output files in VC7 and later, such as whether to append a "Debug" subdirectory to the path, are hard-coded into various *.cxx files. A powerful and very general solution to all the problems of this sort that I've encountered would be to remove most of this logic from the *.cxx files and implement it in functions or macros defined in a file in the CMake installed directory, written in the same language as CMakeLists.txt. Then just read the contents of this file before reading the user's CMakeLists.txt file. Users of VC6 would still have to create their own templates to get adequate control over the results, but for later versions of VC (and presumably for make) the user could simply redefine some of these functions in his or her own CMakeLists.txt file, and only the functions whose behavior must be changed for that particular user's needs.

This doesn't imply that cmAddExecutableCommand.cxx and cmAddLibraryCommand.cxx would no longer exist, merely that at some points during the execution of their functions, control would pass to an object that implements a function defined at runtime rather than to a C++ function that hard-codes rules for building directory paths.

On the other hand, this approach would require far more effort to implement in CMake than simply adding a few variables to the environment. And it would call for stringent regression testing, as the logic to be re-encoded is quite complex. If it were done right, however, it would only need to be done once.
(0014393)
Thorsten Köster   
2008-12-18 06:25   
I second the request for a possibility to eliminate the configuration name from the target path.

We're just switching to CMake, so there are a couple of "historical reasons" involved: In our build environment we have a set of (configuration) files that needs to be present in the same directory as the executable, and we'd really like to not need to keep these in sync between the Release and the Debug directory. For the same historical reasons, Release and Debug versions have been stored in the same output directory.
(0014773)
Philip Lowman   
2009-02-03 21:30   
I also think this would be a good feature to add, both at the target and global property levels.

Do any of the other CMake generators do something similar to VS in appending Release Configuration to the output directory?
(0015127)
Philip Lowman   
2009-02-18 08:11   
This has come up on the mailing list quite a bit in the past few weeks (3 times).

Using the PREFIX hack there is a workaround for this, but it is ugly. Using it comes with a *WARNING* to be *SURE* you have unique filenames for all of your targets as Visual Studio will simply overwrite them if you do not with whatever configuration type was built last.

if(MSVC)
   set_target_properties(foo PROPERTIES PREFIX "../")
endif()

Better support for changing the output directory of multi-solution generators would be useful.
(0015224)
David Cole   
2009-02-19 14:26   
This is more of a feature request than a bug fix..... So I changed Severity to "feature". In my view, this is a reasonable request, but it should be implemented such that the default behavior after the code changes should be to produce the same layout of files that it does before the code changes.

It might be ok to introduce user control over these things, but if the user is in charge, then they have to assume responsibility for location clashes. Right now, CMake is in charge and guarantees that location clashes do not occur among all the targets and obj files that it knows about, even for multiple configurations in the same build tree using Visual Studio or Xcode. Users who want to put stuff where they want it are going to have to maybe deal with additional issues that they are avoiding now because CMake carefully puts things in their places.

Just stuff to think about before rushing into an implementation.

(0015293)
David Karr   
2009-02-23 12:01   
David Cole's remarks from 2009-02-19 reflect exactly the intent of the original request. I apologize for not making the Severity "feature" in the first place, as it always should have been.

"Don't change the default behavior" is an excellent design principle. In order to meet my immediate needs while continuing to use my CMakeLists.txt files, I created a modified version of CMake that adds the desired features. But although this version is for local use only, I still maintained the following criteria: (1) the user has to make use of a new set of variables to activate these features; (2) if you do not use these specific variables, CMake's behavior is exactly what it was before any code was changed.

If it helps, I can provide copies of the modified source files in my version of CMake. There aren't many of them. But these files follow the "less powerful" approach according to my own comment on 2008-12-15. I'd be happy to discuss the possible implementation of the "more powerful" approach.
(0015299)
Philip Lowman   
2009-02-23 21:29   
Regardless of whether or not your patch is accepted, modified and then accepted, or rejected, it's usually a good idea to submit it (at least I think).
(0015596)
Pau Garcia i Quiles   
2009-03-07 08:20   
I'd like to propose a different approach: let's make this behavior consistent across all platforms and compilers by having new target properties:

SET_TARGET_PROPERTIES( thetarget PROPERTIES CMAKE_APPEND_BUILDTYPE_TO_RUNTIME_OUTPUT_PATH 1 )

SET_TARGET_PROPERTIES( thetarget PROPERTIES CMAKE_APPEND_BUILDTYPE_TO_LIBRARY_OUTPUT_PATH 1 )

SET_TARGET_PROPERTIES( thetarget PROPERTIES CMAKE_APPEND_BUILDTYPE_TO_ARCHIVE_OUTPUT_PATH 1 )

By default they would be set to 1 if on MSVC_IDE, and false in any other case.

By using these properties, we can get the same behavior in every compiler in every platform without hacks.
(0015607)
David Karr   
2009-03-09 12:22   
I've uploaded the four files I modified for the features I needed. I suppose the features could be made cross-platform, but in the current design of CMake I think this would require some duplication of effort since the places where I needed to add optional behaviors were in highly platform-specific functions (mainly writing the XML files that VC7 introduced). There may be a way to put some of the functionality into a common area so that the Unix makefile generator can use it too, but I don't know the CMake design well enough to say whether this can actually be done; I'm pretty sure it would involve changes to several files in addition to the ones I touched, however. (I don't think it can be done without changes to the VC7 local generator that are almost as extensive as what I did.)

I got the desired behavior by setting ordinary CMake variables rather than target properties, but that's because I haven't learned enough yet to know how to do it with target properties. It seems to make sense to do it that way.

In a way, though, the features I added were much more powerful (and probably more applicable across platforms) than CMAKE_APPEND_BUILDTYPE_TO_X_OUTPUT_PATH. I defined variables such as EXPLICIT_OUTPUT_FILE_NAME that (if defined) specify *exactly* the full path to the file that is to be generated. This lets me do things such as direct executable files to a directory named ${myproject_BINARY_DIR}/bin, not just remove the "Debug" or "Release" components from their paths. Of course by using CMake's predefined variables I could just as easily have used my new variables to simply remove "Debug" or "Release" from the paths without additional changes from the default behavior.

By the way, note that to get the effect I wanted, I also had to define a variable EXPLICIT_PROGRAM_DATABASE_FILE for the generated PDB file, which I don't think has a Unix counterpart.

Anyway, I think the chief hindrance to making a non-platform-specific approach is that all the relevant code is currently deeply embedded inside highly platform-specific source files.
(0015939)
Alexey Stukalov   
2009-04-06 18:36   
Sorry, if my comments are irrelevant, I'm new to CMake.
It's my understanding that currently VStudio generator ignores the RUNTIME_OUTPUT_DIRECTORY for specifying project's output - because cmake have to generate the settings for all buildtypes.

If so, is it possible to implement VS projects generation in that way: generator actually uses ${RUNTIME_OUTPUT_DIRECTORY} value, with the exception that references to ${CMAKE_BUILD_TYPE}, instead of being resolved, are substituted to '$(ConfigurationName)'?

That should support more schemes of output files placement, including those where buildtype appears in the middle of the path.
(0018258)
Brad King   
2009-10-28 14:24   
Issue 0009163 requests what I consider the proper solution to this problem. I'm closing this issue as a duplicate.
(0018261)
David Karr   
2009-10-28 16:05   
Issue 0009163 addresses a similar issue to this one, but it is not the same issue. The difference is in this summary from the original description of this issue:

"There are several different features involved here, including the ability to control the destination of each type of output file (exe, dll, lib, pdb, obj) independently of the other types of output, the ability to eliminate the configuration name (e.g. Debug or Release) from the path of output files of one type, and the ability to eliminate the component ${projectname}.dir from the paths of some of the output files."

So there are at least three different aspects to the type of control that is requested. Issue 0009163 only partially addresses the second aspect, namely removing "Debug" and "Release" from the path of output files (because issue 0009163 does not give you control for individual file types, only for groups of file types assigned to the existing CMake variables). Issue 0009163 says nothing at all about either of the other two aspects of controlling where files go.
(0018262)
Brad King   
2009-10-28 16:23   
Feature 0009163 allows separate control of .exe, .dll, and .lib file locations.

No CMake generator allows control of .obj or .pdb file locations. I consider that a totally separate issue from the target output directories, and it is not specific to the VS IDE.

Please submit a new feature request for .pdb (debug info) files (but not .obj). I've never seen a convincing use-case for customizing .obj location, but if you have one please open yet another feature request.