development – openSUSE Lizards https://lizards.opensuse.org Blogs and Ramblings of the openSUSE Members Fri, 06 Mar 2020 11:29:40 +0000 en-US hourly 1 openSUSE and GCC part 3: RPM devel packages https://lizards.opensuse.org/2013/10/22/opensuse-and-gcc-part-3/ https://lizards.opensuse.org/2013/10/22/opensuse-and-gcc-part-3/#comments Tue, 22 Oct 2013 06:11:31 +0000 http://lizards.opensuse.org/?p=10057 In last blog I explained how to compile application with Gnu C Compiler as knows as ‘gcc‘. In blog I try to explain what are RPM devel packages and how to use them in C-application with ‘gcc‘.

RPM Package Manager

RPM started as Redhat Package Manager but now it seems to get along with nesting acronym RPM Package Manager (Like GNU is acronym from GNU’s Not Unix) so it doesn’t mean anything special. There is neat how to install RPM in openSUSE-guide and complete Wikipedia article about RPM.

RPM Packages what are they

One can think RPM packages are just like Zip archives or tar-balls with binaries inside them so if you install rpm package it just knows where to copy application information to get this particular application running. Source RPM packages contains ways to build particular application to binary form so end user can make use of it. So simple is that. If it’s not you can read more from openSUSE wiki.
RPM packages are named after format ‘project_name-version-build-arch‘ they can be more difficult when we are dealing with C-libraries example GUI library GTK3 is named after scheme ‘liblibname-libversion-apiversion-version-build‘. Most of the libraries tends to follow that naming scheme.

It just get fuzzier

There is possibility to RPM have subpackages like ‘project_name-subname-version-build-arch‘. There is three should know subpackages that are commonly available (most cases not)

  • docs – contains doumentation
  • lang – contains localization
  • devel – hmm.. this one is little bit trickier

RPM devel packages

Devel package contains files needed develop your/new application with library. If we use

rpm -ql libSDL_image-devel

we see as output what pacakge ‘libSDL_image-devel’ really contains

/usr/include/SDL
/usr/include/SDL/SDL_image.h
/usr/lib64/libSDL_image.so
/usr/lib64/pkgconfig/SDL_image.pc

