How do you force link time symbol resolution to a particular library on linux g++

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



here is what we are trying to do

1. we have 2, 3rd party DMAPI libraries libdmapi.so(for gpfs) and
libdm.so(for xfs)

2. we have a base class (class lowlevel) with virtual interfaces, we
have two derived classes which
derive from lowlevel.cpp gpfslowlevel.cpp and xfslowlevel.cpp

3. each of the derived classes are packaged into their own .so and
each one individually links
with the respective 3rd party dmapi library.

(There is another layer in between the lowlevel and the 3rd party
DMAPI but I have left
it out for simplicity here)

4. we create a top level shared object called lowlevel.so which is
used by all the apps.


so the app will create a lowlevel object depending on which FS we deal
with at run time.
and then it makes calls on that object. Depending on which object is
making the call,
it should get routed to the right 3rd party DMAPI library.

but what is happening is that all calls are getting routed to the
first 3rd party dmapi library that
gets loaded, the first one that gets loaded is always the one that
appears first in the order of
libraries to be linked in the makefile.


***so that question is , is there a way to force symbol resolution to
happen to a particular
library at link time on linux? (w/o using an explicit dlopen call)***

I got this working on AIX. things gets routed properly to the right
library depending on which
object is making the calls.

I used -qmkshrobj on AIX WITHOUT the -brtl option. -brtl enables run
time linking.


I am attaching the code on both AIX and Linux.

(to make the binaries just execute the Makefile (so its a file with
all the commands not a real makefile).)
(to run the library run ./main)
going through the source and the makefiles may be a little laborious.

I thank you for your patience :) and would appreciate any help in the matter.

thanks
Sudha




begin DMAPI.cpp
===========

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>


/* Include FS specifc dmapi jheader files */
#include "DMAPI.h"
#ifdef XFSDMAPI
//xfs dmapi.h in linux src code path
///usr///src/linux-2.6.5-7.244/fs/dmapi/dmapi.h
#include <dmapi.h>
#endif

#ifdef GPFSDMAPI
//in /usr/include/dmapi.h on both linux + aix
#include <dmapi.h>
#endif

#ifdef JFSDMAPI
#include <sys/dmapi.h>
#endif



extern int errno;

char*
FS_DMAPI::init_dmapi(void)
{
       const char * func="DMAPI::init";

#ifdef JFSDMAPI
	logfile="/tmp/jfsdmapi.log";
#endif
#ifdef XFSDMAPI
	logfile="/tmp/xfsdmapi.log";
#endif
#ifdef GPFSDMAPI
	logfile="/tmp/gpfsdmapi.log";
#endif
       fprintf(stdout, "opening logfile %s for writing\n", logfile);

	if ((logfp = fopen(logfile, "a")) == NULL) {
       printf("Unable to open logfile %s for writing\n", logfile);
       exit(-1);
	}
       if (dmapi_ver==0 && dm_init_service(&dmapi_ver)<0) {
               fprintf(logfp, "Failed to initialize DMAPI service: %s\n",
			strerror(errno));
		exit(-1);
	}
	
	fprintf(stdout, "Initialized DMAPI service successfully: %s\n",
			dmapi_ver);
	fprintf(logfp, "Initialized DMAPI service successfully: %s\n",
			dmapi_ver);
	fflush(logfp);
       return dmapi_ver;


}

void
FS_DMAPI::print_objtype(void)
{
#ifdef GPFSDMAPI
	fprintf(logfp, "GPFS\n");
	printf("GPFS\n");
#elif XFSDMAPI
	printf("XFS\n");
#elif JFSDMAPI
	fprintf(logfp, "JFS\n");
	printf("JFS\n");
#endif
	char *a = new char;
}
======================================= end DMAPI.cpp
begin DMAPI.h
===========

#ifndef DMAPI_H
#define DMAPI_H
#include <stdio.h>
#include <string.h>

namespace FS_DMAPI {
	char* init_dmapi(void);
	void print_objtype(void);
	static char *dmapi_ver;
	static char *logfile;
	static FILE *logfp;	
};

#endif /* DMAPI_H */
======================================= end DMAPI.h
begin fs_lowlevel.cpp
===========

#include <stdio.h>
#include "lowlevel.h"
#include "jfs_lowlevel.h"
#include "gpfs_lowlevel.h"
#include "xfs_lowlevel.h"
#include "DMAPI.h"

char*
fs_lowlevel::init_dmapi(void)
{
	char *v;
       v = FS_DMAPI::init_dmapi();
	printf("fs_lowlevel: v : %s\n", v);
	return v;
}

void
fs_lowlevel::print_objtype()
{
       FS_DMAPI::print_objtype();
}

fs_lowlevel::fs_lowlevel()
{
#if 0
	fprintf(stdout, "Creating DMAPI object for FS %s\n", fs);
	po_dm = DMAPI::create(fs);
#endif
}

