[project @ 2000-05-12 15:59:37 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / Makefile.DLLs
1 #-----------------------------------------------------------------------------#
2
3 # Makefile.DLLs, version 0.7.
4
5 # This Makefile contains rules for creating DLLs on Windows using gnu-win32.
6
7 #-----------------------------------------------------------------------------#
8
9 # The SYM_PREFIX is used as a prefix for the symbols in the files
10 # that this makefiles automatically generates.
11 #
12 # The default SYM_PREFIX for libfoo.dll is `libfoo'.
13 # But you can override this by setting `SYM_PREFIX-libfoo = blah'.
14
15 SYM_PREFIX = $(firstword $(SYM_PREFIX-$*) $*)
16
17 GUARD_MACRO =           $(SYM_PREFIX)_GLOBALS_H
18 DEFINE_DLL_MACRO =      $(SYM_PREFIX)_DEFINE_DLL
19 USE_DLL_MACRO =         $(SYM_PREFIX)_USE_DLL
20 IMP_MACRO =             $(SYM_PREFIX)_IMP
21 GLOBAL_MACRO =          $(SYM_PREFIX)_GLOBAL
22 IMPURE_PTR =            $(SYM_PREFIX)_impure_ptr
23
24 # This rule creates a `.def' file, which lists the symbols that are exported
25 # from the DLL.  We use `nm' to get a list of all the exported text (`T')
26 # symbols and data symbols -- including uninitialized data (`B'),
27 # initialized data (`D'), read-only data (`R'), and common blocks (`C').
28 # We also export `_impure_ptr', suitably renamed, so that the 
29 # main program can do the necessary initialization of the DLL's _impure_ptr.
30 # (Since there can be more than one DLL, we must rename _impure_ptr as
31 # $(SYM_PREFIX)_impure_ptr to prevent name collisions.)
32 #%.def: %.a
33 #       echo EXPORTS > $@
34 #       echo $(IMPURE_PTR) = _impure_ptr >> $@
35 #       nm $< | sed -n '/^........ [BCDRT] _/s/[^_]*_//p' >> $@
36
37 # We need to use macros to access global data:
38 # the user of the DLL must refer to `bar' as `(*__imp_bar)'.
39 # This rule creates a pair of files `foo_dll.h' and `foo_globals.h'
40 # which contains macros for doing this.
41 #
42 # The DLL may also contain some references to _impure_ptr
43 # (e.g. stdin is defined as a macro which expands to _impure_ptr.stdin).
44 # We need to provide a definition for this (otherwise it will link in
45 # the definition in libccrt.o, which causes lots of problems,
46 # eventually leading to undefined symbol `WinMain').
47 # The DLL's entry function (below) will initialize the _impure_ptr variable
48 # in the DLL so that they point to the main program's reent_data struct.
49
50 %_dll.h:
51         echo "/* automatically generated by Makefile.DLLs */"   > $@
52         echo "#ifndef $(GUARD_MACRO)"                           >> $@
53         echo "#define $(GUARD_MACRO)"                           >> $@
54         echo ""                                                 >> $@
55         echo "#if defined(__GNUC__) && defined(__CYGWIN32__)"   >> $@
56         echo "  #if defined($(USE_DLL_MACRO))"                  >> $@
57         echo "    #define $(IMP_MACRO)(name)    __imp_##name"   >> $@
58         echo "    #define $(GLOBAL_MACRO)(name) (*$(IMP_MACRO)(name))" >> $@
59         echo "    #include \"$*_globals.h\""                    >> $@
60         echo "  #endif /* $(USE_DLL_MACRO) */"                  >> $@
61         echo "#endif /* __GNUC__ && __CYGWIN32__ */"            >> $@
62         echo ""                                                 >> $@
63         echo "#endif /* $(GUARD_MACRO) */"                      >> $@
64
65 %_globals.h: %.a
66         echo "/* automatically generated by Makefile.DLLs */"   > $@
67         for sym in $(IMPURE_PTR) \
68                 `nm $< | grep '^........ [BCDR] _' | sed 's/[^_]*_//'`; \
69         do \
70                 echo "#define $$sym     $(GLOBAL_MACRO)($$sym)" >> $@; \
71         done
72
73 %_dll.c:
74         echo "/* automatically generated by Makefile.DLLs */"   > $@
75         echo "void *_impure_ptr;"                               >> $@
76
77 # This rule creates the export object file (`foo.exp') which contains the
78 # jump table array; this export object file becomes part of the DLL. 
79 # This rule also creates the import library (`foo_dll.a') which contains small
80 # stubs for all the functions exported by the DLL which jump to them via the
81 # jump table.  Executables that will use the DLL must be linked against this
82 # stub library.
83 %.exp %_dll.a : %.def
84         dlltool $(DLLTOOLFLAGS) $(DLLTOOLFLAGS-$*)              \
85                 --def $<                                        \
86                 --dllname $*.dll                                \
87                 --output-exp $*.exp                             \
88                 --output-lib $*_dll.a
89
90 # The `sed' commands below are to convert DOS-style `C:\foo\bar'
91 # pathnames into Unix-style `//c/foo/bar' pathnames.
92 CYGWIN32_LIBS = $(shell echo                                    \
93         -L`dirname \`gcc -print-file-name=libgcc.a |            \
94         sed -e 's@^\\\\([A-Za-z]\\\\):@//\\\\1@g' -e 's@\\\\\\\\@/@g' \` ` \
95         -L`dirname \`gcc -print-file-name=libcygwin.a | \
96         sed -e 's@^\\\\([A-Za-z]\\\\):@//\\\\1@g' -e 's@\\\\\\\\@/@g' \` ` \
97         -L`dirname \`gcc -print-file-name=libkernel32.a | \
98         sed -e 's@^\\\\([A-Za-z]\\\\):@//\\\\1@g' -e 's@\\\\\\\\@/@g' \` ` \
99         -lgcc -lcygwin -lkernel32 -lgcc)
100
101 # Making relocatable DLLs doesn't seem to work.
102 # Not quite sure why.  The --image-base values below
103 # where chosen at random, they seem to work on my machine.
104 RELOCATABLE=no
105 LDFLAGS-libgc +=        --image-base=0x2345000
106 LDFLAGS-libmer +=       --image-base=0x1234000
107 LDFLAGS-libmercury +=   --image-base=0x3456000
108
109 ifeq "$(strip $(RELOCATABLE))" "yes"
110
111 # to create relocatable DLLs, we need to do two passes
112 # (warning: this is untested)
113 %.dll: %.exp %.a %_dll.o dll_init.o dll_fixup.o
114         $(LD) $(LDFLAGS) $(LDFLAGS-$*) --dll -o $*.base                 \
115                 -e _dll_entry@12                                        \
116                 $*.exp $*.a $*_dll.o                                    \
117                 dll_init.o dll_fixup.o                                  \
118                 $(LDLIBS) $(LDLIBS-$*)                                  \
119                 $(CYGWIN32_LIBS)
120         # untested
121         dlltool $(DLLTOOLFLAGS) $(DLLTOOLFLAGS-$*)              \
122                 --def $*.def                                    \
123                 --dllname $*.dll                                \
124                 --base-file $*.base                             \
125                 --output-exp $*.exp
126         $(LD) $(LDFLAGS) $(LDFLAGS-$*) --dll -o $*.base                 \
127                 -e _dll_entry@12                                        \
128                 $*.exp $*.a $*_dll.o                                    \
129                 dll_init.o dll_fixup.o                                  \
130                 $(LDLIBS) $(LDLIBS-$*)                                  \
131                 $(CYGWIN32_LIBS)
132         dlltool $(DLLTOOLFLAGS) $(DLLTOOLFLAGS-$*)              \
133                 --def $*.def                                    \
134                 --dllname $*.dll                                \
135                 --base-file $*.base                             \
136                 --output-exp $*.exp
137         # end untested stuff
138         $(LD) $(LDFLAGS) $(LDFLAGS-$*) --dll --base-file $*.base -o $@  \
139                 -e _dll_entry@12                                        \
140                 $*.exp $*.a $*_dll.o                                    \
141                 dll_init.o dll_fixup.o                                  \
142                 $(LDLIBS) $(LDLIBS-$*)                                  \
143                 $(CYGWIN32_LIBS)
144         rm -f $*.base
145
146 else
147
148 %.dll: %.exp %.a %_dll.o dll_fixup.o dll_init.o
149         $(LD) $(LDFLAGS) $(LDFLAGS-$*) --dll -o $@                      \
150                 -e _dll_entry@12                                        \
151                 $*.exp $*.a $*_dll.o                                    \
152                 dll_init.o dll_fixup.o                                  \
153                 $(LDLIBS) $(LDLIBS-$*)                                  \
154                 $(CYGWIN32_LIBS)
155
156 endif
157
158 # This black magic piece of assembler needs to be linked in in order to
159 # properly terminate the list of imported DLLs.
160 dll_fixup.s:
161         echo '.section .idata$$3'       > dll_fixup.s
162         echo '.long 0,0,0,0,0'          >> dll_fixup.s
163
164 dll_fixup.o: dll_fixup.s
165         $(AS) $(ASFLAGS) -o dll_fixup.o dll_fixup.s
166
167 # Windows requires each DLL to have an initialization function
168 # that is called at certain points (thread/process attach/detach).
169 # This one just initializes `_impure_ptr'.
170 dll_init.c:
171         echo '#include <stdio.h>'                               > dll_init.c
172         echo 'extern struct _reent *_impure_ptr;'               >> dll_init.c
173         echo 'extern struct _reent *__imp_reent_data;'          >> dll_init.c
174         echo '__attribute__((stdcall))'                         >> dll_init.c
175         echo 'int dll_entry(int handle, int reason, void *ptr)' >> dll_init.c
176         echo '{ _impure_ptr=__imp_reent_data; return 1; }'      >> dll_init.c
177
178 # The following rule is just there to convince gcc
179 # to keep otherwise unused intermediate targets around.
180 dont_throw_away: dll_fixup.o dll_init.o