Shared library linking - undefined symbol

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
'; DROP DATABASE;--
Posts: 3284
Joined: Thu Nov 22, 2007 9:38 am UTC
Location: Midwest Alberta, where it's STILL snowy
Contact:

Shared library linking - undefined symbol

Postby '; DROP DATABASE;-- » Fri Jun 11, 2010 4:11 am UTC

So I'm trying to compile a shared library, which itself links to another shared library. ldd shows it's linked correctly, but I'm still getting "undefined symbol" when I load it.

My makefile is thus (and frankly it's a mess and I hardly understand it):

Code: Select all

# Program info
# LIBRARY is the library filename "$(LIBRARY).so"
# LUANAME is the Lua table name
# OS and ARCH are currently only used as defines for the preprocessor.
LIBRARY = wiimote
LUANAME = $(LIBRARY)
OS = LINUX
ARCH = x86

# The C preprocessor is a massive pile of ass
STUPIDFUNCNAMEHACK = luaopen_$(LUANAME)

# Library installation path
#INSTALLPATH=/usr/lib/lua/5.1/
#INSTALLPATH=/usr/local/lib/lua/5.1/
INSTALLPATH=/home/hyperhacker/dev/lua/libs

# Options to pass to linker
LDOPTIONS =

# Location of shared source files
SHARED = ../../../shared/

# Shared object files and source files used here
SHARED_OBJS =
SHARED_SRCS =

# Object files program uses.
OBJS = $(SHARED_OBJS)

# Other files that must be present to compile.
OTHER_DEP =

# Libraries being used.
#LIBS = -L/usr/lib -llua -lm `pkg-config --libs gtk+-2.0`
LIBS = -L/usr/lib -lwiiuse

# Path to library files.
LIBPATH = /usr/lib/

# Additional directories for header files.
INCLUDES = -I$(SHARED) -I$(LUA)

# Used to generate build ID. Change BUILD_INDEX if multiple releases in one day.
DAY = `date +%-d`
MONTH = `date +%-m`
YEAR = `date +%-y`
BUILD_INDEX = 0
BUILD_ID = "((BUILD_YEAR << 13) | (BUILD_MONTH << 9) | (BUILD_DAY << 4) | BUILD_INDEX)"
BUILD_DEFS = -DBUILD_DAY=$(DAY) -DBUILD_MONTH=$(MONTH) -DBUILD_YEAR=$(YEAR) -DBUILD_INDEX=$(BUILD_INDEX) -DBUILD_ID=$(BUILD_ID)

# Variables to define for the preprocessor.
DEFS = -DPROGRAMNAME="\"$(PROGNAME)\"" -D$(OS) -DOSNAME=\"$(OS)\" -DARCH=$(ARCH) -DLUANAME=\"$(LUANAME)\" -DLUAOPENFUNC=$(STUPIDFUNCNAMEHACK) $(BUILD_DEFS)

# Commands and flags used for various actions
LUA_CFLAGS = `pkg-config lua5.1 --cflags`
DELETE = rm -rf
CXX = gcc
CXXFLAGS = -O3 -Wall $(DEFS) -fpic -c -o $(INCLUDES) $(LIBS)
LD = $(CXX)
LDFLAGS = -O2 -fpic $(LIBS) -c -o $(LIBRARY).o $(LIBRARY).c
COMPILE = $(CXX) $(CXXFLAGS) -c
MAKESO = $(CXX) -O $(LIBS) -shared -fpic -o

# Make library
all: $(LIBRARY).so

# Install
install:
   cp $(LIBRARY).so $(INSTALLPATH)
   
.PHONY : all install clean

$(LIBRARY): $(OBJS)
   @echo LD
   $(LD) $(LDFLAGS) $(OBJS) $(LIBS) $(LDOPTIONS)
   
%.o: %.c $(OTHER_DEP)
   @echo COMPILE
   $(COMPILE) $(<) -o $(@)

$(LIBRARY).so: $(LIBRARY).o
   @echo MAKESO
   $(MAKESO) $(@) $(^)
   
$(SHARED_OBJS): $(SHARED_SRCS)
   @echo COMPILE SHARED
   $(COMPILE) $(^)
   
#this is stupidly complex for a simple recursive delete V_v
clean:
   $(DELETE) $(LIBRARY)
   find . -name "*.la" -exec rm -f {} \;
   find . -name "*.lo" -exec rm -f {} \;
   find . -name "*.so" -exec rm -f {} \;
   find . -name "*.o" -exec rm -f {} \;
   find . -name "*.log" -exec rm -f {} \;
ldd says:
$ ldd wiimote.so
linux-gate.so.1 => (0x00dfc000)
/usr/lib/libwiiuse.so (0x00f27000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x007dd000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00bad000)
libbluetooth.so.3 => /usr/lib/libbluetooth.so.3 (0x00696000)
/lib/ld-linux.so.2 (0x00fc2000)
libwiiuse.so defines the symbol wiiuse_find, but when I then go to load my library (in Lua, which uses dlopen):
lua: error loading module 'wiimote' from file '/home/hyperhacker/dev/lua/libs/wiimote.so':
/home/hyperhacker/dev/lua/libs/wiimote.so: undefined symbol: wiiuse_find
Seems at runtime, it can't find the symbols of libwiiuse now?
poxic wrote:You suck. And simultaneously rock. I think you've invented a new state of being.

Sandor
Posts: 180
Joined: Sat Feb 13, 2010 8:25 am UTC

Re: Shared library linking - undefined symbol

Postby Sandor » Fri Jun 11, 2010 3:51 pm UTC

'; DROP DATABASE;-- wrote:libwiiuse.so defines the symbol wiiuse_find, but when I then go to load my library (in Lua, which uses dlopen):
lua: error loading module 'wiimote' from file '/home/hyperhacker/dev/lua/libs/wiimote.so':
/home/hyperhacker/dev/lua/libs/wiimote.so: undefined symbol: wiiuse_find
Seems at runtime, it can't find the symbols of libwiiuse now?


Ar you sure the symbol is defined? Maybe the compilation went wrong. To check:

Code: Select all

nm -D /home/hyperhacker/dev/lua/libs/wiimote.so | grep wiiuse_find

User avatar
'; DROP DATABASE;--
Posts: 3284
Joined: Thu Nov 22, 2007 9:38 am UTC
Location: Midwest Alberta, where it's STILL snowy
Contact:

Re: Shared library linking - undefined symbol

Postby '; DROP DATABASE;-- » Fri Jun 11, 2010 10:21 pm UTC

Yep, it's there.

Code: Select all

00000920 T luaopen_wiimote
         U wiiuse_cleanup
         U wiiuse_connect
         U wiiuse_find
         U wiiuse_init
Would the U mean undefined? Why would that happen?
poxic wrote:You suck. And simultaneously rock. I think you've invented a new state of being.

Rysto
Posts: 1460
Joined: Wed Mar 21, 2007 4:07 am UTC

Re: Shared library linking - undefined symbol

Postby Rysto » Sat Jun 12, 2010 12:36 am UTC

Yes, U means undefined. That means that it's not there. There's something wrong with how you're linking the library.

Edit:

Code: Select all

$(LIBRARY).so: $(LIBRARY).o
   @echo MAKESO
   $(MAKESO) $(@) $(^)


Don't you want:

Code: Select all

$(LIBRARY).so: $(SHARED_OBJS)
   @echo MAKESO
   $(MAKESO) $(@) $(^)

User avatar
'; DROP DATABASE;--
Posts: 3284
Joined: Thu Nov 22, 2007 9:38 am UTC
Location: Midwest Alberta, where it's STILL snowy
Contact:

Re: Shared library linking - undefined symbol

Postby '; DROP DATABASE;-- » Sat Jun 12, 2010 1:30 am UTC

SHARED_OBJS is the object files from the "shared" directory (i.e. my own source files that are used in multiple programs); it's empty in this case.
poxic wrote:You suck. And simultaneously rock. I think you've invented a new state of being.

Rysto
Posts: 1460
Joined: Wed Mar 21, 2007 4:07 am UTC

Re: Shared library linking - undefined symbol

Postby Rysto » Sat Jun 12, 2010 3:59 am UTC

As the Makefile is currently written, only wiimote.o is making it into library. Are there any other source files?

User avatar
'; DROP DATABASE;--
Posts: 3284
Joined: Thu Nov 22, 2007 9:38 am UTC
Location: Midwest Alberta, where it's STILL snowy
Contact:

Re: Shared library linking - undefined symbol

Postby '; DROP DATABASE;-- » Sat Jun 12, 2010 4:31 am UTC

Nope. All one file.
Spoiler:

Code: Select all

/* Wiimote library for Lua
 * Created: May 31 2010 by HyperHacker
 */

//#define lwiimotelib_c
#define LUA_LIB
#include <stdlib.h>
#include <lua5.1/lua.h>
#include <lua5.1/lauxlib.h>
#include <lua5.1/lualib.h>

#ifdef __cplusplus
extern "C" {
#endif
#include <wiiuse.h>

static const char *InstTypeName = "WIIMOTELIB_INST";
typedef struct {
   wiimote **Wiimotes;
   int NumWiimotes; //# allowed
} WiiuseInstance;

static int wiimote_init (lua_State *Lua);
static int wiimote_search (lua_State *Lua);
static int wiimote_meta_gc (lua_State *Lua);

/* Initializes Wiimote library.
 * Inputs:
 * -Maximum number of Wiimotes to support.
 * Returns: Instance - A userdata that must be passed to all other functions.
 */
static int wiimote_init (lua_State *Lua) {
   int num = luaL_checknumber(Lua, 1);
   if(num < 1) return luaL_error(Lua, "Maximum Wiimotes must be at least 1.");
   WiiuseInstance *self = (WiiuseInstance*)lua_newuserdata(
      Lua, sizeof(WiiuseInstance));
   luaL_newmetatable(Lua, InstTypeName);
   lua_pushcfunction(Lua, wiimote_meta_gc);
   lua_pushstring(Lua, "__gc");
   lua_settable(Lua, -4);
   lua_setmetatable(Lua, -2);
   self->NumWiimotes = num;
   self->Wiimotes = wiiuse_init(num);
   return 1;
}

/* Searches for Wiimotes.
 * Inputs:
 * -Library instance.
 * -Number of seconds to spend searching.
 * Returns:
 * -Number of Wiimotes found
 * -Number connected
 */
static int wiimote_search (lua_State *Lua) {
   WiiuseInstance *self = (WiiuseInstance*)luaL_checkudata(Lua,1,InstTypeName);
   int time = luaL_checkinteger(Lua, 2);
   int num = wiiuse_find(self->Wiimotes, self->NumWiimotes, time);
   if(!num) {
      lua_pushinteger(Lua, 0);
      lua_pushinteger(Lua, 0);
      return 2;
   }
   int numconnect = wiiuse_connect(self->Wiimotes, self->NumWiimotes);
   lua_pushinteger(Lua, num);
   lua_pushinteger(Lua, numconnect);
   return 2;
}

/* __gc metamethod.
 * Inputs:
 * -Library instance.
 */
static int wiimote_meta_gc (lua_State *Lua) {
   WiiuseInstance *self = (WiiuseInstance*)luaL_checkudata(Lua,1,InstTypeName);
   wiiuse_cleanup(self->Wiimotes, self->NumWiimotes);
   return 0;
}


static const luaL_Reg libfuncs[] = {
   {"init",   wiimote_init},
   {"search",   wiimote_search},
   {NULL, NULL}
};

/*
** Open Wiimote library
*/
LUALIB_API int LUAOPENFUNC (lua_State *Lua) {
   luaL_register(Lua, LUANAME, libfuncs);
   
   lua_createtable(Lua, 0, 1); //_info = {
   
      lua_pushstring(Lua, "version");
      lua_pushinteger(Lua, BUILD_ID);
      lua_settable(Lua, -3);
      
      lua_pushstring(Lua, "luaver"); //Lua version library was written for
      lua_pushstring(Lua, "5.1"); //not guaranteed to work on others
      lua_settable(Lua, -3);
   
      lua_pushstring(Lua, "build_date"); //build_date =
      lua_createtable(Lua, 0, 3); //{
   
         lua_pushstring(Lua, "year");
         lua_pushnumber(Lua, BUILD_YEAR+2000);
         lua_settable(Lua, -3);
   
         lua_pushstring(Lua, "month");
         lua_pushnumber(Lua, BUILD_MONTH);
         lua_settable(Lua, -3);
   
         lua_pushstring(Lua, "day");
         lua_pushnumber(Lua, BUILD_DAY);
         lua_settable(Lua, -3);
   
      lua_settable(Lua, -3); // }, --build_date
   
      lua_pushstring(Lua, "author");
      lua_pushstring(Lua, "HyperHacker");
      lua_settable(Lua, -3);
      
      lua_pushstring(Lua, "license");
      lua_pushstring(Lua, "GPLv3");
      lua_settable(Lua, -3);
      
      lua_pushstring(Lua, "purpose");
      lua_pushstring(Lua, "Interface with Wii Remotes.");
      lua_settable(Lua, -3);
      
      lua_pushstring(Lua, "credits");
      lua_pushstring(Lua, "Uses libWiiuse (http://www.wiiuse.net).");
      lua_settable(Lua, -3);
      
      lua_pushstring(Lua, ".hack");
      lua_pushstring(Lua, "is awesome.");
      lua_settable(Lua, -3);
   
   lua_setfield(Lua, -2, "_info"); // } --_info
   
/*  lua_pushnumber(L, PI);
  lua_setfield(L, -2, "pi"); */
  return 1;
}

#ifdef __cplusplus
}
#endif

Tried without the extern "C" as well. All the lua_ and luaL_ symbols are also showing up as undefined.
poxic wrote:You suck. And simultaneously rock. I think you've invented a new state of being.

User avatar
PM 2Ring
Posts: 3715
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Shared library linking - undefined symbol

Postby PM 2Ring » Sat Jun 12, 2010 7:37 am UTC

I have't done any coding that involves making shared libraries for many years, and that was on the Amiga, so feel free to ignore me, but I suspect that you have some kind of name-mangling issue.

0xBADFEED
Posts: 687
Joined: Mon May 05, 2008 2:14 am UTC

Re: Shared library linking - undefined symbol

Postby 0xBADFEED » Sat Jun 12, 2010 3:13 pm UTC

PM 2Ring wrote:I have't done any coding that involves making shared libraries for many years, and that was on the Amiga, so feel free to ignore me, but I suspect that you have some kind of name-mangling issue.

It seems like everything is being declared with C-linkage correctly and the symbols do not appear to be mangled, so mangling shouldn't be an issue.

I'm not really up on my C semantics, but declaring a function 'static' indicates that the function should be local to the translation unit. I'm not sure what the implications are for exporting a symbol declared as 'static', but this seems very suspect.

User avatar
PM 2Ring
Posts: 3715
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Shared library linking - undefined symbol

Postby PM 2Ring » Sat Jun 12, 2010 4:37 pm UTC

0xBADFEED wrote:I'm not really up on my C semantics, but declaring a function 'static' indicates that the function should be local to the translation unit. I'm not sure what the implications are for exporting a symbol declared as 'static', but this seems very suspect.

It's exceedingly suspect!
Kernighan & Ritchie 2, p83 wrote:The static declaration, applied to an external variable or function, limits the scope of that object to the rest of the source file being compiled.
[...]
Normally, function names are global, visible in any part of the entire program. If a function is declared static, however, its name is invisible outside of the file in which it is declared.

User avatar
'; DROP DATABASE;--
Posts: 3284
Joined: Thu Nov 22, 2007 9:38 am UTC
Location: Midwest Alberta, where it's STILL snowy
Contact:

Re: Shared library linking - undefined symbol

Postby '; DROP DATABASE;-- » Sat Jun 12, 2010 8:52 pm UTC

Well that makes sense, and after changing that, wiimote_* show up as 'T' from nm, but wiiuse_* and lua_* are still undefined.
poxic wrote:You suck. And simultaneously rock. I think you've invented a new state of being.


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 9 guests