C-Language – 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 10: Distributing to other distributions than openSUSE with OBS https://lizards.opensuse.org/2014/01/07/opensuse-and-gcc-part-10/ Tue, 07 Jan 2014 08:15:54 +0000 http://lizards.opensuse.org/?p=10387 Last time I talked about OBS and how to compile your application that you have developed with GCC. OBS is much more than just a tool for compiling openSUSE additional packages. You can also compile Debian, Ubuntu, Arch and Fedora (and couple more) but why on earth you want to do that? Short answer: because you can! Little bit longer answer: because you can and freedom is two way road. You can’t guess what Linux distribution or OS your user wants to use but you can make sure that you application is first class citizen in that Linux distribution. Of course You can use Fedora build service or Ubuntu launchpad but they are just for that distribution only. If it’s fine with you. Be happy and use these marvelous services. If you have woken up in night all sweat. Thinking all these openSUSE lizards that are unhappy because they can’t use your fabulous application.. it’s time to start sleeping well.

Fedora distribution or RHEL

RPM based Linux distributions are very easy with OBS. You just have to make SPEC file generic. If you like to do it right you should read openSUSE:Build Service cross distribution howto and learn how to do it.

OBS and DEB based distributions

This is little bit trickier but not much. You needed decent DSC-file (Most dsc files goes without changes. If you like to use Bzip2 file then you need to add ‘DEBTRANSFORM-TAR’ in dsc-file) file and then you need ‘debian.tar.gz’ in your project or ‘debian/’-dir in your project. What are files that you need in you debian package/dir? That is a very good question and it stays unanswered here because it’s not point of this blog. If you are curious enough you can always download ‘debian.tar.gz’ from example application and study files or look Debian documentation about it.

Arch

Arch is most unknown distribution for me but it has vibrant community and active development so providing packages to them is good thing. They seems to like live bleeding edge. So Just add Arch distribution in your project in OBS and then fill PKGBUILD-file with necessary lines and like magic you have Arch supported (Look at example PKGBUILD-file if you don’t understand a thing).

This was it! No more articles about GCC or around it. Next I’ve going to dive low level Linux Multimedia especially in audio and FFmpeg (and how you do them in openSUSE). if you haven’t read rest of articles and you feel you missed something. Go on a read them and if you missed good OSC-blog you can read it too.

]]>
openSUSE and GCC part 8: RPMs and how to write them https://lizards.opensuse.org/2013/12/03/opensuse-and-gcc-part-8-rpms-and-how-to-write-them/ Tue, 03 Dec 2013 09:30:00 +0000 http://lizards.opensuse.org/?p=10208 It seems this it’s already 8 of this 10 part series of using GCC with openSUSE. This time topic is: RPM. RPM started as Redhat Package Manager and then it involved to RPM package manager (self explaining acronym like GNU). RPM packages are just files containing all the needed stuff to install application, font or something else in to openSUSE system.
RPM is currently wide adopted in Linux distributions openSUSE, embedded Yocto, Fedora and Madriva for name few. Although Yocto can use Debian packages also as base. I have been using an example program to show how to develop very easy application with openSUSE and GCC. Currently it uses Autotools tools. Take my advise your application is not worth of anything if you can’t delivery it to users. Most of the applications (especially closed source) under Linux are distributed as tar-ball format. RPM is not about having Windows style setup it’s about knowing what is installed in you system.

RPM agnostics

There is actually two kinds of RPMs. Binary RPM and then there is Source RPM. Source RPM contains everything needed to compile this package again. Source rpm ending is ‘.src.rpm’ or ‘nosrc.rpm’. Binary RPM is architecture specific. So if you have ‘arm7v.rpm’ it wont run your x86_64 or x86 machine because it’s ARM7 binary code. There is also noarch.rpm that is architectural non specific.
In openSUSE traditionally if you build RPM it goes to ‘/usr/src/packages’ directory and there is sub directories

