win32 version info

Started by Magnus Haganderabout 22 years ago27 messagespatches
Jump to latest
#1Magnus Hagander
magnus@hagander.net

This patch along with the attached files (.tar.gz unpacks in src/) adds
VERSIONINFO to all binaries under win32. This is generally considered a
good thing (actually, I think it's required to be allowed to call your
program "Designed for Microsoft Windows". We're not going to get that
anyway, but it gives those of you who don't know about it an idea of how
common/good it is).

The string-based version number is read from whatever is in pg_config.h.

The patch also requires a new define in pg_config.h along the line of:
#define PG_VERSION_NUMERIC 7,4,999,999
(note - commas, not dots)

This is because the versioninfo structure has a 4-number numeric field
that is the one that is used when comparing versions.

As pg_config.h is generated from configure.in, I know the change has to
be made there. And since I'm not that experienced with autoconf, I'm
hoping the eventual committer can add this. I assume just a simple
define right along the line where it sets the version string would be
the easiest. It just has to be bumped on new releases (so it should
probably go in the "what do we do when doing a new release" list as
well).

As the number has to be numerical and should always be increasing, I set
the devel verison number to 7,4,999,999. That should get us well out of
the way of any future 7.4 releases, and when we actually release 7.5 we
change it to 7,5,0,0. I don't think we need/should increase the version
between beta builds etc - let's just focus on the actual releases.

The patch also makes sure that the already existing versioninfo resource
available to libpq.dll is actually compiled and linked when building
with mingw. This one can't use the same #include to get the actual
version number because we don't have the necessary files on MSVC
installs.

