codbcclangunixodbcmacos-high-sierra

Why doesn't clang find the symbols for unixodbc functions?


I'm trying to use unixodbc in my C program, and I've included the sql.h header file that's needed to use the odbc functions. For some reason, though, when trying to compile a simple example file I get the following output:

➜  practica2 gcc sale.c
Undefined symbols for architecture x86_64:
  "_SQLAllocHandle", referenced from:
      _main in sale-179b46.o
  "_SQLDescribeCol", referenced from:
      _main in sale-179b46.o
  "_SQLExecDirect", referenced from:
      _main in sale-179b46.o
  "_SQLFetch", referenced from:
      _main in sale-179b46.o
  "_SQLGetData", referenced from:
      _main in sale-179b46.o
  "_SQLNumResultCols", referenced from:
      _main in sale-179b46.o
  "_odbc_connect", referenced from:
      _main in sale-179b46.o
  "_odbc_disconnect", referenced from:
      _main in sale-179b46.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Those are supposed to be the functions that odbc provides, so I don't know why they're not found. I installed unixodbc using Homebrew, and I'm running OSX 10.13.1


Solution

  • Transferring a comment into an answer.

    Your command line doesn’t mention that you need the library, so the compiler doesn’t link with it. It finds the header, so probably all you need is -lodbc after the object (or source) file on the command line. Headers inform the compiler. They are not relevant to the linker, and it is the linker that’s complaining.

    Hence, in your example, you should be able to compile and link with:

    gcc -o sale sale.c -lodbc
    

    And, for the benefit of those not familiar with Macs, given that you're on a Mac, your gcc sale.c command line really does use clang rather than a genuine GNU gcc/usr/bin/gcc is really a reference to the clang compiler.

    $ /usr/bin/gcc --version
    Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
    Apple LLVM version 9.0.0 (clang-900.0.38)
    Target: x86_64-apple-darwin17.2.0
    Thread model: posix
    InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
    $
    

    If you had found that it was necessary to specify where the header was using an option such as -I/opt/unixodbc/include, then you would also have needed to specify where the library was using an option such as -L/opt/unixodbc/lib.

    gcc -o sale -I/opt/unixodbc/include sale.c -L/opt/unixodbc/lib -lodbc
    

    On Unix-like systems (Linux, BSD, macOS, AIX, HP-UX, Solaris, …), the 'base location' (/opt/unixodbc in this example) is very variable, but it is common to install the headers in the include directory under the base location and the libraries in the lib directory under the base location. There are tools such as pkg-config that are sometimes used to help you collect the requisite flags for different sets of libraries that your project needs.