MantisBT - CMake
View Issue Details
0009568CMakeCMakepublic2009-09-19 00:572009-10-01 10:30
Shirokov Anatoly 
Brad King 
normalmajoralways
closedfixed 
CMake-2-6 
 
0009568: Visual Studio 6 generator issue
Visual Studio 6 generator does not include all dependencies into workspaces for nested project.
I have a simple project with the following structure:
root
  CMakeLists.txt
  app
     CMakeLists.txt
     app.cpp
  lib
     CMakeLists.txt
     lib.cpp

The root\CMakeLists.txt contains:
cmake_minimum_required(VERSION 2.6)
project(ROOT)
add_subdirectory(app)
add_subdirectory(lib)

The root\app\CMakeLists.txt contains:
project( APP )
add_executable( app app.cpp )
target_link_libraries( app lib )
add_dependencies( app lib )

The root\app\CMakeLists.txt contains:
project( LIB )
add_library( lib STATIC lib.cpp)

I try to generate Visual Studio 6 project:
cd root
mkdir build
cd build
cmake -G "Visual Studio 6" ..

CMake generates the following:
ALL_BUILD.dsp
ALL_BUILD.dsp.cmake
CMakeCache.txt
cmake_install.cmake
ROOT.dsw
app\ALL_BUILD.dsp
app\ALL_BUILD.dsp.cmake
app\app.dsp
app\app.dsp.cmake
app\APP.dsw
app\CMakeFiles
app\cmake_install.cmake
app\CMakeFiles\ALL_BUILD.rule
CMakeFiles\ALL_BUILD.rule
CMakeFiles\cmake.check_cache
CMakeFiles\CMakeCCompiler.cmake
CMakeFiles\CMakeCPlatform.cmake
CMakeFiles\CMakeCXXCompiler.cmake
CMakeFiles\CMakeCXXPlatform.cmake
CMakeFiles\CMakeDetermineCompilerABI_C.bin
CMakeFiles\CMakeDetermineCompilerABI_CXX.bin
CMakeFiles\CMakeOutput.log
CMakeFiles\CMakeRCCompiler.cmake
CMakeFiles\CMakeSystem.cmake
CMakeFiles\CMakeTmp
CMakeFiles\CMakeTmp\CMakeFiles
CMakeFiles\CMakeTmp\Debug
lib\ALL_BUILD.dsp
lib\ALL_BUILD.dsp.cmake
lib\CMakeFiles
lib\cmake_install.cmake
lib\lib.dsp
lib\lib.dsp.cmake
lib\LIB.dsw
lib\CMakeFiles\ALL_BUILD.rule

When I open ROOT.dsw, I can build all targets correctly according to dependencies. Why cannot I do the same when I open nested app\APP.dsw workspace?
In other words, why does not CMake include the lib project into the APP.DSW workspace?

I have tested the Visual Studio 2005 generator for this project. There are no such problems with one. The app.sln solution includes lib.vcproj as expected.

