Repository: spack/spack

Issue:
Installation issue: xfd
Hi, I have met the "DSO missing" error when building xfd. 

### Steps to reproduce the issue

```console
$ spack install xfd
==> pkgconf is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/pkgconf-1.4.2-ljfy2kib5lfdxd7nhlhwcna76pndewpp
==> util-macros is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/util-macros-1.19.1-xztluvf4isgescjuzzhxhq7u6f6svv3p
==> font-util is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/font-util-1.3.1-6kve7liuipanbxoxec2kintpythf2hw7
==> diffutils is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/diffutils-3.6-p4gfaaiefcrg6o7j24cu4mrzklmec5kr
==> bzip2 is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/bzip2-1.0.6-57yzgp65casoks6if445a2dl7cp4fvmz
==> zlib is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/zlib-1.2.11-fuwbsyd4h6milgbzfi362t25s46hd75r
==> libpng is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libpng-1.6.34-aiz5qo7sshiccqk7vpqgkpjh6hnh53hy
==> freetype is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/freetype-2.9.1-sjjaqsfziyl7lgxgfk5gzm24uultybuj
==> gperf is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/gperf-3.0.4-qeav62tavckccguzh3f4nva26yvwrovr
==> xz is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/xz-5.2.4-tn4b4qxe4pvdtnee5qbbpldysgkgmzzh
==> libxml2 is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxml2-2.9.8-x3pyrm4ew6ixelzva6u6xztiupg7t354
==> fontconfig is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/fontconfig-2.12.3-obh4r7fmqrnd4sb4dn3gvwsync5ozk7j
==> inputproto is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/inputproto-2.3.2-qdvtz4d4obdjmaq6vp2c7vdwnvva6jri
==> kbproto is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/kbproto-1.0.7-ugjncua66uvnmu4a4tds466g2yb554f6
==> libpthread-stubs is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libpthread-stubs-0.4-5qusfmwhj643if7d56c2sj5f6jnjpk2u
==> xproto is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/xproto-7.0.31-dgxpc2csiybtqqqq443uxfqzgf4pzeas
==> libxau is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxau-1.0.8-jgl3aylnau7nv5q75bbuuerv7jllm2zr
==> libxdmcp is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxdmcp-1.1.2-vna7k5vznqwyguh7owb3jlynomtz7czh
==> xcb-proto is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/xcb-proto-1.13-ewngu4r5sjlugqg6tnuvhss4hpnpbhcs
==> libxcb is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxcb-1.13-xhuphvj57jxtp52egx3q2ny3kp4vh6av
==> ncurses is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/ncurses-6.1-65ihozz47uxacyvyvniwjc43jkj23bcz
==> readline is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/readline-7.0-lvibxmqhxyriy6vtp6mfsycrw5qc3aci
==> gdbm is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/gdbm-1.14.1-27eqb7wsi5erbtrx2to22kp2gdxuzt7d
==> perl is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/perl-5.26.2-lf4pv5wkukmvpyi73hbakbyb3duoomul
==> xextproto is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/xextproto-7.3.0-g7gt42frvtnltq5zjyvpheuniohjr6ox
==> xtrans is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/xtrans-1.3.5-7oedxb2hj3hqxi7b2lvia5xwogbn4sa7
==> libx11 is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libx11-1.6.5-q5yzoobfb6ew5vs7hjvpmnuzkjkrb2ta
==> libxext is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxext-1.3.3-6np2ytnyclk3g4cuzuvhstcatqqqw2xz
==> libice is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libice-1.0.9-a3soxsxfn4p7uhpecs5b4ot2w7qtwujb
==> libsm is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libsm-1.2.2-xhgtt3ydvehr44mf533x4nw26jt35urm
==> libxt is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxt-1.1.5-7idwvqlnhe4v2ooyh7nprcqmkb4rkjr7
==> libxmu is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxmu-1.1.2-vbmq7fvao6nplory7dthuped6khypqd2
==> tar is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/tar-1.30-6zoebaik3rs3mfbns2jf3h2nvcraupq7
==> gettext is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/gettext-0.19.8.1-oc4yzjzifmyjtqgierjqg4jtexct3w33
==> libxpm is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxpm-3.5.12-65ps6hlfhleijstdaea3pnfntobug4ye
==> libxaw is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxaw-1.0.13-memyh5hgw6cntok6uodjmrrvls534n7b
==> renderproto is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/renderproto-0.11.1-vw5demew34rfddem4jlh2bsyf3vajdsx
==> libxrender is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxrender-0.9.10-jdcq5rqckbkxh2wd6h7cybayptsj4fgd
==> libxft is already installed in $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/libxft-2.3.2-ymeb5hjkxhsohencoeczelqzysgslyix
==> Installing xfd
==> Searching for binary cache of xfd
==> Warning: No Spack mirrors are currently configured
==> No binary for xfd found: installing from source
==> Using cached archive: $SPACK_ROOT/var/spack/cache/xfd/xfd-1.1.2.tar.gz
==> Staging archive: $SPACK_ROOT/var/spack/stage/xfd-1.1.2-gus4ivkr4vrytpqjsdztxa73faqmmf5f/xfd-1.1.2.tar.gz
==> Created stage in $SPACK_ROOT/var/spack/stage/xfd-1.1.2-gus4ivkr4vrytpqjsdztxa73faqmmf5f
==> No patches needed for xfd
==> Building xfd [AutotoolsPackage]
==> Executing phase: 'autoreconf'
==> Executing phase: 'configure'
==> Executing phase: 'build'
==> Error: ProcessError: Command exited with status 2:
    'make' '-j8'

6 errors found in build log:
     848     #define XtNcallback ((char*)&XtStrings[136])
     849                          ^
     850    grid.c:994:26: note: in expansion of macro 'XtNcallback'
     851         XtCallCallbacks (gw, XtNcallback, (XtPointer) &rec);
     852                              ^~~~~~~~~~~
     853      CCLD     xfd
  >> 854    /usr/bin/ld: xfd.o: undefined reference to symbol 'libintl_textdomain'
  >> 855    $SPACK_ROOT/opt/spack/linux-centos7-x86_64/gcc-7.2.0/gettext-0.19.8.1-oc4yzjzifmyjtqgi
            erjqg4jtexct3w33/lib/libintl.so.8: error adding symbols: DSO missing from command line
  >> 856    collect2: error: ld returned 1 exit status
  >> 857    make[2]: *** [xfd] Error 1
     858    make[2]: Leaving directory `/tmp/cusgunx/spack-stage/spack-stage-WJEnK6/xfd-1.1.2'
  >> 859    make[1]: *** [all-recursive] Error 1
     860    make[1]: Leaving directory `/tmp/cusgunx/spack-stage/spack-stage-WJEnK6/xfd-1.1.2'
  >> 861    make: *** [all] Error 2

See build log for details:
  $SPACK_ROOT/var/spack/stage/xfd-1.1.2-gus4ivkr4vrytpqjsdztxa73faqmmf5f/xfd-1.1.2/spack-build.out
```

