On 8/4/2010 2:15 PM, Ralf Wildenhues wrote:
> * Charles Wilson wrote on Tue, Aug 03, 2010 at 07:22:46AM CEST:
>> Now, since I've used --prefix=/mingw and NOT
>> --prefix=/usr/i686-pc-mingw32/sys-root/mingw, I can "cheat" even on
>> win32.  I can take the binary runtime components -- even the -devel
>> components! -- and install them in
>>    C: (or D: or E:)
>> and they'll end up under
>>    C:/mingw
>>    D:/mingw
>> or whathaveyou.  Thanks to a quirk in window's path resolution, any
>> unixish absolute path is interpreted as if it were a path from the drive
>> root of the CWD.  So, if CWD is on C:, then /mingw/libexec is
>> interpreted as C:/mingw/libexec.  Since ALL the unixish paths will start
>> with /mingw, this will Do The Right Thing.
> 
> Sorry, but I don't think that is viable.  Say, C:/mingw is owned by the
> administrator, but D:/mingw is domain of user A.  Starting your app on
> D: as user B makes B susceptible to files which A owns.  In general, you
> cannot leave away the drive letter when specifying the --prefix.

Then you are stuck with building twice.  Once for your sysroot
installation, and once for the "real" installation on $host.
However...that would STILL break:

libfoo.la
a)  compiled for sysroot using the cross compiler, and installed there,
    with --prefix=/something and --with-sysroot
b)  compiled for $host using the cross compiler, and installed THERE,
    with --prefix=E:/mingw or whatever.

Then, you compile libbar.la which depends on libfoo:
a)  compiled for sysroot using the cross compiler, and installed there,
    with --prefix=/something and --with-sysroot.  libbar.la(a)'s
    dependency_libs will look like
        -L=/something =/something/lib/libfoo.la
    This is obviously useful for future compilation of libbaz.la.

b)  compiled for $host using the cross compiler, and eventually
    installed there, with --prefix=E:/mingw or whatever.  However...
    libbar.la(b)'s dependency_libs will look like
        -L=/something =/something/lib/libfoo.la
    too!  But that's clearly wrong, if you want to copy libbar.la(b)
    directly over to $host and use it there, under E:/mingw.

Now, this is cross-compiler 101, for all architectures.  You really need
to use the same "prefix" underneath your sysroot that you use on the
actual $host.  Unfortunately, there is no such thing, on unix, as a
prefix named "E:/somedir" (note the missing initial '/').


But, that is untenable: on the one hand you want to assert that "thou
shalt include X: in thy prefixes when configuring for $host=mingw" even
when cross-compiling for any purpose, but then there's this impossible
requirement that the "prefix" underneath the sysroot be identical to the
"prefix" on $host -- otherwise this whole cross compile thing falls
apart, once you start chaining dependencies.

Now, if "/something" in the (a) cases above were "/mingw" (e.g.
"matched" the drive-letter-stripped version from the (b) cases above),
then it would actually work correctly -- but, you'd be open to exploits
from D:/mingw.


And this problem is not limited to libtool's .la files; if any path
containing $prefix is compiled into a binary, or recorded anywhere,
you'll have this problem.

The only real solution, as I've said, is:

  1) don't cross compile for $host=mingw. Ever. Always compile
     natively, and use --prefix=X:/stuff WITH the drive letter.

  2) Fix *every* package that records ANY directory information
     so that it is completely relocatable. Each binary or script, or
     tool that parses a text file containing directory information,
     should autodetect its installation location, and deduce relative
     paths to its resources from that.

#2 is a gigantic job, and it's not libtool's task to do that for the
universe of software packages. Now, MAYBE, we might take a look at
relocation support for .la files -- but I fear that would open us up to
more security holes than you could shake a stick at.  Resolving all
paths into relative paths from whatever is recorded in libdir=''? Oh, boy...


#1 is clearly unacceptable as well.

Hence...I think the consensus is:

  I) if you're compiling natively for mingw, use --prefix=X:/foo,