fs_lowlevel::~fs_lowlevel()
{
#if 0
	delete po_dm;
#endif

}

#if 0

char*
fs_lowlevel::init_dmapi(void)
{
       return(po_dm->init_dmapi());
}

void
fs_lowlevel::print_objtype()
{
       po_dm->print_objtype();
}
#endif
======================================= end fs_lowlevel.cpp
begin fs_lowlevel.h
===========

#ifndef FS_LOWLEVEL_H
#define FS_LOWLEVEL_H

#include "DMAPI.h"
class fs_lowlevel : public lowlevel {
public:
	char* init_dmapi(void);
       void print_objtype(void);
};
#endif
======================================= end fs_lowlevel.h
begin GPFS_DMAPI.h
===========

#ifndef GPFS_DMAPI_H
#define GPFS_DMAPI_H
#include <stdio.h>
#include <string.h>

namespace GPFS_DMAPI {
	char* init_dmapi(void);
	void print_objtype(void);
	/*static*/ char *dmapi_ver;
	/*static*/ char *logfile;
	/*static*/ FILE *logfp;	
};
#if 0
char* GPFS_DMAPI::logfile="/tmp/gpfsdmapi.log";
char* GPFS_DMAPI::dmapi_ver=NULL;
FILE* GPFS_DMAPI::logfp=NULL;
#endif
#endif /* DMAPI_H */
======================================= end GPFS_DMAPI.h
begin gpfs_lowlevel.h
===========

#ifndef GPFS_LOWLEVEL_H
#define GPFS_LOWLEVEL_H

#include "DMAPI.h"

class gpfs_lowlevel : public lowlevel {
public:
	gpfs_lowlevel();
	~gpfs_lowlevel();
	char* init_dmapi(void);
       void print_objtype(void);
};
#endif
======================================= end gpfs_lowlevel.h
begin JFS_DMAPI.h
===========

#ifndef JFS_DMAPI_H
#define JFS_DMAPI_H
#include <stdio.h>
#include <string.h>

namespace JFS_DMAPI {
	char* init_dmapi(void);
	void print_objtype(void);
/* making these variables /*static*/ does not work for some reason */
	/*static*/ char *dmapi_ver;
	/*static*/ char *logfile;
	/*static*/ FILE *logfp;	
};
#if 0
static char* JFS_DMAPI::logfile="/tmp/gpfsdmapi.log";
static char* JFS_DMAPI::dmapi_ver=NULL;
static FILE* JFS_DMAPI::logfp=NULL;
#endif
#endif /* DMAPI_H */
======================================= end JFS_DMAPI.h
begin jfs_lowlevel.h
===========

#ifndef JFS_LOWLEVEL_H
#define JFS_LOWLEVEL_H

#include "DMAPI.h"

class jfs_lowlevel : public lowlevel {
public:
	jfs_lowlevel();
	~jfs_lowlevel();
	char* init_dmapi(void);
       void print_objtype(void);
};
#endif
======================================= end jfs_lowlevel.h
begin lowlevel.cpp
===========

#include<stdio.h>
#include "lowlevel.h"
#include "gpfs_lowlevel.h"
#include "xfs_lowlevel.h"
#include <string.h>


#define JFS 0
#define GPFS 1
/*
main() {
       lowlevel *pobj;
       lowlevel *pobj1;

       pobj = lowlevel::create(0);
       pobj->init_dmapi();
       pobj1 = lowlevel::create(1);
       pobj1->init_dmapi();

       pobj->get_print_token();
       pobj1->get_print_token();
}
*/

lowlevel*
lowlevel :: create(char* fs)
{
	lowlevel *pd;
	if (!strcasecmp(fs, "gpfs"))
	{
		printf("creating gpfs lowlevel obj\n");
		pd = new gpfs_lowlevel();
	}
	if (!strcasecmp(fs, "xfs"))
	{
		printf("creating xfs lowlevbel obj\n");
		pd = new xfs_lowlevel();
	}
	return pd;
}
======================================= end lowlevel.cpp
begin lowlevel.h
===========

#ifndef LOWLEVEL_H
#define LOWLEVEL_H

#include<stdio.h>

class lowlevel
{
public:
static  lowlevel* create(char *fstype);
	virtual char* init_dmapi(void) = 0;
	virtual void print_objtype(void) = 0;
};
#endif
======================================= end lowlevel.h
begin main.cpp
===========

#include<stdio.h>
#include "lowlevel.h"

#if 0
#include "JFS_DMAPI.h"
#include "GPFS_DMAPI.h"
#endif

