polymake on FreeBSD -- some questions and help needed

Discussions on installation issues go here.
Philipp
Posts: 10
Joined: 17 Jun 2021, 20:30

polymake on FreeBSD -- some questions and help needed

Postby Philipp » 17 Jun 2021, 20:42

Hello everyone,

I am currently working on bringing polymake into the FreeBSD ports system. It builds fine and the testsuite runs without errors.
I am working with the polymake-4.4-minimal version.

Because of problems with the respective ports, libnormaliz and SymPol are currently disabled. Java support is disabled, too, as neither javaview nor jReality are currently in the ports tree.
That being said, I ran into some problems on which I would like some help and comments:

- perlx path is configuration dependent:

The perlx pathname depends on the build time configuration of the perl interpreter. On FreeBSD, the lang/perl5 ports let the user set both multiplicity and threading support independently; they default to on. As a result, the perlx path can be one of

$ARCH-freebsd
$ARCH-freebsd-multi
$ARCH-freebsd-thread-multi

What's the reason behind this? Wouldn't it be sufficient to just use $ARCH-$OSNAME instead?

Can this be changed without causing too much trouble?

FreeBSD prefers static packing lists. So far, I've not yet found a satisfying solution how to handle this.

- Staging issues:

On FreeBSD, a port must not install files directly to the regular destination directories, but into a separate staging directory from which the package will be built - see the Porters Handbook on staging.

Polymake's install target does not easily conform to this requirement. `make stage`, e.g., installs everything directly on the system. As a temporary workaround, I set DESTDIR=${STAGEDIR} in the port's Makefile. This, however, will not be accepted by the FreeBSD project, as DESTDIR is used with a different meaning
(it could point to an alternative environment, where the port should be installed, e.g. in a jail).
The port must unconditionally respect the value of DESTDIR (defaults to "/").

What is the preferred way to tackle this?

Currently, this is a showstopper.

- Broken symbolic links with a non-default directory layout:

Letting polymake pick its directory structure, I get the following:

Code: Select all

$ ls -ilF work/stage/usr/local/lib/libpolymake* 269718 lrwxr-xr-x 1 root wheel 39 Jun 16 17:22 work/stage/usr/local/lib/libpolymake-apps-rt.so@ -> polymake/lib/libpolymake-apps-rt.so.4.4 271362 lrwxr-xr-x 1 root wheel 39 Jun 16 17:22 work/stage/usr/local/lib/libpolymake-apps-rt.so.4@ -> polymake/lib/libpolymake-apps-rt.so.4.4 265547 lrwxr-xr-x 1 root wheel 39 Jun 16 17:22 work/stage/usr/local/lib/libpolymake-apps-rt.so.4.4@ -> polymake/lib/libpolymake-apps-rt.so.4.4 270393 lrwxr-xr-x 1 root wheel 36 Jun 16 17:22 work/stage/usr/local/lib/libpolymake-apps.so@ -> polymake/lib/libpolymake-apps.so.4.4 269717 lrwxr-xr-x 1 root wheel 36 Jun 16 17:22 work/stage/usr/local/lib/libpolymake-apps.so.4@ -> polymake/lib/libpolymake-apps.so.4.4 265551 lrwxr-xr-x 1 root wheel 36 Jun 16 17:22 work/stage/usr/local/lib/libpolymake-apps.so.4.4@ -> polymake/lib/libpolymake-apps.so.4.4 271361 lrwxr-xr-x 1 root wheel 18 Jun 16 17:22 work/stage/usr/local/lib/libpolymake.so@ -> libpolymake.so.4.4 271278 lrwxr-xr-x 1 root wheel 18 Jun 16 17:22 work/stage/usr/local/lib/libpolymake.so.4@ -> libpolymake.so.4.4 271363 -r-xr-xr-x 1 root wheel 979936 Jun 16 17:22 work/stage/usr/local/lib/libpolymake.so.4.4* $ ls -ilF work/stage/usr/local/lib/polymake/lib/libpolymake-apps* 265548 lrwxr-xr-x 1 root wheel 26 Jun 16 17:22 work/stage/usr/local/lib/polymake/lib/libpolymake-apps-rt.so@ -> libpolymake-apps-rt.so.4.4 265546 -r-xr-xr-x 1 root wheel 6656 Jun 16 17:21 work/stage/usr/local/lib/polymake/lib/libpolymake-apps-rt.so.4.4* 265552 lrwxr-xr-x 1 root wheel 23 Jun 16 17:22 work/stage/usr/local/lib/polymake/lib/libpolymake-apps.so@ -> libpolymake-apps.so.4.4 265550 -r-xr-xr-x 1 root wheel 880352 Jun 16 17:21 work/stage/usr/local/lib/polymake/lib/libpolymake-apps.so.4.4* $

