Bug 702905 - /usr/bin/ld: cannot find -liconv
Summary: /usr/bin/ld: cannot find -liconv
Status: RESOLVED LATER
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: Build Process (show other bugs)
Version: 9.53.1
Hardware: PC Linux
: P4 normal
Assignee: Chris Liddell (chrisl)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-09-15 11:49 UTC by Jeffrey Walton
Modified: 2021-02-11 14:32 UTC (History)
1 user (show)

See Also:
Customer:
Word Size: ---


Attachments
config.log file (15.56 KB, application/zip)
2020-09-15 11:49 UTC, Jeffrey Walton
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jeffrey Walton 2020-09-15 11:49:19 UTC
Created attachment 19830 [details]
config.log file

Hi Everyone. I'm building ghostpdl-9.53.1.tar.gz on Ubuntu 18.04 x86_64 fully patched. Make is failing with:

gcc   -O2 -DNDEBUG -Wall -Wstrict-prototypes -Wundef -Wmissing-declarations -Wmissing-prototypes -Wwrite-strings -fno-strict-aliasing -Werror=declaration-after-statement -fno-builtin -fno-common -Werror=return-type -DHAVE_STDINT_H=1 -DHAVE_DIRENT_H=1 -DHAVE_SYS_DIR_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIMES_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_LIBDL=1 -DGX_COLOR_INDEX_TYPE="unsigned long long" -D__USE_UNIX98=1  -g2 -O2 -march=native -fPIC -pthread -DHAVE_RESTRICT=1 -fno-strict-aliasing -DHAVE_POPEN_PROTO=1  -I./base -o ./obj/aux/genconf ./base/genconf.c  -lm -ldl -ldl -lpthread -liconv -rdynamic
/usr/bin/ld: cannot find -liconv
collect2: error: ld returned 1 exit status
base/unix-aux.mak:71: recipe for target 'obj/aux/genconf' failed
make: *** [obj/aux/genconf] Error 1

I am pretty sure the makefiles are not using LDFLAGS in recipes that need libraries like iconv. I say that because I have a new GetText and iConv built/installed:

$ ls ~/tmp/ok2delete/lib | grep -E 'iconv|gettext|intl'
gettext
libgettextlib-0.20.2.so
libgettextlib.la
libgettextlib.so
libgettextpo.a
libgettextpo.la
libgettextpo.so
libgettextpo.so.0
libgettextpo.so.0.5.6
libgettextsrc-0.20.2.so
libgettextsrc.la
libgettextsrc.so
libiconv.la
libiconv.so
libiconv.so.2
libiconv.so.2.6.1
libintl.a
libintl.la
libintl.so
libintl.so.8
libintl.so.8.1.7

Alternately, I also have PKG_CONFIG_PATH set, so the flags could be picked up using pkg-config.

Attached is config.log.

For completeness, here is the way my environment is setup. I'm currently testing the build, so everything is installed in $HOME/tmp/ok2delete. Once the test builds succeed, I switch to a location like /usr/local.

       AUTOCONF: x86_64-pc-linux-gnu
PKG_CONFIG_PATH: /home/jwalton/tmp/ok2delete/lib/pkgconfig
       CPPFLAGS: -I/home/jwalton/tmp/ok2delete/include -DNDEBUG
        ASFLAGS: -Wa,--noexecstack
         CFLAGS: -g2 -O2 -march=native -fPIC -pthread
       CXXFLAGS: -g2 -O2 -march=native -fPIC -pthread
        LDFLAGS: -L/home/jwalton/tmp/ok2delete/lib -Wl,-R,'$ORIGIN/../lib' -Wl,-R,/home/jwalton/tmp/ok2delete/lib -Wl,--enable-new-dtags -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,-z,origin
         LDLIBS: -ldl -lpthread

As you can see, there's a lot going on with LDFLAGS. The flags include runpaths to ensure the proper library is loaded at runtime. LDFLAGS also has some GOT and PLT hardening. GhostScript really needs to use LDFLAGS in its recipes.
Comment 1 Chris Liddell (chrisl) 2020-09-15 14:48:37 UTC
I suspect the problem is that for a few of the tools we do a one step compilation/link, for which we seem to only use CFLAGS, and not LDFLAGS.

As a work around, you might be able to just add your LDFLAGs settings to your CFLAGS.

