Compiling CGUI for 64 bit

Linux specific questions.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Compiling CGUI for 64 bit

Post by Dinosaur »

Hi All

Trying to run my applications in Linux Mint 64 bit.
A problem I have struck is in compiling CGUI as I get the following error.

Code: Select all

/usr/bin/ld: obj/unix/cgui/cursdata.o: relocation R_X86_64_32 against `curs_cursors' can not be used when making a shared object; recompile with -fPIC
Adding the compiler switch simply results in the exact same error.
Any suggestions ?

The process is straight forward.
1. Unzip CGUI from
http://sourceforge.net/projects/cgui/fi ... urce=files

2. In Terminal type ./fix.sh unix
3. Make (this is where the error happens)
4. Make Install
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: Compiling CGUI for 64 bit

Post by srvaldez »

I have the suspicion that there's 32-bit specific code in cgui, hope somebody can help you.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Compiling CGUI for 64 bit

Post by caseih »

There could well be 64-bit problems in the code, since it's a very old library that hasn't been maintained. But the problem you are seeing is not from that, it's from a very primitive and not very smart Makefile. The problem is with 64-bit code, in order to make a shared library you have to compile object files with -fPIC, whereas on 32-bit you didn't have to do that. Of course if you can convince cgui to produce a static library then you won't see this problem. I know the Makefile can produce a static build, but I'm not sure how to do that.

I have modified the makefile to work, though. I've attached it here as "makefile.uni." Drop it in the misc/ folder, do a make clean and try building it again.

Code: Select all

#  makefile.uni:
#  Makefile for the CGUI library with Unix. Should not be used directly!
#
#  By Christer Sandberg (ported from ADIME made by Sven Sandberg)
#
#  See readme.txt for more information about CGUI.
#
#  See makefile.all for a list of the available targets.



# -------- Define some variables that the primary makefile may use. --------

PLATFORM = UNIX

EXE_SUFFIX =
OBJ_SUFFIX = .o
LIB_SUFFIX = .a
HTML_SUFFIX = .html
INFO_SUFFIX = .info
TEXI_SUFFIX = .texi

_TX_HTML_FLAG = -html
_TX_TEXI_FLAG = -texi

ifndef OBJ_ROOT_DIR
OBJ_ROOT_DIR = obj
endif
OBJ_PLATFORM_ROOT_DIR = $(OBJ_ROOT_DIR)/unix

ifndef LIB_ROOT_DIR
LIB_ROOT_DIR = lib
endif
LIB_DIR = $(LIB_ROOT_DIR)/unix

HAVE_TEXINFO = 1

ifdef STATICLINK

# link as a static library
OBJ_DIR = $(OBJ_PLATFORM_ROOT_DIR)/$(PACKAGE5)_s
IMPLIB_BASENAME = lib$(PACKAGE5)_s.a
IMPLIB_NAME = $(LIB_DIR)/$(IMPLIB_BASENAME)
LIB_NAME = $(IMPLIB_NAME)

else

# link as a shared object
OBJ_DIR = $(OBJ_PLATFORM_ROOT_DIR)/$(PACKAGE5)
IMPLIB_BASENAME = lib$(PACKAGE5).so
IMPLIB_NAME = $(LIB_DIR)/$(IMPLIB_BASENAME)
LIB_NAME = $(IMPLIB_NAME)

endif



# -------- Default system paths. ------------

ifndef SYSTEM_DIR
SYSTEM_DIR = /usr/local
endif
SYSTEM_INCLUDE_DIR = $(SYSTEM_DIR)/include
SYSTEM_LIB_DIR = $(SYSTEM_DIR)/lib



# -------- Set up mktext --------
ALLEGRO_DAT = $(ALLEGRO_DAT_X)
ALLEGRO_DAT2C = $(ALLEGRO_DAT2C_X)
CGUI_DAT2C = $(CGUI_DAT2C_X)
CGUI_FONTS = $(CGUI_FONTS_X)
CGUI_FONTS_C = $(CGUI_FONTS_C_X)
CGUI_FONTS_H = $(CGUI_FONTS_H_X)
CGUI_ICONS = $(CGUI_ICONS_X)
CGUI_ICONS_C = $(CGUI_ICONS_C_X)
CGUI_ICONS_H = $(CGUI_ICONS_H_X)
CGUI_CURSORS = $(CGUI_CURSORS_X)
CGUI_CURSORS_C = $(CGUI_CURSORS_C_X)
CGUI_CURSORS_H = $(CGUI_CURSORS_H_X)
CGUI_DAT = $(CGUI_DAT_X)
CGUI_DAT_C = $(CGUI_DAT_C_X)
CGUI_DAT_H = $(CGUI_DAT_H_X)
CGUI_LABELS = $(CGUI_LABELS_X)
TEXT_SOURCES  = $(TEXT_SOURCES_X)
TEXT_HEADERS = $(TEXT_HEADERS_X)
MKTEXT = $(MKTEXT_X)


# -------- Give a sensible default target for make without any args. --------
# This must be done right after the tests, which can generate error targets.

.PHONY: _default

_default: default


# -------- Decide what compiler options and libraries to use. --------

ifdef WARNMODE
WFLAGS = -Wall -W
# -Wno-unused
else
WFLAGS = -Wall -Wno-unused
endif

ifdef PGCC
OFLAGS = -march=pentium -O6 -ffast-math
else
ifdef PENTIUMONLY
OFLAGS = -march=pentium -O2 -funroll-loops -ffast-math
else
OFLAGS = -O2 -funroll-loops -ffast-math -fPIC
endif
endif

ifdef STATICLINK_ALLEGRO
ALLEGRO_CONFIG_FLAGS = --static
else
ALLEGRO_CONFIG_FLAGS = --shared
endif

ifdef DEBUGMODE
# debugging build
CFLAGS = -DDEBUGMODE=$(DEBUGMODE) $(WFLAGS) -g
SFLAGS = -DDEBUGMODE=$(DEBUGMODE) $(WFLAGS)
LFLAGS += -g -lm
LIB_FLAGS = `allegro-config --libs release $(ALLEGRO_CONFIG_FLAGS)`
else
ifdef PROFILEMODE
# profiling build
CFLAGS = $(WFLAGS) $(OFLAGS) -pg
SFLAGS = $(WFLAGS)
LFLAGS += -pg
LIB_FLAGS = `allegro-config --libs profile $(ALLEGRO_CONFIG_FLAGS)`
else
# optimised build
CFLAGS = $(WFLAGS) $(OFLAGS) -fomit-frame-pointer -fno-strength-reduce
SFLAGS = $(WFLAGS)
ifndef SYMBOLMODE
LFLAGS += -s
LIB_FLAGS = `allegro-config --libs release $(ALLEGRO_CONFIG_FLAGS)`
endif
endif
endif

ifdef CGUI_DEVELOPING
CFLAGS += -D_CGUI_DEVELOPING=1
endif

ifdef CGUI_FORTIFY
CFLAGS += -D_CGUI_FORTIFY=1 -DFORTIFY
endif

ifdef EFENCE
 LIB_FLAGS += -lefence
endif

CFLAGS_NO_OPTIMIZE = $(WFLAGS)

COMPILE_FLAGS = $(subst src/,-DCGUI_SRC ,$(findstring src/, $<))$(CFLAGS)
COMPILE_FLAGS_NO_OPTIMIZE = $(subst src/,-DCGUI_SRC ,$(findstring src/, $<))$(CFLAGS_NO_OPTIMIZE)

ifdef STATICLINK
COMPILE_FLAGS += -DCGUI_STATICLINK
endif

ifdef PROFILEMODE
LIB_FLAGS += -lgmon
endif



# -------- List platform specific objects and programs. --------

VPATH +=

OBJ_LIST = $(COMMON_OBJS)

# Insert names of targets to build platform specific programs here.
PROGRAMS =
# Insert targets to build platform specific programs here.
# myprogram: path/myprogram$(EXE_SUFFIX)



# -------- Define how to compile. --------

GCC2UNIX = -D__UNIX__ -UDJGPP

COMPILE_C_TO_OBJ_DEPS =
define COMPILE_C_TO_OBJ
gcc $(COMPILE_FLAGS) -I./include -o $@ -c $<
endef
define COMPILE_C_TO_OBJ_NO_OPTIMIZE
gcc $(COMPILE_FLAGS_NO_OPTIMIZE) -I./include -o $@ -c $<
endef

COMPILE_S_TO_OBJ_DEPS =
define COMPILE_S_TO_OBJ
gcc $(SFLAGS) -I./include -x assembler-with-cpp -o $@ -c $<
endef

ifdef STATICLINK
# link as a static library

LINK_OBJ_TO_LIB_DEPS =
define LINK_OBJ_TO_LIB
ar rs $(LIB_NAME) $(LIB_OBJS)
endef

LINK_OBJ_TO_EXE_DEPS =
define LINK_OBJ_TO_EXE
gcc $(LFLAGS) -o $@ $< $(IMPLIB_NAME) $(LIB_FLAGS)
endef

LINK_OBJ_TO_EXE_NOLIB_DEPS =
define LINK_OBJ_TO_EXE_NOLIB
gcc $(LFLAGS) -o $@ $<
endef

LINK_OBJ_TO_EXE_NOCGUILIB_DEPS =
define LINK_OBJ_TO_EXE_NOCGUILIB
gcc $(LFLAGS) -o $@ $< $(LIB_FLAGS)
endef

LINK_ALL_OBJ_TO_EXE_DEPS =
define LINK_ALL_OBJ_TO_EXE
gcc $(LFLAGS) -o $@ $^ $(IMPLIB_NAME) $(LIB_FLAGS)
endef

LINK_ALL_OBJ_TO_EXE_NOLIB_DEPS =
define LINK_ALL_OBJ_TO_EXE_NOLIB
gcc $(LFLAGS) -o $@ $^
endef

LINK_ALL_OBJ_TO_EXE_NOCGUILIB_DEPS =
define LINK_ALL_OBJ_TO_EXE_NOCGUILIB
gcc $(LFLAGS) -o $@ $^ $(LIB_FLAGS)
endef

else
# link as a shared object

LINK_OBJ_TO_LIB_DEPS =
define LINK_OBJ_TO_LIB
gcc $(LFLAGS) -shared -o $(IMPLIB_NAME) $(LIB_OBJS) $(LIB_FLAGS)
endef

LINK_OBJ_TO_EXE_DEPS =
define LINK_OBJ_TO_EXE
gcc $(LFLAGS) -o $@ $< -L$(LIB_DIR) -lcgui $(LIB_FLAGS) -lm
endef

LINK_OBJ_TO_EXE_NOLIB_DEPS =
define LINK_OBJ_TO_EXE_NOLIB
gcc $(LFLAGS) -o $@ $<
endef

LINK_OBJ_TO_EXE_NOCGUILIB_DEPS =
define LINK_OBJ_TO_EXE_NOCGUILIB
gcc $(LFLAGS) -o $@ $< $(LIB_FLAGS)
endef

LINK_ALL_OBJ_TO_EXE_DEPS =
define LINK_ALL_OBJ_TO_EXE
gcc $(LFLAGS) -o $@ $^ $(LIB_FLAGS) -L$(LIB_DIR) -lcgui
endef

LINK_ALL_OBJ_TO_EXE_NOLIB_DEPS =
define LINK_ALL_OBJ_TO_EXE_NOLIB
gcc $(LFLAGS) -o $@ $^
endef

LINK_ALL_OBJ_TO_EXE_NOCGUILIB_DEPS =
define LINK_ALL_OBJ_TO_EXE_NOCGUILIB
gcc $(LFLAGS) -o $@ $^ $(LIB_FLAGS)
endef

endif # ifdef STATICLINK



# -------- Rules for installing and removing the library files. --------

# If you don't have the install command, you may use cp and mkdir, but
# this will not set permissions.

$(SYSTEM_LIB_DIR)/$(IMPLIB_BASENAME): $(IMPLIB_NAME)
	install -m 755 -d $(SYSTEM_LIB_DIR)
	install -m 644 $< $@

$(SYSTEM_INCLUDE_DIR)/cgui.h: include/cgui.h
	install -m 755 -d $(SYSTEM_INCLUDE_DIR)
	install -m 644 $< $@

$(SYSTEM_INCLUDE_DIR)/cgui/%.h: include/cgui/%.h include/cgui
	install -m 755 -d $(SYSTEM_INCLUDE_DIR)/cgui
	install -m 644 $< $@


INSTALL_HEADERS = $(addprefix $(SYSTEM_DIR)/,$(wildcard include/cgui/*.h))

INSTALL_FILES = $(SYSTEM_LIB_DIR)/$(IMPLIB_BASENAME) \
 $(SYSTEM_INCLUDE_DIR)/cgui.h \
 $(INSTALL_HEADERS)

install: $(INSTALL_FILES)
	@echo The $(DESCRIPTION) UNIX library has been installed.

UNINSTALL_FILES = $(SYSTEM_LIB_DIR)/libcgui.a $(SYSTEM_LIB_DIR)/libcgui_s.a $(SYSTEM_LIB_DIR)/libcguid.a $(SYSTEM_LIB_DIR)/libcguid_s.a \
     $(SYSTEM_INCLUDE_DIR)/cgui.h

uninstall:
	-rm -fv $(UNINSTALL_FILES)
	-rm -fr $(SYSTEM_INCLUDE_DIR)/cgui
	@echo All gone!



# -------- Compile anything that can't be done in makefile.all. --------

#examples/ex%: $(OBJ_DIR)/ex%$(OBJ_SUFFIX)
#  $(LINK_OBJ_TO_EXE)

#NATIVE_LINK_OBJ_TO_EXE = 1


# -------- generate automatic dependencies --------

DEPEND_PARAMS = $(GCC2UNIX) -MM -MG -I./include -DCGUI_SCAN_DEPEND

depend:
	gcc $(DEPEND_PARAMS) src/*.c examples/*.c > _depend.tmp
	sed -e 's/^\([a-zA-Z0-9_]*\)\.o:/obj\/unix\/cgui\/\1\.o:/' _depend.tmp > obj/unix/cgui/makefile.dep
	sed -e 's/^\([a-zA-Z0-9_]*\)\.o:/obj\/unix\/cguid\/\1\.o:/' _depend.tmp > obj/unix/cguid/makefile.dep
	sed -e 's/^\([a-zA-Z0-9_]*\)\.o:/obj\/unix\/cgui_s\/\1\.o:/' _depend.tmp > obj/unix/cgui_s/makefile.dep
	sed -e 's/^\([a-zA-Z0-9_]*\)\.o:/obj\/unix\/cguid_s\/\1\.o:/' _depend.tmp > obj/unix/cguid_s/makefile.dep
	rm _depend.tmp
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Compiling CGUI for 64 bit

Post by Dinosaur »

Hi All

Caseih , that certainly allowed me to compile it and Install.
Great work, thank you.
However there are a lot of warnings which worry me.

In the meantime I have managed to awaken the author out of his retirement,
and he has duplicated the errors I had, and noted the warnings needed attention also.
He has also promised me a fix by this weekend, so "Fingers Crossed"

When it is resolved I will update "somehow" the FB depository of CGUI.

Once again thanks for your help.
At least now I can see what other obstacles there are to 64 bit Mint.

Regards
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Compiling CGUI for 64 bit

Post by caseih »

I ran several of the example binaries and they appeared to work. But you're correct. An older, unmaintained program might not be 64-bit clean, so there could be assumptions in the code about data sizes that could cause a segfault. With the original author looking at things I'm sure they'll be sorted.

I haven't experienced any significant issues with 64-bit systems in years now. There are a few FB issues to be aware of though. Many of the .bi files for using libraries like GTK haven't been checked out for 64-bit use (again there could be size assumption issues). I have used the GTK .bi files from the 32-bit FB and they seem to work on 64-bit. I know the cairo examples segfault because the code uses Sizeof(Integer) when they really wanted to say 4 (as in four bytes for 32-bit color). There's also differences in basic FB sizes between Windows and Linux that can bite you sometimes. An Integer is always 32-bit on Windows, but on Linux it's either 32-bit or 64-bit, whereas Long is always 32-bit. But similar issues crop up in C also.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Compiling CGUI for 64 bit

Post by Dinosaur »

Hi All

Yes there are numerous errors like:
"Passing different pointer types at parameter 2 of AddTab"

which is a Sub called Get_UserNbr

AddTab(Tabs.ID, @Get_UserNbr, @Tabs.Button, "User Button")

which is defined as:

Declare Sub Get_UserNbr CDecl ( Byval userdata as any Ptr , Byval id as Integer)

That worked in 32 bit of course, but fails now, but I can't figure out what to change the declare to.

Regards
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Compiling CGUI for 64 bit

Post by caseih »

What is the prototype for AddTab? and is that a C function or FB function?
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Compiling CGUI for 64 bit

Post by Dinosaur »

Hi All

The CGUI.bi file has the following stament:
declare function AddTab(byval id as long, byval callback as sub(byval data as any ptr, byval id as long), byval data as any ptr, byval label as const zstring ptr) as
It is a C function in the CGUI Library.

EDIT:
and in the cgui.h file
CGUI_FUNC(int, AddTab, (int id, CGUI_METHOD(void, callback, (void *data, int id)), void *data, const char *label));
Regards
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Compiling CGUI for 64 bit

Post by caseih »

Remember what I was saying about Integer and Long in fb? That's what's biting you now. The C code is expecting a C int. On Linux 64-bit, gcc has "int" being 32-bits. The prototype for AddTab defines the callback correctly as requiring long, however your callback sub Get_UserNbr uses Integer instead of Long. Simple (we hope) fix.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Compiling CGUI for 64 bit

Post by Dinosaur »

Hi All

Yep, just finished changing them all to long.
Now it compiles with no errors at all.

However when I run the program, I get:
./WinMain: error while loading shared libraries: libcgui.so: cannot open shared object file: No such file or directory.
Would be nice if it named the missing obj file ???

Regards

EDIT: This happens when i Compile any of the Examples as well.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Compiling CGUI for 64 bit

Post by caseih »

But Linux did name it. The missing library is libcgui.so. Did you install that library to somewhere where the linker looks by default? Unlike Windows, libraries have to go in specific places so the loader can find them. If you want to temporarily point the loader at a particular location, you can set the LD_LIBRARY_PATH variable. For example typing this at the shell prompt:

Code: Select all

export LD_LIBRARY_PATH=/home/bob/project/cgui/lib

./myapp
myapp will now try to load libraries in the path specified by the export line.

Hope this helps.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Compiling CGUI for 64 bit

Post by Dinosaur »

Hi All

I thought that is what "Make Install" did.

Regards

EDIT:
Something wrong there though, setting the path does not solve the problem.
How does one find out where Linux Mint 64 bit looks for the library ?

So the path statement didn't work but searching where Allegro library was located gave me /usr/lib/x86-64-linux-gnu
so putting the library there solved that problem.
Now I will have to wait for the CGUI fixes as it bombs out with Seg fault on Allegro.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Compiling CGUI for 64 bit

Post by caseih »

I'm afraid make install is probably naive, and doesn't know about 64-bit paths. Because you can run both 64-bit and 32-bit software at the same time, Debian has a scheme for installing parallel versions of the libraries. The makefile is just ignorant of that and placing libaries in the 32-bit location no doubt.

You're probably right that there's still an incompatibility in cgui. It may take some time to make it 64-bit clean. And then to make sure the .bi files are right. In the meantime you could install 32-bit allegro, 32-bit FreeBASIC, and then build a 32-bit version of cgui.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Compiling CGUI for 64 bit

Post by Dinosaur »

Hi All

I already have the 32 bit version running on my machines in the factory, and it runs very well.
The 64 bit version is a bit of a project to "Keep up".

Some of the cgui library compile errors are related to different size variables or pointers,
so I am not surprised that I got a seg fault.

Many thanks for your help caseih.

Will post when cgui is 64 bit ready.

Regards
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: Compiling CGUI for 64 bit

Post by srvaldez »

hello Dinosaur
any progress with the cgui 64-bit?
Post Reply