[Gnome-devtools] Project Configuration Management



(LotR asked me to describe the project configuration management features
in Microsoft Visual C++/Studio.)

The developer starts Visual C++ with a "Workspace".  A Workspace is a
collection of "Projects".  A Project is typically an executable, but
libraries, dynamic libraries, and arbitrary Makefiles can also be
Projects.  (Most developers work with workspaces containing one
executable project and one project for each DLL.)  A Project is a
collection of source files, organized into a tree of folders (more on
this later).

A Workspace is stored in a .dsw file, which is a proprietary ASCII
format.  (Its format isn't interesting, but I can post one if anyone
would like to see one.)  Projects are stored in .dsp files.  The .dsp
files look so much like Makefiles and they have a comment at the top
explaining that they are not valid Makefiles and giving instructions for
creating a valid Makefile.

Every Project has Configurations.  When a new project is created it
starts with two default configurations: "Debug" and "Release".  It is
possible to add new Configurations, for example a configuration to build
executables for profiling, or configurations to build Unicode versions
of the Debug and Release configurations.  Typically a build places
object files and executables in a directory with the same name as the
configuration, although this is set-able.  One of the configurations is
"Active," and it is the only one used when building the project.

A Configuration is a collection of make, compile, link and debug
settings for a Project.  A Configuration can specify individual settings
for every file (and folder) in the project, but naive developers don't
need to know because Microsoft cleverly hides this complexity unless it
is needed.

The Project Settings dialog, and the FileView tab of the Workspace
display the workspace as a tree.  For a small new project, the tree
looks something like the below.  (I've drawn the folders in [square
brackets], and I've added columns for the Configurations that users
wouldn't see and put gcc-style compiler flags into those columns.)

----------------------------
Workspace 'test': 2 projects
  foo files                  Debug           Release
    [Source Files]           -g              -O2 -DNDEBUG
      foo.c
    [Header Files]
      foo.h
    [Resource Files]
      foo.ico (an icon)
    ReadMe.txt

  bar files                  Debug           Release          Profile
    [Source Files]           -g              -O2 -DNDEBUG     -g -O2 -pg
-DNDEBUG
      bar.c
     
baz.c                                                                                                            
-O3 -funroll-loops  -g -O3 -funroll -pg
    [Header Files]
      bar.h
----------------------------

In this example, the project includes two executables, foo and bar.  foo
has two configurations: Debug and Release.  bar has an additional third
configuration, Profile.  The Source Files folder specifies that the
Debug build include debugging, and the release build include
optimization.  (bar has optimization and debugging turned on for it's
profiling configuration, because we want to profile the optimized
build).  The file baz.c overrides some compiler flags because it needs
more specialized optimization.

The release builds specify -DNDEBUG, so that assert() checks don't ship
in our final build.  Although baz.c's Configuration doesn't specify
-DNDEBUG it will inherit NDEBUG from its parent, [Source Files].

When a folder setting is changed the IDE erases all customizations for
the same parameter for all tree nodes which could inherit the change. 
For example, if the [Source Files] specified -DNDEBUG and bar.c
specified -DNDEBUG,USE_LOOP, then changing [Source Files] to -D erases
the specialization and all reference to USE_LOOP.  (This may seem
counterintuitive, but let me point out that Borland C++ 3.x did it the
other way and it was murder when a project global setting needed to be
changed.)

The folder names [Source Files], [Header Files], etc., are merely
defaults.  The folders can be renamed, new folders can be added, and
folders can contain other folders.  Some developers use this to organize
a large project into modules, each possibly with custom settings.

The Project Settings dialog is used to change the build options.  The
dialog has two panes: the left side is the workspace tree and a box for
selecting which configuration is being edited (or "All
Configurations").  The right side is a tab control with a panel for each
kind of project below the file/folder selected on the left.  The tab
arrangement is how Microsoft cleverly hides the complexity from the
user.  If an executable is selected in the workspace pane, then there
are many tabs available and the right pane settings specify the entire
project.  If [Source Files] is selected then the linker and debugger
tabs go away and we just see C/C++ compilation options.

Now that we've seen how the configuration is edited we shall move on to
the tabs themselves and look at what can be specified in a
configuration.  The tabs are General, Debug, C/C++, Link, Resources,
Browse Info, Custom Build, Pre-link Step, Post-build Step.

"General" specifies the object file directory (remember, this is "Debug"
or "Release").  Depending on what it is being applied to it may have an
option to exclude from build (this lets the developer remove stuff on a
trial basis.  If the developer simply deleted and then changed his mind
many settings would need to be recreated).  (There is also some stuff
about the MFC class library that belongs somewhere else, but Microsoft
put it up front.)

"Debug" specifies the arguments and working directory for the
executable.  The name of the executable to debug can be specified here
as well, in case it is different from the target, for example when the
target is a DLL, or (rarely) when it's desired to invoke a program that
will eventually shell out to our target.)

"C/C++" specifies all the kinds of things one would pass to the compiler
when generating object files.

"Link" specifies the target, the libraries to include, and various
linker parameters.

"Resources" specifies settings for the "Resource Compiler", a tool for
compiling GUI specifications into something that will be linked into the
binaries.

"Browse Info" has settings for generating files which work with an
included class browser.

"Custom Build" has dialogs where the developer can enter bits of scripts
that will be used when unknown content has to be compiled by the IDE. 
For example, although the IDE doesn't know about YACC it is possible to
get the IDE to invoke yacc by specifying some commands and the names of
the YACC output file here.

The "Pre-Link" and "Post Build" tabs are used to specify special actions
to take after the project has been built.  (I've only used these to copy
files to an additional location, but I believe they serve a functional
analogous to the fake targets in a Makefile.  For example, you could
specify stuff here to build a tarball.)


That concludes this tour of the Microsoft IDE's project configuration
management features.  I'd like to conclude with my thoughts on the
places where Microsoft's system breaks down:

o The idea of having a different target for different versions, such as
an ASCII target and a Unicode target, is contrary to the autoconf
philosophy of modern Unix.  I feel a gnome devtool should be writing a
flexible configure.in as well as a GNU-compliant Makefile.

o The Project Settings dialog (and it's underlying tree-based/multiple
config paradigm) are intuitive for new and advanced users, but difficult
for intermediate users because of complex interactions between the
project tree, the configuration drop down, and the large number of
settings tabs.

o Because a Project file (.dsp) contains many important settings it is
as important to include with a source archive as as a Makefile would
be.  Still, a large number of developers don't or won't ship their .dsp
files when they provide source.  (I don't know why this convention has
developed -- perhaps some other Windows IDE included too much local
config like color preferences in it's project files).  The patterns and
rituals for an IDE need to encourage sharing of project files.

o I feel the Debug tab is incomplete.  I also spend a lot of time inside
Symantec's Java debugger, and I like the way I can keep debugger
settings such as signal/exception handling persistent on a per-project
basis in that IDE.


As always, comments are welcome.

Ed Snible
esnible acm org




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]