0

I tried to run an example program from a book called 'The Linux Programming Interface'. I copied all user-defined header files and functions from official website of book to my booklib location. When I compiled the program, I took these errors. I need help about'Undefined reference to [functions_name]**.
code:

    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <stdio.h>

    #include "tlpi_hdr.h"

    #ifndef BUF_SIZE
    #define BUF_SIZE 1024
    #endif

    int main(int argc, char *argv[])
    {

      int inputFd, outputFd, openFlags;
      mode_t filePerms;
      ssize_t numRead;
      char buf[BUF_SIZE];

      if(argc != 3 || strcmp(argv[1], "--help") == 0)
        {
          usageErr("%s old-file new-file\n", argv[0]);
        }

      //open input old-file
      inputFd = open(argv[1], O_RDONLY);

      //error check
      if(inputFd == -1)
        {
          errExit("opening file %s", argv[1]);
        }

      openFlags = O_CREAT | O_WRONLY | O_TRUNC;
      filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;

      //open output the new-file
      outputFd = open(argv[2], openFlags, filePerms);

      if(outputFd == -1)
        {
          errExit("opening file %s", argv[2]);
        }

      //transfer data until we encounter end of input or an error
      while((numRead = read(inputFd, buf, BUF_SIZE)) > 0)
        {
          if(write(outputFd, buf, numRead) != numRead)
            fatal("couldn't write whole buffer");
if(numRead == -1)
        errExit("read");

      if(close(inputFd) == -1)
        errExit("close input");

      if(close(outputFd) == -1)
        errExit("close output");

    }

  exit(EXIT_SUCCESS);
}


You can see user-defined header files from here.

$gcc -I booklib -o copy copy.c 

c
/tmp/ccqC9Tg9.o: In function `main':
copy.c:(.text+0x62): undefined reference to `usageErr'
copy.c:(.text+0xb3): undefined reference to `errExit'
copy.c:(.text+0x11c): undefined reference to `errExit'
copy.c:(.text+0x14b): undefined reference to `fatal'
copy.c:(.text+0x163): undefined reference to `errExit'
copy.c:(.text+0x183): undefined reference to `errExit'
copy.c:(.text+0x1a3): undefined reference to `errExit'
collect2: error: ld returned 1 exit status

gcc -v output:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 6.3.0-6' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 6.3.0 20170205 (Debian 6.3.0-6)
metarose
  • 171
  • 1
  • 5
  • 17
  • 3
    It looks like you've misdefined `main()` — probably `int main(int argc, char *argv)` (or perhaps `int main(int argc, char argv[])`) instead of `int main(int argc, char **argv)`. The undefined functions are irresolvable from the information given. You've called functions but not provided their definition. There's no way we can tell where those functions are defined. It might be another C file that you're supposed to compile to an object file and link with the main program; it might be supposed to be in a library you're not linking with; it might be some other issue. – Jonathan Leffler Feb 28 '17 at 19:04
  • 1
    Could we see *some* of your code. It is really impossible to debug anything without looking at the source code. More specifically I would like to look at the signature of main. I suspect you have written int main(int argc, char argv[]) instead of int main(int argc, char* argv[]); – Ajay Brahmakshatriya Feb 28 '17 at 19:05
  • @AjayBrahmakshatriya actually I give the link of source code in the question. I didn't enter the code to my question because it would be long. I edited the question. – metarose Feb 28 '17 at 19:18
  • I see that the code mentioned on the link should not fail, I want to specifically see what you have written. Because I suspect you made a mistake copying the code. Just the one line where main is defined/declared should be enough. – Ajay Brahmakshatriya Feb 28 '17 at 19:20
  • OK. I see my mistake. `int main(int argc, char argv)` instead of `int main(int argc, char* argv[])`. When I corrected the code, all warnings gone but I still take undefined reference error. – metarose Feb 28 '17 at 19:28
  • 2
    The code from TLPI doesn't compile particularly well on a Mac, it seems. At least, it's giving me more grief than I've time to resolve right now. Basically, you need to get the code from the TLPI `lib` directory compiled into a library (maybe `libtlpi.a` or `libtlpi.so`), and you include `-I /path/to/tlpi/lib` and `-L /path/to/tlpi/lib` and `-ltlpi` on the compiler command lines. – Jonathan Leffler Feb 28 '17 at 19:35
  • Please check your code yourself against the examples before posting a question. Read the signature of your `main` carefully` and then from a correct one. – too honest for this site Feb 28 '17 at 19:41
  • 1
    Are the missing functions defined earlier in the book? You might need to compile (and link) the appropriate sources for them. In particular, you'll want to make [`lib/error_functions.c`](http://man7.org/tlpi/code/online/dist/lib/error_functions.c.html) from Chapter 3, at least. – Toby Speight Mar 01 '17 at 16:02

4 Answers4

2

For the undefined references, someone asked a very similar answer here How to compile examples in the book "The Linux Programming Interface" by Michael Kerrisk

Then, if that does not work, I would suggest to try again by downloading the source file as specified at the TLPI web site and you can look into the makefile for your script, which is in the fileio/ subfolder and the Makefile.inc file.

Community
  • 1
  • 1
anne75
  • 77
  • 3
2

I was having the exact same issues with undefined references to his error-handling functions, but if you're doing everything in your own directories my advice may not help. If you downloaded the compressed tarball from his website everything should work. As stated in the BUILDING.txt file it includes, all you have to do is run make from the tlpi-dist or tlpi-book directory, depending on which one you downloaded, and all programs will be compiled and ready to run (subject to some OS specific issues obviously). If you want to modify a program, just add the name you save it as to that directory's Makefile and run make again, and you should be good to go.

taras
  • 6,566
  • 10
  • 39
  • 50
1

I was having similar troubles on Ubuntu 16.04. and MacOSX. Running 'make' always gave errors containing:

No rule to make target `../libtlpi.a'

This has a simple solution for Ubuntu:

sudo apt-get install libcap-dev

then run 'make' in the root directory.

Clarence
  • 11
  • 1
  • I was able to make a few programs with your answer. however to do make in the root dir, i needed ` apt-get install libacl1-dev` – marinara Jun 20 '20 at 13:59
0

You would require to ../lib/error_functions.o file along with your compilation.

gcc -I booklib -o copy copy.c ../lib/error_functions.o

The error functions are defined and declared in lib/error_functions.c lib/error_function.h Make sure you run make from tlpi-dist by which you would have error_functions.o