1

For a small project I'm working on, I would like to create a “relocatable build” of PostgreSQL, similar to the binaries here. The idea is that you have PostgreSQL and all required libraries packaged so that you can just unpack it in any directory on any machine and it will run. I want the resulting build of Postgres to work on virtually any Linux machine it finds itself on.

I've made it so far as determining which libaries I need to build:

objdumps

My understanding is that I should be getting the source code for these libraries (and their dependencies) and compiling them statically.

As things stand currently, my build script is quite barebones and obviously produces an install that is linked against whatever distribution it was run on:

./configure \
  --prefix="${outputDir}" \
  --with-uuid="ossp"

I'm wondering if anyone could outline what steps I must take to get the relocatable build that I'm after. My hunch right now is that I'm looking for guidance on what environment variables I would need to set and/or parameters I'd need to provide to my build in order to end up with a fully relocatable build of Postgres.

Please note: I don't normally work with C/C++ although I have several years of ./configure, make and doing builds for other much higher level ecosystems under my belt. I'm well aware that distribution-specific releases of Postgres are widely available, to speak nothing of the official docker container. Please take the approach that I'm pursuing a concept in the spirit of research or exploration. I'm looking for a precise solution, not a fast one.

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
Alexander Trauzzi
  • 7,277
  • 13
  • 68
  • 112
  • Everything is open source :) -- Do I have to manipulate the executables at all? Like say `patchelf` or something? How will the executables know to look for the files in the nearby `lib` dir rather than from the system? – Alexander Trauzzi Jan 31 '22 at 21:43
  • 1
    What exactly happened here, @LaurenzAlbe? You seem to have edited this question into a rather different one, with no justification that I can see at this point. – John Bollinger Feb 01 '22 at 14:39
  • 1
    @JohnBollinger I had a lengthy discussion with OP (deleted since), and it became obvious that he wasn't interested in a static build at all, so I did that. Sorry if I overstepped a boundary - OP can always roll back my edit. – Laurenz Albe Feb 01 '22 at 15:02
  • 2
    @LaurenzAlbe, I suspected something like that. It would have been better to leave the discussion, or at least enough of it to explain why the change was made. It would also have been a good idea to use the edit comment to explain. – John Bollinger Feb 01 '22 at 15:08
  • It was a bit dragged out, but we got there. I'm ultimately thankful for Laurenz help. – Alexander Trauzzi Feb 01 '22 at 16:01

2 Answers2

2

This answer is for Linux; this will work differently on different operating systems.

You can create a “relocatable build” of PostgreSQL if you build it with the appropriate “run path”. The documentation gives you these hints:

The method to set the shared library search path varies between platforms, but the most widely-used method is to set the environment variable LD_LIBRARY_PATH [...]

On some systems it might be preferable to set the environment variable LD_RUN_PATH before building.

The manual for ld tells you:

If -rpath is not used when linking an ELF executable, the contents > of the environment variable LD_RUN_PATH will be used if it is defined.

It also tells you this about the run path:

The tokens $ORIGIN and $LIB can appear in these search directories. They will be replaced by the full path to the directory containing the program or shared object in the case of $ORIGIN and either lib - for 32-bit binaries - or lib64 - for 64-bit binaries - in the case of $LIB.

See also this useful answer.

So the sequence of steps would be:

./configure --disable-rpath [other options]
export LD_RUN_PATH='$ORIGIN/../lib'
make
make install

Then you package the PostgreSQL binaries in the bin subdirectory and the shared libraries plus all required libraries (you can find them with ldd) in the lib subdirectory. The libraries will then be looked up relative to the binaries.

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
  • Wonderful, thank you so much, and it works! You can see the relevant portion of my updated build script here: https://github.com/atrauzzi/protoculture-dotnet-postgres/blob/main/Protoculture.Postgres.Embedded/build-postgres-linux.sh#L22-L27 – Alexander Trauzzi Feb 01 '22 at 16:02
0

Here is a example Github Actions pipeline for building portable build of postgre https://github.com/typerefinery-ai/postgres-postgres/blob/release/v15.3/.github/workflows/pipeline.yml

Max Barrass
  • 2,776
  • 1
  • 19
  • 10