main() {
       lowlevel *pobj, *pobj1;
       pobj = lowlevel::create("xfs");
       if (pobj != NULL) {
               pobj->init_dmapi();
               pobj->print_objtype();
       } else {
               printf("pobj is NULL\n");
       }

       char *a = new char;
       pobj1 = lowlevel::create("gpfs");
       pobj1->init_dmapi();
       pobj1->print_objtype();
#if 0
       JFS_DMAPI pobj;
       GPFS_DMAPI pobj1;

       pobj.init_dmapi();
       pobj1.init_dmapi();
#endif
}
======================================= end main.cpp
begin xfs_lowlevel.h
===========

#ifndef XFS_LOWLEVEL_H
#define XFS_LOWLEVEL_H

#include "DMAPI.h"

class xfs_lowlevel : public lowlevel {
public:
	xfs_lowlevel();
	~xfs_lowlevel();
	char* init_dmapi(void);
       void print_objtype(void);
};
#endif
======================================= end xfs_lowlevel.h

Makefile
=======================================

# makefile w/o rtl + with namespace
ROOTDIR=`pwd`/..
CURDIR=`pwd`
BINDIR=`pwd`
#OPT="-qexpfile="
#OPT=-bE:
OPT=--version-script=
CC=/usr/bin/gcc

#create fs specific header files. I am not doign that here. That needs
#to be done.
#create the FS specific .o
${CC} -c -fPIC -frepo -g -DFS_DMAPI=XFS_DMAPI -DXFSDMAPI -o XFSDMAPI.o
DMAPI.cpp

${CC} -c -fPIC -frepo -g -DFS_DMAPI=GPFS_DMAPI -DGPFSDMAPI -o
GPFSDMAPI.o DMAPI.cpp

#create the fs specific DMAPI library.
#create the exports file
g++  -shared -fPIC   ${OPT}xfs_mapfile -frepo  -pthread -DUNIX
-D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -D_FILE_OFFSET_BITS=64
-DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR
-DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS
-DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat
-Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn
-DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4
-DSIZEOF_LONGLONG=8 -DSOCKLEN_T.acklen_t -DFDSET=fd_set -DHAVE_ERRNO_H
-DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME -DGETHOSTBYNAME_R_6
-DGETSERVBYNAME_R_6 -DNO_LONGLONG_T -DNO_U_LONGLONG_T -DTIME_R_RET_TM
-DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2 -DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS
-DNO_USHORT_T -DNO_UINT_T -DHAVE_X_PUTINT32 -DATFORK_ARG=void
-DLINUX_ACL -gstabs+ -Wl,-rpath-link=. -Wl,-rpath=. -L. -shared
-shared-libgcc XFSDMAPI.o -L. -L/lib -o libXFSDMAPI.so -ldm

g++ -shared -fPIC  ${OPT}gpfs_mapfile  -frepo  -pthread -DUNIX
-D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -D_FILE_OFFSET_BITS=64
-DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR
-DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS
-DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat
-Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn
-DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4
-DSIZEOF_LONGLONG=8 -DSOCKLEN_T.acklen_t -DFDSET=fd_set -DHAVE_ERRNO_H
-DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME -DGETHOSTBYNAME_R_6
-DGETSERVBYNAME_R_6 -DNO_LONGLONG_T -DNO_U_LONGLONG_T -DTIME_R_RET_TM
-DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2 -DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS
-DNO_USHORT_T -DNO_UINT_T -DHAVE_X_PUTINT32 -DATFORK_ARG=void
-DLINUX_ACL -gstabs+ -Wl,-rpath-link=. -Wl,-rpath=. -L. -shared
-shared-libgcc GPFSDMAPI.o -L. -o libGPFSDMAPI.so -ldmapi

#${CC} -qmkshrobj -g  -Wl,-bh:5 -qchars=signed -qinfo=pro -qcpluscmt
-DUNIX -Dunix -D_SVID3 -DAIX_FS_U -Dmthreads -DCV_POSIX_THREADS
-DPOSIX_THREADS -D_PTHREADS -D_THREAD_SAFE -D_LARGE_FILES -DENABLE_NAS
-DENABLE_DMAPI -DENABLE_DMR -Daix -DUNIX -Dunix -DNO_JM_EXCEPTIONS
-DNO_RSM -DNO_MMALERTS -DMAX_PATH=1024 -DCARCH=32 -DCV_BIG_ENDIAN
-DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONGLONG=8
-DSOCKLEN_T=socklen_t -DFDSET=fd_set -DHAVE_ERRNO_H -DHAVE_GRANTPT
-DCONST_ICONV_IPTR -DHAVE_GETHOSTNAME -DGETHOSTBYNAME_R_3
-DGETSERVBYNAME_R_4 -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2 -DSTRTOK_R3
-DPWNAM_R5 -DHAVE_VFS -DHAVE_X_PUTINT32 -DHAVE_X_PUTHYPER
-DATFORK_ARG=void -DSOCKADDR_FAMILY_AT_2ND_BYTE -L${BINDIR} -o
libDMAPI.so -lGPFSDMAPI -lJFSDMAPI


