Author Topic: GetAppPath vs. DetermineExecutablePath  (Read 25237 times)

Offline afb

  • Developer
  • Lives here!
  • *****
  • Posts: 884
Re: GetAppPath vs. DetermineExecutablePath
« Reply #15 on: November 21, 2006, 03:47:43 pm »
Neat that BinReloc is working for FreeBSD, I know that it doesn't for Mac OS X.

Maybe we should start with using BinReloc if available (#ifdef ENABLE_BINRELOC),
and then fall back to Thomas solution for Linux and my own solution for Darwin ?

edit: Or maybe ENABLE_BINRELOC wasn't the definition to use, on second glance
that looks more like a setting to whether use binary relocation or use APP_PREFIX...
« Last Edit: November 21, 2006, 03:52:36 pm by afb »

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: GetAppPath vs. DetermineExecutablePath
« Reply #16 on: November 21, 2006, 03:54:38 pm »
edit: Or maybe ENABLE_BINRELOC wasn't the definition to use, on second glance
that looks more like a setting to whether use binary relocation or use APP_PREFIX...

#ifdef SELFPATH
Be patient!
This bug will be fixed soon...

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: GetAppPath vs. DetermineExecutablePath
« Reply #17 on: November 21, 2006, 05:08:01 pm »
Quote
Do you think we should lose using the BinReloc library, as Thomas suggests above ?
(his implementation is a fair bit shorter than what prefix.cpp and prefix.h are...)

binreloc is working under many unix implementations (including freebsd) while Thomas' solution only works for linux if I understood correctly?
There is no big magic in "many unix implementations". Binreloc returns a "hardcoded path" when /proc/self does not work, according to its documentation. That's what my implementation does too. In fact, "hardcoded path" means ".", because that's all you can really do if /proc fails. This is a hack which fails under many circumstances.

Remember, Unix offers no way to determine a file's location or name from its inode (or an application's location from its image) as there may be an arbitrary number hard links (and those may even be added and removed while the program is running). /proc/self is a notable exception because it points to the FS entry that was used to launch the executable.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline afb

  • Developer
  • Lives here!
  • *****
  • Posts: 884
Re: GetAppPath vs. DetermineExecutablePath
« Reply #18 on: November 21, 2006, 05:51:40 pm »
/proc is indeed empty on FreeBSD (at least on FreeBSD 6.1). So I don't see how BinReloc can "work" there either ? It does have a /usr/compat/linux/proc/self/exe, but that's probably not part of the core...

So since we need special cases for Windows, Mac OS X, FreeBSD, Solaris - I guess that means that the "many unix implementations" are probably the same as Linux in practice anyway ?  :)

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: GetAppPath vs. DetermineExecutablePath
« Reply #19 on: November 21, 2006, 06:00:07 pm »
Probably :)

The question is what to make of it, though. We can always try to read /proc/self, there is no harm -- if it fails, we know it. However, if it fails, we have to use something else.

We could use ".", that works in many cases, but does not work in many other cases. We could hardcode some platform-dependent path like /usr/local/bin, but that does not work in all cases, either. We could use the prefix given by ./configure's --prefix, but that still does not work in all cases.

