- in bochs-testing area, check in shared library tests that I wrote while

trying to get plugins working on Cygwin.

Added Files:
	Makefile
	test1-static/*
	test2-dynamic/*
	test3-twomodules/*
	test4-interdep/*
This commit is contained in:
Bryce Denney 2002-10-11 14:51:27 +00:00
parent 51aa1fc3f0
commit 059b59c98e
27 changed files with 329 additions and 0 deletions

View File

@ -0,0 +1,7 @@
SUBDIRS = test1-static test2-dynamic test3-twomodules test4-interdep
all:
for i in $(SUBDIRS); do make -C $$i all; done
clean:
for i in $(SUBDIRS); do make -C $$i clean; done

View File

@ -0,0 +1,18 @@
CXX=g++
CXXFLAGS=-Wall -g
LIBTOOL=libtool
all: uselib
uselib: uselib.cc libmodule1.la
$(LIBTOOL) $(CXX) $(CXXFLAGS) -o uselib uselib.cc libmodule1.la
libmodule1.la: module1.lo
$(LIBTOOL) $(CXX) -o libmodule1.la module1.lo
%.lo: %.cc
$(LIBTOOL) $(CXX) -c $<
clean:
-libtool rm libmodule1.la module1.lo uselib.exe uselib
rm -rf .libs

View File

@ -0,0 +1,4 @@
test1-static
Use libtool to build module1 as a static library, and then use it in
uselib.cc.

View File

@ -0,0 +1,8 @@
#include "module1.h"
const char *module_name = "AddModule";
int operate (int a, int b)
{
return a + b;
}

View File

@ -0,0 +1,2 @@
extern const char *module_name;
extern int operate (int a, int b);

View File

@ -0,0 +1,13 @@
#include <stdio.h>
#include "module1.h"
int main ()
{
printf ("start\n");
printf ("Module name is '%s'\n", module_name);
int a=5, b=12;
int c = operate (a, b);
printf ("operate(%d,%d) = %d\n", a, b, c);
printf ("stop\n");
return 0;
}

View File

@ -0,0 +1,22 @@
CXX=g++
CXXFLAGS=-Wall -g
LIBTOOL=libtool
RPATH=`pwd`/lib
all: uselib
uselib: uselib.cc libmodule1.la
$(LIBTOOL) $(CXX) $(CXXFLAGS) -o uselib uselib.cc libmodule1.la
libmodule1.la: module1.lo
$(LIBTOOL) $(CXX) -no-undefined -o libmodule1.la module1.lo -rpath ${RPATH}
mkdir -p lib bin
$(LIBTOOL) cp libmodule1.la ${RPATH}
%.lo: %.cc
$(LIBTOOL) $(CXX) -c $<
clean:
-libtool rm libmodule1.la module1.lo
rm -rf *.o uselib.exe bin lib uselib uselib.exe
rm -rf .libs

View File

@ -0,0 +1,38 @@
test2-dynamic
In this directory I use the same source code as test1-static, but
I try to build a shared library instead. To build a shared library
for libmodule1.la, first I add the -rpath variable. This makes libtool
attempt to build shared libraries, but it gives this warning:
libtool: link: warning: undefined symbols not allowed in i686-pc-cygwin shared libraries
Then it proceeds to build only static libraries. So I add -no-undefined to
the link of libmodule1.la. This makes it actually build a shared library.
When it does the libtool install step, I see that these files were installed:
-rwxr-xr-x 1 bryce unknown 668055 Oct 11 02:40 bin/cygmodule1-0.dll
-rw-r--r-- 1 bryce unknown 664 Oct 11 02:40 lib/libmodule1.a
-rw-r--r-- 1 bryce unknown 2946 Oct 11 02:40 lib/libmodule1.dll.a
-rw-r--r-- 1 bryce unknown 728 Oct 11 02:40 lib/libmodule1.la
File types are
bin/cygmodule1-0.dll: MS Windows PE Intel 80386 console DLL
lib/libmodule1.a: current ar archive
lib/libmodule1.dll.a: current ar archive
lib/libmodule1.la: ASCII English text
But, trying to link with this shared library fails.
libtool g++ -Wall -g -o uselib uselib.cc libmodule1.la
g++ -Wall -g -o .libs/uselib uselib.cc .libs/libimp-cygmodule1-0.a -Wl,--rpath -Wl,/home/bryce/plugin-test/test2-dynamic/lib
Warning: resolving _module_name by linking to __imp__module_name (auto-import)
fu000001.o(.idata$3+0xc): undefined reference to `_libs_libimp_cygmodule1_0_a_iname'
nmth000000.o(.idata$4+0x0): undefined reference to `_nm__module_name'
collect2: ld returned 1 exit status
make: *** [uselib] Error 1
Then I finally read about __declspec(dllexport) and __declspec(dllimport).
When compiling the module I add __declspec(dllexport) on data and functions.
When using the module, the prototypes for say __declspec(dllimport).
Now it works!

View File

@ -0,0 +1,9 @@
#define DLLINTERFACE __declspec(dllexport)
#include "module1.h"
const char *module_name = "AddModule";
int operate (int a, int b)
{
return a + b;
}

View File

@ -0,0 +1,6 @@
#ifndef DLLINTERFACE
#define DLLINTERFACE __declspec(dllimport)
#endif
DLLINTERFACE extern const char * module_name;
DLLINTERFACE extern int operate (int a, int b);

View File

@ -0,0 +1,13 @@
#include <stdio.h>
#include "module1.h"
int main ()
{
printf ("start\n");
printf ("Module name is '%s'\n", module_name);
int a=5, b=12;
int c = operate (a, b);
printf ("operate(%d,%d) = %d\n", a, b, c);
printf ("stop\n");
return 0;
}

View File

@ -0,0 +1,27 @@
CXX=g++
CXXFLAGS=-Wall -g
LIBTOOL=libtool
RPATH=`pwd`/lib
all: uselib
uselib: uselib.cc libmodule1.la libmodule2.la
$(LIBTOOL) $(CXX) $(CXXFLAGS) -o uselib uselib.cc libmodule1.la libmodule2.la
libmodule1.la: module1.lo
$(LIBTOOL) $(CXX) -no-undefined -o libmodule1.la module1.lo -rpath ${RPATH}
mkdir -p lib bin
$(LIBTOOL) cp libmodule1.la ${RPATH}
libmodule2.la: module2.lo
$(LIBTOOL) $(CXX) -no-undefined -o libmodule2.la module2.lo -rpath ${RPATH}
mkdir -p lib bin
$(LIBTOOL) cp libmodule2.la ${RPATH}
%.lo: %.cc
$(LIBTOOL) $(CXX) -c $<
clean:
-libtool rm libmodule1.la module1.lo libmodule2.la module2.lo
rm -rf *.o uselib.exe bin lib uselib uselib.exe
rm -rf .libs

View File

@ -0,0 +1,8 @@
test3
Add a second module
module1 exports module_name and operate(int,int).
module2 exports n_operations
Both are used in uselib.cc. They don't use each other's symbols.

View File

@ -0,0 +1,11 @@
#define DLLINTERFACE __declspec(dllexport)
#include "module1.h"
#undef DLLINTERFACE
#include "module2.h"
const char *module_name = "AddModule";
int operate (int a, int b)
{
return a + b;
}

View File

@ -0,0 +1,7 @@
#ifndef DLLINTERFACE
#define DLLINTERFACE __declspec(dllimport)
#endif
DLLINTERFACE extern const char * module_name;
DLLINTERFACE extern int operate (int a, int b);

View File

@ -0,0 +1,12 @@
#include <stdio.h>
#define DLLINTERFACE __declspec(dllexport)
#include "module2.h"
#undef DLLINTERFACE
int n_operations = 0;
void operation_occurred () {
printf ("module2: operation_occurred\n");
n_operations++;
}

View File

@ -0,0 +1,7 @@
#ifndef DLLINTERFACE
#define DLLINTERFACE __declspec(dllimport)
#endif
DLLINTERFACE extern int n_operations;
DLLINTERFACE void operation_occurred ();

View File

@ -0,0 +1,17 @@
#include <stdio.h>
#include "module1.h"
#include "module2.h"
int main ()
{
printf ("start\n");
printf ("at first, n_operations = %d\n", n_operations);
printf ("Module name is '%s'\n", module_name);
int a=5, b=12;
int c = operate (a, b);
operation_occurred ();
printf ("operate(%d,%d) = %d\n", a, b, c);
printf ("stop\n");
printf ("at end, n_operations = %d\n", n_operations);
return 0;
}

View File

@ -0,0 +1 @@
extern int n_operations;

View File

@ -0,0 +1,27 @@
CXX=g++
CXXFLAGS=-Wall -g
LIBTOOL=libtool
RPATH=`pwd`/lib
all: uselib
uselib: uselib.cc libmodule1.la libmodule2.la
$(LIBTOOL) $(CXX) $(CXXFLAGS) -o uselib uselib.cc libmodule1.la libmodule2.la
libmodule1.la: module1.lo libmodule2.la
$(LIBTOOL) $(CXX) -no-undefined -o libmodule1.la module1.lo -rpath ${RPATH} libmodule2.la
mkdir -p lib bin
$(LIBTOOL) cp libmodule1.la ${RPATH}
libmodule2.la: module2.lo
$(LIBTOOL) $(CXX) -no-undefined -o libmodule2.la module2.lo -rpath ${RPATH}
mkdir -p lib bin
$(LIBTOOL) cp libmodule2.la ${RPATH}
%.lo: %.cc
$(LIBTOOL) $(CXX) -c $<
clean:
-libtool rm libmodule1.la module1.lo libmodule2.la module2.lo
rm -rf *.o uselib.exe bin lib uselib uselib.exe
rm -rf .libs

View File

@ -0,0 +1,17 @@
test4-interdep
Can one module reference objects in another module? Yes.
module1 exports module_name and operate(int,int).
module2 exports n_operations and operation_occurred().
uselib.cc uses symbols and functions from both modules.
Module1 calls operation_occurred() in module2.
To do this, module2 must be built first. Then module1 is linked
against module2 so that the missing symbols are available. Then,
uselib is linked against both.
This shows that we can chain libraries. I haven't seen any way to
resolve a circular dependency, where mod1 depends on mod2 and vice
versa, in win32 DLLs. Probably those are not supported.

View File

@ -0,0 +1,12 @@
#define DLLINTERFACE __declspec(dllexport)
#include "module1.h"
#undef DLLINTERFACE
#include "module2.h"
const char *module_name = "AddModule";
int operate (int a, int b)
{
operation_occurred ();
return a + b;
}

View File

@ -0,0 +1,7 @@
#ifndef DLLINTERFACE
#define DLLINTERFACE __declspec(dllimport)
#endif
DLLINTERFACE extern const char * module_name;
DLLINTERFACE extern int operate (int a, int b);

View File

@ -0,0 +1,12 @@
#include <stdio.h>
#define DLLINTERFACE __declspec(dllexport)
#include "module2.h"
#undef DLLINTERFACE
int n_operations = 0;
void operation_occurred () {
printf ("module2: operation_occurred\n");
n_operations++;
}

View File

@ -0,0 +1,7 @@
#ifndef DLLINTERFACE
#define DLLINTERFACE __declspec(dllimport)
#endif
DLLINTERFACE extern int n_operations;
DLLINTERFACE void operation_occurred ();

View File

@ -0,0 +1,16 @@
#include <stdio.h>
#include "module1.h"
#include "module2.h"
int main ()
{
printf ("start\n");
printf ("at first, n_operations = %d\n", n_operations);
printf ("Module name is '%s'\n", module_name);
int a=5, b=12;
int c = operate (a, b);
printf ("operate(%d,%d) = %d\n", a, b, c);
printf ("stop\n");
printf ("at end, n_operations = %d\n", n_operations);
return 0;
}

View File

@ -0,0 +1 @@
extern int n_operations;