I'm calling the configure script with

Code: Select all

--prefix=${PREFIX} \ --exec-prefix=${PREFIX} \ --bindir=${PREFIX}/bin \ --includedir=${PREFIX}/include \ --libdir=${PREFIX}/lib \ --libexecdir=${PREFIX}/libexec/polymake \ --datadir=${PREFIX}/share/polymake \ --docdir=${DOCSDIR}

to conform with FreeBSD's directory structure. As a result I get:

Code: Select all

$ ls -ilF work/stage/usr/local/lib/libpolymake* 237294 lrwxr-xr-x 1 root wheel 26 Jun 17 16:16 work/stage/usr/local/lib/libpolymake-apps-rt.so@ -> libpolymake-apps-rt.so.4.4 237292 lrwxr-xr-x 1 root wheel 44 Jun 17 16:16 work/stage/usr/local/lib/libpolymake-apps-rt.so.4.4@ -> exec/polymake/lib/libpolymake-apps-rt.so.4.4 237298 lrwxr-xr-x 1 root wheel 23 Jun 17 16:16 work/stage/usr/local/lib/libpolymake-apps.so@ -> libpolymake-apps.so.4.4 237296 lrwxr-xr-x 1 root wheel 41 Jun 17 16:16 work/stage/usr/local/lib/libpolymake-apps.so.4.4@ -> exec/polymake/lib/libpolymake-apps.so.4.4 236848 lrwxr-xr-x 1 root wheel 18 Jun 17 16:16 work/stage/usr/local/lib/libpolymake.so@ -> libpolymake.so.4.4 234482 lrwxr-xr-x 1 root wheel 18 Jun 17 16:16 work/stage/usr/local/lib/libpolymake.so.4@ -> libpolymake.so.4.4 235122 -r-xr-xr-x 1 root wheel 1213184 Jun 17 16:16 work/stage/usr/local/lib/libpolymake.so.4.4* $ ls -ilF work/stage/usr/local/libexec/polymake/lib/libpolymake-apps* 237293 lrwxr-xr-x 1 root wheel 26 Jun 17 16:16 work/stage/usr/local/libexec/polymake/lib/libpolymake-apps-rt.so@ -> libpolymake-apps-rt.so.4.4 237291 -r-xr-xr-x 1 root wheel 6656 Jun 17 16:16 work/stage/usr/local/libexec/polymake/lib/libpolymake-apps-rt.so.4.4* 237297 lrwxr-xr-x 1 root wheel 23 Jun 17 16:16 work/stage/usr/local/libexec/polymake/lib/libpolymake-apps.so@ -> libpolymake-apps.so.4.4 237295 -r-xr-xr-x 1 root wheel 880352 Jun 17 16:16 work/stage/usr/local/libexec/polymake/lib/libpolymake-apps.so.4.4* $
The links from ${STAGEDIR}/libexec/polymake/lib/libpolymake-apps* to ${STAGEDIR}/lib/libpolymake-apps* are broken, as the 'exec' directory does not exist.

Could this be a pattern matching problem?

The *.so.4 links are created in the port's Makefile, as FreeBSD needs these to register the shared library in the ldconfig hints file.

- File permissions:

This is just a question: Why does install.pl sets file permissions to 777? Wouldn't 644 (and 755 for executables) be sufficient?


Thanks in advance for any help!

Philipp

blorenz
Developer
Posts: 139
Joined: 10 Jan 2011, 17:21

Re: polymake on FreeBSD -- some questions and help needed

Postby blorenz » 18 Jun 2021, 09:42

Hi,
I am currently working on bringing polymake into the FreeBSD ports system. It builds fine and the testsuite runs without errors.
I am working with the polymake-4.4-minimal version.
Thanks a lot for working on this and that is already a very good starting point.

Because of problems with the respective ports, libnormaliz and SymPol are currently disabled. Java support is disabled, too, as neither javaview nor jReality are currently in the ports tree.
The java based visualization backends are not developed any further, so disabling them is totally fine, we recommend using the threejs-based interface which just needs a webbrowser at runtime.
Sympol is not used very much in the codebase, so that should be fine.
libnormaliz is used for quite a lot of things, so having this would be really nice and I might have a look if you can provide some details.

- perlx path is configuration dependent:

The perlx pathname depends on the build time configuration of the perl interpreter. On FreeBSD, the lang/perl5 ports let the user set both multiplicity and threading support independently; they default to on. As a result, the perlx path can be one of

$ARCH-freebsd
$ARCH-freebsd-multi
$ARCH-freebsd-thread-multi

What's the reason behind this? Wouldn't it be sufficient to just use $ARCH-$OSNAME instead?

Can this be changed without causing too much trouble?