It looks like something is wrong with Visual Studio 6 generator.
No tags attached.
parent of 0008223closed Brad King Visual Studio 6 generator does not add targets to workspace in subdirs with EXCLUDE_FROM_ALL set 
txt cmGlobalVisualStudio6Generator.cxx.patch.txt (17,590) 2009-09-19 14:31
https://public.kitware.com/Bug/file/2461/cmGlobalVisualStudio6Generator.cxx.patch.txt
txt cmGlobalVisualStudio6Generator.h.patch.txt (1,374) 2009-09-19 14:31
https://public.kitware.com/Bug/file/2462/cmGlobalVisualStudio6Generator.h.patch.txt
txt cmGlobalVisualStudio6Generator.h.patch.ansi.txt (686) 2009-09-19 17:17
https://public.kitware.com/Bug/file/2463/cmGlobalVisualStudio6Generator.h.patch.ansi.txt
txt cmGlobalVisualStudio6Generator.cxx.patch.ansi.txt (8,794) 2009-09-19 17:17
https://public.kitware.com/Bug/file/2464/cmGlobalVisualStudio6Generator.cxx.patch.ansi.txt
zip utilitytest.zip (1,620) 2009-09-22 10:19
https://public.kitware.com/Bug/file/2481/utilitytest.zip
Issue History
2009-09-19 00:57Shirokov AnatolyNew Issue
2009-09-19 04:03Shirokov AnatolyNote Added: 0017619
2009-09-19 08:43Bill HoffmanNote Added: 0017633
2009-09-19 08:44Bill HoffmanStatusnew => assigned
2009-09-19 08:44Bill HoffmanAssigned To => Bill Hoffman
2009-09-19 14:31Shirokov AnatolyFile Added: cmGlobalVisualStudio6Generator.cxx.patch.txt
2009-09-19 14:31Shirokov AnatolyFile Added: cmGlobalVisualStudio6Generator.h.patch.txt
2009-09-19 14:35Shirokov AnatolyNote Added: 0017645
2009-09-19 15:10Shirokov AnatolyNote Added: 0017646
2009-09-19 15:55Bill HoffmanNote Added: 0017649
2009-09-19 17:17Shirokov AnatolyFile Added: cmGlobalVisualStudio6Generator.h.patch.ansi.txt
2009-09-19 17:17Shirokov AnatolyFile Added: cmGlobalVisualStudio6Generator.cxx.patch.ansi.txt
2009-09-19 17:18Shirokov AnatolyNote Added: 0017651
2009-09-22 02:41Shirokov AnatolyNote Added: 0017692
2009-09-22 09:43Brad KingNote Added: 0017696
2009-09-22 10:18Shirokov AnatolyNote Added: 0017697
2009-09-22 10:19Shirokov AnatolyFile Added: utilitytest.zip
2009-09-22 10:34Shirokov AnatolyNote Added: 0017699
2009-09-22 10:39Brad KingNote Added: 0017700
2009-09-22 10:39Shirokov AnatolyNote Added: 0017701
2009-09-30 15:21Brad KingRelationship addedparent of 0008223
2009-09-30 16:07Brad KingNote Added: 0017855
2009-09-30 16:08Brad KingAssigned ToBill Hoffman => Brad King
2009-09-30 16:08Brad KingNote Edited: 0017855
2009-10-01 10:27Brad KingNote Added: 0017863
2009-10-01 10:30Brad KingStatusassigned => closed
2009-10-01 10:30Brad KingResolutionopen => fixed

Notes
(0017619)
Shirokov Anatoly   
2009-09-19 04:03   
I have tried to patch the Visual Studio 6 generator using the Visual Studio 7 generator approach. May be it helps to fix this issue:
http://www.cmake.org/pipermail/cmake/2009-September/032053.html [^]

BR,
Anatoly Shirokov.
(0017633)
Bill Hoffman   
2009-09-19 08:43   
Do you have a patch? If so attach it to this bug report.
(0017645)
Shirokov Anatoly   
2009-09-19 14:35   
I've attached.
(0017646)
Shirokov Anatoly   
2009-09-19 15:10   
I want to say that I'm not sure that this patch takes a care about all possible details. So please review changes and make needed corrections.
Thanks.
(0017649)
Bill Hoffman   
2009-09-19 15:55   
The patch seems to be in non-ascii. Can you convert to 8 bit ascii and re-attach?
(0017651)
Shirokov Anatoly   
2009-09-19 17:18   
Done
(0017692)
Shirokov Anatoly   
2009-09-22 02:41   
Additionally, I found that current implementation of void
cmGlobalGenerator::AddTargetDepends(cmTarget* target,
                                    cmGlobalGenerator::TargetDependSet&
                                    projectTargets)
