86

I'm getting the following issue when trying to run make on the HTK library:

(cd HTKLib && make HTKLib.a) \
  || case "" in *k*) fail=yes;; *) exit 1;; esac;
make[1]: Entering directory '/home/william/speech/htk/HTK-3.4.1/htk/HTKLib'
gcc  -m32 -ansi -D_SVID_SOURCE -DOSS_AUDIO -D'ARCH="x86_64"' -Wall -Wno-switch -g -O2 -I. -DPHNALG   -c -o HGraf.o HGraf.c
In file included from HShell.h:40:0,
                 from HGraf.c:54:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory
 #include <bits/libc-header-start.h>
          ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
<builtin>: recipe for target 'HGraf.o' failed
make[1]: *** [HGraf.o] Error 1
make[1]: Leaving directory '/home/william/speech/htk/HTK-3.4.1/htk/HTKLib'
Makefile:96: recipe for target 'HTKLib/HTKLib.a' failed
make: *** [HTKLib/HTKLib.a] Error 1

I'm unsure what to do about this error. The libc-header-start.h file is present on my system:

$ find /usr -name libc-header-start.h
/usr/include/x86_64-linux-gnu/bits/libc-header-start.h

Running gcc -H -fsyntax-only /usr/include/stdio.h appropriately returns

. /usr/include/x86_64-linux-gnu/bits/libc-header-start.h
.. /usr/include/features.h
... /usr/include/x86_64-linux-gnu/sys/cdefs.h

etc.

Also, compiling and running a sanity-check C file works fine (simply executing printf("hello!"); in its main method).

Apologies if this is a well-known error - my experience with C libraries stops at compiling and installing them using make.

UPDATE Per the accepted answer below I executed sudo apt-get install gcc-multilib to install the missing 32 bit libraries.

Afterwards I got an error with a similar cause: "/usr/bin/ld: cannot find -lX11" error when installing htk. I resolved this by executing sudo apt-get install libx11-dev:i386 libx11-dev to retrieve the missing 32 bit library.

William
  • 1,154
  • 1
  • 9
  • 15
  • Is this a 64 or 32 bit system? (i.e. what's the output of `uname -a`?) – Nick ODell Jan 07 '19 at 22:09
  • 1
    The gcc invocation you show is `gcc -m32`, which tells gcc to compile a 32-bit binary. For that purpose, it will not look for header files in `/usr/include/x86_64-linux-gnu/`, because that directory (as hinted at by its name) contains headers for 64-bit builds. – rici Jan 07 '19 at 22:23

2 Answers2

114

The -m32 is telling gcc to compile for a 32-bit platform. On a 64-bit platform, gcc normally only comes with 64-bit libraries. You have two options:

  1. Install 32-bit headers and libraries. Here's how you'd do this on Ubuntu.

    Run this command:

    sudo apt-get install gcc-multilib
    
  2. Compile for 64-bit instead. Modify this line in the file named configure:

     CFLAGS="-m32 -ansi -D_SVID_SOURCE -DOSS_AUDIO -D'ARCH=\"$host_cpu\"' $CFLAGS"
    

    Delete -m32, giving you:

     CFLAGS="-ansi -D_SVID_SOURCE -DOSS_AUDIO -D'ARCH=\"$host_cpu\"' $CFLAGS"
    

    Run ./configure, then make clean, then make

    However, I would recommend against this approach. The library authors went out of their way to make this build for 32 bits on a 64 bit system, and I can't guarantee that it will work correctly if you do this. (It does compile, though.)

Nick ODell
  • 15,465
  • 3
  • 32
  • 66
17

Below is one way to debug and fix this issue. Since most linux installations differ in one way or another, YMMV.

  1. Find which package installed libc-header-start.h.
$ dpkg -S libc-header-start.h
libc6-dev:amd64: /usr/include/x86_64-linux-gnu/bits/libc-header-start.h

On a working system, /usr/include/bits is a symlink to /usr/include/x86_64-linux-gnu/bits. Running dpkg search gives us:

$ dpkg -S /usr/include/bits
libc6-dev-i386: /usr/include/bits

Installing libc6-dev-i386 creates the symlink and the error is addressed.

However, subsequently I ran into a linker error with the linker not being able to find libgcc (-lgcc). Apparently Linux default linker needs libgcc in most cases. Further debugging the issue with linker verbosity enabled lead me to missing lib32gcc-10-dev package.

In short, unless a very controlled build environment is desired, just install gcc-multilib package when using -m32 (needed for gcc or clang). For C++, g++-multilib is also required.

akhan
  • 2,952
  • 2
  • 22
  • 13
  • I ran into a python2.7 binary, in an android repo on a Centos rel 8 machine, which bash was unable to run. Running `file`, `objdump`, and `ldd` on the binary showed dynamic linkage and a 32 bit elf. Resolved by `sudo dnf install glibc.i686`. – akhan Jun 03 '22 at 23:32