Bug 209173 - lang/perl5.22: port build has inappropriate use of -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE before the update libperl.so.5.22.2 is there to use (11.0-CURRENT in use)
Summary: lang/perl5.22: port build has inappropriate use of -Wl,-R/usr/local/lib/perl5...
Status: Closed Unable to Reproduce
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-perl (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-05-01 08:35 UTC by Mark Millard
Modified: 2016-07-06 12:33 UTC (History)
0 users

See Also:
bugzilla: maintainer-feedback? (perl)


Attachments
patch-v1 (5.29 KB, patch)
2016-05-10 14:58 UTC, Mathieu Arnold
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Millard 2016-05-01 08:35:12 UTC
[Mostly take from https://lists.freebsd.org/pipermail/freebsd-ports/2016-May/103059.html but simplified/shortened. ]

When building lang/perl5.22 for 5.22.2 . . .

The following happens when /usr/local/lib/perl5/5.22/mach/CORE does not yet exist or does yet have any libperl.so* files:

--- perl ---
/usr/bin/clang -target armv6--freebsd11.0-gnueabi -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mno-unaligned-access -o perl -lpthread -Wl,-E  -fstack-protector-strong -L/usr/local/lib -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE perlmain.o  libperl.so.5.22.2 `cat ext.libs` -lpthread -lm -lcrypt -lutil
--- MANIFEST.srt ---
--- extras.make ---
--- MANIFEST.srt ---
Shared object "libperl.so.5.22" not found, required by "perl"
WARNING: re-sorting MANIFEST
Shared object "libperl.so.5.22" not found, required by "perl"
*** [MANIFEST.srt] Error code 1

make[2]: stopped in /usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2



By contrast when /usr/local/lib/perl5/5.22/mach/CORE/libperl.so.5.22.1 is in place (and libperl.so and libperl.so.5.22 reference it) the following happens:

--- pod/perltoc.pod ---
LD_LIBRARY_PATH=/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl\-5.22.2  ./perl -Ilib -f pod/buildtoc -q
pod/buildtoc: Perl lib version (5.22.2) doesn't match executable '/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/perl' version (5.22.1) at lib/Config.pm line 62.
Compilation failed in require at lib/locale.pm line 4.
BEGIN failed--compilation aborted at lib/locale.pm line 4.
Compilation failed in require at pod/buildtoc line 10.
BEGIN failed--compilation aborted at pod/buildtoc line 10.
*** [pod/perltoc.pod] Error code 255

make[2]: stopped in /usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2
1 error



This last happens because:

# /usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/perl --version

This is perl 5, version 22, subversion 1 (v5.22.1) built for powerpc-freebsd-thread-multi



That in turn happened from linking against the wrong libperl.so or libperl.so.5.22 : an older vintage is linked to.

Both of the above cases trace back to the following sorts of uses of -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE notation: (from the build's log, note how "-o perl" uses -Wl,-R so ld will do the -R style of linking):

rm -f libperl.so.5.22.2
/usr/local/bin/gcc49 -o libperl.so.5.22.2 -shared -L/usr/local/lib -fstack-protector-strong -Wl,-soname,libperl.so.5.22 op.o perl.o  gv.o toke.o perly.o pad.o regcomp.o dump.o util.o mg.o reentr.o mro_core.o keywords.o hv.o av.o run.o pp_hot.o sv.o pp.o scope.o pp_ctl.o pp_sys.o doop.o doio.o regexec.o utf8.o taint.o deb.o universal.o globals.o perlio.o perlapi.o numeric.o mathoms.o locale.o pp_pack.o pp_sort.o caretx.o   DynaLoader.o -lpthread -lm -lcrypt -lutil
/usr/local/bin/gcc49 -o perl -lpthread -Wl,-E  -fstack-protector-strong -L/usr/local/lib -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE perlmain.o  libperl.so.5.22.2 `cat ext.libs` -lpthread -lm -lcrypt -lutil



And were does the -Wl,-R notation come from?:

# find /usr/obj/portswork/usr/ports/lang/perl5.22/ -exec grep Wl,-R {} \; -print | more
. . . (most are omitted but some interesting ones follow) . . .
               -L*|-R*|-Wl,-R*)
               xxx="-Wl,-R$shrpdir"
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/Configure.orig
               -L*|-R*|-Wl,-R*)
               xxx="-Wl,-R$shrpdir"
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/Configure.bak
ccdlflags='  -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE'
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/config.sh
CCDLFLAGS =   -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/Makefile
   dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='  -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE'
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/myconfig
CCDLFLAGS =   -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/makefile
CCDLFLAGS =   -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/makefile.old



For FreeBSD the use of the notation -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE (as seen in the log file) is also odd for the "does not exist yet" case because of the dual use of -R in ld for FreeBSD:

if the -R option is
          followed by a directory name, rather than a file name, it is
          treated as the -rpath option

So which interpretation does -R get when /usr/local/lib/perl5/5.22/mach/CORE does not exist yet because 5.22 has yet to even be created in /usr/local/. . .? /usr/local/lib/perl5/5.22/mach/CORE is then neither a directory nor a named file that can supply symbols.


/usr/local/lib/perl5/5.22/mach/CORE will not have appropriate material to use until some point during the install step: not even the staging step is enough context for that path to find the right vintage of files. During the build's linking it is too early to be using -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE .
Comment 1 Mark Millard 2016-05-01 20:15:13 UTC
(In reply to Mark Millard from comment #0)

I will note that when /usr/local/lib/perl5/5.22/mach/CORE does not exist I can rebuild successfully (rerunning the portmaster command) if I first do a mkdir -p /usr/local/lib/perl5/5.22/mach/CORE and copy from /usr/obj/. . . .  the libperl.so*'s into /usr/local/lib/perl5/5.22/mach/CORE/ .

Similarly when /usr/local/lib/perl5/5.22/mach/CORE already exists with older libperl.so*'s if I replace them with the 3 from the newly built /usr/obj/. . . ones and then rerun the portmaster the build completes (because the perl it builds the reported 5.22.2 since that is what libperl.so* it ended up bound to).


I should have reported:

-r414369 for /usr/ports/ .

# uname -apKU
FreeBSD FBSDG5C0 11.0-CURRENT FreeBSD 11.0-CURRENT #32 r298518M: Sat Apr 23 20:01:08 PDT 2016     root@FBSDG5C0:/usr/obj/xtoolchain/powerpc.powerpc64/usr/src/sys/GENERIC64vtsc-NODEBUG  powerpc powerpc64 1100106 1100106

(using gcc49)


# uname -apKU
FreeBSD FBSDG4C1 11.0-CURRENT FreeBSD 11.0-CURRENT #9 r297048M: Sat Mar 19 17:33:56 PDT 2016     markmi@FreeBSDx64:/usr/obj/clang_gcc421/powerpc.powerpc/usr/src/sys/GENERICvtsc-NODEBUG  powerpc powerpc 1100103 1100103

(using gcc5)


# uname -apKU
FreeBSD rpi2 11.0-CURRENT FreeBSD 11.0-CURRENT #21 r297769M: Sat Apr  9 22:51:03 PDT 2016     markmi@FreeBSDx64:/usr/obj/clang/arm.armv6/usr/src/sys/RPI2-NODBG  arm armv6 1100105 1100105


(using clang 3.8.0 and extra compiler options are targeting armv7a/cortex-a7 to match the rpi2 details for such things)
Comment 2 Mathieu Arnold freebsd_committer freebsd_triage 2016-05-02 11:52:13 UTC
I have works in the way to get rid of the linker fiddeling

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=209123
https://reviews.freebsd.org/D6107

I'm waiting for the result of the exp-run.
Comment 3 Mathieu Arnold freebsd_committer freebsd_triage 2016-05-09 15:35:42 UTC
Ok, bug #209123 was committed, can you tell me if the problem you have is still here ?
Comment 4 Mark Millard 2016-05-09 21:17:05 UTC
(In reply to Mathieu Arnold from comment #3)

Unfortunately my initial test has failed. The details follow.

I updated my /usr/ports to -r414889 to pick up the latest.

I did:

pkg delete perl5

to get rid of my prior work-around style 5.22 build (no other perl build present). Then I did:

portmaster -DK lang/perl5.22

So this is the case of no-prior perl 5.22 install instead of one of updating an older install of 5.22.

The result was:

Shared object "libperl...so.5.22" not found, required by "perl"

listed a couple of times with a "WARNING: re-sorting MANIFEST" between. (But this test was without MAKE_JOBS_UNSAFE=yes .)

The log file still shows use of:

-Wl,-R/usr/local/lib/perl5/5.22/mach/CORE

such as it saying:

Adding -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE to the flags

and again later using the -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE in the line that does the "-o perl" via linking perlmain.o libperl.so.5.22.2 and other things.

Checking /usr/obj/. . . for continued use of -Wl,-R notation still shows

# find /usr/obj/portswork/usr/ports/lang/perl5.22/ -exec grep Wl,-R {} \; -print | more
. . . (most are omitted but some interesting ones follow) . . .
               -L*|-R*|-Wl,-R*)
               xxx="-Wl,-R$shrpdir"
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/Configure.orig
               -L*|-R*|-Wl,-R*)
               xxx="-Wl,-R$shrpdir"
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/Configure.bak
ccdlflags='  -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE'
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/config.sh
CCDLFLAGS =   -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/Makefile
   dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='  -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE'
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/myconfig
CCDLFLAGS =   -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/makefile
CCDLFLAGS =   -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/makefile.old

I confirmed today's date on the files via:

ls -lt /usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/
Comment 5 Mark Millard 2016-05-09 21:46:43 UTC
(In reply to Mark Millard from comment #4)

This whole thing makes me wonder if the use of the staging step that ports builds use (a temporary place) simply violates the structure the perl installation materials are designed for.

In other words: without using a staging area and directly installing under /usr/local/. . . during the install the kind of -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE usage that I see in the logs would work. (Of course failed builds would then not have left the old install in place.)

I'm not suggesting that staging be abandoned but any port with a tie such as this needs a more extensive adjustment to support staging, apparently including the disabling/adjusting of the build code that reports its activity as:

Adding -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE to the flags passed to . . . so that the perl executable will find the installed shared libperl.so.5.22.2

Or possibly linking for staging with a staging path in -Wl,-R , do the tests based on the staging area, then if they pass (re)linking with the final installation-path in -Wl,-R into staging and finally installing. (This would have its own risks.)
Comment 6 Mark Millard 2016-05-10 00:54:41 UTC
(In reply to Mark Millard from comment #5)

In my context 3 scripts have the "perl executable will find" wording:

/usr/obj/portswork/usr/ports/lang/perl5.22/work/Configure
/usr/obj/portswork/usr/ports/lang/perl5.22/work/Configure.orig
/usr/obj/portswork/usr/ports/lang/perl5.22/work/Configure.bak

It appears to be tied to setting ccdlflags that is used later.
Comment 7 Mathieu Arnold freebsd_committer freebsd_triage 2016-05-10 14:58:02 UTC
Created attachment 170180 [details]
patch-v1

Does this fix the problem ?

I admit, I have not used anything else than poudriere and pkg upgrade for the last two+ years, so your scenarios are kinda alien to me.
Comment 8 Mark Millard 2016-05-11 02:42:15 UTC
(In reply to Mathieu Arnold from comment #7)

I intend to test the patch but have not gotten to it yet: other things have priority on my time. Sorry for the delay.
Comment 9 Mark Millard 2016-05-15 02:28:22 UTC
(In reply to Mathieu Arnold from comment #7)

No difference after the patch I'm afraid: It still says. . .

Adding -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE to the flags passed to . . . so that the perl executable will find the installed shared libperl.so.5.22.2

and so still looks for the libperl.so* in /usr/local/lib/perl5/5.22/mach/CORE before the updated material has been installed there. find/grep still shows:

cdlflags='  -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE'
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/config.sh
CCDLFLAGS =   -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/Makefile
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='  -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE'
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/myconfig
CCDLFLAGS =   -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/makefile
CCDLFLAGS =   -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE
/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/makefile.old


As far as the applied patch goes: The lang/perl5.22 difference from /usr/ports -r414889 was:

# svnlite diff /usr/ports/lang/perl5.22
Index: /usr/ports/lang/perl5.22/Makefile
===================================================================
--- /usr/ports/lang/perl5.22/Makefile   (revision 414889)
+++ /usr/ports/lang/perl5.22/Makefile   (working copy)
@@ -91,8 +91,8 @@
 # lddlflags is used for all .so linking
 # shrpldflags is used for libperl.so, so remove all the extra bits inherited from lddlflags.
 CONFIGURE_ARGS+= \
-       -Alddlflags='-L${WRKSRC} -L${PREFIX}/${_ARCH_LIB}/CORE -lperl' \
-       -Dshrpldflags='$$(LDDLFLAGS:N-L${WRKSRC}:N-L${PREFIX}/${_ARCH_LIB}/CORE:N-lperl) -Wl,-soname,$$(LIBPERL:R)'
+       -Alddlflags='-L${WRKSRC} -lperl' \
+       -Dshrpldflags='$$(LDDLFLAGS:N-L${WRKSRC}:N-lperl) -Wl,-soname,$$(LIBPERL:R)'
 
 # Give a hint of where libperl.so can be found.
 USE_LDCONFIG=  ${PREFIX}/${_ARCH_LIB}/CORE
@@ -233,7 +233,7 @@
                ${WRKSRC}/hints/freebsd.sh
 
 post-build:
-       @${REINPLACE_CMD} -e '/^lddlflags/s|-L${WRKSRC} ||' \
+       @${REINPLACE_CMD} -e '/^lddlflags/s|-L${WRKSRC} |-L${PREFIX}/${_ARCH_LIB}/CORE |' \
                ${WRKSRC}/lib/Config_heavy.pl
 .if ${CC} == /nxb-bin/usr/bin/cc
        @${REINPLACE_CMD} -e 's=/nxb-bin==‘ \
Comment 10 Mark Millard 2016-05-15 22:03:50 UTC
Looking around I see that in the ordering of things tracing where the -Wl,-R comes from (working backwards from a particular point):

. . ./work/perl-5.22.2/config.sh

contains a line that assigns ccdlflags:

ccdlflags='  -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE'

The build's log file shows a line that says:

Creating config.sh...

at around 28% into the log file. By contrast the line:

Adding -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE to the flags

is at around 6% into the log file and is the first mention of "CORE" in the log file.

At around 5% is the question/answer:

Where do you want to put the public architecture-dependent libraries? (~name okay)
[/usr/local/lib/perl5/5.22/mach]  

which seems to be the source of the path before "/CORE" in the -Wl,-R use.

The question is from:

. . ./work/perl-5.22/Configure

It is Configure that is causing . . ./work/perl-5.22/config.sh and the like to use "-Wl,-R/usr/local/lib/perl5/5.22/mach/CORE" for "$osname" being "freebsd".

This is in part because of the answer to a prior question:

Any special flags to pass to $cc to use dynamic linking?
[none]

being "none" so that the default value for ccdlflags is assigned, which happens to reference the final installation place and so presumes no staging.

If the answer was something else but "none" that answer would be the ccdlflags value instead.

With "none" the default ends up being based on:

shrpdir=$archlibexp/CORE

via (for "$osname" being "freebsd"):

xxx="-Wl,-R$shrplibdir"

and a later:

ccdlflags="$ccdlflags $xxx"


For the wrong-.so-place tests (as long as they are used) as long as a staging area is in use by FreeBSD ports design instead of direct use of the final installation place the perl command built for use in those tests needs to refer to the staging area libperl.so.5.22, not to the installation place. (5.22 is just my specific example context and so is over specific overall.)

An alternative is to skip all tests that are before installation in the final place that would be using the wrong/missing libperl.so.5.* from the reference to the final place instead of the staging place.

Of course the final installed perl executable would need to refer to the final installation place instead of the staging area.

Or perl needs to allow external control of the place to find the dynamic linking materials and then to be externally controlled for the staging vs. final stages.

This would appear to need at least a different answer to:

Any special flags to pass to $cc to use dynamic linking?
[none]

unless . . ./work/perl-5.22/Configure is reworked in some other way.
Comment 11 Mark Millard 2016-05-15 22:19:24 UTC
Using something like

sysutls/patchelf

might be a way change the -rpath in use back and forth between the staging area and the final installation area for the built perl command without relinking.
Comment 12 Mathieu Arnold freebsd_committer freebsd_triage 2016-07-06 10:28:31 UTC
I'm going to close this because I can't reproduce it, and not being able to reproduce it makes it hard to fix it.

To test, what I did was:

- Update the ports tree to r414354 (the last revision where lang/perl5.22 was 5.22.1)
- Install lang/perl5.22 in a pristine jail. I used poudriere, but doing it manually would achieve the same
- Update the ports tree to the latest revision.
- Build lang/perl5.22.

I tried this on 9.3, 10.1 and CURRENT, and in all the cases, I was able to build lang/perl5.22 without any problems.
Comment 13 Mark Millard 2016-07-06 11:22:20 UTC
(In reply to Mathieu Arnold from comment #12)

I wish that you had reported the commands from the build logs that in my case showed the -Wl,-R/usr/local/lib/perl5/5.22/mach/CORE use that I reported.

Without copies of those commands I've no way to see what might have been different or to verify the replication of the commands that happened with simple portmaster use without poudriere.

It would not be the first time that I've found that official (style) builds did something that only worked for official-style builds and not for general source builds via portmaster and the like. Differing path needs have been involved in the past.

Also my reports were for armv6 and powerpc64 and powerpc contexts, not amd64.

It would not be the first time that I've found builds were broken for non-tier-1 TARGET_ARCH's but they worked for tier-1.
Comment 14 Mathieu Arnold freebsd_committer freebsd_triage 2016-07-06 11:37:47 UTC
The log from the 5.22.1 build are there http://package22.nyi.freebsd.org/data/headamd64-default/2016-07-06_10h19m52s/logs/perl5-5.22.1_8.log the 5.22.2 is not, because it is done later in an interactive session.

Building in poudriere, and with portmaster is about the same, only poudriere build everything in a clean place, and thus, never bails out.

I used a non patched ports tree, and system.

As for the architecture thing, now that you mention it, is is well hidden in the reports, and I did not even see it until today.

I do not have, however, any mean to test anything else than i386 or amd64.  I don't see why the linker/compiler would behave in a radically different way though.
Comment 15 Mark Millard 2016-07-06 12:33:18 UTC
(In reply to Mathieu Arnold from comment #14)

Actually LD_LIBRARY_PATH not overriding  the -WL,-R/. . . path correctly could be an explanation for when I reported. . .

--- pod/perltoc.pod ---
LD_LIBRARY_PATH=/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl\-5.22.2  ./perl -Ilib -f pod/buildtoc -q
pod/buildtoc: Perl lib version (5.22.2) doesn't match executable '/usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2/perl' version (5.22.1) at lib/Config.pm line 62.
Compilation failed in require at lib/locale.pm line 4.
BEGIN failed--compilation aborted at lib/locale.pm line 4.
Compilation failed in require at pod/buildtoc line 10.
BEGIN failed--compilation aborted at pod/buildtoc line 10.
*** [pod/perltoc.pod] Error code 255

make[2]: stopped in /usr/obj/portswork/usr/ports/lang/perl5.22/work/perl-5.22.2
1 error


In other words: it did not pick up the library from /usr/obj/portswork/usr/ports/lang/perl5.22/work/perl\-5.22.2 but might have instead still used the -WL,-R/. . . path. This could be (have been?) TARGET_ARCH specific if it was true at the time.

Your poudriere log does show the -Wl,-R/. . . path's that I reported. So the manual run (without script output or such for review) likely did as well.