what are all these files? There is one C-header file at least ‘/usr/include/SDL/SDL_image.h‘. Then there seems to be ‘/usr/lib64/libSDL_image.so‘ symlink to C-library and ‘/usr/lib64/pkgconfig/SDL_image.pc‘ which I’ll get back in future blogs (since it make ones life easier). but what is ‘/usr/lib64/libSDL_image.so’ file? Like said it’s symbolic link to C-library. you can check where it locates with (I assume you are using AMD64/x86_64 openSUSE if you are using something else like i586 use ‘/usr/lib‘ instead of ‘/usr/lib64

readlink /usr/lib64/libSDL_image.so

in my case it prints ‘libSDL_image-1.2.so.0.8.4‘.

Shared objects

Microsoft Windows operating system have DLL and Apple Mac OS X have dylib. In linux world they are Shared Objects (.so files). Shared Objects contains all the library functions in binary format. So you can link your applications with it (If you have headers).
GCC Linker (ld) seeks only for ‘.so‘ ending file but in these days most of the Shared Objects follow scheme with number file-ending which is ‘so.API.MINOR.PATCH’. Every API numbering (greater that 0) should be compatible with each other. If new functions are in place older stays API/ABI compatible. It should be like that so ‘so.1.0.0‘ is normally first stable. version ‘so.1.0.1‘ there is bug fixed and ‘so.1.1.0‘ there is new functions declared. It can be like that or project has adapted it’s own system.

How to use these files

I wondered what would be easy enough example with this? I Thought NCurses would do just fine. So copy text from Paul Griffiths Ncurses Hello World example or below to file ‘ncurseshelloworld.c‘:

/*

  CURHELL2.C
  ==========
  (c) Copyright Paul Griffiths 1999
  Email: mail@paulgriffiths.net

  "Hello, world!", ncurses style (now in colour!)

*/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>                  /*  for sleep()  */
#include <curses.h>

int main(void) {

    WINDOW * mainwin;

    /*  Initialize ncurses  */

    if ( (mainwin = initscr()) == NULL ) {
	fprintf(stderr, "Error initialising ncurses.\n");
	exit(EXIT_FAILURE);
    }

    start_color();                    /*  Initialize colours  */

    /*  Print message  */

    mvaddstr(6, 32, " Hello, world! ");

    /*  Make sure we are able to do what we want. If
	has_colors() returns FALSE, we cannot use colours.
	COLOR_PAIRS is the maximum number of colour pairs
	we can use. We use 13 in this program, so we check
	to make sure we have enough available.               */

    if ( has_colors() && COLOR_PAIRS >= 13 ) {

	int n = 1;

	/*  Initialize a bunch of colour pairs, where:

	        init_pair(pair number, foreground, background);

	    specifies the pair.                                  */

	init_pair(1,  COLOR_RED,     COLOR_BLACK);
	init_pair(2,  COLOR_GREEN,   COLOR_BLACK);
	init_pair(3,  COLOR_YELLOW,  COLOR_BLACK);
	init_pair(4,  COLOR_BLUE,    COLOR_BLACK);
	init_pair(5,  COLOR_MAGENTA, COLOR_BLACK);
	init_pair(6,  COLOR_CYAN,    COLOR_BLACK);
	init_pair(7,  COLOR_BLUE,    COLOR_WHITE);
	init_pair(8,  COLOR_WHITE,   COLOR_RED);
	init_pair(9,  COLOR_BLACK,   COLOR_GREEN);
	init_pair(10, COLOR_BLUE,    COLOR_YELLOW);
	init_pair(11, COLOR_WHITE,   COLOR_BLUE);
	init_pair(12, COLOR_WHITE,   COLOR_MAGENTA);
	init_pair(13, COLOR_BLACK,   COLOR_CYAN);

	/*  Use them to print of bunch of "Hello, world!"s  */

	while ( n <= 13 ) {
	    color_set(n, NULL);
	    mvaddstr(6 + n, 32, " Hello, world! ");
	    n++;
	}
    }

    /*  Refresh the screen and sleep for a
	while to get the full screen effect  */

    refresh();
    sleep(3);

    /*  Clean up after ourselves  */

    delwin(mainwin);
    endwin();
    refresh();

    return EXIT_SUCCESS;
}

if you just try to compile it with

gcc -o ncurseshelloworld ncurseshelloworld.c
/tmp/cc7CD9vN.o: In function `main':
ncurseshelloworld.c:(.text+0x9): undefined reference to `initscr'
ncurseshelloworld.c:(.text+0x41): undefined reference to `start_color'
ncurseshelloworld.c:(.text+0x48): undefined reference to `stdscr'
ncurseshelloworld.c:(.text+0x5a): undefined reference to `wmove'
ncurseshelloworld.c:(.text+0x66): undefined reference to `stdscr'
ncurseshelloworld.c:(.text+0x78): undefined reference to `waddnstr'
ncurseshelloworld.c:(.text+0x7d): undefined reference to `has_colors'
ncurseshelloworld.c:(.text+0x8b): undefined reference to `COLOR_PAIRS'
ncurseshelloworld.c:(.text+0xaf): undefined reference to `init_pair'
ncurseshelloworld.c:(.text+0xc3): undefined reference to `init_pair'
ncurseshelloworld.c:(.text+0xd7): undefined reference to `init_pair'
ncurseshelloworld.c:(.text+0xeb): undefined reference to `init_pair'
ncurseshelloworld.c:(.text+0xff): undefined reference to `init_pair'
/tmp/cc7CD9vN.o:ncurseshelloworld.c:(.text+0x113): more undefined references to `init_pair' follow
/tmp/cc7CD9vN.o: In function `main':
ncurseshelloworld.c:(.text+0x1ae): undefined reference to `stdscr'
ncurseshelloworld.c:(.text+0x1bd): undefined reference to `wcolor_set'
ncurseshelloworld.c:(.text+0x1ca): undefined reference to `stdscr'
ncurseshelloworld.c:(.text+0x1d9): undefined reference to `wmove'
ncurseshelloworld.c:(.text+0x1e5): undefined reference to `stdscr'
ncurseshelloworld.c:(.text+0x1f7): undefined reference to `waddnstr'
ncurseshelloworld.c:(.text+0x208): undefined reference to `stdscr'
ncurseshelloworld.c:(.text+0x210): undefined reference to `wrefresh'
ncurseshelloworld.c:(.text+0x226): undefined reference to `delwin'
ncurseshelloworld.c:(.text+0x22b): undefined reference to `endwin'
ncurseshelloworld.c:(.text+0x232): undefined reference to `stdscr'
ncurseshelloworld.c:(.text+0x23a): undefined reference to `wrefresh'
collect2: error: ld returned 1 exit status

so what to do? Probably you already have ncurses Development package installed like me but if not first install ncurses devel rpm to you system

zypper install ncurses-devel

then we little bit make our gcc line different:

gcc -o ncurseshelloworld ncurseshelloworld.c -lncurses
./ncurseshelloworld

which ‘-l’ tells you how to use ncurses library when seeking dependencies, After that you see many colors. So that was that and next time we go little bit into SDL_image 1.2 world and learn how to use pkg-config so we know what libraries are needed.

]]>
https://lizards.opensuse.org/2013/10/22/opensuse-and-gcc-part-3/feed/ 3