does not include UTILITY projects to dependency set for the target.
My solution is
1) add virtual to cmGlobalGenerator::AddTargetDepends signature
2) override it in cmGlobalVisualStudio6Generator. Implementation looks like the following:
void cmGlobalVisualStudio6Generator::AddTargetDepends(cmTarget* target,
                                                      cmGlobalGenerator::TargetDependSet&
                                                      projectTargets)
{
    if( projectTargets.find(target) != projectTargets.end() )
        return;

    // add the target itself
    projectTargets.insert(target);
    // get the direct depends of target
    cmGlobalGenerator::TargetDependSet const& tset
        = this->GetTargetDirectDepends(*target);
    if(tset.size())
    {
        // if there are targets that depend on target
        // add them and their depends as well
        for(cmGlobalGenerator::TargetDependSet::const_iterator i =
            tset.begin(); i != tset.end(); ++i)
        {
            cmTarget* dtarget = *i;
            this->AddTargetDepends(dtarget, projectTargets);
        }
    }

    {
        std::set<cmStdString>::const_iterator i, end;
        i = target->GetUtilities().begin();
        end = target->GetUtilities().end();
        for(;i!= end; ++i)
        {
            cmTarget* dtarget = FindTarget(0, i->c_str());
            if( dtarget ) {
                std::string depName = this->GetUtilityForTarget(*dtarget, i->c_str());
                cmTarget* utarget = FindTarget(0, depName.c_str());
                if(utarget)
                    this->AddTargetDepends(utarget, projectTargets);
            }
        }
    }
}
(0017696)
Brad King   
2009-09-22 09:43   
The GetTargetDirectDepends method returns results computed by the cmComputeTargetDepends class. That class follows dependencies in the method:

  cmComputeTargetDepends::CollectTargetDepends

which clearly loops over both library and utility dependencies. Can you post an example project where this does not work?
(0017697)
Shirokov Anatoly   
2009-09-22 10:18   
Ok, I've attached utilitytest.zip.

- unzip utilitytest.zip
- cd utilityzip
- mkdir build
- cd build
- cmake -G "Visual Studio 6" ..
- cd app
- start app.dsw

As you can see the app.dsw does not include libbase, libder and libbase_UTILITY, but app.dsp depends on libbase and libder.
(0017699)
Shirokov Anatoly   
2009-09-22 10:34   
If you apply the attached *.ansi.txt patches, libbase and libder will appear in app.dsw, but libbase_UTILITY will be still missing.
If you implement AddTargetDepends as it mentioned above, libbase will appear in app.dsw as expected.
(0017700)
Brad King   
2009-09-22 10:39   
Okay, I see the difference. The "*_UTILITY" targets are different from what CMake calls "utility" targets internally. A normal utility target is the implementation of add_custom_target(). A "somelib_UTILITY" target is a fake custom target inserted as an implementation detail for this case:

  add_dependencies(my_exe my_library)

The goal is to make "my_exe" depend on "my_library", so that it builds afterwards, but NOT actually LINK to it. Unfortunately the VS IDE will link my_exe to my_library if the .dsw (or in VS 7 the .sln) lists a direct dependency between the targets even though my_exe.dsp does not mention my_library at all. Even worse, IIRC, in the case

  add_dependencies(my_static_lib_1 my_static_lib_2)

VS will list my_static_lib_2.lib on the librarian line for my_static_lib_1 and *copy* all of the objects, again even though my_static_lib_1.dsp file does not specify my_static_lib_2...just the .dsw reference is enough!

The work-around we use is to replace the direct dependency on a library "somelib" with a dependency on an intermediate "somelib_UTILITY" target which then depends on "somelib". CMake's VS generators do this using a last-second replacement of the real direct dependency with the intermediate target just as they write the .dsw or .sln files. We want to avoid every including the _UTILITY targets in analysis of build rules before generation.

You're see a ..._UTILTITY target because of the line

  add_dependencies( app lib )

in your example. It makes 'lib' a non-link dependency of 'app'. This is unnecessary. Just the line

  target_link_libraries( app lib )

already adds the dependency. The add_dependencies call is only necessary if you want the dependency *without* linking.