because it avoids the possible security issues.  And, it's just
objectively the correct thing to do.

  II) if you're cross-compiling -- whether for installation into
      the $build's sysroot, or for actual deployment onto $host -- use
      --prefix=/unixish/path, and make sure it matches in both cases.
      You'll exploit a quirk -- AND open your users up to a possible
      security exploit -- but there currently is no other viable way
      to do cross-compiles for $host=mingw with chained dependencies,
      such that they would actually WORK.

> Sure.  I don't disagree with leaving the sysroot part out of --prefix.
> 
>> However, items built for case (2) -- direct deployment on the $host (or
>> compiled "natively" ON the mingw host, that is MSYS/MinGW) -- are by
>> convention configured as:
>>    configure --prefix=`cd /mingw && pwd -W`
>> which ends up as
>>    configure --prefix=C:/MinGW
>> and the installation is usually preformed as
>>    make install prefix=/tmp/something/MinGW
> 
> I guess what I don't see is why the former case doesn't also use
>   --prefix=C:/MinGW

Because if you then try to reconstruct the actual location on the disk,
on $build under sysroot, you get:
   /usr/i686-pc-mingw32/sysrootC:/MinGW/
and now, the word "sysrootC:", besides being a sibling, rather than a
child, of the ACTUAL sysroot returned by the compiler via
-print-sysroot, is unsplitable: how can libtool extract the "C:/MinGW"
part when it is geared towards splitting paths at path-delimiter characters?

Because "C:/MinGW" doesn't start with "/", $sysroot$prefix is not a
reversible operation.  And the reversibility is a KEY requirement for
any sane sysroot handling -- by libtool or pkg-config or anybody else.

> [...]
>> Anyway, this workflow ensures that the actual, DOS-ish paths are
>> embedded anywhere such things are hardcoded, which is both good and bad.
>>  But it also ensures that there IS no concatenation of paths that might
>> start with X:, since we replace the ENTIRE prefix with a unixish one
>> during make install.  This technique works, even today on cross setups,
>> if you build one package at a time for deployment on $host.
> 
> Ahh.
> 
>> But you
>> can't easily do a "chain" of such builds on a cross system, without
>> effort.  You sorta have to do twice the builds: one of type (1) and one
>> of type (2), for each library in the chain:
>>
>>   a) zlib class (1) installed on $build in sysroot under $prefix
>>   b) zlib class (2) installed on $host under $prefix
>>   c) libpng class (1) installed on $build in sysroot under $prefix
>>      this will link against the libz.dll.a from (a).  If you have
>>      support on $build for running $host binaries (wine?) then at
>>      runtime it would use the libz-1.dll from (a) as well.
>>   d) libpng class (2) installed on $host under $prefix
>>      this will link against libz.dll.a from (a)!!!  However, once
>>      installed on $host, it will RUN against zlib-1.dll from (b).
>>   and so on, and so on.
>>
>> Using method (2) alone would not yet be appropriate for a case (1)
>> installation (e.g. into a cross $build system's sysroot), because then
>> you WOULD be concatenating a unixish sysroot with a dosish "prefix".
>> (e.g. you can't really use (b) and install it on $build in sysroot, and
>> pretend that's a suitable replacement for (a); ditto (d) vs. (c)).
> 
> Is this still relevant in light of my above reply?

Actually, I think it's even MORE relevant.  Short version:

1) cross-compiler-101: --prefix under $sysroot must == prefix on $host.
   Otherwise lots of stuff breaks.

2) for $host=mingw, the prefered prefix formula is a dos path, X:/foo.

3) but you can't use that formula under $sysroot on $build, because
   $sysroot$prefix where prefix=X:/foo is not a reversible operation

4) so we are stuck with a workaround for $host=mingw cross compiles,
   where we exploit a flaw in Windows path resolution: "unix-style"
   absolute paths (that start with /) are always interpreted with
   an implied X: drive spec, where 'X' is derived from CWD.  While
   this is a possible security hole, it is also the only current
   mechanism to actual build chains of dependent projects using a
   cross compiler for this $host.

>>> If yes, then
>>> very cool, and I'd very much like this to be exposed in the testsuite
>>> (only on w32 systems, of course, and the C:/... path should be something
>>> unlikely to clash with any actual user files, in case make install does
>>> write there after all).
>>
>> I'm not entirely sure what you want to test here -- or that it would be
>> something that *libtool's* testsuite should cover (wouldn't it be more
>> appropriate as part of automake's?)
> 
> Please allow me to give a sort-of simple-minded answer, hope I can make
> the gist of it clear:
> 
> If Libtool gains the --with-sysroot feature, then that should be tested
> as part of the Libtool testsuite.