### Platform and user environment

```commandline
$ uname -a 
Linux n2005 3.10.0-957.12.1.el7.x86_64 #1 SMP Mon Apr 29 14:59:59 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ spack --version
0.12.1
``` 

At the same time, I am wondering about a more general & fundamental question on how to explicitly specify a lib dependency (in a package) in package.py. Any advices?


Discussion:
`libintl_textdomain` is provided by libintl from package gettext.

Looking at `spack spec xfd`, gettext is a transitive dependency for
xfd, but not a direct dependency.  I would bet that if you added this
line to the xfd `package.py` file, then it would pick up the libintl
linkage.

```
depends_on('gettext', type='link')
```

That will add the appropriate libraries on the link line.  This should
either work or else get you to a different error.  If it works, then
submit a pull request.

There are three types of dependencies: build, link and run.  In this
case you want link.  The default is build + link which would also
work.

See: https://spack.readthedocs.io/en/latest/packaging_guide.html#extensions

Hi Mark,

Thanks so much for your reply and the good info about library dependencies. However when I added the line you suggested, it doesn't help and gives exactly the same error as in my original post. 

Any further hints? BTW, the updated package.py looks like this:

```console
$ cat $SPACK_ROOT/var/spack/repos/builtin/packages/xfd/package.py
# Copyright 2013-2018 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *


class Xfd(AutotoolsPackage):
    """xfd - display all the characters in a font using either the
    X11 core protocol or libXft2."""

    homepage = "http://cgit.freedesktop.org/xorg/app/xfd"
    url      = "https://www.x.org/archive/individual/app/xfd-1.1.2.tar.gz"

    version('1.1.2', '12fe8f7c3e71352bf22124ad56d4ceaf')

    depends_on('libxaw')
    depends_on('fontconfig')
    depends_on('libxft')
    depends_on('libxrender')
    depends_on('libxmu')
    depends_on('libxt')

    depends_on('xproto@7.0.17:', type='build')
    depends_on('pkgconfig', type='build')
    depends_on('util-macros', type='build')

    depends_on('gettext', type='link')
```
And here I naively thought it was a simple problem.
No good deed ....