Although the line is not necessary in your example, it might be in a real project that wants such a dependency. This is potentially an existing bug that affects VS generators for all versions. I think your fix is correct but it can be simpler, and should be done for all generators. I'll investigate further.
(0017701)
Shirokov Anatoly   
2009-09-22 10:39   
Sorry, the last sentence must be changed on
If you implement AddTargetDepends as it mentioned above, libbase_UTILITY will appear in app.dsw as expected.
(0017855)
Brad King   
2009-09-30 16:07   
(edited on: 2009-09-30 16:08)
I've combined changes from patch

  cmGlobalVisualStudio6Generator.(h|cxx).patch.ansi.txt

with those from the patch in issue 0008223. Both patches actually address both bugs because they both use the VS 7 generator's approach to computing the set of targets in a solution.

The following commits represent the combined patches plus some more cleanup:

Move OrderedTargetDependSet into VS superclass
/cvsroot/CMake/CMake/Source/cmGlobalVisualStudio7Generator.cxx,v <-- Source/cmGlobalVisualStudio7Generator.cxx
new revision: 1.110; previous revision: 1.109
/cvsroot/CMake/CMake/Source/cmGlobalVisualStudio7Generator.h,v <-- Source/cmGlobalVisualStudio7Generator.h
new revision: 1.53; previous revision: 1.52
/cvsroot/CMake/CMake/Source/cmGlobalVisualStudioGenerator.cxx,v <-- Source/cmGlobalVisualStudioGenerator.cxx
new revision: 1.19; previous revision: 1.18
/cvsroot/CMake/CMake/Source/cmGlobalVisualStudioGenerator.h,v <-- Source/cmGlobalVisualStudioGenerator.h
new revision: 1.13; previous revision: 1.12

Use target dependency closure for VS 6 solutions
/cvsroot/CMake/CMake/Source/cmGlobalVisualStudio6Generator.cxx,v <-- Source/cmGlobalVisualStudio6Generator.cxx
new revision: 1.80; previous revision: 1.79

Remove unused members of local VS 6 generator
/cvsroot/CMake/CMake/Source/cmLocalVisualStudio6Generator.cxx,v <-- Source/cmLocalVisualStudio6Generator.cxx
new revision: 1.161; previous revision: 1.160
/cvsroot/CMake/CMake/Source/cmLocalVisualStudio6Generator.h,v <-- Source/cmLocalVisualStudio6Generator.h
new revision: 1.26; previous revision: 1.25

(0017863)
Brad King   
2009-10-01 10:27   
I've committed additional changes to address the **_UTILITY target problem from comments #c17692 and #c17700.

Cleanup cmGlobalGenerator::GetTargetSets method
/cvsroot/CMake/CMake/Source/cmGlobalGenerator.cxx,v <-- Source/cmGlobalGenerator.cxx
new revision: 1.260; previous revision: 1.259
/cvsroot/CMake/CMake/Source/cmGlobalGenerator.h,v <-- Source/cmGlobalGenerator.h
new revision: 1.127; previous revision: 1.126
/cvsroot/CMake/CMake/Source/cmGlobalVisualStudio6Generator.cxx,v <-- Source/cmGlobalVisualStudio6Generator.cxx
new revision: 1.81; previous revision: 1.80
/cvsroot/CMake/CMake/Source/cmGlobalVisualStudio71Generator.cxx,v <-- Source/cmGlobalVisualStudio71Generator.cxx
new revision: 1.56; previous revision: 1.55
/cvsroot/CMake/CMake/Source/cmGlobalVisualStudio7Generator.cxx,v <-- Source/cmGlobalVisualStudio7Generator.cxx
new revision: 1.111; previous revision: 1.110

Add alternative _UTILITY targets to all solutions
/cvsroot/CMake/CMake/Source/cmGlobalVisualStudioGenerator.cxx,v <-- Source/cmGlobalVisualStudioGenerator.cxx
new revision: 1.20; previous revision: 1.19
/cvsroot/CMake/CMake/Source/cmGlobalVisualStudioGenerator.h,v <-- Source/cmGlobalVisualStudioGenerator.h
new revision: 1.14; previous revision: 1.13