If that works, I will give some thought to how best to fix it "properly". At the moment, I think I'm leaning towards switching all those "auxiliary" tools to two step compile then link rules.
Comment 2 Jeffrey Walton 2020-09-15 19:02:15 UTC
(In reply to Chris Liddell (chrisl) from comment #1)
> I suspect the problem is that for a few of the tools we do a one step
> compilation/link, for which we seem to only use CFLAGS, and not LDFLAGS.
> 
> As a work around, you might be able to just add your LDFLAGs settings to
> your CFLAGS.
> 
> If that works, I will give some thought to how best to fix it "properly". At
> the moment, I think I'm leaning towards switching all those "auxiliary"
> tools to two step compile then link rules.

Thanks Chris. Let me see if I can help out.

Looking at top-level configure.ac, it looks liek CPPFLAGS and LDFLAGS are not being used like expected. It also looks like CFLAGS is being slightly abused:

   CFLAGS="$CFLAGS -DHAVE_RESTRICT=1"

There's a few minor problems that are easy to correct. First, -DHAVE_RESTRICT=1 goes in CPPFLAGS. Second, use CPPFLAGS and LDFLAGS in your recipes. Third, the user own CPPFLAGS, CFLAGS, LDFLAGS, etc. Projects should not touch them. Instead, projects should use AM_CPPFLAGS, AM_CFLAGS, AM_LDFLAGS, etc.

So GhostScript's configure.ac test result would look like:

   AM_CPPFLAGS="$AM_CPPFLAGS -DHAVE_RESTRICT=1"

At the end of configure.ac, call:

   AC_SUBST(AM_CPPFLAGS)
   AC_SUBST(AM_CFLAGS)
   AC_SUBST(AM_LDFLAGS)

Finally, change GhostScript's Makefile.am recipes to use something like:

   CAL_CPPFLAGS=@AM_CPPFLAGS@ @CAL_CPPFLAGS@ @CPPFLAGS@
   CAL_CFLAGS=@AM_CFLAGS@ @CAL_CFLAGS@ @CFLAGS@
   CAL_LDFLAGS=@AM_LDFLAGS@ @CAL_LDFLAGS@ @LDFLAGS@

So AM_CPPFLAGS (and friends) are GhostScript flags applied to all output artifacts. CAL_CPPFLAGS (and friends) are specific to the CAL artifact. CFLAGS (and friends) are user flags applied to all output artifacts.

I think that's the way to treat Makefile.am (all three flags collected together). I'll know more later tonight when I have some time to work on patches.

While it is not obvious, that is what the GNU Coding Standard says to do at https://www.gnu.org/prep/standards/html_node/Command-Variables.html.
Comment 3 Chris Liddell (chrisl) 2020-09-16 08:05:00 UTC
Well we are not a GNU project, and never have been, so we are not bound by their coding standards.

I don't see any real value (in *our* case) in splitting CPPFLAGS from CFLAGS and, worse, that would cause upheaval and confusion for long term, existing "users". So without a solid technical reason for doing so, I would be hesitant to make that change.

And, honestly, we are *far* from unique in using CFLAGS the way we do.

I would really like to find a solution for the problem you reported, rather than a drawn out discussion of the "style" of our configure/makefile setup (at least, at this point, in this forum).
Comment 4 Jeffrey Walton 2020-09-16 09:54:51 UTC
(In reply to Chris Liddell (chrisl) from comment #3)
> Well we are not a GNU project, and never have been, so we are not bound by
> their coding standards.

Correct me if I am wrong, but GhostScript is an Autotools project. Autotools is tightly coupled to the conventions used by GNU, like use of CPPFLAGS, CFLAGS and LDFLAGS. They cannot be disgorged.

Additionally, the command variables established by (or documented by) GNU are the defacto standard. They've been used well over 50 years now. It is what developers expect for make-based C projects.

> I don't see any real value (in *our* case) in splitting CPPFLAGS from CFLAGS
> and, worse, that would cause upheaval and confusion for long term, existing
> "users". So without a solid technical reason for doing so, I would be
> hesitant to make that change.

I think there would be only benefit and no real downsides. There are two cases to consider: (1) folks accustomed to GhostScript conventions; and (2) folks doing things as intended.

If flags are split and handled as expected, then things work as expected for both (1) and (2). The only downside is users in (1) may see some options listed twice. But the group from (2) get their flags used.

If flags are _not_ split, then things only work for group (1). The folks in group (2) get unexpected results because their flags are not used.

> And, honestly, we are *far* from unique in using CFLAGS the way we do.

I guess my mileage varies. I regularly build about 100 different projects, and nearly all of them are Autotools based. I find nearly all (all?) Autotools use separate flags for CPPFLAGS, CFLAGS, and LDFLAGS.

Based on my experience, the projects that seem to need the most help are Make-based projects like Zlib. They omit CPPFLAGS in their recipe and need a small patch like https://github.com/noloader/Build-Scripts/blob/master/patch/zlib.patch.

In the big picture, the reason _not_ to combine CPPFLAGS, CFLAGS, and LDFLAGS is the compiler driver. Compilation gets CPPFLAGS and CFLAGS, and link gets CFLAGS and LDFLAGS (and LIBS, if needed). For example:

  foo.exe: foo.h foo.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c foo.c
    $(CC) -o foo.exe $(CFLAGS) foo.o $(LDFLAGS) $(LIBS)

> I would really like to find a solution for the problem you reported, rather
> than a drawn out discussion of the "style" of our configure/makefile setup
> (at least, at this point, in this forum).

My bad... to be clear, I don't care about style.

The only thing I care about is things work as expected. I don't think I have unreasonable expectations. My expectations are the same as a typical Autotools user, and other Autotools users like Debian, Fedora, Red Hat and Ubuntu.
Comment 5 Chris Liddell (chrisl) 2020-09-16 10:13:57 UTC
(In reply to Jeffrey Walton from comment #4)
> (In reply to Chris Liddell (chrisl) from comment #3)
> > Well we are not a GNU project, and never have been, so we are not bound by
> > their coding standards.
> 
> Correct me if I am wrong, but GhostScript is an Autotools project. Autotools
> is tightly coupled to the conventions used by GNU, like use of CPPFLAGS,
> CFLAGS and LDFLAGS. They cannot be disgorged.
> 
> Additionally, the command variables established by (or documented by) GNU
> are the defacto standard. They've been used well over 50 years now. It is
> what developers expect for make-based C projects.

Ghostscript uses *some* autotools, it is not an autotools project. Ghostscript pre-dates autotools by a considerable period. And predates widespread use of autotools by even longer.

The use of autoconf was, I would say, "grafted" onto an existing build system - whilst largely maintaining, for a long time, the non-autoconf based build, as well. There were compromises made and, it is fair to say, it's not how I would author a new project to use those tools.

> > I don't see any real value (in *our* case) in splitting CPPFLAGS from CFLAGS
> > and, worse, that would cause upheaval and confusion for long term, existing
> > "users". So without a solid technical reason for doing so, I would be
> > hesitant to make that change.
> 
> I think there would be only benefit and no real downsides. There are two
> cases to consider: (1) folks accustomed to GhostScript conventions; and (2)
> folks doing things as intended.
> 
> If flags are split and handled as expected, then things work as expected for
> both (1) and (2). The only downside is users in (1) may see some options
> listed twice. But the group from (2) get their flags used.
> 
> If flags are _not_ split, then things only work for group (1). The folks in
> group (2) get unexpected results because their flags are not used.

Well, the evidence doesn't support that, since it's been this way for 18 years, and you are the first person to raise it.

<SNIP> 
> > I would really like to find a solution for the problem you reported, rather
> > than a drawn out discussion of the "style" of our configure/makefile setup
> > (at least, at this point, in this forum).
> 
> My bad... to be clear, I don't care about style.
> 
> The only thing I care about is things work as expected. I don't think I have
> unreasonable expectations. My expectations are the same as a typical
> Autotools user, and other Autotools users like Debian, Fedora, Red Hat and
> Ubuntu.

Well, see above....

To be equally clear, I'm not unwilling to make changes, even if they are mainly aesthetic. But it would be a fair amount of work, and require a *lot* of testing and, for a while, at least, I don't have that time available.

As I said, you have found a real problem, I would like to (in the context of this thread) resolve that problem. I'm perfectly happy, if you want to open an enhancement issue for the CPPFLAGS/CFLAGS/LDFLAGS stuff, to discuss it, look at it and think about it properly when I have the time to do so.

Like a lot of stuff with Ghostscript, changing our build is not something the word "simply" can ever be used to refer to safely!