Finally, the patch adds an elephant icon to psql.exe (so it'll go nicely
in the start menu for example). This icon was taken from Gavin Roys
postgresql artwork page (http://pgsql.gavinroy.com/art).

//Magnus

Attachments:

resource.tar.gzapplication/x-gzip; name=resource.tar.gzDownload
resource.patchapplication/octet-stream; name=resource.patchDownload+166-41
#2Peter Eisentraut
peter_e@gmx.net
In reply to: Magnus Hagander (#1)
Re: win32 version info

Magnus Hagander wrote:

This patch along with the attached files (.tar.gz unpacks in src/)
adds VERSIONINFO to all binaries under win32. This is generally
considered a good thing

Out of curiosity: Why?

Finally, the patch adds an elephant icon to psql.exe (so it'll go
nicely in the start menu for example). This icon was taken from Gavin
Roys postgresql artwork page (http://pgsql.gavinroy.com/art).

Would it be possible to provide a scalable version of the logo in the
source code and generate the appropriate format from that at build
time? I know, for example, that some Linux packages put psql in their
menu and might like an endorsed logo for that. If we used, say, SVG
for that, we could also avoid storing more binary files in the source
tree. (I have an SVG version of the elephant available, btw.) We
could even provide a .desktop file.

Moreover, the file should be called psql.ico, not pgsql.ico.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#1)
Re: win32 version info

"Magnus Hagander" <mha@sollentuna.net> writes:

This patch along with the attached files (.tar.gz unpacks in src/) adds
VERSIONINFO to all binaries under win32.

Ya know, this is the sort of invasive junk that I was afraid people
would try to force on us for the Windows port :-(.

Can't you localize this into a single build rule somewhere? And surely
we do not need to maintain a boilerplate .rc file for every executable.

Finally, the patch adds an elephant icon to psql.exe (so it'll go nicely
in the start menu for example).

You need a lot better reason than that to convince me to put a binary
file into CVS.

regards, tom lane

#4Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#3)
Re: win32 version info

This patch along with the attached files (.tar.gz unpacks in src/)
adds VERSIONINFO to all binaries under win32. This is generally
considered a good thing

Out of curiosity: Why?

Well, because it allows the user as well as other programs to identify
what version of a file is installed. For error-checking purposes (which
DLL version is really there? And debugger will also tell you which
version of the DLL is actually loaded in the process working space if yo
uhave more than one on your system), software distribution (all
installers are required to check this field to make sure they don't
overwrite a file with an older version), software inventory, the list
goes on.

Finally, the patch adds an elephant icon to psql.exe (so it'll go
nicely in the start menu for example). This icon was taken from Gavin
Roys postgresql artwork page (http://pgsql.gavinroy.com/art).

Would it be possible to provide a scalable version of the logo in the
source code and generate the appropriate format from that at build
time? I know, for example, that some Linux packages put psql in their
menu and might like an endorsed logo for that. If we used, say, SVG
for that, we could also avoid storing more binary files in the source
tree. (I have an SVG version of the elephant available, btw.) We
could even provide a .desktop file.

I have no idea, actually. I don't know of any software that will do
this, but that certainly doesn't mean it exists. And I'm not enough of a
graphics guy to comment on if there would be issues with the convert
(quality-wise for example).

Moreover, the file should be called psql.ico, not pgsql.ico.

Well, it is a general pgsql icon :-) But yes, since it's in the psql
directory it should probably be renamed. BTW, for those who aren't aware
- this file is never actually installed along with the binary. It's
statically linked into the binary at build time.

//Magnus

#5Magnus Hagander
magnus@hagander.net
In reply to: Magnus Hagander (#4)
Re: win32 version info

This patch along with the attached files (.tar.gz unpacks in

src/) adds

VERSIONINFO to all binaries under win32.

Ya know, this is the sort of invasive junk that I was afraid people
would try to force on us for the Windows port :-(.

I fail to see how this is so invasive. And I definitly don't think it's
junk. But that's just me, I suppose (along with windows users, but "we"
clearly don't care much about them).

Can't you localize this into a single build rule somewhere? And surely
we do not need to maintain a boilerplate .rc file for every executable.

There is a field in the RC file that is "file description". It's pretty
much different for every file. (There is also a "product description" in
there which is the same).

As for putting it in a single build rule - I don't know if that can be
done. I thought it over and didn't come up with a way, but there may be
other who are better at writing Makefiles... I guess a script could be
written that generates the file, but the per-binary information has to
be somewhere. Not sure how that method would be cleaner.

Finally, the patch adds an elephant icon to psql.exe (so

it'll go nicely

in the start menu for example).

You need a lot better reason than that to convince me to put a binary
file into CVS.

Well, if someone can come up with a way to build an icon and link it
into the binary without any binary files, I'm all for it. We can of
course do without it, but it does make the win32 look very
unproffessional.

I probably don't understand what the potential problems are with binary
files in cvs, because I don't quite see the issue...

//Magnus

#6Andrew Dunstan
andrew@dunslane.net
In reply to: Magnus Hagander (#5)
Re: win32 version info

Magnus Hagander wrote:

Can't you localize this into a single build rule somewhere? And surely
we do not need to maintain a boilerplate .rc file for every executable.

There is a field in the RC file that is "file description". It's pretty
much different for every file. (There is also a "product description" in
there which is the same).

As for putting it in a single build rule - I don't know if that can be
done. I thought it over and didn't come up with a way, but there may be
other who are better at writing Makefiles... I guess a script could be
written that generates the file, but the per-binary information has to
be somewhere. Not sure how that method would be cleaner.

We would not need to generate it at all. Maybe something like this would
work:

In the makefile, symlink each .rc file to the boilerplate version
somewhere, and put a definition like this:

FILEDESC="\"whatever you like\""

and also conditionally include the *rc.o file in its objects list.

The rc file would, of course, have this line:

VALUE "FileDescription", FILEDESC

Makefile.global or similar could define the build rule once, like

%.o: %.rc
windres -DFILEDESC=$(FILEDESC) $< -o $@
--include-dir=$(top_builddir)/src/include

I hope you get the idea.

cheers

andrew

#7Peter Eisentraut
peter_e@gmx.net
In reply to: Magnus Hagander (#1)
Re: win32 version info

Magnus Hagander wrote:

This patch along with the attached files (.tar.gz unpacks in src/)
adds VERSIONINFO to all binaries under win32.

What this apparently completely ignores is that all libraries and some
other pieces (e.g., ecpg) have their own version number.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

#8Peter Eisentraut
peter_e@gmx.net
In reply to: Magnus Hagander (#4)
Re: win32 version info

Magnus Hagander wrote:

Well, because it allows the user as well as other programs to
identify what version of a file is installed.

psql --version

For error-checking
purposes (which DLL version is really there? And debugger will also
tell you which version of the DLL is actually loaded in the process
working space if yo uhave more than one on your system),

OK, that should go into the DLL, just as it goes into shared libraries
on Unix. But then you need to use the actual shared library versions
that we use.

software
distribution (all installers are required to check this field to make
sure they don't overwrite a file with an older version), software
inventory, the list goes on.

This is the packager's business, not ours.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

#9Magnus Hagander
magnus@hagander.net
In reply to: Peter Eisentraut (#8)
Re: win32 version info

Well, because it allows the user as well as other programs to
identify what version of a file is installed.

psql --version

That works for an executable. And that works for the user. Doesn't work
as well for a piece of software that does this. How is it supposed to
know which .EXEs it can send "--version" to? And it won't work for any
DLLs.

For error-checking
purposes (which DLL version is really there? And debugger will also
tell you which version of the DLL is actually loaded in the process
working space if yo uhave more than one on your system),

OK, that should go into the DLL, just as it goes into shared libraries
on Unix. But then you need to use the actual shared library versions
that we use.

Um. Right. That goes on some things (like libpq). But all DLLs don't
have that (seems plpgsql still claims 1.0, which can hardly be correct,
for example. There has to have been *some* revisions to it since it was
created...). But perhaps that should be fixed in the general shared lib
version, then?

The common way to do it on win32, if we want to follow that, is to have
<majorversion>.<minorversion>.<build>.<sub-build>. Mapping that to the
shlib would be more along the line of 7.5.<shlibmajor>.<shlibminor>. If
we want to go down that path.

software
distribution (all installers are required to check this field to make
sure they don't overwrite a file with an older version), software
inventory, the list goes on.

This is the packager's business, not ours.

It's our business to make it *possible* for the packager, IMHO. And by
not including version information, we make it impossible for someone to
use the unpatched source tree to make a compliant installer for
postgresql.

And putting the responsibility on the packager still doesn't help for
the inventory case.

//Magnus

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#6)
Re: win32 version info

Andrew Dunstan <andrew@dunslane.net> writes:

Makefile.global or similar could define the build rule once, like

%.o: %.rc
windres -DFILEDESC=$(FILEDESC) $< -o $@
--include-dir=$(top_builddir)/src/include

Actually, I was wondering if we could not include this in a build rule
for executables, so that it's not necessary for the individual Makefiles
to be explicitly aware of it at all ...

regards, tom lane

#11Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#10)
Re: win32 version info

Makefile.global or similar could define the build rule once, like

%.o: %.rc
windres -DFILEDESC=$(FILEDESC) $< -o $@
--include-dir=$(top_builddir)/src/include

Actually, I was wondering if we could not include this in a build rule
for executables, so that it's not necessary for the individual
Makefiles
to be explicitly aware of it at all ...

Ok. I got part of the way, by putting the following in Makefile.global:
ifeq ($(PORTNAME), win32)
win32ver.o: $(top_builddir)/src/port/win32ver.rc
sed "s/FILEDESC/\"$(FILEDESC)\"/"
$(top_builddir)/src/port/win32ver.rc | windres -o win32ver.o
--include-dir=$(top_builddir)/src/include
endif

(couldn't get the -D stuff to escape things right... It would put a
backslash in front of every space - that's the closest I got. So I moved
to sed. Thanks anyway, Andrew, sent me off in the right direction.)

All that is then needed is to teach each binary to link in "win32ver.o".
For initdb, I've done this like:
ifeq ($(PORTNAME), win32)
FILEDESC=initdb - initialize a new database cluster
OBJS+=win32ver.o
endif

I assume what you would like is to have just the FILEDESC row in there?
Two questions about that:
1) How would I go about to have the Makefile actually build those files
and link them in without explicitly teaching it about it? I guess I
could link them in by adding it to LDFLAGS or something like that (feels
kind of hackish, though), but I need to have it build it as well, right?
And that line just contains $(OBJS) and libpq.a... None of wich is
inherited from Makefile.global, from what I can tell.
One way would be to just add something like $(PORTOBJ) and have
Makefile.global add whatever special .o files are required for the
current port. That way we wouldn't teach it specifically about the win32
version stuff, but we'd still have to teach it to look somewhere...
Or am I missing some other piece of the Makefile puzzle?

2) This whole concept is not going to work too well with for example
pg_dump which builds three different binaries from the same Makefile.
But I guess they could all be given some kind of shared description (as
I already did for all the stuff in bin/scripts) - that would be good
enough for me.

Mainly, I'd need help with (1) before I can proceed at all down this
path. I just have no idea how to do that.

//Magnus

#12Peter Eisentraut
peter_e@gmx.net
In reply to: Magnus Hagander (#11)
Re: win32 version info

Magnus Hagander wrote:

1) How would I go about to have the Makefile actually build those
files and link them in without explicitly teaching it about it?

There is no (useful) implicit rule to build executables. Either you
make one up (difficult), or you just do the explicit thing.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

#13Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#11)
Re: win32 version info

"Magnus Hagander" <mha@sollentuna.net> writes:

All that is then needed is to teach each binary to link in "win32ver.o".
For initdb, I've done this like:
ifeq ($(PORTNAME), win32)
FILEDESC=initdb - initialize a new database cluster
OBJS+=win32ver.o
endif

I assume what you would like is to have just the FILEDESC row in there?

That would be ideal, but this is probably close enough if no one has a
great idea about how to get rid of the manual addition to $(OBJS).

One way would be to just add something like $(PORTOBJ) and have
Makefile.global add whatever special .o files are required for the
current port. That way we wouldn't teach it specifically about the win32
version stuff, but we'd still have to teach it to look somewhere...

Yeah, that's not a bad idea. If anyone can think of plausible reasons
why we might end up with other things needing to be built for every
executable, it would be quite reasonable to go this route.

I was originally thinking of somehow migrating the executable build
rules into a single pattern rule, but given the lack of any suffix on
executable names it's not clear how to use a pattern rule for the
purpose. And the existing rules are diverse enough that it might be
a real pain to construct such a pattern rule anyway.

regards, tom lane

#14Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#13)
Re: win32 version info

Tom Lane wrote:

I was originally thinking of somehow migrating the executable build
rules into a single pattern rule, but given the lack of any suffix on
executable names it's not clear how to use a pattern rule for the
purpose.

You can write a rule for that using

%: %.o

but...

And the existing rules are diverse enough that it might be
a real pain to construct such a pattern rule anyway.

...is the problem.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

#15Bruce Momjian
bruce@momjian.us
In reply to: Magnus Hagander (#4)
Re: win32 version info

Magnus Hagander wrote:

This patch along with the attached files (.tar.gz unpacks in src/)
adds VERSIONINFO to all binaries under win32. This is generally
considered a good thing

Out of curiosity: Why?

Well, because it allows the user as well as other programs to identify
what version of a file is installed. For error-checking purposes (which

Didn't you and Claudio disagree just a week ago when I asked for some
Win32 C code to auto-check versions like initdb calling postgres? That
was only in one C file ifdef'ed and you thought it was overkill. Now
you want to put stuff in every binary directory?

Seems inconsistent to me.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#16Claudio Natoli
claudio.natoli@memetrics.com
In reply to: Bruce Momjian (#15)
Re: win32 version info

Bruce writes:

Didn't you and Claudio disagree just a week ago when I asked for some
Win32 C code to auto-check versions like initdb calling postgres? That
was only in one C file ifdef'ed and you thought it was overkill. Now
you want to put stuff in every binary directory?

Magnus and I both thought the auto version check for binaries in the same
directory for win32 was overkill, yes. However, IIRC (and it appears I do:
http://archives.postgresql.org/pgsql-hackers-win32/2004-07/msg00194.php)
Magnus stated his opposition whilst also suggesting that we ought to add
win32 versioning to the binaries. As for myself, I am ambivalent towards the
requirement for win32 versioning, and would certainly have been against
using it to solve the auto version check issue.

Seems inconsistent to me.

There is no inconsistency, as the two requirements are aimed at very
different "issues". It was just the case that one (win32 versioning) was
inadvertently a potential (and rejected) solution to the other (auto version
check).

The question now is simply whether or not this versioning cruft justifies
its existence, presumably for facilitating packaging and installation of
binaries (particularly those that cannot report their version readily, such
as DLLs). I personally certainly have no use for it, and I don't see us
getting the "Designed for Microsoft Windows" tick any time soon, but I have
no doubt that Magnus, in working on the win32 installer, is perhaps seeing
the need in an entirely different light.

Cheers,
Claudio

--- 
Certain disclaimers and policies apply to all email sent from Memetrics.
For the full text of these disclaimers and policies see 
<a
href="http://www.memetrics.com/emailpolicy.html">http://www.memetrics.com/em
ailpolicy.html</a>
#17Bruce Momjian
bruce@momjian.us
In reply to: Claudio Natoli (#16)
Re: win32 version info

Claudio Natoli wrote:

Seems inconsistent to me.

There is no inconsistency, as the two requirements are aimed at very
different "issues". It was just the case that one (win32 versioning) was
inadvertently a potential (and rejected) solution to the other (auto version
check).

The question now is simply whether or not this versioning cruft justifies
its existence, presumably for facilitating packaging and installation of
binaries (particularly those that cannot report their version readily, such
as DLLs). I personally certainly have no use for it, and I don't see us
getting the "Designed for Microsoft Windows" tick any time soon, but I have
no doubt that Magnus, in working on the win32 installer, is perhaps seeing
the need in an entirely different light.

"Designed for Microsoft Windows" :-)

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#18Magnus Hagander
magnus@hagander.net
In reply to: Bruce Momjian (#17)
Re: win32 version info

All that is then needed is to teach each binary to link in

"win32ver.o".

For initdb, I've done this like:
ifeq ($(PORTNAME), win32)
FILEDESC=initdb - initialize a new database cluster
OBJS+=win32ver.o
endif

I assume what you would like is to have just the FILEDESC

row in there?

That would be ideal, but this is probably close enough if no
one has a great idea about how to get rid of the manual
addition to $(OBJS).

Ok. Since nobody has added anything, I assume there is nobody around
with an idea on how to do that. :-(

One way would be to just add something like $(PORTOBJ) and have
Makefile.global add whatever special .o files are required for the
current port. That way we wouldn't teach it specifically about the
win32 version stuff, but we'd still have to teach it to

look somewhere...

Yeah, that's not a bad idea. If anyone can think of
plausible reasons why we might end up with other things
needing to be built for every executable, it would be quite
reasonable to go this route.

Again, since nobody said anything, I assume nobody had an idea there.
The question then - would you prefer me to add $(WIN32VER) to specify
what it is, or should I go with $(PORTOBJ) anyway, in case we find
something in the future?

I was originally thinking of somehow migrating the executable
build rules into a single pattern rule, but given the lack of
any suffix on executable names it's not clear how to use a
pattern rule for the purpose. And the existing rules are
diverse enough that it might be a real pain to construct such
a pattern rule anyway.

Yeah, that's what I figured.

One more thing I realised - we need two different types of versioninfo
structures, because one fields tells wether it's a DLL or an app. How
would you prefer this done - either using $(WIN32VERDLL)/$(WIN32VERAPP)
(or $(PORTOBJSHLIB)/$(PORTOBJAPP) if we go down that route), or by
setting another field along FILEDESC called FILETYPE or similar?

//Magnus

#19Andrew Dunstan
andrew@dunslane.net
In reply to: Magnus Hagander (#18)
Re: win32 version info

Magnus Hagander said:

One more thing I realised - we need two different types of versioninfo
structures, because one fields tells wether it's a DLL or an app. How
would you prefer this done - either using $(WIN32VERDLL)/$(WIN32VERAPP)
(or $(PORTOBJSHLIB)/$(PORTOBJAPP) if we go down that route), or by
setting another field along FILEDESC called FILETYPE or similar?

I think I would go with PORTOBJ + FILEDESC + FILETYPE for now. ISTM that
gets it clean enough, and it can be revisited later if necessary.

One thing that I think Peter referred to - libraries that we version (e.g.
libpq) in standard Unix major.minor style should probably carry that version
rather than the PostgreSQL version number.

cheers

andrew

#20Magnus Hagander
magnus@hagander.net
In reply to: Andrew Dunstan (#19)
Re: win32 version info

One more thing I realised - we need two different types of

versioninfo

structures, because one fields tells wether it's a DLL or

an app. How

would you prefer this done - either using
$(WIN32VERDLL)/$(WIN32VERAPP) (or

$(PORTOBJSHLIB)/$(PORTOBJAPP) if we

go down that route), or by setting another field along

FILEDESC called FILETYPE or similar?

I think I would go with PORTOBJ + FILEDESC + FILETYPE for
now. ISTM that gets it clean enough, and it can be revisited
later if necessary.

One thing that I think Peter referred to - libraries that we
version (e.g.
libpq) in standard Unix major.minor style should probably
carry that version rather than the PostgreSQL version number.

Aggh, I knew there was one more issue that needed resolving before I
could move on :)

This we can do, but it does two things:
1) We'll have to add extra code somewhere to have it pick
SO_MAJOR_VERSION,SO_MINOR_VERSION in the cases where it is a shared
library, and PG_VERSION_NUMERIC when it's an app. But this can probably
be done in the rule in Makefile.global.

2) We'll *have* to start actually bumping at least minor versions
whenever we change the code in a sharaed lib. Which we don't do now,
except for libpq. For example, plperl still says 0.0, and plpgsql says
1.0. Also, all the conversion procs are at 0.0, and they all build from
the same rule. That means they all need to get bumped when one of them
changes. That may be a good idea for unix platforms as well, but it is
more work during releases that has to be included. Not sure if we want
to buy into that?

Oh, and for the record, we version libpq.dll on windows in the 7.x.y
manner, and have been doing so ever since we first added win32 support.
We can't really back that one down, so we'd need an exception for that
one.

//Magnus

#21Andrew Dunstan
andrew@dunslane.net
In reply to: Magnus Hagander (#20)
#22Magnus Hagander
magnus@hagander.net
In reply to: Andrew Dunstan (#21)
#23Peter Eisentraut
peter_e@gmx.net
In reply to: Magnus Hagander (#20)
#24Magnus Hagander
magnus@hagander.net
In reply to: Peter Eisentraut (#23)
#25Peter Eisentraut
peter_e@gmx.net
In reply to: Magnus Hagander (#24)
#26Magnus Hagander
magnus@hagander.net
In reply to: Peter Eisentraut (#25)
#27Mark Cave-Ayland
m.cave-ayland@webbased.co.uk
In reply to: Magnus Hagander (#26)