The problem with hardcoding an absolute path is that Code::Blocks will be bound to that one location. Unluckily, "." is not much better, it works in arbitrary locations, but depends on the mode of execution... :(

What to do?
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: GetAppPath vs. DetermineExecutablePath
« Reply #20 on: November 22, 2006, 09:37:51 am »
Quote
There is no big magic in "many unix implementations". Binreloc returns a "hardcoded path" when /proc/self does not work, according to its documentation. That's what my implementation does too. In fact, "hardcoded path" means ".", because that's all you can really do if /proc fails. This is a hack which fails under many circumstances.

We do have *BSD users and it does work for them. Heck, we had even got a patch for binreloc to work on *BSD.
Admittedly, I have not looked into binreloc's code but it was safe to assume that it works, since *BSD users were saying so?

Quote
We could use ".", that works in many cases, but does not work in many other cases. We could hardcode some platform-dependent path like /usr/local/bin, but that does not work in all cases, either. We could use the prefix given by ./configure's --prefix, but that still does not work in all cases.

Hardcoding is out of the question.

Why, all of the sudden, do you want to change things regarding this matter? It does work as it is anyway, AFAIK. And if there are cases which don't work and there is no OS-provided workaround available, C::B already allows you to set the data path in two distinct ways: 1) by adding a command-line option or 2) by setting an environment variable.
The bottom line is that C::B, most of the times, will determine its path automatically but if it doesn't it can be directed to it by the user.
Be patient!
This bug will be fixed soon...

Offline afb

  • Developer
  • Lives here!
  • *****
  • Posts: 884
Re: GetAppPath vs. DetermineExecutablePath
« Reply #21 on: November 22, 2006, 10:14:03 am »
Quote
There is no big magic in "many unix implementations". Binreloc returns a "hardcoded path" when /proc/self does not work, according to its documentation. That's what my implementation does too. In fact, "hardcoded path" means ".", because that's all you can really do if /proc fails. This is a hack which fails under many circumstances.

We do have *BSD users and it does work for them. Heck, we had even got a patch for binreloc to work on *BSD.
Admittedly, I have not looked into binreloc's code but it was safe to assume that it works, since *BSD users were saying so?

I think the patches were only to have it compile without throwing warning/errors... ? (don't think it "works")

The FreeBSD ports I've seen do a: #define APP_PREFIX "/usr/local", and don't use binary relocation (I believe Linux has the same default, but haven't tried using binreloc on Linux yet) We used to do the same in the Mac OS X wrapper, before I ported app/configmanager (i.e. set a prefix explicitly, by using the --prefix option to codeblocks).


Using the BinReloc "library" or Thomas's readlink("/proc/self/exe") should amount to the same thing in the end, but will only work reliably on Linux. All I was asking was that app.cpp and configmanager.cpp should use the same code to determine prefix/datadir ? But I can test the --enable-binreloc version on Linux, and see if it relocates OK.
« Last Edit: November 22, 2006, 10:21:35 am by afb »

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: GetAppPath vs. DetermineExecutablePath
« Reply #22 on: November 22, 2006, 10:26:09 am »
We do have *BSD users and it does work for them. Heck, we had even got a patch for binreloc to work on *BSD.
It's nice that it works for them :)  For your reference, the code that we use looks like this:
base = wxString(SELFPATH,wxConvUTF8);
if (base.IsEmpty())
   base = _T(".");

#define SELFPATH   (br_thread_local_store (br_locate ((void *) "")))

char *br_locate (void *symbol)
{
   char line[5000];
   FILE *f;
   char *path;

   br_return_val_if_fail (symbol != NULL, (char*)NULL);

   f = fopen ("/proc/self/maps", "r");
   if (!f)
      return (char*)NULL;


   while (!feof (f))
        ... <more code>

#define br_return_val_if_fail(expr,val) if (!(expr)) {fprintf (stderr, "..."); return val;
}

I'm so happy it works nicely for BSD. :)


Quote
Hardcoding is out of the question.
That's unfortunate, because that's what we do now.
Quote
Why, all of the sudden, do you want to change things regarding this matter?
I don't want to change things regarding this matter at all. Heck, I could imagine more pleasant things to do.
As you asked for, I was making user plugin paths depending on the location of the config file found. The ConfigManager instances know nothing about the underlying file, that's handled by the related factory class.
Thus, the executable's path (and other paths) must be known a lot earlier now, this can no longer wait until the application eventually figures it out and sets it. Therefore, I implemented something which I thought should work.
In the end, as binreloc depends on /proc/self too, my 6 lines of code do not change any single thing, except they are 6 lines instead of 550 lines...
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline afb

  • Developer
  • Lives here!
  • *****
  • Posts: 884
Re: GetAppPath vs. DetermineExecutablePath
« Reply #23 on: November 22, 2006, 11:24:38 am »
AFAIK: FreeBSD ports will find stuff relative to the $PREFIX it is compiled for (default /usr/local but could be /opt). I don't think we need any binary relocation other than that, i.e. like AutoPackage's BinReloc does it - so that you can move the binaries ? But I only know what I read in the FreeBSD Porter's Handbook, I'm not really a BSD user.

I will be happy to test on PC-BSD 1.2 (based on FreeBSD 6.1). But /proc is empty, so that does not work.

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: GetAppPath vs. DetermineExecutablePath
« Reply #24 on: November 22, 2006, 11:35:36 am »
Quote
For your reference, the code that we use looks like this:
Quote from: mandrav
Admittedly, I have not looked into binreloc's code

Thanks for posting the code here or else I couldn't read it, should I wanted to...

Quote from: thomas
I'm so happy it works nicely for BSD. :)

And thanks for the sarcasm too.

Quote
Quote
Hardcoding is out of the question.
That's unfortunate, because that's what we do now.

So we are hardcoding /usr/local, /opt or whatever? Strange, I haven't noticed... What revision did this happen in and who did it?

Quote
Quote
Why, all of the sudden, do you want to change things regarding this matter?
I don't want to change things regarding this matter at all.

All I know is that there was no need to discuss this issue (i.e. it was a non-issue, we had no complaints so far) up to now and suddenly I see a two pages long topic on the subject. I just want to know what triggered this.
« Last Edit: November 22, 2006, 11:37:37 am by mandrav »
Be patient!
This bug will be fixed soon...

Offline afb

  • Developer
  • Lives here!
  • *****
  • Posts: 884
Re: GetAppPath vs. DetermineExecutablePath
« Reply #25 on: November 22, 2006, 11:37:59 am »
But I can test the --enable-binreloc version on Linux, and see if it relocates OK.

Tested on Ubuntu, interestingly the default installation did not work (it looked in /usr/local/share/codeblocks, while the file had been installed in /usr/share/codeblocks). However, if you copied all of it over from /usr to /opt/codeblocks - then it found the files in /opt/codeblocks/share/codeblocks just fine, so binreloc seems to be working fine on Linux.

Offline afb

  • Developer
  • Lives here!
  • *****
  • Posts: 884
Re: GetAppPath vs. DetermineExecutablePath
« Reply #26 on: November 22, 2006, 11:40:39 am »
All I know is that there was no need to discuss this issue (i.e. it was a non-issue, we had no complaints so far) up to now and suddenly I see a two pages long topic on the subject. I just want to know what triggered this.

Thomas did a refactoring of configmanager.cpp, that broke the wxMac support I added.
And it featured a reimplementation of the same code that was in app.cpp, so I asked...
« Last Edit: November 22, 2006, 11:45:50 am by afb »

Offline afb

  • Developer
  • Lives here!
  • *****
  • Posts: 884
Re: GetAppPath vs. DetermineExecutablePath
« Reply #27 on: November 22, 2006, 12:09:52 pm »
Just for the record here is what I found the default locations to be:

Code::Blocks
  • wxMSW:
    @executable_path/share/CodeBlocks
    @executable_path/share/CodeBlocks/plugins
  • wxGTK:
    $PREFIX/share/codeblocks
    $PREFIX/share/codeblocks/plugins
  • wxMac:
    CodeBlocks.app/Contents/Resources/share/codeblocks
    CodeBlocks.app/Contents/Resources/share/codeblocks/plugins

wxStandardPaths (GetDataDir and GetPluginsDir)
  • wxMSW:
    @executable_path
    @executable_path
  • wxGTK:
    $PREFIX/share/codeblocks
    $PREFIX/lib/codeblocks
  • wxMac:
    CodeBlocks.app/Contents/SharedSupport
    CodeBlocks.app/Contents/PlugIns

Where "@executable_path" is the directory where the .exe is located.

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: GetAppPath vs. DetermineExecutablePath
« Reply #28 on: November 23, 2006, 11:13:57 am »
Quote
So we are hardcoding /usr/local, /opt or whatever? Strange, I haven't noticed...
Yes, and yes.

But anyway, I am sick of endlessly justifying every 6 lines of code that I ever wrote. Do whatever you want, and if you think SELFPATH is so much of a better solution then for pity's sake use it...
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline afb

  • Developer
  • Lives here!
  • *****
  • Posts: 884
Re: GetAppPath vs. DetermineExecutablePath
« Reply #29 on: November 23, 2006, 11:17:12 am »
Should we add a second function to just get the app prefix ?
The "/usr/local/bin/.." works fine, but looks a bit strange...