Tuesday, January 12, 2010 10:41 PM
A VS2008 solution I have inherited leverages a handful of 3rd party components that are precompiled (.h and .dll/.lib files), each stored separately in Subversion as .CAB files. The real C++ projects in the solution reference these components where they get unpacked by relative paths (e.g. ../Prebuilt/Debug/libjpeg/include), so obviously the first step in any clean build is to download and unpack the 3rd party components. I've heard of similar situations where "static" components were pulled down from FTP servers, but I've never had to deal with either before.
I have a Makefile project in the solution named "Prebuilt" that is first in the build order (the lowest-level library explicitly depends upon it - project to project in VS2010 terminology?), and it's responsible for getting the .CAB files from SVN and expanding them into the appropriate subdirectory structure. This is done by calling a .BAT script in the "NMake" section. As you can guess, this is more than a little awkward.
A few of the problems are:
1. unlike with native C++ projects, it seems like makefile projects always have to be invoked each build, since there is no knowledge of its dependencies other than to let it run and either do something or not. This slows down hitting F5 to launch a bit, and it creates some distracting spew to the Output window:
------ Build started: Project: Prebuilt, Configuration: Debug Win32 ------
Performing Makefile project actions
GetAndUnpackPrebuiltPackages.bat: expanding cabs in w:\work\Current\Prebuilt\Debug
Build log was saved at "file://w:\work\Current\Prebuilt\Support\Debug\BuildLog.htm"
Prebuilt - 0 error(s), 0 warning(s)
========== Build: 1 succeeded, 0 failed, 34 up-to-date, 0 skipped ==========
2. we do end up re-inventing the wheel in the .BAT script as far as dependency checking (i.e. is the .CAB file already downloaded? is it downloaded but older than the .BAT script itself - which contains the SVN revisions # to pull). Some of this could be made easier if an actual Nmake makefile had been used instead of raw .BAT scripting, but I'm not sure NMake is even the right approach looking forward at VS2010. I'm curious if there is a better way using native MSBuild features going forward?
3. the automatic conversion from VS2008 to VS2010 causes havok. After the projects were converted, there are build errors in native projects that try to reference the build "output" directory of this Prebuilt project, even though this makefile project doesn't generate any libraries in a Debug or Release directory. I think this is due to the lowest-level native C++ project having its project-to-project dependency on the Prebuilt project, and then higher-level libraries try to recursively pull in any dependent project output for projects it depends upon (like a transitive closure). I'm sure this can be tweaked, but it threw me off since VS 2008 doesn't behave this way and the various linker settings are kind of confusing.
I'd love to hear about any suggestions for either the VS2008 approach or the options for VS2010.
Tuesday, January 12, 2010 11:04 PMOpps..I wanted to mention one more similar question regarding a VS2008 project issue that stumped me. Hopefully there is a better way, or at least a better way in VS2010...
The issue here is with a project that just generates a resource .DLL. The .RC file referenced in the project is actually just doing a bunch of #include "foo.rc" / #include "bar.rc" lines to reference a bunch of lower-level .RC files that really contain the dialogs, etc. It was broken up to be more modular and avoid contention on a single huge .RC file.
The issue is that editing any of the lower-level .RC files will not trigger a rebuild of the resource DLL. A manual "clean" or "rebuild" is required, which is very easy to forget. There is a little bit of #ifdef / #ifndef logic in the top-level .RC file (e.g. omit certain dialogs unless its a Debug build), but otherwise it is pretty simple. Otherwise, the project just contains a little stub .CPP file with the DllMain and AFX_EXTENSION_MODULE.
So the general question is whether there is a better way, and whether in general it is possible to declare "extra" dependencies within the project?
Wednesday, January 13, 2010 9:15 PM
VS2010 makefile up to date check behavior is still the same as VS2008. As you mentioned, there does not seem to be a good way for VS to know its dependencies so it will be run always and it is up to the makefile itself to determine the up to date-ness.
For (2), one suggestion would be to use "Custom build Steps" feature in VS2010. The build order of Custom Build Steps can be customized through UI using Before/After Targets MSBuild concept. Incremental build is also enabled for Custom build steps. Outputs and dependencies can be specified for custom build steps and are being tracked when doing incremental build.
For (3), yes, you can config the project so that it is part of the project to project reference but its output is not being passed to the referencing project. Here are the steps:
· Right click on referencing project node in solution explorer, choose "Add Reference"
· In the "Add Reference" dialog, there will be a list of referenced project
· Click on the project of your interest, you will see the "Link Library Dependencies" property in the right pane.
· The default value for this property is "true", if you set it to "false", its output will not be passed to the referencing project
VS2010 incremental build/Dependency check experience will be much better in the scenario you have described for RC. We look into all included files including headers/RC files and rebuild the RC file if any of its dependencies are more recent.
Li Shao, MSFT
- Marked As Answer by Abe10 Friday, January 15, 2010 2:00 AM