I’m running OpenSuSE 13.1 on x86_64 hardware. I’m trying to compile the examples from TLDP howto for ncurses with gcc4.8.1, and it has worked fine up until the examples for the extensions for panels,menus and forms.
At first when I compiled with
$gcc -o ../obj/example14 example14.c
I got an error saying that panel.h is not found:
example14.c:1:19: fatal error: panel.h: No such file or directory
#include <panel.h>
^
compilation terminated.
/tmp/ccOJDxnY.o: In function `main':
example14.c:(.text+0x25): undefined reference to `initscr'
example14.c:(.text+0x2a): undefined reference to `cbreak'
example14.c:(.text+0x2f): undefined reference to `noecho'
example14.c:(.text+0x42): undefined reference to `newwin'
example14.c:(.text+0x5f): undefined reference to `newwin'
example14.c:(.text+0x7c): undefined reference to `newwin'
example14.c:(.text+0xd0): undefined reference to `wborder'
example14.c:(.text+0xe6): undefined reference to `new_panel'
example14.c:(.text+0xf6): undefined reference to `new_panel'
example14.c:(.text+0x106): undefined reference to `new_panel'
example14.c:(.text+0x10f): undefined reference to `update_panels'
example14.c:(.text+0x114): undefined reference to `doupdate'
example14.c:(.text+0x11b): undefined reference to `stdscr'
example14.c:(.text+0x123): undefined reference to `wgetch'
example14.c:(.text+0x128): undefined reference to `endwin'
collect2: error: ld returned 1 exit status
Looking in /usr/lib64, I see the following libraries:
That’s wrong syntax.
“-l” specifies a library to link to, so -l/usr/lib64 is just plain nonsense. You can specify the linker search path with “-L” instead, but it isn’t necessary in this case as /usr/lib64 is of course is the standard search path.
And “-l/usr/lib64/ncurses6” is wrong as well. You should only specify the library name, not the directory. It is automatically searched in the linker search path.
So “-lncurses6” should work.
See also “man ld”.
A note though: you should probably use “-lncurses5”, as /usr/include/ncurses/ contains the includes for ncurses5.
The ncurses6 includes are in /usr/include/ncurses6/.
And another hint:
You can use “ncursesX-config” to get the necessary compiler/linker switches.
E.g.:
Building repository ‘openSUSE BuildService - Mozilla’ cache …[done]
Loading repository data…
Reading installed packages…
‘ncurses6-devel’ not found in package names. Trying capabilities.
No provider of ‘ncurses6-devel’ found.
Resolving package dependencies…
How can that be? The ncurses-devel for 5.9 provides ncurses6 parts? But it looks like all of the ncurses pieces I need are installed.](http://tinyurl.com/openSUSE-T-C)*
Okay. Reading the gcc User Guide, I had trouble understanding whether a directory or a file is intended. Sorry 'bout that.
And “-l/usr/lib64/ncurses6” is wrong as well. You should only specify the library name, not the directory. It is automatically searched in the linker search path.
Again, I did not find that clearly stated in the gcc User Guide.
So “-lncurses6” should work.
That sounds reasonable. But,
$**gcc -lncurses6 -Incurses -Ipanel -o ../obj/example14 example14.c**
example14.c:1:19: fatal error: panel.h: No such file or directory
#include <panel.h>
^
compilation terminated.
it doesn’t work.
See also “man ld”.
A note though: you should probably use “-lncurses5”, as /usr/include/ncurses/ contains the includes for ncurses5.
The ncurses6 includes are in /usr/include/ncurses6/.
And another hint:
You can use “ncursesX-config” to get the necessary compiler/linker switches.
E.g.:
If you want to compile/link against ncurses6, you should use “ncurses6-config” instead obviously.
That sounds helpful. For my development efforts, I prefer to use ncurses6 over ncurses5. ncurses5 is installed because it is a prerequisite of other packages.
And, here's what comes back from your suggestions:
$**gcc `ncurses6-config --cflags --libs` -o ../obj/example14 example14.c**
/tmp/ccvCibsb.o: In function `main':
example14.c:(.text+0xe6): undefined reference to `new_panel'
example14.c:(.text+0xf6): undefined reference to `new_panel'
example14.c:(.text+0x106): undefined reference to `new_panel'
example14.c:(.text+0x10f): undefined reference to `update_panels'
collect2: error: ld returned 1 exit status
$**gcc `ncurses5-config --cflags --libs` -o ../obj/example14 example14.c**
/tmp/cc6ln4IE.o: In function `main':
example14.c:(.text+0xe6): undefined reference to `new_panel'
example14.c:(.text+0xf6): undefined reference to `new_panel'
example14.c:(.text+0x106): undefined reference to `new_panel'
example14.c:(.text+0x10f): undefined reference to `update_panels'
collect2: error: ld returned 1 exit status
So there’s still something else out of whack here besides my confusion with gcc options. See my response to hendersj earlier in the thread for installed package info as well.
Well, of course not.
You now specified the include path wrongly, so the include files are not found.
Run “ncurses5-config --cflags” or “ncurses6-config --cflags” as I told you to see the correct flags for compiling, and notice the difference:
How should the compiler know where to find the ncurses includes when you specify “-Incurses”? They are not in a folder called “ncurses” in the current directory.
And “-Ipanel” doesn’t make sense at all. You rather wanted “-lpanel” there I suppose.
Again:
‘-I’ adds a directory to the path where include files are searched
‘-L’ adds a directory to the path where linker libraries are searched
‘-l’ links against a specific linker library
That’s not the problem here.
“ncurses-config” doesn’t specify the libpanel that’s used/needed in this particular case/example.
So for compiling/linking against ncurses6, those should work:
Yes, all three work (after adding a space after ‘gcc’ on the last one). The last two merely have the options in different order, correct?
Again:
‘-I’ adds a directory to the path where include files are searched
‘-L’ adds a directory to the path where linker libraries are searched
‘-l’ links against a specific linker library
makes everything much clearer.
The issue of placing some flags after the program they refer to is still a bit confusing. They would go after the reference to the source file? Or the reference to the object file?
Yes.
And sorry about the missing space. It somehow got lost during copy/paste… :shame:
The issue of placing some flags after the program they refer to is still a bit confusing. They would go after the reference to the source file? Or the reference to the object file?
Which flags do you mean now?
The order of the flags should not really matter. You could specify all before the “program they refer to”/the source file or after, or interspersed in any way. They are global for that gcc invokation.
But it does matter in which order you specify object files (e.g. xxx.o) for linking.
In short: if x.o uses a symbol from y.o, you have to specify x.o before y.o.