Compiling 32-bit GTK+ Applications of 64 bit Linux - c

I am having some trouble compiling 32-bit GTK+ applications on 64-bit Linux, specifically Ubuntu 10.04. Compiling 64-bit GTK+ applications works fine, and everything is set up to compile 32-bit apps as well, but it doesn't work with GTK+
I have a very simple test program that I am using for trouble shooting that is simply a gtk_init and a gtk_main, which compiles fine as -m64. I am compiling with gcc 4.6.2, calling it with:
gcc -m32 gtktest.c `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`
These are the two different kinds of error messages I get:
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../x86_64-unknown-linux-gnu/bin/ld: warning: libXext.so.6, needed by /usr/lib/../lib32/libgtk-x11-2.0.so, not found (try using -rpath or -rpath-link)
and
/usr/lib/../lib32/libgdk-x11-2.0.so: undefined reference to `XmbSetWMProperties'
Keep in mind that these aren't the only errors, I just included the two specific types for reference and to keep it short, I get errors for the whole stack of GTK+ libraries.
I do have all of the proper 32-bit versions of the libraries in my lib32 folders.
Hopefull someone has had this problem before and can help me, this is really causing me quite the headaches, and I can't fine much help any where on the net.
Please ask if there is any other information you need me to provide to help with diagnosing this problem.
Note: I do have the ia32-libs and gcc-multilib packages. Ubuntu 10.04 does not have a separate ia32-libs-gtk packages, but I think these are wrapped in to the ia32-libs packages. They all are present on my system.
I think this must be some sort of linker config problem. I've recently built the new Free Pascal compiler and a 32 bit cross compiler, and I also upgraded GCC to 4.6.2 to take advantage of some of the new C++ features and fixes to C99 support. The default 4.4.3 GCC still exists on my system. Where I think the problem has been introduced is when I installed a new binutils because I've been experimenting with Clang and LLVM as a toolchain, and I wanted and ld with plug-in capabilities, so I figured might as well upgrade them all.
Everything works fine compiling 64 bit programs, there hasn't been a single problem with the new tools at all, and I can compile 32-bit programs but when it comes time to explicitly link something in I have problems.
I know my current set of libs is appropriate, and I have Free Basic installed which only emits 32 bit code, and I was able to build 32-bit GTK+ programs no problem before this upgrade.
Just wondering if anyone has any ideas what configs might have been changed in this upgrade or has had this happen to them before? I really should upgrade to a newer distro so I can take advantage of all the new software with out have to hack up all of my packages, but unfortunatly there is a bug in the newer kernels that prevents my computer from coming back from standby, and this is a laptop I use for personal side projects, so proper power management is pretty important, and it's not a huge loss if I bork the system, other than I have it set up pretty much perfect for my workflow.

You may tell pkg-config to search for the 32-bit libraries with the environment variable PKG_CONFIG_PATH.
For Ubuntu:
export PKG_CONFIG_PATH=/usr/lib32/pkgconfig:$PKG_CONFIG_PATH
For Redhat:
export PKG_CONFIG_PATH=/usr/lib/pkgconfig:$PKG_CONFIG_PATH

I think you need to install the ia32-libs-gtk & gcc-multilib packages, and you need to compile and link with gcc -m32 as you already do.

The GTK package in 12.04 doesn't seem to work correctly with multiarch. You can work around this on Ubuntu 12.04 by creating the following symlinks:
sudo ln -s /lib/i386-linux-gnu/libglib-2.0.so.0 /usr/lib32/libglib-2.0.so
sudo ln -s /usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0 /usr/lib32/libgtk-x11-2.0.so
sudo ln -s /usr/lib/i386-linux-gnu/libgdk-x11-2.0.so.0 /usr/lib32/libgdk-x11-2.0.so
sudo ln -s /usr/lib/i386-linux-gnu/libatk-1.0.so.0 /usr/lib32/libatk-1.0.so
sudo ln -s /usr/lib/i386-linux-gnu/libpangox-1.0.so.0 /usr/lib32/libpangox-1.0.so
sudo ln -s /usr/lib/i386-linux-gnu/libpango-1.0.so.0 /usr/lib32/libpango-1.0.so
sudo ln -s /usr/lib/i386-linux-gnu/libgmodule-2.0.so.0 /usr/lib32/libgmodule-2.0.so
sudo ln -s /usr/lib/i386-linux-gnu/libgobject-2.0.so.0 /usr/lib32/libgobject-2.0.so
sudo ln -s /usr/lib/i386-linux-gnu/libgdk_pixbuf-2.0.so.0 /usr/lib32/libgdk_pixbuf-2.0.so
I found the answer in this thread: http://www.blitzbasic.com/Community/posts.php?topic=101357
Alternatively (probably better), you can leave the base system untouched and update your link to search by file name instead of library name. Something like:
gcc -m32 gtktest.c `pkg-config --cflags gtk+-2.0` -L/usr/lib/i386-linux-gnu -l:libgio-2.0.so.0 ...
This isn't great. You'll have to add a -l: for each library that the linker can't find and your build will break if the library file name ever changes.

Related

Makefile for C code

I inherited a code which has a makefile, but so far I was unable to run it on a linux server. The main complain of the compiler is that it is unable to load libgmp.so.3 : error while loading shared libraries: libgmp.so.3. I know that libgmp.so.10 exists on this server, but I was wondering which part of the makefile needs to be changed so the compiler looks for libgmp.so.10 rather than libgmp.so.3.
OPTFLAG = -O2 -Wall -fPIC -fexceptions -DNDEBUG
LDFLAGS = -O2 -Wl,-no_compact_unwind -DNDEBUG -lm -pthread
COMPILER = gcc ${OPTFLAG}
LINKER = gcc ${LDFLAGS}
# CPLEX directory
CPLEX_HOME = /opt/ibm/ILOG/CPLEX_Studio1263/cplex
CPLEX_INC = ${CPLEX_HOME}/include/
CPLEX_LIB = ${CPLEX_HOME}/lib/x86-64_linux/static_pic/ -lcplex
# Compile the main file
code: code.c
${COMPILER} -c code.c -o code.o -I${CPLEX_INC}
${LINKER} -o code code.o -L${CPLEX_LIB}
clean::
rm -f *.o
rm -f ${LIB}/*.o
rm -f *~
rm -f ${SRC}/*~ ${INCLUDE}/*~
You need to rebuild whatever program or library uses libgmp.so.3 from source code. Could you provide the exact command run by make and the error message it produces?
EDIT The problem here is that the system has installed a version of the IBM CPLEX software which comes with its own GCC binary, and that GCC binary uses libgmp.so.3. The easiest way to fix this would be to upgrade the CPLEX software to a version which supports the operating system being used, or use the software on the operating system for which it was written (i.e., something really old that actually ships libgmp.so.3).
The most easy way it to install libgmp-dev package, from your linux distribution. GMP is a package library to do multiple precision calculations on large integers, which is probably needed by your program. As you put in some comments, adding -L/usr/lib64/libgmp.so.10 is an error, as -L option allows to add a directory to search for libraries, and not a specific library.
If only the library is needed and no header file is missing in your compilation (this is something strange, but sometimes happen) then you can still link with only the libgmp.so.10 object, but you have to do in a something nasty way. Just add /usr/lib64/libgmp.so.10 as an object file (not a library, with -l option) to your link command.
EDIT
From looking more closely your Makefile I see no reference to the libgmp.so.3 library, so I only can assume this is a indirect reference from some other already compiled library that comes from outside with your package. Just use
ldd lib<nameOfLibrary>.so.x.x
with all the libraries needed by your final executable, so see which shared objetc is the one that requests libgmp.so.3 soname, and then recompile it, reinstall it, or use your system's libraries ONLY, and not mesh anymore with libraries coming from another system. For example you can try (this is an expensive command, but it will get the answer)
find / -name "lib*.so.*" -print | xargs ldd > all_libs.lddout
and then find all_libs.lddout to see which library uses libgmp.so.3 (this will be the outdated library) You'll need to deinstall it or upgrade it, to be able to continue.
Linux systems have a library version system that allows an executable to be able to load different versions of the same library and allow them to live together in the same system. One of two: or you are able to locate the sources of version 3 of the shared libgmp.so.3 library and install it on your system, or you'll need to update the libraries your program uses to be able to link with the libgmp.so.10 already installed on your system.
2ND EDIT
As I see in the comments, you have changed the default compiler on your system by another coming possibly from other linux distribution (as your installed library is libgmp.so.10 while the one cc1 requests is libgmp.so.3, which is not installed on your system.
Installing a different compiler from the one you have installed, and doing that without previously deinstalling the other compiler, can lead you to this kind of problems.
The most reliable thing you can do is to reinstall the compiler from your distribution, or better, reinstall the whole linux system, as you have probably broken many things that will be emerging as you use your system. There's very poor info on what you have done to go further in your problem. Anyway, my recommendation is to not use the comment parts to add new information about your problem, just edit your question and add all those new information to it.

Creating a DLL file of C program on ubuntu [duplicate]

I have written some effects in C++ (g++) using freeglut on Linux, and I compile them with
g++ -Wall -lglut part8.cpp -o part8
So I was wondering if it is possible to have g++ make static compiled Windows executables that contains everything needed?
I don't have Windows, so it would be really cool, if I could do that on Linux :)
mingw32 exists as a package for Linux. You can cross-compile and -link Windows applications with it. There's a tutorial here at the Code::Blocks forum. Mind that the command changes to x86_64-w64-mingw32-gcc-win32, for example.
Ubuntu, for example, has MinGW in its repositories:
$ apt-cache search mingw
[...]
g++-mingw-w64 - GNU C++ compiler for MinGW-w64
gcc-mingw-w64 - GNU C compiler for MinGW-w64
mingw-w64 - Development environment targeting 32- and 64-bit Windows
[...]
Suggested method gave me error on Ubuntu 16.04: E: Unable to locate package mingw32
===========================================================================
To install this package on Ubuntu please use following:
sudo apt-get install mingw-w64
After install you can use it:
x86_64-w64-mingw32-g++
Please note!
For 64-bit use: x86_64-w64-mingw32-g++
For 32-bit use: i686-w64-mingw32-g++
One option of compiling for Windows in Linux is via mingw. I found a very helpful tutorial here.
To install mingw32 on Debian based systems, run the following command:
sudo apt-get install mingw32
To compile your code, you can use something like:
i586-mingw32msvc-g++ -o myApp.exe myApp.cpp
You'll sometimes want to test the new Windows application directly in Linux. You can use wine for that, although you should always keep in mind that wine could have bugs. This means that you might not be sure that a bug is in wine, your program, or both, so only use wine for general testing.
To install wine, run:
sudo apt-get install wine
Install a cross compiler, like mingw64 from your package manager.
Then compile in the following way: instead of simply calling gcc call i686-w64-mingw32-gcc for 32-bit Windows or x86_64-w64-mingw32-gcc" for 64-bit Windows. I would also use the --static option, as the target system may not have all the libraries.
If you want to compile other language, like Fortran, replace -gcc with -gfortran in the previous commands.
I've used mingw on Linux to make Windows executables in C, I suspect C++ would work as well.
I have a project, ELLCC, that packages clang and other things as a cross compiler tool chain. I use it to compile clang (C++), binutils, and GDB for Windows. Follow the download link at ellcc.org for pre-compiled binaries for several Linux hosts.
From: https://fedoraproject.org/wiki/MinGW/Tutorial
As of Fedora 17 it is possible to easily build (cross-compile) binaries for the win32 and win64 targets. This is realized using the mingw-w64 toolchain: http://mingw-w64.sf.net/. Using this toolchain allows you to build binaries for the following programming languages: C, C++, Objective-C, Objective-C++ and Fortran.
"Tips and tricks for using the Windows cross-compiler": https://fedoraproject.org/wiki/MinGW/Tips
For Fedora:
# Fedora 18 or greater
sudo dnf group install "MinGW cross-compiler"
# Or (not recommended, because of its deprecation)
sudo yum groupinstall -y "MinGW cross-compiler"

Questions about how libraries work in C

I am a newbie student learning C and wish to use the gLib library functions for a project: http://www.linuxfromscratch.org/blfs/view/svn/general/glib2.html
(I am using Ubuntu)
I have a couple questions about how libraries work in C and what happens when you install one or want to use one:
When I install this (run ./configure && make && make install inside the folder), what exactly is it doing? From what I learned there are shared libraries in C and static libraries in C. Is it true that it is installing library and include files to /usr/lib/ or somewhere?
When using gcc with external libraries, you have to specify -L and -I flags to specify where to look for library and header files. When I install glib, will I need to specify these flags?
If I want to package my executable for another machine, what would happen if the other machine doesn't have glib? I think if I had static libraries I would be able to include it in the binary, but how would it work for glib?
I am familiar with developing with GTK+ and GLIB. As i'm aware library files reside in /usr/lib and include files are found in /usr/include. Some libraries might be in places such as /usr/local/lib. I will attempt to answer your questions as best as I could.
When installing a library through the source package yes it installs files to the various folders /usr/share /usr/lib /usr/include and etc. It's highly recommended you use your distribution's package manager to install library packages and development headers. Installing from source is always bound to fail as necessary dependencies might be required.
This is where tools such as autogen and makefiles come handy. You don't necessarily need to concern yourself with specifying all that. tools such as pkg-config handle all that work. Most libraries will install a package configuration file into /usr/lib/pkgconfig & /usr/share/pkgconfig directories. This helps anyone developing an application easily link their code to the libraries.
Using package config to get the config:
$ pkg-config --cflags --libs glib-2.0
-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0
Linking using GCC & package config:
$gcc example.c `pkg-config --cflags --libs gtk+2.0 glib-2.0` -o example
The above command would link my program with gtk & glib.
Using Makefile to not ever have to enter those long lines again:
Makefile:
OBJS = main.o callbacks.o
CFLAGS = `pkg-config --cflags --libs gtk+-2.0`
program: $(OBJS)
gcc -o program $(OBJS)
main.o: main.c
gcc -c main.c $(FLAGS)
callbacks.o: callbacks.c callbacks.h
gcc -c callbacks.c $(FLAGS)
.PHONY : clean
clean:
rm *.o
rm program
.PHONY : install
install:
cp program /usr/bin
.PHONY : uninstall
uninstall:
rm /usr/bin/program
The above makefile is for a simple GTK+2.0 application as you can tell by what package config is including in CFLAGS to make the program executable all you have to enter in your source directory would be make. pkg-config will only work if you have installed the development packages for the library you are trying to work with. For ubuntu to install GTK+-3.0 and GLIB development files you would enter:
$ apt-get install libgtk-3-dev
I think this is a good concern for portability. No single static library is going to be cross platform. It would have to be compiled for those platforms manually. I reckon to get rid of all the headache you would use Anjuta IDE developed by the GNOME software foundation. It makes developing GLIB & GTK+ apps a breeze supporting both C & C++. It will create the Makefile, configure and other files to make developing code on cross platforms easy and make deployment easy. I could link you some resources, but my reputation on stack overflow is less then 10. So I will just mention the name of some resources below.
Further Reading
Makefile Tutorial
Anjuta IDE (C/C++)): ://anjuta.org/
GTK+-3.0 Hello World with Compiling and linking using pkg-config:
When I install this (run ./configure && make && make install inside
the folder), what exactly is it doing? From what I learned there are
shared libraries in C and static libraries in C. Is it true that it is
installing library and include files to /usr/lib/ or somewhere?
Well it is running first ./configure and then if that succeeds it runs make and if that succeeds it runs make install. configure is a script that takes care of a lot of compatibility issues between systems. They are usually shell scripts as this is the common denominator across systems so the configure script will work across various systems. One of the thing configure does is create a Makefile. The second command make will use the newly created Makefile to build the library or executable. Since you did not specify a target (like you will in the make install) make will build the default target, which is typically the all target. This is just by convention. Makefiles are basically a list of things to build (targets) along with what they depend on (dependencies) and how to build to target (rules). Finally, make install will actually install the necessary components. For libraries this is the library and necessary header files for executables it is just the program. man pages might also be installed. Where you install the libraries depends on where you specify to install them. Typically configure will take the --prefix argument that lets you control where they are installed. If you do not use --prefix you will most likely install in the default location for your system.
When using gcc with external libraries, you have to specify -L and -I
flags to specify where to look for library and header files. When I
install glib, will I need to specify these flags?
Your question is a little unclear, so let me first make sure I understand. Are you asking if after you install glib will you need to use -L and -I to tell gcc where to look for them? If so it depends on where you install them. Typically when you make and install a library you will install the library and header files in the default location or not. If you did then assuming your gcc is configured correctly then no you will not. If you did not then you will most likely have to use -L and -I
If I want to package my executable for another machine, what would
happen if the other machine doesn't have glib? I think if I had static
libraries I would be able to include it in the binary, but how would
it work for glib?
If it doesn't have glib and you used the shared libraries your application will not work. You will need to either have the same version glib libraries on the other machine or build the libraries statically. How to build them statistically depends on the library. This SO question might help.
Regarding configure, make and make install. configure is a shell script that is used to discover (and configure) your development environment. make and make install are convenient way of building your software. Where make would normally involve compiling and linking, where as make install would normally involve copying executables and libraries to standard path and setting up things (also include files if any usually in /usr/include), so that you don't have to explicitly give path before running the executable. What make does can be done by hand, but it's very cumbersome.
For glibc - yes you have to specify those flags. Normally all libraries will come in two flavors on most of the platforms. The binary form are used for dynamic linking when programs are actually loaded. Also - most distributions will have -dev or -devel versions of those libraries. Those are required for building software that makes use of those libraries (configure above can help find out whether devel libraries are installed). Typically when you see a library installed but not it's devel - you are likely to see configure errors. In short you require devel versions if you want to link with those libraries. This step is not needed if you are building libraries also from source using make and make install.
If you want to package your executable for another machine and you are not sure whether another glib is there or you want to be sure that the glib to be installed should be one specific version that you want, you should statically link while building (compiling/linking) the library. this gcc man page has got several details about link options. I believe there should be a way to statically link glib(or glib2). Though normally that may not be required if you have enough applications that are using it already.

Building/Linking libgcrypt for Mingw

I'd like to implement some features of libgcrypt in my program, but it is currently running on Windows, OSX, and Linux (Arch/Xubuntu), so I can only really do so if I can build it for all three platforms. On OSX and Linux I had no problem.
I got the sources from the github page for libgcrypt and libgpg-error, and I've successfully built and run the libraries on both Linux and OSX, so I know that my test code is valid (which I am now having trouble with on Windows w/MinGW).
I did the following on Xubuntu (and similar on Arch but using pacman instead of apt-get):
sudo apt-get install mingw32 mingw32-runtime mingw32-binutils
to get the cross compiling tool chain and
git clone https://github.com/Chronic-Dev/libgcrypt.git
git clone https://github.com/Chronic-Dev/libgpg-error.git
cd libgpg-error
autoreconf -vfi
./autogen.sh --build-w32
make
sudo make install
cd ../libgcrypt
autoreconf -vfi
./autogen.sh --build-w32
make
sudo make install
to build, and it successfully builds these files in home/myuser/w32root/:
libgcrypt.a
libgcrypt.def
libgcrypt.dll.a
libgcrypt.la
libgpg-error.dll.a
libgpg-error.la
include/
gcrypt.h
gcrypt-module.h
gpg-error.h
I took these files over to windows, and tried compiling the test code (named main.c locally) with
gcc main.c -o main.exe -lgcrypt
but I get undefined reference errors leading me to the conclusion that the library wasn't linked correctly (initially only using libgcrypt.a), so I looked some stuff up, and found that some libraries require a set of files like .a, .def, et al. to work, so I dropped them all in C:\Mingw\lib to see if it made a difference; it didn't. The following was also silent in finding the library file to link, but didn't resolve the undefined references:
gcc main.c -o main.exe -lgcrypt -lgpg-error
So I'm not really sure where to go from here. The readme doesn't get into cross compiling too much, like what files to copy and link once you're on the Windows side. Any pointers (to docs for it I missed maybe?) are appreciated! Thanks a bunch for reading my wall of text.

GTK3-lib windows are empty in Ubuntu

I want to compile and run examples of how to use the GTK3 library for my C-programs, but when I run them they only consist of a blank empty space (no buttons or text).
I'm running Ubuntu 12.04 with GTK-3.0
Some examples I tried to compile and run are these: http://developer.gnome.org/gtk3/3.0/gtk-getting-started.html
GCC output no errors or warnings with flag pkg-config --cflags --libs gtk+-3.0
also no warnings when running the binary.
What am I missing?
Ok. Problem is kind of solved.
I formatted my Ubuntu drive and installed a fresh version 12.10 - this didn't change anything!
What fixed my problem was to install GTK 2.0 too, even though I used GTK3 flags to compile and the tutorial mentioned in original post is meant for GTK3.
I'm going to report it as a bug, if no one has an explanation.

Resources