BUILD/ - Building is done here
SOURCES/ - Contains needed sources for building including patches
SRPMS/ - Where Source RPMS are placed after build
BUILDROOT/ - This is ROOT place where make install places installed files (because you don't want them to go real root dir) 
RPMS/ - All the RPMs are placed here (It contains i686, x86_64 and noarch subdirs where those arch files are placed)
SPECS/ - Where .spec files are placed

So if you build i686 RPM with your x86 openSUSE then it would go to ‘/usr/src/packages/RPMS/i686’ directory and Source RPM ‘/usr/src/packages/SRPMS’ directory.

Example

Now you should read Part 7 and part 6 of this series to have example application and autotools installed. then we install rpm-build

zypper install rpm-build

and make distribution tar-ball of sdl_displaybitmap with

make dist

there should be ‘sdl_displaybitmap-1.0.tar.bz2’ file now in same directory. then copy this SPEC file to file named ‘sdl_displaybitmap.spec’ in same directory you have ‘sdl_displaybitmap-1.0.tar.bz2’

Name:           sdl_displaybitmap
Version:        1.0
Release:        1%{?dist}
Summary:        Some SDL Sample

Group:          Amusements/Toys/Other
License:        SUSE-Public-Domain
URL:            http://content.gpwiki.org/index.php/SDL:Tutorials:Displaying_a_Bitmap
Source0:        sdl_displaybitmap-1.0.tar.bz2
BuildRoot:      %{_tmppath}/%{name}-%{version}-build

BuildRequires:  gcc
BuildRequires:  SDL_image-devel
BuildRequires:  libtool
BuildRequires:  automake
BuildRequires:  autoconf

%description
Small example how to use SDL to display bitmap

%prep
%setup -q

%build
%configure
make %{?_smp_mflags}

%install
rm -rf $RPM_BUILD_ROOT
# There is nothing to install so we do it with hand
#make install DESTDIR=$RPM_BUILD_ROOT

mkdir -p $RPM_BUILD_ROOT%{_bindir}
mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{name}
cp SDL_DisplayBitmap  $RPM_BUILD_ROOT%{_bindir}
chmod +x $RPM_BUILD_ROOT%{_bindir}/*
cp image.bmp $RPM_BUILD_ROOT%{_datadir}/%{name}

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root,-)
%doc LICENSE.TXT
%{_bindir}
%dir %{_datadir}/%{name}
%{_datadir}/%{name}/*


%changelog

and copy our tar-ball to ‘/usr/src/packages/SOURCES’. After that we build rpmbuild command to create RPM packages

rpmbuild -ba sdl_displaybitmap.spec

If everything goes right you should have this RPM in ‘/usr/src/packages/RPMS/YOURARCHHERE/sdl_displaybitmap-1.0-1.YOURARCHHERE.rpm’ and SRPM in ‘/usr/src/packages/SRPMS/sdl_displaybitmap-1.0-1.src.rpm’. You can check with less that what files it contains

less /usr/src/packages/RPMS/YOURARCHHERE/sdl_displaybitmap-1.0-1.YOURARCHHERE.rpm

OBS If you install this RPM it won’t work! Application only works if you go to folder ‘/usr/share/sdl_displaybitmap’ and run it there. Next time we patch our app to work from other places also.

What does this mean?

There is better documentation else where than I can write. For openSUSE conventions see Packaging in Wiki. If you curious read it from there and learn. Next time we make OBS (openSUSE Build Service) build from this RPM and last part is how we use OBS to create also Debian, Ubuntu and Fedora packages from our marvelous app.

]]>
openSUSE and GCC part 7: autotools and how I do it https://lizards.opensuse.org/2013/11/19/opensuse-and-gcc-part-7/ Tue, 19 Nov 2013 08:54:05 +0000 http://lizards.opensuse.org/?p=10147 Last time I was little bit too hard to autotools. Okay they are not easy but they work. I also let last time people to figure how to get a long with autotools. Now I show how I do it.

Let’s dance

First put some good music on and relax. Starting new project and trying to get it compile is very unpleasant experience. Then read blog about autotools and then also see example that I’ve been using. Now you should have files: ‘configure.ac’, ‘Makefile.am’, ‘SDL_DisplayBitmap.c’, ‘LICENSE.TXT’ and ‘image.bmp’ in same directory/folder also you should have rpm libSDL_image-devel installed. Then we zypper needed autotools in.

zypper install libtool automake autoconf

after that we need to make directory contain needed scripts and M4-macros. You don’t need to copy them manually just make like this in console:

aclocal --force
libtoolize -c
automake --copy --add-missing
autoconf --force

So we run ‘aclocal’ to copy those M4-macros after that we ‘libtoolize’ our directory and then ‘automake’ creates needed ‘Makefile.in’ files from ‘Makefile.am’. Last ‘autoconf’ creates configure-script from configure.ac. If everything went fine you ca continue:

./configure
make
./SDL_DisplayBitmap

Okay now it should work as expected. If you are interested you can try also

make dist

and you should have ‘SDL_DisplayBitmap-1.0.tar.gz’ and ‘SDL_DisplayBitmap-1.0.tar.bz2’ to distribute you application.

Let’s dig further

I’ll explain what these sentences mean in ‘configure.ac’:

AC_PREREQ([2.57])
AC_CONFIG_MACRO_DIR([m4])

Just tell what Autoconf is needed at least 2.57 and what is M4-macro directory (in this case it’s ‘m4’)

AC_INIT([SDL_DisplayBitmap], [1.0], [http://lizards.opensuse.org])

Let’s have application named SDL_DisplayBitmap which version is 1.0 and URL to see something more is http://lizards.opensuse.org

AM_INIT_AUTOMAKE([foreign dist-bzip2])

Initialize automake. We want ‘tar.bz2’ package also made.

AC_LANG_C
AC_PROG_CC
AM_PROG_LIBTOOL

Make sure we have C++ and C-compiler and Libtools.

C_OPTIONS="-ansi -Wall -Werror -std=c99 -fno-strict-aliasing"

I use these C-Flags in my applications. You should use yours.

AC_SUBST(C_OPTIONS)

Make them available in Makefile.in/.am

PKG_CHECK_MODULES(SDL, SDL_image)

Check SDL_image from pkg-config and store it in SDL-prefix (SDL_LIBS and SDL_CFLAGS) variable.

AC_OUTPUT([Makefile])

Configure these files from configure here. In our case only use formulate Makefile.in file.

Makefile.am

Now it’s time to listen Scorpions Still loving you if don’t already listening it.

INCLUDES = $(SDL_CFLAGS) $(C_OPTIONS)

This actually old school way of doing it but it compatible downwards. We but our C_OPTIONS from configure.ac and SDL needed build flags in build.

EXTRA_DIST = LICENSE.TXT image.bmp

We also pack these files in distribution tar-ball.

noinst_PROGRAMS = SDL_DisplayBitmap

This tell we want to have binary named: ‘SDL_DisplayBitmap’ that ain’t installed anywhere. If you but bin_PROGRAMS application will be installed to ‘/usr/local/bin’ or ‘prefix/bin’ you mentioned in ‘./configure –prefix=/prefix’ (sbin_PROGRAMS will install it to ‘/usr/local/sbin’).

SDL_DisplayBitmap_SOURCES = SDL_DisplayBitmap.c
SDL_DisplayBitmap_LDFLAGS = $(SDL_LIBS)

Actually tell what sources belongs to SDL_DisplayBitmap and what libs are need to build this.

Yes that was so easy and nice. Next time is time to make RPM from our example application.

]]>
openSUSE and GCC part 6: Introduction to autotools https://lizards.opensuse.org/2013/11/12/opensuse-and-gcc-part-6/ https://lizards.opensuse.org/2013/11/12/opensuse-and-gcc-part-6/#comments Tue, 12 Nov 2013 06:47:56 +0000 http://lizards.opensuse.org/?p=10114 Autotools, autotools and once again autotools. Years ago I started with autotools I thought, ‘Hey someone has really get into linking and compiling’. I was sold for a while and tried to learn it inside out. Then I understood that I will never be good at autotools (So I started to go to gym instead). M4 macro language it is not my thing.
It’s just something that should be put on one way Mars shuttle and send to gray ones to figure out. I think mr. Spock’s brains functioned with M4 but mine won’t. If there is some M4 specialist. Send me e-mail or post comment about it and tell why M4 is best macro language on earth. If nobody stands up for poor M4-macro language I’ll keep unloving it. I can start liking it because I was so wrong with Rexx.

Autotools

Autotools are designed to work with GNU GCC (GNU Compiler Collection) and visa versa. You can use Autotools with any C-compiler or with any language but it works best when compiling GNU C or C++ applications. Autotools are actually four tools aclocal, libtool, autoconf and automake.

GNU aclocal

It’s easier to tell what aclocal is not than what it is. Aclocal checks your needed M4 macros and copies or symlinks them to your project. I hope you never need to tackle with this or write your own M4 macro for find you great library (use pkg-config I say it once more use pkg-config) or new something that other M4 macros sucks to do. I don’t have anything else to say about this.

GNU libtool

If you like to make Share Objects (.so), Windows DLL or something your operating system supports libtool is your friend. You’ll need this anyways wanted or not.

GNU autoconf

This one is also strange tool. I compiles from M4 macros an ‘configure’-named bash script. So you have ‘configure.ac’ M4 based script that is formulated to ‘configure’-named bash script and autoconf does that.

GNU automake

Last time we talked about Makefiles and how to use them with compiling. Autotools is make based. You can probably use other build tools but I never have seen them in use. Automake seeks for ‘Makefile.am’ files and turns macros and stuff inside them to ‘Makefile.in’ that is usable with ‘configure’-script from autoconf. Actually its not that simple but with this you can live you life happilly ever after.
Because everyone wants to know everything these days read more here.

And this was complicated you moron!

Yes I can admit it! I’m not very clever guy. When I was young I though hell there ain’t nobody that I better than me. Now I can admin there is and I’m just a ordinary guy from Finland. So you think you are more clever than me okay let’s test it. I’ll just throw you a bone and you tackle with by yourself and search machine (I won’t use that G-word there is so many other ones also). Example is the same that have been use in other posts and all the needed info is here so you should be able to figure this out by yourself and ask from mr. NSA the rest. Here are configure.ac and Makefile.am but how to utilize them? Good question.. hmm.. use zypper to install automake.. maybe.. maybe?

configure.ac

AC_PREREQ([2.57])
AC_CONFIG_MACRO_DIR([m4])
AC_INIT([SDL_DisplayBitmap], [1.0], [http://lizards.opensuse.org])
AM_INIT_AUTOMAKE([foreign dist-bzip2])

EXTRA_DIST = LICENSE.TXT image.bmp

AC_LANG_C
AC_PROG_CC
AM_PROG_LIBTOOL

C_OPTIONS="-ansi -Wall -Werror -std=c99 -fno-strict-aliasing"

AC_SUBST(C_OPTIONS)

PKG_CHECK_MODULES(SDL, SDL_image)

AC_OUTPUT([Makefile])

Makefile.am

INCLUDES = $(SDL_CFLAGS) $(C_OPTIONS)

EXTRA_DIST = LICENSE.TXT image.bmp

noinst_PROGRAMS = SDL_DisplayBitmap

SDL_DisplayBitmap_SOURCES = SDL_DisplayBitmap.c
SDL_DisplayBitmap_LDFLAGS = $(SDL_LIBS)

Now you have everything and go for the bad thing. Next time I’ll tell how I do it..

]]>
https://lizards.opensuse.org/2013/11/12/opensuse-and-gcc-part-6/feed/ 2
openSUSE and GCC part 5: Make love me do https://lizards.opensuse.org/2013/11/05/opensuse-and-gcc-part-5/ Tue, 05 Nov 2013 07:03:08 +0000 http://lizards.opensuse.org/?p=10095 In this point of time if you haven’t any idea what is pkg-config or GCC you should be reading this. Or if you still do please make sure you read about them from these blog posts. ‘Make‘ as a tool doesn’t do anything easier it just hides not-so-easy-part from eyes of public. ‘Make’-tool executes (in default) Makefile-script that should tell how to build your applications step by step. There is no guaranties that it’s easier to understand how it’s build or you to understand that after a while.

What should I make then?

As ‘make’ spreads wide area of operating system it’s not very new tool. You can use make in AIX, HP/UX, BSD variants, Linux, Windows or Solaris. Most of them they got their own make tool that got it’s own dialect. If you are not using AIX, HP-UX, Solaris or pure nmake from Visual Studio I recommend to learn GNU Make dialect. With that you can easily adapt those others. One can pretend that ‘make’ is nearly programming language for building application.
Mostly because ‘make’ ain’t cleanest way building applications there is also other tools as well: Python Scons, Apache Ant and CMake for example. They all are as powerful as ‘make’ if compare them as building tools. You got to remeber Ant is mostly for Java applications but you can use it for anything if you are willing and SCons is general building tool. One can argue all the day and night which of them is the best. One thing is correct ‘make’ is not the cleanest but is factory standard.

First forget everything

First thing I like to say about make is forget everything you have learned in your life. There is only one way on doing things in ‘make’ and it’s only open for those who are true believers. Now forget those two sentences and you are in correct state of taking example building script as it is. This particular builds last blogs ‘SDL_image’ example program. First we install make

zypper install make

then make script. Save this in sample directory/Folder as ‘SDL_DisplayBitmap.c’ named ‘Makefile’ (In this case capitals are needed). If you use pico/nano make sure intend tabs are tabs not spaces if they are converted make won’t work.

SRC := SDL_DisplayBitmap.c
CFLAGS = $(shell pkg-config --cflags SDL_image)
LIBS = $(shell pkg-config --libs SDL_image)

all: 
	@echo "Building with make is so fun"
	gcc -o SDL_DisplayBitmap $(SRC) $(CFLAGS) $(LIBS)

.PHONY: install clean

clean:
	rm -f SDL_DisplayBitmap

install:
	@echo "This just PHONY install target"

What does it mean?

Okay let’s go line by line

SRC := SDL_DisplayBitmap.c

Variable that contains ‘SDL_DisplayBitmap.c’. Why it got ‘:=’ and no ‘=’ that’s is up to you find out.

CFLAGS = $(shell pkg-config --cflags SDL_image)
LIBS = $(shell pkg-config --libs SDL_image)

This could be done in one variable but it’s easier to use in future if it’s divided in two. Tell to run ‘pkg-config’-tool and pass what ever is output to variable ‘CFLAGS’ or ‘LIBS’. So they now have correct building flags and libraries.

all: 
<TAB>@echo "Building with make is so fun"
<TAB>gcc -o SDL_DisplayBitmap $(SRC) $(CFLAGS) $(LIBS)

Okay this is the main thing of ‘all:’-target. Traditionally there is ‘all’-target in ‘Makefile’ to build applications from ground up.
Now be attended! Always use intending tabs before commands in ‘Makefile’ no spaces. Okay? If ‘make’-tool says you are using spaces to intend convert them to tabs. ‘@’-mark is just don’t show what we are doing only print what is outputted to stdout and after that we compile using SRC, CFLAGS and LIBS variables. If you are using variable in Makefile it have to be ‘$(VARIABLENAME)’ not ‘$VARIABLENAME’ or ‘VARIABLENAME’. You can also use lowercase names but again tradition and habits comes in a way.

.PHONY: install clean

clean:
<TAB>rm -f SDL_DisplayBitmap

install:
<TAB>@echo "This just PHONY install target"

Normally there is clean and install targets available in every ‘Makefile’. It’s more easier your life stuff than must. I recommend to create them! It will not lead you to hate or suffering. These targets are easy to explain ‘clean’-target should get you source tree in state that if was before building and ‘install’-target should install your binary/binaries. Ahh.. and then there is ‘.PHONY’ target is you really are interested read all about it from docs.

How to make application

Copy Makefile to folder/directory you have ‘SDL_DisplayBitmap.c’ and run

make

after that you should have binary ‘SDL_DisplayBitmap’. if you want to clean your source just run

make clean

This was just hands dirty example. Make is so much more and more complicated you ever can imagine. Next we jump into Autotools for couple of blogs as they use make as tools to build applications.

]]>
openSUSE and GCC part 4: Pkg-config and what one can do with it https://lizards.opensuse.org/2013/10/28/opensuse-and-gcc-part4/ Mon, 28 Oct 2013 16:37:38 +0000 http://lizards.opensuse.org/?p=10083 When I re-booted my blogging habits with very UN-sexy and technical topic ‘GNU C Compiler and how to make it with openSUSE’. I thought nobody bothers to read these because A) Everyone who reads openSUSE blogs are PRO B) everyone wants to do Javascript, Python or ‘Put your script language here not C. I can tell actually C ain’t that bad you just have to shoot yourself to leg and then learn how to walk again.
Last blog entry was about ‘openSUSE and GCC part 3: RPM devel packages‘ someone (thanks for pointing that out really!) noted that I should fix C-Code example I was stunned! There were someone that really readied blog entry. Okay he/she didn’t say did he/she like it but some one read it.
I have one real reason to this blog-stuff. I hope I have found something like this when I young and I was starting my journey in Linux land. Currently there is so many more people now in populating it and it’s coming up fast. So If you find errors or don’t understand something be welcome to ask or want to know about something specific let me know! Now we get on today’s topic that is ‘pkg-config and what one can do with it’.

Pkg-config makes things easy/complicated (choose one)

You can live you whole C developer life with Linux and GCC without ever toughing ‘pkg-config‘. pkg-config is just something that can make you life easier with C. It’s not easy to say in couple of words what it does but closest I can get it provides information how to compile application with specific C-library. In other words if you read blog before there were these bare ‘gcc’ library entries in command-line (-lname stuff).
With more complicated libaries: like GTK+ or SDL you can get yourself wondering what libraries shall I include and what not that I can get my application build. Every self respecting developer wants to keep library dependencies as low as possible. So if you don’t want to wonder anymore you can use ‘pkg-config’.

So what it really does?

Last time I promised SDL_image 1.2 example as it’s little bit more complicated to get build. Actually it’s not that complicated but it’s simple example library and you get nice GUI stuff. First we have to zypper or YaST pkg-config, unzip and SDL_image-devel packages so we can use and link against SDL_image.

zypper install pkg-config SDL_image-devel unzip

after you have managed to install it you can download this blog example application made by Ryan Clark from here: ‘SDL_DisplayBitmap.zip‘. It comes from nice SDL gaming wiki (This tutorial actually) and so if you are interested making games with SDL 1.2 or 2.0 you should pop there. You can download files and unzip it or you can crap same source below and save it as ‘SDL_DisplayBitmap.c’ if you do that remember to have some BMP-image in same directory where you compile named: ‘image.bmp‘. Real nerds goes with unzip. If you do it like me it goes like this.

unzip SDL_DisplayBitmap.zip
cd SDL_DisplayBitmap

Or code for copying

// THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION
// AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN.
//
// THE ORIGINAL AUTHOR IS RYAN CLARK.
//
// THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
// OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
// MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
// ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
// RESULTING FROM THE USE, MODIFICATION, OR
// REDISTRIBUTION OF THIS SOFTWARE.

#include <stdlib.h>
#include <SDL/SDL.h&lgt;

int main(int argc, char *argv[])
{
	SDL_Surface *screen;	//This pointer will reference the backbuffer
	SDL_Surface *image;	//This pointer will reference our bitmap sprite
	SDL_Surface *temp;	//This pointer will temporarily reference our bitmap sprite
	SDL_Rect src, dest;	//These rectangles will describe the source and destination regions of our blit
	
	//We must first initialize the SDL video component, and check for success
	if (SDL_Init(SDL_INIT_VIDEO) != 0) {
		printf("Unable to initialize SDL: %s\n", SDL_GetError());
		return 1;
	}
	
	//When this program exits, SDL_Quit must be called
	atexit(SDL_Quit);
	
	//Set the video mode to fullscreen 640x480 with 16bit colour and double-buffering
	screen = SDL_SetVideoMode(640, 480, 16, SDL_DOUBLEBUF | SDL_FULLSCREEN);
	if (screen == NULL) {
		printf("Unable to set video mode: %s\n", SDL_GetError());
		return 1;
	}
	
	//Load the bitmap into a temporary surface, and check for success
	temp = SDL_LoadBMP("image.bmp");
	if (temp == NULL) {
		printf("Unable to load bitmap: %s\n", SDL_GetError());
		return 1;
	}
	
	//Convert the surface to the appropriate display format
	image = SDL_DisplayFormat(temp);
	
	//Release the temporary surface
	SDL_FreeSurface(temp);
	
	//Construct the source rectangle for our blit
	src.x = 0;
	src.y = 0;
	src.w = image->w;	//Use image->w to display the entire width of the image
	src.h = image->h;	//Use image->h to display the entire height of the image
	
	//Construct the destination rectangle for our blit
	dest.x = 100;		//Display the image at the (X,Y) coordinates (100,100)
	dest.y = 100;
	dest.w = image->w;	//Ensure the destination is large enough for the image's entire width/height
	dest.h = image->h;
	
	//Blit the image to the backbuffer
	SDL_BlitSurface(image, &src, screen, &dest);
	
	//Flip the backbuffer to the primary
	SDL_Flip(screen);
	
	//Wait for 2500ms (2.5 seconds) so we can see the image
	SDL_Delay(2500);
	
	//Release the surface
	SDL_FreeSurface(image);
	
	//Return success!
	return 0;
}

I chose this one because it doesn’t have any compiling aid for poor fellow in ZIP. So we can compile it in openSUSE and most of Linux distros like this:

gcc -o SDL_Display Bitmap SDL_DisplayBitmap.c $(pkg-config --libs --cflags SDL_image)
./SDL_Display

You should just see nice spaceship for 2.5 seconds nothing more or you own nice BMP-image.

Do I have to be BASH wizard and what even is BASH?

If you are reading this in openSUSE you probably use BASH (Bourne Again Shell) and that is all I want to say about that. It’s not the topic and you can forget all about it. You don’t have to be wizard of BASH to understand what happens in that sentence above. again we are compiling with ‘gcc‘ file named ‘SDL_DisplayBitmap.c‘ to binary ‘SDL_DisplayBitmap‘. New stuff starts after that. It just tells to BASH ask from ‘pkg-config’ libraries and needed c-flags that comes with SDL_image and attach them here. If you just run you get something like this

pkg-config --libs --cflags SDL_image
-D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL  -lSDL_image -lSDL -lpthread

So compile string is actual then

gcc -o SDL_Display Bitmap SDL_DisplayBitmap.c -D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL  -lSDL_image -lSDL -lpthread

But in every distro tends to tune these cflags stuff and every release of ‘SDL_image’ can tune needed libraries. This what you don’t want to know anything about! You don’t want to hassle openSUSE’s or Fedora’s or Ubuntu’s global building flags or include neither library locations by hand. You should just go with the automatic ‘pkg-config’ way. If I can give you one bit of advise other than always use suncream for libraries have ‘pkg-config’-config files and use them. Next we get on ‘make’ and Makefiles. As I’m too lazy to copy’n’paste my ‘gcc‘ strings here.

]]>
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
openSUSE and GCC part 2: compiling ‘Hello World’ https://lizards.opensuse.org/2013/10/15/opensuse-and-gcc-part-2/ Tue, 15 Oct 2013 05:43:00 +0000 http://lizards.opensuse.org/?p=10010 I really hope you readied last article ‘OpenSUSE and GCC part 1: getting started‘ or you understand basics and you have GCC (Only GNU C Compiler as GCC stands Gnu Compiler Collection) installed. This time we learn how to compile application called ‘Hello World’. It’s so popular application even wikipedia have article about it. If you are not in reading mood I’ll explain it in short.

Hello world

Hello world is small application that programmer tends to start with when learning new programming language. It’s just something that prints ‘Hello World’-string in console. It’s good starting point to learn new programming language as in compiling languages you get the idea how to make application run.
Github is the programming project hosting place that uses git. If you adventurous you can see all the language ‘Hello World’ programs from this Github page. Just click them around and see that every program has the same idea. If you have no clue what all this means don’t feel bad! I hope in some point of you openSUSE hacking time you probably get back there and understand value of that small application.
In C-Language ‘Hello World’ looks like this:

#include <stdio.h>

int main(void) {
printf("Hello World\n");
return 0;
}

Copy these sentences as they are to ‘helloworld.c‘ file with pico, nano, vim, emacs, gedit, kate or some other text editor. Pay some attention where you save that ‘helloworld.c’. Easiest place would be you home dirs root /home/’yourusername’/. I won’t tell you want all this C-language means if you are interested please read how to get along with C and you see how easy language C really is.

Compiling

If you have used PHP, Python, Bash or Perl (maybe Ruby) in other words some programming language that doesn’t need compiling you are point of life to take a deep breath. If you have ever touched any programming language you in my position when I was 16 and started typing in Borland Turbo C++ and take event deeper breath. If you have used Microsoft Visual Studio and which is incredible piece of IDE and you tell yourself you know something about programming you take mild breathe and zip of water. Only problem with IDEs is you never know how the magic happens behind the scenes. Specially Visual Studio is very very good make you application just compile and in most of the cases that is what you want right?
There is some cases you need to get in the bottom and understand basic of compiling process. I tell one example from my life. In some point of my life I was ext in Nokia (Way before it was Microsoft owned phone company) and their phone build scripts were in HP-UX or AIX (can’t remember anymore sorry). There were nearly ‘NaN’ of people who understand how these Makefile scripts worked (they were mostly very cryptic cross compile Makefile stuff) and they just saw my fellow ext-buddy sitting there behind his desk. They gave these scripts to this poor fellow and weeks he cried, moaned and felt pain in his brains from compiling extremely complicated application. In the end he did it. He made those build scripts to work because he understand how compiling and linking was actually made and if I’m not wrong he got work place from Nokia for years to come.
Now I Cut the sentimental crap and tell how to compile program. It’s easy go to directory you have created ‘helloworld.c‘ and write this in console

gcc -o helloworld helloworld.c

was it so hard? In setence ‘gcc‘ is GNU C Compiler and paramter ‘-o‘ is application binary name (choose wisely young badawan it will write over your files if have same file name).

Run program

Running the program isn’t hard at all. Stay in directory that program is and write to console

./helloworld
Hello World

Now you have compiled you first program. Next we look at RPM devel packages and using libraries and headers. Remember ‘./’ is very needed in front this example because you want to run application from your current location.

]]>