FreeBSD prefers static packing lists. So far, I've not yet found a satisfying solution how to handle this.
We are relying on the perl-configuration here, that string is given by perl -V:archname and part of the default lookup paths for custom perlxs modules. We add a custom directory with use lib $dir; and perl will then look into $dir/$version/$archname, so our path needs to fit to this lookup. (see here).

Also the perlxs module that we put there does depend on the perl configuration. If the user would first install polymake and later on decide to reinstall perl with / without perl-threads or multiplicity this will probably cause weird segfaults (instead of an error saying that some module cannot be found).

- Staging issues:

On FreeBSD, a port must not install files directly to the regular destination directories, but into a separate staging directory from which the package will be built - see the Porters Handbook on staging.

Polymake's install target does not easily conform to this requirement. `make stage`, e.g., installs everything directly on the system. As a temporary workaround, I set DESTDIR=${STAGEDIR} in the port's Makefile. This, however, will not be accepted by the FreeBSD project, as DESTDIR is used with a different meaning
(it could point to an alternative environment, where the port should be installed, e.g. in a jail).
The port must unconditionally respect the value of DESTDIR (defaults to "/").

What is the preferred way to tackle this?

Currently, this is a showstopper.
I am not sure that I totally understand how this is supposed to work, polymake does support both a destdir and a prefix similar to what autotools provides. How is this done in other autotools based packages which I think also need to have DESTDIR set for such a staging directory? Where should install.pl put all the files if the user would set DESTDIR and STAGEDIR is also set by the ports system?

- Broken symbolic links with a non-default directory layout:

Letting polymake pick its directory structure, I get the following:
...

The links from ${STAGEDIR}/libexec/polymake/lib/libpolymake-apps* to ${STAGEDIR}/lib/libpolymake-apps* are broken, as the 'exec' directory does not exist.

Could this be a pattern matching problem?

The *.so.4 links are created in the port's Makefile, as FreeBSD needs these to register the shared library in the ldconfig hints file.
That should not happen and I will look into this. (Probably very few users set a custom libexec-directory...)

- File permissions:

This is just a question: Why does install.pl sets file permissions to 777? Wouldn't 644 (and 755 for executables) be sufficient?
At least under Linux all the installed files have '-r-xr-xr-x' or '-r--r--r--' and I did not set anything special, so I don't really know what is happening there but I will try to replicate this on a Freebsd machine.

Best,
Benjamin

User avatar
gawrilow
Main Author
Posts: 423
Joined: 25 Dec 2010, 17:40

Re: polymake on FreeBSD -- some questions and help needed

Postby gawrilow » 18 Jun 2021, 12:15

Hi,
since Ben has already perfectly explained almost everything, I'd just like to provide some details.
  • installation paths
    Out of the box, polymake is not relocatable after the installation: It must know where to find its components (application modules, rule files, etc.) The locations are configured at the very beginning of the build process by providing various paths to configure script, then eventually recorded in the preamble of the standalone script bin/polymake. If FreeBSD requires relocatable ports, you'll have to execute a custom post-installation script modifying this preamble; alternatively, you can modify the code in the preamble itself such that it derives the required paths from the script location, that is, $0. Symbolic links to shared libraries and "shared" directory created by the install script also might need special care; albeit they are relative, you should ensure that they are still valid after a relocation, if the final directory structure does not match the configured layout. Otherwise users' programs linked against polymake callable library won't start.
  • DESTDIR
    The purpose of this variable is exactly the same as in many (if not all) autoconf-based projects: it is prepended to all configured paths during the installation step, so that a packager can pick up the complete directory tree and archive it wherever it wants. I guess, setting DESTDIR=${STAGEDIR} is a perfectly correct way to go. If you want to minimize the interference with FreeBSD ecosystem, you can specify this variable as part of ./configure call, together with --prefix and all other stuff. It will be recorded in a temporary configuration file and honored during the install step, but won't be copied into the final package, while the value of DESTDIR environment variable passed from outside to the port build process will be happily ignored.
  • perlx path
    There are two problems related to this.
    The first one is binary compatibility betwen perl main interpreter and so called extension modules. There is a multitude of ways of breaking it, that's why all extension modules have to be built with exactly the same set of configuration options as perl itself. The choices for multiplicity and interpreter threads are just two options out of many, albeit the most prominent ones. And the bad thing is that perl does not offer any checking mechanism for binary compatibility which would at least produce a comprehensive error message; an extension module built with wrong configuration options will simply crash the interpreter with a segfault or similar disaster. That's why most systems (MacOS or Linux or Windows) stick to a certain perl configuration and do not let the user change it at their will. If FreeBSD port system gives this flexibility to the user, it must provide a mechanism for automatic rebuild or reinstallation of all dependent perl modules. This peculiarity is not specific to polymake, many hundreds if not thousands of CPAN modules would suffer from such configuration switching too.
    The second problem is a logical consequence of the first one, it is the compatibility with the behavior of "use lib" perl pragma. Usually, it appends version- and architecture-dependent tokens to every module path, and these tokens are configured when the perl itself is built and recorded in its Config module. The purpose of this is to provide a minimal safety against binary incompatibility, as explained above. polymake simply has to follow this convention, otherwise it won't run at all. If you know that the FreeBSD perl port adheres to a different convention, you'll have to patch corresponding parts of the configure and install scripts appropriately.
  • file permissions
    The install script simply takes the umask as set in the environment. Just set umask 022 when executing the install step.