There is a mistake in how xfd configure tests for `libintl`.  It looks
for the function `gettext` in libintl, but gettext is in libc, so
configure concludes that it doesn't need to add `-lintl` to the link
line, so `libintl_bindtextdomain` doesn't exist.

If they tested for `libintl_bindtextdomain` instead, then configure
would figure out that it needs to add -lintl and it would work, with
`depends_on('gettext')`.  Sloppy.

Anyway, spack has the machinery to workaround this.  I should be able
to put together a pull request to fix this tomorrow or Friday.

Btw, 1.1.2 is from 2013.  There is a later version, 1.1.3 from March
2019.  I might add that as well.  1.1.3 has one extra option for `xbd`,
so it will depend on how much work it takes to deal with that.  It
looks like kbd is just for sounding a bell, so I'll probably just turn
it off.

Resolving patch:
diff --git a/var/spack/repos/builtin/packages/xfd/package.py b/var/spack/repos/builtin/packages/xfd/package.py
--- a/var/spack/repos/builtin/packages/xfd/package.py
+++ b/var/spack/repos/builtin/packages/xfd/package.py
@@ -13,10 +13,12 @@ class Xfd(AutotoolsPackage):
     homepage = "http://cgit.freedesktop.org/xorg/app/xfd"
     url      = "https://www.x.org/archive/individual/app/xfd-1.1.2.tar.gz"
 
+    version('1.1.3', '4a1bd18f324c239b1a807ed4ccaeb172ba771d65a7307fb492d8dd8d27f01527')
     version('1.1.2', '12fe8f7c3e71352bf22124ad56d4ceaf')
 
-    depends_on('libxaw')
     depends_on('fontconfig')
+    depends_on('gettext')
+    depends_on('libxaw')
     depends_on('libxft')
     depends_on('libxrender')
     depends_on('libxmu')
@@ -25,3 +27,20 @@ class Xfd(AutotoolsPackage):
     depends_on('xproto@7.0.17:', type='build')
     depends_on('pkgconfig', type='build')
     depends_on('util-macros', type='build')
+
+    # Xfd requires libintl (gettext), but does not test for it
+    # correctly, so add it here.
+    def flag_handler(self, name, flags):
+        if name == 'ldlibs':
+            flags.append('-lintl')
+
+        return (flags, None, None)
+
+    def configure_args(self):
+        args = []
+
+        # Xkb only rings a bell, so just disable it.
+        if self.spec.satisfies('@1.1.3:'):
+            args.append('--without-xkb')
+
+        return args


Test patch: