Upgrade Perl 5.40 to 5.42: /usr/local/include/crypt.h:73:8: error: redefinition of 'crypt_data'

Hello everyone!

I tried to upgrade Perl 5.40 to 5.42, and I got an error "redefinition of 'crypt_data'".

The full build log and my /etc/make.conf are attached.

I ran:
portmaster -o lang/perl5.42 lang/perl5.40

The error:
Code:
===>  Building for perl5-5.42.0_1
--- op.o ---
--- universal.o ---
--- op.o ---
cc -c -DPERL_CORE -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -DNO_POSIX_2008_LOCALE -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -O2 -pipe -march=core2 -fstack-protector-strong -fno-strict-aliasing -Wall -DPIC -fPIC op.c
cc -c -DPERL_CORE -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -DNO_POSIX_2008_LOCALE -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -O2 -pipe -march=core2 -fstack-protector-strong -fno-strict-aliasing -Wall -DPIC -fPIC universal.c
--- universal.o ---
In file included from universal.c:31:
In file included from ./perl.h:4517:
In file included from ./op.h:709:
In file included from ./reentr.h:126:
/usr/local/include/crypt.h:73:8: error: redefinition of 'crypt_data'
   73 | struct crypt_data
      |        ^
/usr/include/unistd.h:488:8: note: previous definition is here
  488 | struct crypt_data {
      |        ^
--- op.o ---
In file included from op.c:163:
In file included from ./perl.h:4517:
In file included from ./op.h:709:
In file included from ./reentr.h:126:
/usr/local/include/crypt.h:73:8: error: redefinition of 'crypt_data'
   73 | struct crypt_data
      |        ^
/usr/include/unistd.h:488:8: note: previous definition is here
  488 | struct crypt_data {
      |        ^
--- universal.o ---
1 error generated.
*** [universal.o] Error code 1

make: stopped in /usr/ports/lang/perl5.42/work/perl-5.42.0
--- op.o ---
1 error generated.
*** [op.o] Error code 1

make: stopped in /usr/ports/lang/perl5.42/work/perl-5.42.0
2 errors

make: stopped in /usr/ports/lang/perl5.42/work/perl-5.42.0
===> Compilation failed unexpectedly.
Try to set MAKE_JOBS_UNSAFE=yes and rebuild before reporting the failure to
the maintainer.
*** Error code 1

Stop.
make[1]: stopped in /usr/ports/lang/perl5.42
*** Error code 1

Stop.
make: stopped in /usr/ports/lang/perl5.42

===>>> make build failed for lang/perl5.42
===>>> Aborting update
 

Attachments

Perhaps force delete libxcrypt, upgrade to perl5.42, install libxcrypt.
What do you mean? User pkg delete?
Well, I'd tried it:
Code:
pkg delete security/libxcrypt
Code:
Updating database digests format: 100%
Code:
Checking integrity... done (0 conflicting)
Code:
Deinstallation has been requested for the following 449 packages (of 0 packages in the universe):
 
What do you mean? User pkg delete?
Well, I'd tried it:
Code:
pkg delete security/libxcrypt
Code:
Updating database digests format: 100%
Code:
Checking integrity... done (0 conflicting)
Code:
Deinstallation has been requested for the following 449 packages (of 0 packages in the universe):
Deleting 449 packages is too much for me.
It isn't impossible, but ....
 
This will remove only libxcrypt, not the packages depending on it.
Mind you, you're going to have to rebuild everything that depends on libxcrypt too, or else your dependency chain will be wrecked.
 
Well, the command
portmaster -d --no-confirm -x dom4j -a
failed with the same error.
Code:
DEFAULT_VERSIONS+= perl5=5.42
 
SevenDayz a general recommendation is to *not* mess with your system perl. Leave that to the system to manage. The reason is, if you "break" your system perl somehow, your system might get affected when it attempts to run a broken perl.

You should instead install a different perl for your user. You can do that very easily with with "perl version manager", for example:

perlbrew: https://perlbrew.pl/ (https://metacpan.org/pod/App::perlbrew).

or, local::lib: https://metacpan.org/pod/local::lib

There are others too, like "plenv" but perlbrew or local::lib should do.

Plus you dont need root to install them and to install modules for them.

To install modules, use "cpanm" : https://metacpan.org/pod/App::cpanminus#Installing-to-local-perl-(perlbrew,-plenv-etc.)
 
SevenDayz a general recommendation is to *not* mess with your system perl. Leave that to the system to manage. The reason is, if you "break" your system perl somehow, your system might get affected when it attempts to run a broken perl.

You should instead install a different perl for your user. You can do that very easily with with "perl version manager", for example:

perlbrew: https://perlbrew.pl/ (https://metacpan.org/pod/App::perlbrew).

or, local::lib: https://metacpan.org/pod/local::lib

There are others too, like "plenv" but perlbrew or local::lib should do.

Plus you dont need root to install them and to install modules for them.

To install modules, use "cpanm" : https://metacpan.org/pod/App::cpanminus#Installing-to-local-perl-(perlbrew,-plenv-etc.)
Do you mean I should comment the line "DEFAULT_VERSIONS+= perl5=5.42"?
 
Do you mean I should comment the line "DEFAULT_VERSIONS+= perl5=5.42"?
Yes, you should remove "DEFAULT_VERSIONS+= perl5=5.42".

The default versions are set in the ports framework globally in /usr/ports/Mk/bsd.default-versions.mk
Rich (BB code):
# Possible values: 5.38, 5.40, 5.42, devel
.  if !exists(${LOCALBASE}/bin/perl) || (!defined(_PORTS_ENV_CHECK) && \
    defined(PACKAGE_BUILDING))
# When changing the default here, make sure the DEPRECATED/EXPIRATION lines in
# the older Perl 5 ports are uncommented at the same time.
PERL5_DEFAULT?=         5.42
Unless you want to override default versions, don't specify default versions which are already default.

The upgrade procedure for perl5 using ports-mgmt/portmaster described in /usr/ports/UPDATING does also advice the removal.
Rich (BB code):
20231017:
  AFFECTS: users of lang/perl5*
  AUTHOR: delphij@FreeBSD.org
 
  ...
    First, add to /etc/make.conf:

  DEFAULT_VERSIONS+=  perl5=5.36
 
  ...
    Portmaster users:
        portmaster -o lang/perl5.36 lang/perl5.34

          You can now remove the DEFAULT_VERSIONS line added earlier
          from /etc/make.conf
 
Yes, you should remove "DEFAULT_VERSIONS+= perl5=5.42".

Unless you want to override default versions, don't specify default versions which are already default.

The upgrade procedure for perl5 using ports-mgmt/portmaster described in /usr/ports/UPDATING does also advice the removal.
Rich (BB code):
You can now remove the DEFAULT_VERSIONS line added earlier
          from /etc/make.conf
Thank you for your reminder.
 
Do you mean I should comment the line "DEFAULT_VERSIONS+= perl5=5.42"?
No, i mean you *should not* mess with system perl. Unless you have a reason to do it, and know what you are doing.

When you change that setting, you are changing system settings.

You dont need to change any system settings to install a new perl.

My advice is: Leave that as is, since your system is handling those settings. You should, instead, install a new perl with perlbrew. And, you wont need root to do it. *If you need root, you are probably overriding your system perl*, and that is 99% not what you want.

USE: perlbrew to install a new perl. It is very easy. SEE: https://metacpan.org/pod/App::perlbrew

Just look at that documentation... it is very easy:

Code:
# See what is available
perlbrew available

# install perl 5.42.0 -- you can install as many perl versions as you wish
perlbrew install perl-5.42.0

# List what versions you have installed
perlbrew list

# use the version you installed
perlbrew switch perl-5.42.0

Simple as that. Dont use root

Source: I am a perl dev
 
Probably I can finally solve my problem.

My big mistake was installing back manually the security/libxcrypt port.

So I had two versions of libcrypt.so: libcrypt.so.5 into the /lib directory and libcrypt.so.2 into the /usr/local/lib directory.

The solve
1. I find all ports depend on libcrypt.so.2 from the security/libxcrypt port:
Code:
pkg  info -Ba|grep -B 4 crypt|less

They were only 11 ports:
  1. apr-1.7.6.1.6.3
  2. cnagios-nagios3-0.33_2
  3. cyrus-sasl-2.1.28_5
  4. freeradius3-3.2.8
  5. nagios-plugins-2.4.4_1,1
  6. nginx-1.28.2_12,3
  7. python312-3.12.13
  8. ruby40-4.0.1,1
  9. smbftpd-2.4_2
  10. squid-7.4
  11. cups-2.4.16
2. Deleted the security/libxcrypt port:
Code:
pkg del -f libxcrypt

3. Reinstall every dependent port like this:
  1. Code:
    cd /usr/ports/devel/apr1/
  2. Code:
    make clean reinstall clean
    The first clean is important.
  3. Check required share libs:
    Code:
    pkg  info -B apr-1.7.6.1.6.3
  4. The libcrypt.so.2 shouldn't exist, but the libcrypt.so.5 should.

4. Done!
 
How does this help?

1. New FreeBSD installation (or new BE and pkg delete all packages).
2. Build and install lang/perl5.42
3. Build and install security/libxcrypt
4. Try to rebuild lang/perl5.42
 
This is a problem with building ports in-place in general. And why package builders like poudriere and Synth build in a "clean-room" environment.

You also have the problem with various ./configure scripts enabling options/dependencies even if they're explicitly disabled (i.e. --without-foo), because the configure script detects the library is installed. Which results in an executable depending on something but pkg(8) not being aware of it (the port option was turned off).
 
Have you read UPDATING, especially dated 20250817 and 20231017 and do as documented there?
Well, is there any mention about the security/libxcrypt port?

20250817:
AFFECTS: users of lang/perl5.*
AUTHOR: mat@FreeBSD.org

The default Perl version has been switched to 5.42.

See entry 20231017 for updating instructions.


20231017:
AFFECTS: users of lang/perl5*
AUTHOR: delphij@FreeBSD.org

The default Perl version has been switched to Perl 5.36. If you are using
binary packages to upgrade your system, you do not have anything to do, pkg
upgrade will do the right thing. For the other people, assuming you are
migrating from 5.34 to 5.36, do:

First, add to /etc/make.conf:

DEFAULT_VERSIONS+= perl5=5.36

Portupgrade users:
portupgrade -o lang/perl5.36 -f lang/perl5.34

You can now remove the DEFAULT_VERSIONS line added earlier
from /etc/make.conf

Then you will need to rebuild everything that uses libperl.so, you
can do so with:

portupgrade -f `pkg shlib -qR libperl.so.5.34`

If, for some reason, this command fails at one point, it is safe to
run it again, it will not rebuild what it already rebuilt, as the
ports that have been rebuilt no longer depend on libperl.so.5.34 but
on libperl.so.5.36.

Portmaster users:
portmaster -o lang/perl5.36 lang/perl5.34

You can now remove the DEFAULT_VERSIONS line added earlier
from /etc/make.conf

Then you will need to rebuild everything that uses libperl.so, you
can do so with:

portmaster -f `pkg shlib -qR libperl.so.5.34`

If, for some reason, this command fails at one point, it is safe to
run it again, it will not rebuild what it already rebuilt, as the
ports that have been rebuilt no longer depend on libperl.so.5.34 but
on libperl.so.5.36.
 
Back
Top