Philipp
Posts: 10
Joined: 17 Jun 2021, 20:30

Re: polymake on FreeBSD -- some questions and help needed

Postby Philipp » 18 Jun 2021, 19:30

Hello,

thank you both very much for your replies and help!
Because of problems with the respective ports, libnormaliz and SymPol are currently disabled. Java support is disabled, too, as neither javaview nor jReality are currently in the ports tree.
The java based visualization backends are not developed any further, so disabling them is totally fine, we recommend using the threejs-based interface which just needs a webbrowser at runtime.
This works fine out of the box.
libnormaliz is used for quite a lot of things, so having this would be really nice and I might have a look if you can provide some details.
It seems to just miss header files:

Code: Select all

---- libnormaliz ---- Could not compile a test program checking for libnormaliz configuration. The complete error log follows: /tmp/polymake_1301_configure.cc:4:10: fatal error: 'libnormaliz/nmz_config.h' file not found #include <libnormaliz/nmz_config.h> ^~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. Please investigate the reasons and fix the installation.
That file is indeed missing. I will work on a patch for the libnormaliz port.

When I started working on this, the configure script complained about not being able to find libnormaliz.so which led me to put this into the "to be investigated later" bucket. ;-) The port only provides libnormaliz.a.

We are relying on the perl-configuration here, that string is given by perl -V:archname and part of the default lookup paths for custom perlxs modules. We add a custom directory with use lib $dir; and perl will then look into $dir/$version/$archname, so our path needs to fit to this lookup. (see here).
Thank you for the hint! I wasn't aware of that.

I am not sure that I totally understand how this is supposed to work, polymake does support both a destdir and a prefix similar to what autotools provides. How is this done in other autotools based packages which I think also need to have DESTDIR set for such a staging directory? Where should install.pl put all the files if the user would set DESTDIR and STAGEDIR is also set by the ports system?
PREFIX determines where the port will be installed, by default it's set to /usr/local. On FreeBSD, DESTDIR specifies a complete alternative environment, which might be a jail or a complete system mounted somewhere other than /. The actual location a port installs to is therefore DESTDIR/PREFIX.
STAGEDIR is set to WRKDIR/stage. This get's populated with a bare directory tree of what's to be found under PREFIX:

Code: Select all