${CC} -c -fPIC -frepo   -g -Dfs_lowlevel=xfs_lowlevel -DXFSLOWLEVEL
-DFS_DMAPI=XFS_DMAPI -DXFSDMAPI -o XFSLOWLEVEL.o fs_lowlevel.cpp

${CC} -c  -fPIC -frepo  -g -Dfs_lowlevel=gpfs_lowlevel -DGPFSLOWLEVEL
-DFS_DMAPI=GPFS_DMAPI -DGPFSDMAPI -o GPFSLOWLEVEL.o fs_lowlevel.cpp


#create the fs specific DMAPI library.
#create the exports file
g++ -shared -fPIC  ${OPT}xfs_llmapfile   -frepo  -pthread -DUNIX
-D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -D_FILE_OFFSET_BITS=64
-DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR
-DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS
-DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat
-Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn
-DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4
-DSIZEOF_LONGLONG=8 -DSOCKLEN_T=socklen_t -DFDSET=fd_set
-DHAVE_ERRNO_H -DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME
-DGETHOSTBYNAME_R_6 -DGETSERVBYNAME_R_6 -DNO_LONGLONG_T
-DNO_U_LONGLONG_T -DTIME_R_RET_TM -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2
-DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DNO_USHORT_T -DNO_UINT_T
-DHAVE_X_PUTINT32 -DATFORK_ARG=void -DLINUX_ACL -gstabs+
-Wl,-rpath-link=. -Wl,-rpath=. -shared-libgcc XFSLOWLEVEL.o -L. -o
libXFSLOWLEVEL.so -lXFSDMAPI

g++ -shared -fPIC  ${OPT}gpfs_llmapfile   -frepo  -pthread -DUNIX
-D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -D_FILE_OFFSET_BITS=64
-DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR
-DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS
-DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat
-Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn
-DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4
-DSIZEOF_LONGLONG=8 -DSOCKLEN_T=socklen_t -DFDSET=fd_set
-DHAVE_ERRNO_H -DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME
-DGETHOSTBYNAME_R_6 -DGETSERVBYNAME_R_6 -DNO_LONGLONG_T
-DNO_U_LONGLONG_T -DTIME_R_RET_TM -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2
-DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DNO_USHORT_T -DNO_UINT_T
-DHAVE_X_PUTINT32 -DATFORK_ARG=void -DLINUX_ACL -gstabs+
-Wl,-rpath-link=. -Wl,-rpath=. -shared-libgcc GPFSLOWLEVEL.o -L. -o
libGPFSLOWLEVEL.so -lGPFSDMAPI

g++ -shared -fPIC ${OPT}ll_mapfile   -frepo  -pthread -DUNIX
-D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -D_FILE_OFFSET_BITS=64
-DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR
-DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS
-DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat
-Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn
-DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4
-DSIZEOF_LONGLONG=8 -DSOCKLEN_T=socklen_t -DFDSET=fd_set
-DHAVE_ERRNO_H -DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME
-DGETHOSTBYNAME_R_6 -DGETSERVBYNAME_R_6 -DNO_LONGLONG_T
-DNO_U_LONGLONG_T -DTIME_R_RET_TM -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2
-DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DNO_USHORT_T -DNO_UINT_T
-DHAVE_X_PUTINT32 -DATFORK_ARG=void -DLINUX_ACL -gstabs+
-Wl,-rpath-link=. -Wl,-rpath=. -L. -shared-libgcc -I${ROOTDIR}/DMAPI
-L${BINDIR} -o libLOWLEVEL.so lowlevel.cpp -lGPFSLOWLEVEL
-lXFSLOWLEVEL

g++ -pthread -fPIC -DUNIX -D_PTHREADS -DCV_POSIX_THREADS
-DPOSIX_THREADS -DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI
-DENABLE_CDR -DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS
-DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat
-Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn
-DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4
-DSIZEOF_LONGLONG=8 -DSOCKLEN_T=socklen_t -DFDSET=fd_set
-DHAVE_ERRNO_H -DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME
-DGETHOSTBYNAME_R_6 -DGETSERVBYNAME_R_6 -DNO_LONGLONG_T
-DNO_U_LONGLONG_T -DTIME_R_RET_TM -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2
-DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DNO_USHORT_T -DNO_UINT_T
-DHAVE_X_PUTINT32 -DATFORK_ARG=void -DLINUX_ACL -gstabs+
-Wl,-rpath-link=. -Wl,-rpath=. -L. -shared-libgcc -L${BINDIR} -o main
main.cpp -lLOWLEVEL

========================================================== end of Makefile

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux