Page 1 of 1

["more or less" SOLVED] DC Dev: libimageload linker error

Posted: Fri Feb 14, 2014 9:17 am
by shmup73
Hey everyone!

I currently keep getting an error when linking against libimageload.a.

This is the Cygwin Bash Shell Output:
Tom@TOMPUTER /cygdrive/e/projects/dreamcast/dctest
$ cd e:/projects/dreamcast/dctest && make clean && make all
rm -f cast.elf cast_input_mgr.o cast_texture.o main.o romdisk.o
rm -f cast.elf
rm -f romdisk.img
kos-c++   -c cast_input_mgr.cpp -o cast_input_mgr.o
kos-c++   -c cast_texture.cpp -o cast_texture.o
kos-c++   -c main.cpp -o main.o
/home/Tom/kos/utils/genromfs/genromfs -f romdisk.img -d romdisk -v -x .svn
0    rom 52fe2e67         [0xffffffff, 0xffffffff] 37777777777, sz     0, at 0x0
1    .                    [0xac173237, 0xa027    ] 0040000, sz     0, at 0x20   
1    ..                   [0xac173237, 0x25923   ] 0040000, sz     0, at 0x40     [link to 0x20    ]
1    test.png             [0xac173237, 0xa641    ] 0100000, sz 46520, at 0x60   
/home/Tom/kos/utils/bin2o/bin2o romdisk.img romdisk romdisk.o
/opt/toolchains/dc/sh-elf/bin/sh-elf-g++   -std=gnu++11 -fno-operator-names -fno-rtti -fno-exceptions  -ml -m4-single-only -Wl,-Ttext=0x8c010000 -Wl,--gc-sections -T/home/Tom/kos/utils/ldscripts/shlelf.xc -nodefaultlibs -L/home/Tom/kos/lib/dreamcast -L/home/Tom/kos/addons/lib/dreamcast -o cast.elf  \
         cast_input_mgr.o cast_texture.o main.o romdisk.o -lm -lkosutils -lkosext2fs -Wl,--start-group -lkallisti -lc -lgcc -Wl,--end-group -lpng -limageload