$ ls work/stage/usr/local/* work/stage/usr/local/bin: polymake polymake-config work/stage/usr/local/etc: devd man.d pam.d rc.d libmap.d newsyslog.conf.d rc.conf.d work/stage/usr/local/include: X11 polymake work/stage/usr/local/lib: X11 libpolymake-apps-rt.so.4.4 libpolymake.so debug libpolymake-apps.so libpolymake.so.4 libpolymake-apps-rt.so libpolymake-apps.so.4.4 libpolymake.so.4.4 work/stage/usr/local/libdata: ldconfig ldconfig32 pkgconfig work/stage/usr/local/libexec: polymake work/stage/usr/local/man: cat1 cat5 cat9 en.ISO8859-1 man3 man7 mann cat2 cat6 catl ja man4 man8 ru.KOI8-R cat3 cat7 catn man1 man5 man9 cat4 cat8 de.ISO8859-1 man2 man6 manl work/stage/usr/local/sbin: work/stage/usr/local/share: aclocal doc info man pixmaps skel applications emacs java misc polymake xml dict examples locale nls sgml work/stage/usr/local/tests: work/stage/usr/local/www:
(This is my current working directory of the port where I set DESTDIR=${STAGEDIR} which is why you'll find some polymake directories there.)

I had expected that install.pl puts everything into this staging directory when called by 'make stage'.

Other ports handle this transparently, with no extra intervention needed. At least that is my understanding.

This is the first port I'm working on entirely from scratch, so it's possible I'm missing something somewhere. I will look into this again.
- Broken symbolic links with a non-default directory layout:

Letting polymake pick its directory structure, I get the following:
...

The links from ${STAGEDIR}/libexec/polymake/lib/libpolymake-apps* to ${STAGEDIR}/lib/libpolymake-apps* are broken, as the 'exec' directory does not exist.

Could this be a pattern matching problem?

The *.so.4 links are created in the port's Makefile, as FreeBSD needs these to register the shared library in the ldconfig hints file.
That should not happen and I will look into this. (Probably very few users set a custom libexec-directory...)
Thank you!


Regarding the file permissions: That was a misunderstanding on my part. Sorry for the noise.

Out of the box, polymake is not relocatable after the installation: It must know where to find its components (application modules, rule files, etc.) The locations are configured at the very beginning of the build process by providing various paths to configure script, then eventually recorded in the preamble of the standalone script bin/polymake. If FreeBSD requires relocatable ports, you'll have to execute a custom post-installation script modifying this preamble; alternatively, you can modify the code in the preamble itself such that it derives the required paths from the script location, that is, $0. Symbolic links to shared libraries and "shared" directory created by the install script also might need special care; albeit they are relative, you should ensure that they are still valid after a relocation, if the final directory structure does not match the configured layout. Otherwise users' programs linked against polymake callable library won't start.
Yes, I am already taking care of the symbolic links. I wasn't aware of the other aspects. That's very helpful, thank you!

perlx path
There are two problems related to this.
The first one is binary compatibility betwen perl main interpreter and so called extension modules. There is a multitude of ways of breaking it, that's why all extension modules have to be built with exactly the same set of configuration options as perl itself. The choices for multiplicity and interpreter threads are just two options out of many, albeit the most prominent ones. And the bad thing is that perl does not offer any checking mechanism for binary compatibility which would at least produce a comprehensive error message; an extension module built with wrong configuration options will simply crash the interpreter with a segfault or similar disaster. That's why most systems (MacOS or Linux or Windows) stick to a certain perl configuration and do not let the user change it at their will. If FreeBSD port system gives this flexibility to the user, it must provide a mechanism for automatic rebuild or reinstallation of all dependent perl modules. This peculiarity is not specific to polymake, many hundreds if not thousands of CPAN modules would suffer from such configuration switching too.
The second problem is a logical consequence of the first one, it is the compatibility with the behavior of "use lib" perl pragma. Usually, it appends version- and architecture-dependent tokens to every module path, and these tokens are configured when the perl itself is built and recorded in its Config module. The purpose of this is to provide a minimal safety against binary incompatibility, as explained above. polymake simply has to follow this convention, otherwise it won't run at all. If you know that the FreeBSD perl port adheres to a different convention, you'll have to patch corresponding parts of the configure and install scripts appropriately.
That aspect had me very puzzled. Thank's a lot for those details!

Regarding the FreeBSD ports/packages: The official binary packages are built using the default options set in each port (for all the available perl interpreters this means mulitplicity and threading are enabled). That means everything should work out of the box.
If you build your own packages locally, you are responsible for taking care of such peculiarities yourself.

Again, thanks a lot for your help! Have a nice weekend!

Philipp

Philipp
Posts: 10
Joined: 17 Jun 2021, 20:30

Re: polymake on FreeBSD -- some questions and help needed

Postby Philipp » 18 Jun 2021, 20:58

libnormaliz is used for quite a lot of things, so having this would be really nice and I might have a look if you can provide some details.
With this patch applied, the content of build/bundled.log is as follows (I've also attached the file):

Code: Select all

Configuration of the following bundled extensions failed, proceeding without them. If you really need them, please carefully read the following explanations, take the suggested actions, and repeat the configuration. ---- libnormaliz ---- Could not compile a test program checking for libnormaliz. The most probable reasons are that the library is installed at a non-standard location, is not configured to build a shared module, or missing at all. Also make sure that libnormaliz was built with the same C++ library as polymake,especially if the errors below show missing symbols containing std::__1::vector or std::vector.The complete error log follows: In file included from /tmp/polymake_19693_configure.cc:6: /usr/local/include/gmpxx.h:1704:42: warning: zero as null pointer constant [-Wzero-as-null-pointer-constant] __gmp_alloc_cstring temp(mpz_get_str(0, base, mp)); ^ nullptr /usr/local/include/gmpxx.h:1816:14: warning: zero as null pointer constant [-Wzero-as-null-pointer-constant] if (s == 0) ^ nullptr /usr/local/include/gmpxx.h:1887:42: warning: zero as null pointer constant [-Wzero-as-null-pointer-constant] __gmp_alloc_cstring temp(mpq_get_str(0, base, mp)); ^ nullptr /usr/local/include/gmpxx.h:2104:42: warning: zero as null pointer constant [-Wzero-as-null-pointer-constant] __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp)); ^ nullptr In file included from /tmp/polymake_19693_configure.cc:7: In file included from /usr/local/include/libnormaliz/libnormaliz.h:27: In file included from /usr/local/include/libnormaliz/general.h:144: /usr/local/include/libnormaliz/integer.h:400:16: warning: implicit conversion loses integer precision: 'std::__1::basic_istream<char, std::__1::char_traits<char> >::int_type' (aka 'int') to 'char' [-Wimplicit-int-conversion] c = in.peek(); ~ ~~~^~~~~~ In file included from /tmp/polymake_19693_configure.cc:7: In file included from /usr/local/include/libnormaliz/libnormaliz.h:30: In file included from /usr/local/include/libnormaliz/automorph.h:31: In file included from /usr/local/include/libnormaliz/matrix.h:38: In file included from /usr/local/include/libnormaliz/vector_operations.h:39: In file included from /usr/local/include/flint/fmpq_poly.h:27: In file included from /usr/local/include/flint/fmpz_poly.h:35: /usr/local/include/flint/nmod_poly.h:406:16: warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'int' [-Wshorten-64-to-32] return r; ~~~~~~ ^ In file included from /tmp/polymake_19693_configure.cc:7: In file included from /usr/local/include/libnormaliz/libnormaliz.h:30: In file included from /usr/local/include/libnormaliz/automorph.h:31: In file included from /usr/local/include/libnormaliz/matrix.h:38: /usr/local/include/libnormaliz/vector_operations.h:154:23: warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'std::__1::__vector_base<int, std::__1::allocator<int> >::value_type' (aka 'int') [-Wshorten-64-to-32] inv_k[k[i]] = i; ~ ^ /usr/local/include/libnormaliz/vector_operations.h:508:17: warning: declaration shadows a local variable [-Wshadow] for (size_t i = 0; i < bv.size(); ++i) ^ /usr/local/include/libnormaliz/vector_operations.h:462:12: note: previous declaration is here size_t i, n = av.size(); ^ /usr/local/include/libnormaliz/vector_operations.h:979:18: warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'std::__1::__vector_base<unsigned int, std::__1::allocator<unsigned int> >::value_type' (aka 'unsigned int') [-Wshorten-64-to-32] key[k] = k; ~ ^ /usr/local/include/libnormaliz/vector_operations.h:986:26: warning: implicit conversion loses integer precision: 'unsigned long' to 'std::__1::__vector_base<unsigned int, std::__1::allocator<unsigned int> >::value_type' (aka 'unsigned int') [-Wshorten-64-to-32] key[k] = (n - 1) - k; ~ ~~~~~~~~^~~ /usr/local/include/libnormaliz/vector_operations.h:1213:27: warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >::value_type' (aka 'unsigned int') [-Wshorten-64-to-32] ret.push_back(i); ~~~~~~~~~ ^ In file included from /tmp/polymake_19693_configure.cc:7: In file included from /usr/local/include/libnormaliz/libnormaliz.h:31: In file included from /usr/local/include/libnormaliz/cone.h:36: /usr/local/include/libnormaliz/sublattice_representation.h:312:43: warning: declaration shadows a variable in namespace 'libnormaliz' [-Wshadow] bool verbose) { ^ /usr/local/include/libnormaliz/general.h:89:33: note: previous declaration is here NORMALIZ_DLL_EXPORT extern bool verbose; ^ 12 warnings generated. /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::kill_nauty(): error: undefined reference to 'nauty_kill_request' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long> libnormaliz::compute_automs_by_nauty_Gens_LF<long>(libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::AutomParam::Quality): error: undefined reference to 'nauty_check' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long> libnormaliz::compute_automs_by_nauty_Gens_LF<long>(libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::AutomParam::Quality): error: undefined reference to 'densenauty' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long> libnormaliz::compute_automs_by_nauty_Gens_LF<long>(libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::AutomParam::Quality): error: undefined reference to 'nauty_freedyn' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long> libnormaliz::compute_automs_by_nauty_FromGensOnly<long>(libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::Matrix<long> const&, libnormaliz::AutomParam::Quality): error: undefined reference to 'nauty_check' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long> libnormaliz::compute_automs_by_nauty_FromGensOnly<long>(libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::Matrix<long> const&, libnormaliz::AutomParam::Quality): error: undefined reference to 'densenauty' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long> libnormaliz::compute_automs_by_nauty_FromGensOnly<long>(libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::Matrix<long> const&, libnormaliz::AutomParam::Quality): error: undefined reference to 'nauty_freedyn' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long long> libnormaliz::compute_automs_by_nauty_Gens_LF<long long>(libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::AutomParam::Quality): error: undefined reference to 'nauty_check' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long long> libnormaliz::compute_automs_by_nauty_Gens_LF<long long>(libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::AutomParam::Quality): error: undefined reference to 'densenauty' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long long> libnormaliz::compute_automs_by_nauty_Gens_LF<long long>(libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::AutomParam::Quality): error: undefined reference to 'nauty_freedyn' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long long> libnormaliz::compute_automs_by_nauty_FromGensOnly<long long>(libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::Matrix<long long> const&, libnormaliz::AutomParam::Quality): error: undefined reference to 'nauty_check' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long long> libnormaliz::compute_automs_by_nauty_FromGensOnly<long long>(libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::Matrix<long long> const&, libnormaliz::AutomParam::Quality): error: undefined reference to 'densenauty' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:function libnormaliz::nauty_result<long long> libnormaliz::compute_automs_by_nauty_FromGensOnly<long long>(libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::Matrix<long long> const&, libnormaliz::AutomParam::Quality): error: undefined reference to 'nauty_freedyn' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:libnormaliz::compute_automs_by_nauty_Gens_LF<long>(libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::AutomParam::Quality)::options: error: undefined reference to 'dispatch_graph' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:libnormaliz::compute_automs_by_nauty_FromGensOnly<long>(libnormaliz::Matrix<long> const&, unsigned long, libnormaliz::Matrix<long> const&, libnormaliz::AutomParam::Quality)::options: error: undefined reference to 'dispatch_graph' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:libnormaliz::compute_automs_by_nauty_Gens_LF<long long>(libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::AutomParam::Quality)::options: error: undefined reference to 'dispatch_graph' /usr/local/lib/libnormaliz.a(nmz_nauty.o):nmz_nauty.cpp:libnormaliz::compute_automs_by_nauty_FromGensOnly<long long>(libnormaliz::Matrix<long long> const&, unsigned long, libnormaliz::Matrix<long long> const&, libnormaliz::AutomParam::Quality)::options: error: undefined reference to 'dispatch_graph' c++: error: linker command failed with exit code 1 (use -v to see invocation) Please install the library and specify its location using --with-libnormaliz option, if needed.
I configured polymake as follows

Code: Select all

./configure --without-prereq --with-libcxx --with-cdd=/usr/local --with-flint=/usr/local --with-permlib=/usr/local/lib --without-java --without-javaview --without-sympol --with-bliss=/usr/local --with-lrs=/usr/local --with-lrs-include=/usr/local/include/lrslib --with-ppl=/usr/local --with-scip=/usr/local --with-singular=/usr/local --with-soplex=/usr/local
For sake of completeness: I'm using clang 10.0.1 on FreeBSD 12.2-Stable
Attachments
bundled.log
(10.47 KiB) Downloaded 277 times

blorenz
Developer
Posts: 139
Joined: 10 Jan 2011, 17:21

Re: polymake on FreeBSD -- some questions and help needed

Postby blorenz » 18 Jun 2021, 23:34

I don't really know how you ended up with these undefined symbol errors for libnormaliz but they should disappear when adding '-lnauty' in the correct place, either in the global 'LIBS' variable passed to configure (./configure LIBS=-lnauty) or by adding an appropriate check in the libnormaliz detection (in 'bundled/libnormaliz/support/configure.pl').
I have added that check using the 'NMZ_NAUTY' flag in the attached patch and another small change to also accept a static library.
With that patch my libnormaliz installation from the ports (with your patch) was accepted by polymake without any nauty errors.
But I got some other errors during the build:

Code: Select all

error: /usr/local/lib/libnormaliz.a(reduction.o): requires dynamic R_X86_64_PC32 reloc against '__stack_chk_guard' which may overflow at runtime; recompile with -fPIC
These can be avoided if libnormaliz is compiled with '-fPIC' added to 'CXXFLAGS' (which would be the default for building shared libraries but unfortunately libnormaliz doesn't provide a make target for that).

I have also attached a patch for the 'install.pl' issue causing the broken symbolic links.

Regarding that DESTDIR, I had a quick look and it seems there are quite a few ports doing something similar to the examples below:

Code: Select all

MAKE_ENV= DESTDIR=${STAGEDIR} ${SETENV} DESTDIR=${STAGEDIR} ${MAKE} -C ${WRKSRC}/common install ${MAKE_CMD} install DESTDIR=${STAGEDIR}

One more remark: I would recommend adding '--without-native' to the configure flags, otherwise polymake will optimize the code for the current CPU (-march=native) and it will probably not run on other machines. So this is needed if this recipe is also used for packages that are installed on other machines.
Attachments
normaliz.patch
(1016 Bytes) Downloaded 268 times
install.patch
(515 Bytes) Downloaded 271 times

User avatar
gawrilow
Main Author
Posts: 423
Joined: 25 Dec 2010, 17:40

Re: polymake on FreeBSD -- some questions and help needed

Postby gawrilow » 19 Jun 2021, 00:04

PREFIX determines where the port will be installed, by default it's set to /usr/local. On FreeBSD, DESTDIR specifies a complete alternative environment, which might be a jail or a complete system mounted somewhere other than /. The actual location a port installs to is therefore DESTDIR/PREFIX.
I need to get the final clarity about this topic: Is DESTDIR specified only when the port is built and prepared for packaging, or also when a ready binary package is installed on the target system? When polymake is eventually running, will it see the full paths including that DESTDIR part, or just the PREFIX part (because of chroot DESTDIR or other mounting tricks?)
I had expected that install.pl puts everything into this staging directory when called by 'make stage'.
install.pl does not know about any makefiles or stages. I thought, you as a port developer are the author of that makefile too. The control of actions taken there should be entirely in your hands.
In particular, if you use DESTDIR=${STAGEDIR} trick during polymake configuration or install step, the responsibility of install.pl will be limited to copying the stuff into the staging area. Any further data movements should be done by extra commands you'd have to put in your makefile.

Philipp
Posts: 10
Joined: 17 Jun 2021, 20:30

Re: polymake on FreeBSD -- some questions and help needed

Postby Philipp » 19 Jun 2021, 17:04

I need to get the final clarity about this topic: Is DESTDIR specified only when the port is built and prepared for packaging, or also when a ready binary package is installed on the target system? When polymake is eventually running, will it see the full paths including that DESTDIR part, or just the PREFIX part (because of chroot DESTDIR or other mounting tricks?)
DESTDIR is specified at least when building and preparing for packaging. Setting DESTDIR is completely transparent to the port being built. Once polymake is installed it only sees the PREFIX parts.
install.pl does not know about any makefiles or stages. I thought, you as a port developer are the author of that makefile too. The control of actions taken there should be entirely in your hands.
Of course. The port's Makefile is entirely my responsibility. I fear this problem arose from unmet expectations on my part. I expected
  • polymake's install.pl to not install everything into /usr/local in the staging phase
  • the FreeBSD ports framework to work according to the documenation in the Porters Handbook
Everything is working fine now. The port now calls polymake's Makefile to build and install. Staging works as expected. Before that, I was calling ninja directly. I suspect it now looks sufficiently like autotools for the framework to take over whereas before it didn't. Polymake is not to blame here.

Philipp
Posts: 10
Joined: 17 Jun 2021, 20:30

Re: polymake on FreeBSD -- some questions and help needed

Postby Philipp » 21 Jun 2021, 00:45

Hello Benjamin,

I somehow missed your reply on Friday. Sorry about that.

Thank you very much for those two patches!
But I got some other errors during the build:

Code: Select all

error: /usr/local/lib/libnormaliz.a(reduction.o): requires dynamic R_X86_64_PC32 reloc against '__stack_chk_guard' which may overflow at runtime; recompile with -fPIC
These can be avoided if libnormaliz is compiled with '-fPIC' added to 'CXXFLAGS' (which would be the default for building shared libraries but unfortunately libnormaliz doesn't provide a make target for that).
I got those, too. The libnormaliz port has some other issues, too. It looks like these need to be fixed first.

As mentioned earlier, I solved the staging issue by working with polymake's Makefile instead of calling ninja directly. There are no DESTDIR trickeries involved. ;-)
One more remark: I would recommend adding '--without-native' to the configure flags, otherwise polymake will optimize the code for the current CPU (-march=native) and it will probably not run on other machines. So this is needed if this recipe is also used for packages that are installed on other machines.
This is taken care of by an option which defaults to off for the reason you stated.

I also found a nice solution for the perlx path in pkg-plist. As it stands now, the only remaining issue is to fix the libnormaliz port. Once that is done, I can do a final check on the polymake port and submit it.

I have another question concerning the shared library: Right now, the port provides libpolymake.so.4.4 and libpolymake-apps-rt.so.4.4. What about libpolymake-apps.so.4.4? Should that one be provided, too? If so, I have to figure out why that one is not picked up by pkg.

Thank you again for your help!

blorenz
Developer
Posts: 139
Joined: 10 Jan 2011, 17:21

Re: polymake on FreeBSD -- some questions and help needed

Postby blorenz » 25 Jun 2021, 13:26

I have another question concerning the shared library: Right now, the port provides libpolymake.so.4.4 and libpolymake-apps-rt.so.4.4. What about libpolymake-apps.so.4.4? Should that one be provided, too? If so, I have to figure out why that one is not picked up by pkg.
Sorry for the delay. That libpolymake-apps.so.4.4 library is kind of special because it only provides fake-symbols for linking, i.e. if some other program is being linked against libpolymake this library provides symbols for all the functions that are only loaded at runtime via dlopen from several other shared libraries. This is done to avoid linker errors for undefined symbols.
The reason that it is not picked up by pkg is probably that the soname points to the runtime version of that library which is libpolymake-apps-rt.so.4.4. So at runtime only the -rt version is needed.
I am not sure about the definition for provided but that library it should not be relevant for for any compiled packages.

Best
Benjamin


Return to “Installing polymake”