J
Joshua Maurice
(I'm sorry if this is too off topic, but I'm not sure where else to
ask. It does specifically relate to a very important aspect of using C+
+, so I think it's (enough) on topic.)
I'm curious how all of you actually build your code. GNU Make, SCONS,
bjam, vcproj files, etc.?
Specifically, I'm very curious how close your build system is to my
"ideal" build system. My ideal build system has two requirements, fast
and correct. Correct means that a full build at any time produces the
same results as a build from a completely clean local view. Fast means
fast. When builds can take hours or more, I don't want to look at an
error, and wonder if it was because I didn't build from clean,
potentially wasting more hours as I do a sanity check rebuild.
All build systems can be made correct by having it first completely
clean out the local view, then building. However, this is also the
polar opposite of fast. I think it's fair to say that the only way to
achieve correct and fast is to have an incremental build system, a
build system that builds everything which is out of date, and does not
build anything already up to date. (Arguably, that definition is
biased. It infers the use of file timestamps, but there could exist
fast and correct build systems which do not rely upon file
timestamps.)
I think it's also fair to say to achieve fast, you need to have a
parallel build system, a build system that does the build steps in
parallel as much as possible.
Something like "ease of use" is a third aspect of my ideal build
system. A naive build system built upon GNU Make which requires
developers to manually specify header file dependencies may be
technically correct, but it would be ridiculously error prone and a
maintenance nightmare. I don't know a better way to describe what I
want than "idiot-proof". If you miss a header file dependency, the
next incremental build may produce correct results, and it may not. I
want a build system where the incremental build always will be correct
(where correct means equivalent to a build from completely clean) no
matter the input to the build system. (However, if the build system
itself changes, then requiring all developers to fully clean would be
acceptable.)
Lastly, I want it to be portable to basically anything with a C++
implementation. My company supports nearly every server and desktop
platform known to man (Ex: Z/OS, HPUX, AIX, Solaris, WIN, Linux,
several mainframes, and more), and several common Make-like tools
purport to not run on all of these systems. Preferably, I would like
to not be bound to the system specific shell either like Make.
(Although you could just require all developers to install sh and
force sh usage, at least for the makefiles.)
For example, for your build systems, how much of the above does it do?
Specific examples:
1- Does it correctly and automatically track header file
dependencies?
2- If a DLL changes, will you relink all dependent DLLs, transitive
and direct, or will you only relink direct dependent DLLs?
3- Can your developer inadvertently break the incremental build in
such a way that it succeeds on his local machine but fails on the
build machine because he missed specifying a dependency?
4- Is your (unit) test framework incorporated into the build, so that
you can run only the tests which have depend upon a change?
5- Can your build system generate vcproj files on windows? (I
personally like the Visual Studios IDE, and it would be a shame to
lose this by going to a fast, correct build system.)
Thus far, I have not found a satisfactory answer to these questions in
the open source world. Thus, I've been developing my own answer for
the last couple of months, where I hope to achieve (almost) all of
these goals.
ask. It does specifically relate to a very important aspect of using C+
+, so I think it's (enough) on topic.)
I'm curious how all of you actually build your code. GNU Make, SCONS,
bjam, vcproj files, etc.?
Specifically, I'm very curious how close your build system is to my
"ideal" build system. My ideal build system has two requirements, fast
and correct. Correct means that a full build at any time produces the
same results as a build from a completely clean local view. Fast means
fast. When builds can take hours or more, I don't want to look at an
error, and wonder if it was because I didn't build from clean,
potentially wasting more hours as I do a sanity check rebuild.
All build systems can be made correct by having it first completely
clean out the local view, then building. However, this is also the
polar opposite of fast. I think it's fair to say that the only way to
achieve correct and fast is to have an incremental build system, a
build system that builds everything which is out of date, and does not
build anything already up to date. (Arguably, that definition is
biased. It infers the use of file timestamps, but there could exist
fast and correct build systems which do not rely upon file
timestamps.)
I think it's also fair to say to achieve fast, you need to have a
parallel build system, a build system that does the build steps in
parallel as much as possible.
Something like "ease of use" is a third aspect of my ideal build
system. A naive build system built upon GNU Make which requires
developers to manually specify header file dependencies may be
technically correct, but it would be ridiculously error prone and a
maintenance nightmare. I don't know a better way to describe what I
want than "idiot-proof". If you miss a header file dependency, the
next incremental build may produce correct results, and it may not. I
want a build system where the incremental build always will be correct
(where correct means equivalent to a build from completely clean) no
matter the input to the build system. (However, if the build system
itself changes, then requiring all developers to fully clean would be
acceptable.)
Lastly, I want it to be portable to basically anything with a C++
implementation. My company supports nearly every server and desktop
platform known to man (Ex: Z/OS, HPUX, AIX, Solaris, WIN, Linux,
several mainframes, and more), and several common Make-like tools
purport to not run on all of these systems. Preferably, I would like
to not be bound to the system specific shell either like Make.
(Although you could just require all developers to install sh and
force sh usage, at least for the makefiles.)
For example, for your build systems, how much of the above does it do?
Specific examples:
1- Does it correctly and automatically track header file
dependencies?
2- If a DLL changes, will you relink all dependent DLLs, transitive
and direct, or will you only relink direct dependent DLLs?
3- Can your developer inadvertently break the incremental build in
such a way that it succeeds on his local machine but fails on the
build machine because he missed specifying a dependency?
4- Is your (unit) test framework incorporated into the build, so that
you can run only the tests which have depend upon a change?
5- Can your build system generate vcproj files on windows? (I
personally like the Visual Studios IDE, and it would be a shame to
lose this by going to a fast, correct build system.)
Thus far, I have not found a satisfactory answer to these questions in
the open source world. Thus, I've been developing my own answer for
the last couple of months, where I hope to achieve (almost) all of
these goals.