cast_texture.o: In function `_ZN11CastTexture12loadFromFileEPKcm':
/cygdrive/e/projects/dreamcast/dctest/cast_texture.cpp:34: undefined reference to `img_load_file(char const*, IMG_INFO*, kos_img*)'
collect2: Fehler: ld gab 1 als Ende-Status zurück
Makefile:24: recipe for target 'cast.elf' failed
make: *** [cast.elf] Error 1
Or for short: [ undefined reference to `img_load_file(char const*, IMG_INFO*, kos_img*)' ]

I'm using KOS 2.0.0 compiled w/ GCC 4.8.2, I've also rebuilt libimageload.a w/ my current Toolchain.
This is what my Makefile looks like at the moment:
TARGET = cast.elf

all: rm-elf $(TARGET)

KOS_ROMDISK_DIR = romdisk

OBJS = cast_input_mgr.o cast_texture.o main.o romdisk.o
include $(KOS_BASE)/Makefile.rules

clean:
    rm -f $(TARGET) $(OBJS)

rm-elf:
    rm -f $(TARGET)
    rm -f romdisk.img

$(TARGET): $(OBJS)
    $(KOS_CCPLUS) $(KOS_CPPFLAGS) $(KOS_LDFLAGS) -o $(TARGET) $(KOS_START) \
        $(OBJS) -lm -lkosutils -lkosext2fs -limageload $(KOS_LIBS)

run: $(TARGET)
    $(KOS_LOADER) $(TARGET) -n

dist:
    rm -f $(OBJS) romdisk.*
    $(KOS_STRIP) $(TARGET)
Please note that, as a "Windows-Person" I'm quite new to Makefiles, still I try my best ;)

Don't know If these are relevant, too, but here they are:
environ.sh:
# KallistiOS environment variable settings
#
# This is a sample script. Configure to suit your setup. Some possible
# alternatives for the values below are included as an example.
#
# This script should be executed in your current shell environment (probably
# by bashrc or something similar).
#

# Build architecture. Set the major architecture you'll be building for.
export KOS_ARCH="dreamcast"
#export KOS_ARCH="gba"
#export KOS_ARCH="ps2"
#export KOS_ARCH="ia32"

# Build sub-architecture. If you need a particular sub-architecture, then set
# that here; otherwise use "pristine".
export KOS_SUBARCH="pristine"
# export KOS_SUBARCH="navi"	# DC
# export KOS_SUBARCH="rte"	# PS2

# KOS main base path
export KOS_BASE="/home/Tom/kos"

# Make utility
export KOS_MAKE="make"
#export KOS_MAKE="gmake"

# Load utility
export KOS_LOADER="dc-tool -x"				# dcload, preconfigured
# export KOS_LOADER="dc-tool-ser -t /dev/ttyS0 -x"	# dcload-serial
# export KOS_LOADER="vgba -sound 44100 -nocrc"		# GBA/vgba

# Genromfs utility
export KOS_GENROMFS="${KOS_BASE}/utils/genromfs/genromfs"
#export KOS_GENROMFS="genromfs"

# Compiler prefixes
#export KOS_CC_BASE="/usr/local/dc/dc-elf"
#export KOS_CC_PREFIX="dc"
export KOS_CC_BASE="/opt/toolchains/dc/sh-elf"		# DC
export KOS_CC_PREFIX="sh-elf"
#export KOS_CC_BASE="${EE}"					# PS2
#export KOS_CC_PREFIX="ee"
#export KOS_CC_BASE="/usr/local/gba/arm-elf"		# GBA
#export KOS_CC_PREFIX="arm-elf"

# If you are compiling for DC and have an ARM compiler, use these too.
# If you're using a newer compiler (GCC 4.7.0 and newer), you should probably be
# using arm-eabi as the target, rather than arm-elf. dc-chain now defaults to
# arm-eabi, so that's the default here.
#export DC_ARM_BASE="/usr/local/dc/arm-elf"
#export DC_ARM_PREFIX="arm-elf"
export DC_ARM_BASE="/opt/toolchains/dc/arm-eabi"
export DC_ARM_PREFIX="arm-eabi"

# Expand PATH (comment out if you don't want this done here)
export PATH="${PATH}:${KOS_CC_BASE}/bin:/usr/local/dc/bin"

# Manually add our second addons tree
export KOS_INC_PATHS="-I${KOS_BASE}/../kos-ports/include"

# reset some options because there's no reason for them to persist across
# multiple sourcing of this
export KOS_CFLAGS=""
export KOS_CPPFLAGS=""
export KOS_LDFLAGS=""
export KOS_AFLAGS=""

# Setup some default CFLAGS for compilation. The things that will go here
# are user specifyable, like optimization level and whether you want stack
# traces enabled. Some platforms may have optimization restrictions,
# please check README.
# GCC seems to have made -fomit-frame-pointer the default on many targets, so
# hence you may need -fno-omit-frame-pointer to actually have GCC spit out frame
# pointers. It won't hurt to have it in there either way.
export KOS_CFLAGS="-O2 -fomit-frame-pointer"
# export KOS_CFLAGS="-O2 -DFRAME_POINTERS -fno-omit-frame-pointer"

# Everything else is pretty much shared. If you want to configure compiler
# options or other such things, look at this file.
. ${KOS_BASE}/environ_base.sh
environ_base.sh:
# KallistiOS environment variable settings. These are the shared pieces
# that are generated from the user config. Configure if you like.

# Pull in the arch environ file
. ${KOS_BASE}/environ_${KOS_ARCH}.sh

# Add the gnu wrappers dir to the path
export PATH="${PATH}:${KOS_BASE}/utils/gnu_wrappers"

# Our includes
export KOS_INC_PATHS="${KOS_INC_PATHS} -I${KOS_BASE}/include \
-I${KOS_BASE}/kernel/arch/${KOS_ARCH}/include -I${KOS_BASE}/addons/include"

# "System" libraries
export KOS_LIB_PATHS="-L${KOS_BASE}/lib/${KOS_ARCH} -L${KOS_BASE}/addons/lib/${KOS_ARCH}"
export KOS_LIBS="-Wl,--start-group -lkallisti -lc -lgcc -Wl,--end-group"

# Main arch compiler paths
export KOS_CC="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-gcc"
export KOS_CCPLUS="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-g++"
export KOS_AS="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-as"
export KOS_AR="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-ar"
export KOS_OBJCOPY="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-objcopy"
export KOS_LD="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-ld"
export KOS_RANLIB="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-ranlib"
export KOS_STRIP="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-strip"
export KOS_CFLAGS="${KOS_CFLAGS} ${KOS_INC_PATHS} -D_arch_${KOS_ARCH} -D_arch_sub_${KOS_SUBARCH} -Wall -g -fno-builtin -fno-strict-aliasing"
export KOS_CPPFLAGS="${KOS_CPPFLAGS} ${KOS_INC_PATHS_CPP} -std=gnu++11 -fno-operator-names -fno-rtti -fno-exceptions"

# Which standards modes we want to compile for
# Note that this only covers KOS itself, not necessarily anything else compiled
# with kos-cc or kos-c++.
export KOS_CSTD="-std=c99"
export KOS_CPPSTD="-std=gnu++11"

GCCVER="4"

case $GCCVER in
  4*)
    export KOS_LDFLAGS="${KOS_LDFLAGS} ${KOS_LD_SCRIPT} -nodefaultlibs ${KOS_LIB_PATHS}" ;;
  *)
    export KOS_LDFLAGS="${KOS_LDFLAGS} -nostartfiles -nostdlib ${KOS_LIB_PATHS}" ;;
esac

# Some extra vars based on architecture
export KOS_ARCH_DIR="${KOS_BASE}/kernel/arch/${KOS_ARCH}"

case $GCCVER in
  4*)
    export KOS_START="" ;;
  *)
    export KOS_START="${KOS_ARCH_DIR}/kernel/startup.o" ;;
esac
(environ_dreamcast.sh remained 100% untouched)

If anybody can point me to the solution I'd appreciate It.
Thanks a lot, shmup. :)

Re: Dreamcast Dev: libimageload linker error

Posted: Fri Feb 14, 2014 10:01 am
by bbguimaraes
I don't know if this is the case (not familiar with dreamcast development) but the order of libraries on the command line to the linker matters. See here.

Basically, if you have an object a.o that needs something from b.a, you need to put a.o before b.a, so that the references on a.o are resolved when the linker sees b.a. If you exchange them, you'll get undefined references in a.o. Practically:
$ gcc a.o b.a # or a.o -lb
# ok
$ gcc b.a a.o # or -lb a.o
# undefined references
edit (off-topic)
How dare the spell checker tell me that "dreamcast" is not a valid word!?

Re: ["more or less" SOLVED] DC Dev: libimageload linker erro

Posted: Sat Feb 15, 2014 8:00 am
by shmup73
Hmm -limageload still won't work, possibly because it depends on other libraries
that I don't know.

But I got another library working that is capable of replacing the imageload lib,
by following your tip & link!

So thank you, Sir :mrgreen: