c++linuxopenglg++devil

g++ with DevIL: unable to link


Firstly, I am using Fedora and learning OpenGL. I would like to work with DevIL a little, so I installed both DevIL and DevIL-ILUT packages from the official repository. I have a test code for loading and rendering a file available, so I decided to test it (I will be learning some DevIL basics at my course, and we were given that file to make sure DevIL works fine for us).

The file contains line:

#include "IL/devil_cpp_wrapper.hpp"

so I copied the IL directory (which we also have available) to the directory with test file (IL directory contains a lot of header files, for example il.h, ilut.h, ilu.h, ...). However, the build failed at

#include <IL/ilut.h>

from the IL/devil_cpp_wrapper.hpp file. I don't get it, since I installed the packages. I tried putting every possible parameter to g++ (since I didn't find any useful manual for it, maybe I am just blind), -lIL, -lILU, -lILUT, -ldevil, for every possibility it gives me the same error. I wasn't able to find any proper solution, so I gave up and copied the IL directory also to /usr/include. This time it gave me this error for every library included:

/usr/bin/ld: cannot find <param>

So I deleted the directory, and tried replacing all system includes like the one in devil_cpp_wrapper.hpp by ones in the directory (since the files are called the same). The linker had the same issue, so I removed all library params and tried compiling it again, this time failing on "undefined reference" for DevIL-specific functions.

We have available also some files for dll (DevIL.dll, ILU.dll, ILUT.dll) and .lib to them, I tried linking also them, but still get the same undefined reference errors. Also, this course is made mainly for VS users, so I am not sure which files I should include.

I also tried building DevIL from their github source as is written in their README.unix file, but failed on the first step (autoreconf -i was failing for some libILUT.la; I tried also autoconf -i in case they have written it wrong, it failed for undefined win32 macro).

So, my question is: I am a noob who can't link DevIL. I tried everything I could think of, but can't find any solution. Can anyone help me?

EDIT: Since the build from github was failing, I decided to give it a chance and download their .tar and tried to compile from it. It seemed to be working at first, but then make returned "undefined reference to `png_set_gray_1_2_4_to_8'" and "collect2: error: ld returned 1 exit status". Even after this I tried to complete the build with make install, which of course failed too, but in this attempt I got a few libraries into /usr/local/lib. However, I still can't compile my test program, because the mentioned undefined reference to png_set_gray_1_2_4_to_8, which the linker complains about now.


Solution

  • There are plenty of options for using libraries on Linux. It's usually fairly easy, but you seem to have stumbled on some of the common gotchas.

    Rule #1: Don't touch /usr or /usr/local yourself.

    The /usr directory is for packages installed by the system (e.g. apt-get on Debian, Ubuntu, or Mint), so you should almost never touch it at all.

    The /usr/local directory is for packages that you install (assuming that you are the administrator of the machine), but you don't manually copy files there. Instead, you run installation scripts that put files there automatically.

    Typically, you install like this:

    ./configure
    make
    sudo make install
    

    Rule #2: Use the package manager first.

    The package manager depends on which Linux distro you are using. For example, on Debian-based systems, the package system is "apt", and you can use synaptic, aptitude, or apt-get to install packages.

    On my system, I would run the command:

    sudo apt-get install libdevil-dev
    

    The -dev means "development", so it includes the headers you need to compile programs that use DevIL.

    Rule #3: If you compile from source, get a proper release before you look at GitHub.

    Proper releases will have configure scripts. Because you downloaded from GitHub, you had to invoke autoconf, which just means installing more packages on your system. Don't bother, just grab a proper source code release.

    Rule #4: Always use a build system.

    You haven't mentioned how you're compiling things, so it makes me worried that you might just be typing gcc on the command line. This is a recipe for frustration.

    Here is a makefile that you can use to compile a simple C++ program that uses DevIL, assuming your program is all in main.cpp:

    all: myprog
    clean:
        rm -f myprog *.o
    
    devil_cflags := $(shell pkg-config --cflags IL)
    devil_libs := $(shell pkg-config --libs IL)
    
    CXXFLAGS := -O0 -g -Wall -Wextra $(devil_cflags)
    LIBS := $(devil_libs)
    
    myprog: main.o
        c++ $(LDFLAGS) -o $@ $^ $(LIBS)
    

    This uses pkg-config to figure out how to link with DevIL. It's much better than writing the linker flags yourself.

    Note that the indentation in a Makefile must be done with tabs, you can't use spaces.