Eugene Sajine [off-list ref] writes:
quoted
If the project is already arranged to be compiled with decent automation,
I do not think you need any change to the workflow.
You would have a version.cc file with
static char program_version[] = "My Program " VERSION_STRING;
in it, and teach the build procedure how to compile and link this file.
Something like:
version.o: version.cc
$(CXX) -o $@ -DVERSION_STRING=\""$(git describe HEAD)"\" $?
Please, correct me if I'm mistaken and forgive me if I'm not correct
in using C++ terms.
Your solution proposes to have a version file which will carry the
info about last state the program was built from.
But as I understand in case of static linking the executable will get
only obj files from a library, which are necessary and everything
irrelevant will be thrown away by linker.
I am not sure what you mean by "static linking" anymore. Usually the word
means that everything you tell the linker to link to the executable is
linked, together with objects from libraries. The resulting executable is
usable on its own and it does not change behaviour regardless of which
version of dynamic libraries you depend on happen to be installed on the
target system (because by definition a statically linked executable does
not depend on dynamic libraries---that is the whole point of static
linking).
So as long as you make sure version.o is linked to the final executable,
you will be fine. One way to do so might be to have
printf("Program version: %s", program_version);
at the beginning of main() ;-)
If your product ships as one main executable _dynamically_ linked with two
dynamic libraries, and all three components are built from the source
material under your source control, obviously you would need to make sure
that the above version.o or some equivalent of what embeds output from
"git describe HEAD" are linked to the main executable and to the two
libraries, but the idea is the same.
I am not sure what you mean by "static linking" anymore. Usually the word
means that everything you tell the linker to link to the executable is
linked, together with objects from libraries. The resulting executable is
usable on its own and it does not change behaviour regardless of which
version of dynamic libraries you depend on happen to be installed on the
target system (because by definition a statically linked executable does
not depend on dynamic libraries---that is the whole point of static
linking).
There seems to be no misunderstanding in the static linking - i meant
the same thing. But let me put an example:
I have a program.exe
This program.exe is built basing on two statically linked libraries
lib1.lib and lib2.lib
I'm not developing any of those libraries, but only my own code of the
program.exe
Now, somebody changed 2 files in lib1.lib and 5 files in lib2.lib. But
i don't know that they are changed because it is different CVS module
or because I'm building against latest released libs or for whatever
reason...
When i rebuild my program the build supposed to pick up changes from
the libraries I'm using and relink, that will include 7 changed obj
files.
How can i say which exactly files are changed in my new version of
executable comparing to the previous version?
Currently they can take a look at the revision number of every
particular file included into the executable, which is put there by
CVS and compare it with the production. If the version is different,
then you know which files are changed and you can get diffs on them...
They also have file path and date and other stuff expanded...
Please note, my personal goal is *to prove that git can do that
better*, with less intrusion into the code sources, not other way
around.So, while keeping the info they want to have they might get
some benefits of git. Although, i understand that there might be no
cure for this state already, you can tell me that and I will close the
topic, but I just keep hoping;)
Thanks a lot,
Eugene
Quoting Junio C Hamano [off-list ref]
If your product ships as one main executable _dynamically_ linked with two
dynamic libraries, and all three components are built from the source
material under your source control, obviously you would need to make sure
that the above version.o or some equivalent of what embeds output from
"git describe HEAD" are linked to the main executable and to the two
libraries, but the idea is the same.
Doesn't the above strategy also apply to the case where the
libraries are linked statically, too? You get the version
string from the main program and two version strings from the
libraries embedded in the final product.
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
On Tue, 20 Oct 2009, Eugene Sajine wrote:
quoted
I am not sure what you mean by "static linking" anymore. Usually the word
means that everything you tell the linker to link to the executable is
linked, together with objects from libraries. The resulting executable is
usable on its own and it does not change behaviour regardless of which
version of dynamic libraries you depend on happen to be installed on the
target system (because by definition a statically linked executable does
not depend on dynamic libraries---that is the whole point of static
linking).
There seems to be no misunderstanding in the static linking - i meant
the same thing. But let me put an example:
I have a program.exe
This program.exe is built basing on two statically linked libraries
lib1.lib and lib2.lib
I'm not developing any of those libraries, but only my own code of the
program.exe
Now, somebody changed 2 files in lib1.lib and 5 files in lib2.lib. But
i don't know that they are changed because it is different CVS module
or because I'm building against latest released libs or for whatever
reason...
When i rebuild my program the build supposed to pick up changes from
the libraries I'm using and relink, that will include 7 changed obj
files.
How can i say which exactly files are changed in my new version of
executable comparing to the previous version?
As Nanako points out, you want a version string from each library,
probably with the name of the library in the symbol. So:
static char *lib1_version = "" VERSION_STRING
in lib1/version.cc.
Currently they can take a look at the revision number of every
particular file included into the executable, which is put there by
CVS and compare it with the production. If the version is different,
then you know which files are changed and you can get diffs on them...
They also have file path and date and other stuff expanded...
Once you've got the version strings from each of the components, and
you've got the repository for each library, you can compare the version in
the string with other versions, and that one hash expands to the hashes
for all of the files, including things like the Makefile that don't
actually become object files but affect them.
You can also do things like: when you build an executable, write it as a
blob to the repository and make a tag (actually, a note will be
better, but that's newer than I've done this) pointing to it that lists
everything used to build it. If you encounter the executable again later,
it'll have the same hash, and git can find the tag with the other
information.
I've actually done something where I tagged the main tree and a few
libraries with matching tags, built the executable with a 20-byte
sequence of zeros, put it into the repository, then wrote its sha1 to
those 20 bytes, and tagged the executable with a tag based on the source
tag. Then I put it on a microcontroller, sealed it in epoxy, mixed it with
other devices with different firmware revisions, and sent it out. When a
device had a problem, I could ask it for those 20 bytes, ask git for the
tag that pointed to those 20 bytes, and check out exactly the source used
to build it.
Please note, my personal goal is *to prove that git can do that
better*, with less intrusion into the code sources, not other way
around.So, while keeping the info they want to have they might get
some benefits of git. Although, i understand that there might be no
cure for this state already, you can tell me that and I will close the
topic, but I just keep hoping;)
You're not going to be able to avoid having different tracking things in
the source, but git does give you the major advantage that you can have
the build system produce one hash that identifies every single file in the
project, rather than having to have each file identify itself (and
probably overlook files that don't directly produce object code). It's a
big help the day you're trying to figure out if an executable came from
before or after someone's commit to change the compiler options, and it's
fewer strings than you need with CVS.
-Daniel
*This .sig left intentionally blank*