I'm using IUP on Manjaro GNU/Linux, and I'm trying to compile the first sample program from this site. However, the compiler says that it cannot locate iup.h
. I installed IUP using yaourt, installing the package named iup-all-bin
.
What should I change my #include
directive for iup.h
to?
Edit: Thanks to one of the comments, I was able to find the header and library files (I think!), but now, I get this error from GCC instead:
$gcc hello0.c -I/usr/include/iup-3.7/ -L/usr/lib -o hello0
/tmp/ccMAbPwz.o: In function `main':
hello0.c:(.text+0x1e): undefined reference to `IupOpen'
hello0.c:(.text+0x28): undefined reference to `IupLabel'
hello0.c:(.text+0x30): undefined reference to `IupDialog'
hello0.c:(.text+0x38): undefined reference to `IupShow'
hello0.c:(.text+0x3d): undefined reference to `IupMainLoop'
hello0.c:(.text+0x42): undefined reference to `IupClose'
collect2: error: ld returned 1 exit status
I know that libiup.so
(along with all the non-Lua libraries) are in /usr/lib
, and that the header file is in /usr/include/iup-3.7
As you may or may not know, there are two steps necessary to get from source code to an executable: compiling and linking. (Each of those steps themselves have steps, but they are irrelevant to the discussion.)
When you include a file with #include
:
#include <iup.h>
#include <stdlib.h>
/* ... */
iup.h
and stdlib.h
do not appear out of thin air. They are real file names, and the compiler needs to know where to find them so it can dutifully include and process them. stdlib.h
is in some directory (usually /usr/include
) that the compiler will look in by default, but when you install nonstandard libraries, you might need to tell the compiler where else it can look for include files it can’t find it elsewhere. That’s where the -I
flag comes in. If iup.h
exists in /usr/include/iup-3.7
, you can tack on -I/usr/include/iup-3.7
and the compiler will look there after it can’t find iup.h
in /usr/include
. As a hat trick, you might find it interesting that since /usr/include/iup-3.7
is a subdirectory of /usr/include
, you can just change the #include
directive if you wanted to:
#include <iup-3.7/iup.h>
But this can be brittle if it’s not always in an iup-3.7
subdirectory.
Now your compiler has finished compiling the C file into an object file, which contains all of your logic in machine code, but with unresolved references to functions like IupOpen
, so it can’t be run quite yet. In order to be able to run it, you have to link the object files of your program together, hoping that functions defined in other files satisfy the references from your file.
By default, gcc
will link in the C standard library, giving you access to functions like printf
and exit
. But when you are referencing functions from an external library, you have to tell it you want to link that into your program and resolve those references. You can do this using -l
.
Lastly, I should note that -l
, too, uses a search path. Like -I
, which adds to the include path, -L
adds to the library search path. If you have your libraries located somewhere nonstandard, you’ll have to include a -L
flag to tell the linker where to find the library in addition to the -l
flag to tell the linker that you want to reference a particular library.