1 #-----------------------------------------------------------------------------#
3 # Makefile.DLLs, version 0.7.
5 # This Makefile contains rules for creating DLLs on Windows using gnu-win32.
7 #-----------------------------------------------------------------------------#
9 # The SYM_PREFIX is used as a prefix for the symbols in the files
10 # that this makefiles automatically generates.
12 # The default SYM_PREFIX for libfoo.dll is `libfoo'.
13 # But you can override this by setting `SYM_PREFIX-libfoo = blah'.
15 SYM_PREFIX = $(firstword $(SYM_PREFIX-$*) $*)
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
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.)
34 # echo $(IMPURE_PTR) = _impure_ptr >> $@
35 # nm $< | sed -n '/^........ [BCDRT] _/s/[^_]*_//p' >> $@
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.
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.
51 echo "/* automatically generated by Makefile.DLLs */" > $@
52 echo "#ifndef $(GUARD_MACRO)" >> $@
53 echo "#define $(GUARD_MACRO)" >> $@
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__ */" >> $@
63 echo "#endif /* $(GUARD_MACRO) */" >> $@
66 echo "/* automatically generated by Makefile.DLLs */" > $@
67 for sym in $(IMPURE_PTR) \
68 `nm $< | grep '^........ [BCDR] _' | sed 's/[^_]*_//'`; \
70 echo "#define $$sym $(GLOBAL_MACRO)($$sym)" >> $@; \
74 echo "/* automatically generated by Makefile.DLLs */" > $@
75 echo "void *_impure_ptr;" >> $@
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
84 dlltool $(DLLTOOLFLAGS) $(DLLTOOLFLAGS-$*) \
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)
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.
105 LDFLAGS-libgc += --image-base=0x2345000
106 LDFLAGS-libmer += --image-base=0x1234000
107 LDFLAGS-libmercury += --image-base=0x3456000
109 ifeq "$(strip $(RELOCATABLE))" "yes"
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 \
116 $*.exp $*.a $*_dll.o \
117 dll_init.o dll_fixup.o \
118 $(LDLIBS) $(LDLIBS-$*) \
121 dlltool $(DLLTOOLFLAGS) $(DLLTOOLFLAGS-$*) \
124 --base-file $*.base \
126 $(LD) $(LDFLAGS) $(LDFLAGS-$*) --dll -o $*.base \
128 $*.exp $*.a $*_dll.o \
129 dll_init.o dll_fixup.o \
130 $(LDLIBS) $(LDLIBS-$*) \
132 dlltool $(DLLTOOLFLAGS) $(DLLTOOLFLAGS-$*) \
135 --base-file $*.base \
138 $(LD) $(LDFLAGS) $(LDFLAGS-$*) --dll --base-file $*.base -o $@ \
140 $*.exp $*.a $*_dll.o \
141 dll_init.o dll_fixup.o \
142 $(LDLIBS) $(LDLIBS-$*) \
148 %.dll: %.exp %.a %_dll.o dll_fixup.o dll_init.o
149 $(LD) $(LDFLAGS) $(LDFLAGS-$*) --dll -o $@ \
151 $*.exp $*.a $*_dll.o \
152 dll_init.o dll_fixup.o \
153 $(LDLIBS) $(LDLIBS-$*) \
158 # This black magic piece of assembler needs to be linked in in order to
159 # properly terminate the list of imported DLLs.
161 echo '.section .idata$$3' > dll_fixup.s
162 echo '.long 0,0,0,0,0' >> dll_fixup.s
164 dll_fixup.o: dll_fixup.s
165 $(AS) $(ASFLAGS) -o dll_fixup.o dll_fixup.s
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'.
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
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