OK.

>  Currently these tests all skip if the
> compiler found is not GCC or has not been configured with a sysroot.

Right.

> These two side-conditions mean that when I run the testsuite on all the
> systems and in all the configurations that I have been testing
> prereleases in the past, *none* of them will actually cover any of the
> new sysroot functionality, because even the cross compilers that I test
> do not use a sysroot.

Ah -- but gcc supports --sysroot even if it wasn't compiled with one (my
cygwin native 4.3.4 doesn't have a -print-sysroot, tho; so I wonder if
the --sysroot=/test/dir actually works for that compiler!)

However, my linux native compiler supports both (and, of course, wasn't
actually compiled with a sysroot of its own):

$ gcc --sysroot=/bob -print-sysroot
/bob

So, you could easily create a test that uses the native system compiler
to "fake" a cross-toolchain "sysroot" test. But to make that work you'd
still have to create a temporary fake sysroot underneath /bob as a
symlink farm using /usr/lib and /usr/include -- which would quickly
become painful, since most systems have LOTS of stuff under those two
directories...

And then there's the fact that the toolchain ITSELF has bits installed
under /usr/lib/gcc/*/...

> Given the experience that new Libtool tests need on the average about
> three or more iterations to get right portably, this makes me a bit
> nervous.  We should really, really try to get test coverage high for
> this feature on as many setups as possible.

Which definitely argues AGAINST making --with-sysroot the default, even
if you ARE using a cross compiler, right away.  The key thing is, we
want to ensure that

  1) native compilers don't break -- that's covered by the rest of the
     test suite

  2) cross-compiler setups don't break, when libtool is used in its
     default --without-sysroot (--with-sysroot=) mode.  I think this
     is covered by "the rest of the test suite" when you build and
     test libtool using a cross toolchain that has no sysroot.

Last -- and frankly least important in comparison to keeping EXISTING
functionality working -- is the

  3) test the new --with-sysroot support in conjunction with cross
     toolchains that actually have a sysroot.  This is covered by the
     three new tests -- but requires toolchains with sysroot support.

The only answer for (3) is "Get Ralf Access To More Cross Toolchains".

FYI, the Mandriva 2010 mingw32-gcc package is built with a sysroot;
there's a VMware image here:
  http://www.vmware.com/appliances/directory/va/434563
but you'd probably have to then do 'urpmi --fuzzy mingw' from inside it
as root to install the cross compiler.  If VirtualBox is more your
style, the newest pre-packaged image I found was Mandriva 2009, and I
don't know how its mingw cross compiler was configured.  So you'd
probably be better off converting the vmware image of 2010 to vdi format
using this procedure;
http://linuxpoison.blogspot.com/2010/06/how-to-convert-vmware-image-vmdk-to.html

> If there is anything in Automake that isn't working for this kind of
> test, well, then let's not use automake for this part of the Libtool
> testsuite.  We've been avoiding it in most of the new testsuite already
> anyway.

Well, my confusion was you seemed to be concerned that 'make install
DESTDIR=...' doesn't work with $host=mingw (or, at least, when
--prefix=D:/Dos/Abs/Path is used).  But DESTDIR is a creature of
automake.  libtool has some support for it, but the "breakage" is
fundamental to the design of the DESTDIR thing: all install paths are
immediately prepended by $(DESTDIR).

That's just broken, unless $prefix begins with a directory separator.
(Even if you cheat and ensure that DESTDIR itself *ends* with a dirsep,
the fact is that
   /my/destdir/C:/mingw
is an invalid path on win32 ANYWAY (e.g. if $build=win32, since $build
is where 'make install' happens), because ':' is not a legal character
for a filename!

But these issues are not something either libtool or automake should
worry about, unless they want to redesign the entire concept of DESTDIR.
(And good luck with that, when --prefix=/entirely/new/tmp/prefix already
works!)

--
Chuck

Reply via email to