[LLVMdev] [PATCH] Capability of Win32.DLL with ENABLE_SHARED

NAKAMURA Takumi geek4civic at gmail.com
Thu Aug 5 03:56:44 PDT 2010


Anton,

Thanks for your comment.
2nd patch attached.

  - s/SharedDir/SharedLibDir/g
  - move prefix=cyg sunk into if(cygwin or mingw)


arigato gozaimasu...Takumi


* Additional issues
  - You may build LLVMHello.dll but I don't modify lib/Transforms/Makefile.
    Because making LLVMHello.dll requires the library LLVM.dll,
    but it oughta be on the way to making libs at building lib/Transforms/Hello.
    You can build LLVMHello.dll later;
      $ make -C lib/Transforms OPTIONAL_DIRS+=Hello

* Why dummy bin/libstdc++.dll.a needed?
  - ld resolves data/bss symbols with *.a on LIBRARY_PATH,
    at next, resolves symbols with "auto-import" after.
    I had to suppress standard -lstdc++, it was the reason.


2010/8/5 Anton Korobeynikov <anton at korobeynikov.info>:
> Hi Takumi,
>
>> Any feedbacks are welcome.
>> Have fun!
> This seems to be pretty useful addition to LLVM on windows! And it
> seems the only painless way to make plugins working, yay!
>
> For me the patch looks pretty good. One minor thing: could you please
> rename SharedDir => SharedLibDir
>
> Thanks!
> --
> With best regards, Anton Korobeynikov
> Faculty of Mathematics and Mechanics, Saint Petersburg State University
>
-------------- next part --------------
diff --git a/Makefile.rules b/Makefile.rules
index 66666b4..8b50eb6 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -498,6 +498,26 @@ LLVMToolDir := $(LLVM_OBJ_ROOT)/$(BuildMode)/bin
 LLVMExmplDir:= $(LLVM_OBJ_ROOT)/$(BuildMode)/examples
 
 #--------------------------------------------------------------------
+# Locations of shared libraries
+#--------------------------------------------------------------------
+
+SharedPrefix     := lib
+SharedLibDir     := $(LibDir)
+LLVMSharedLibDir := $(LLVMLibDir)
+
+# Win32.DLL prefers to be located on the "PATH" of binaries.
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
+  SharedLibDir     := $(ToolDir)
+  LLVMSharedLibDir := $(LLVMToolDir)
+
+  ifeq ($(HOST_OS),Cygwin)
+    SharedPrefix  := cyg
+  else
+    SharedPrefix  :=
+  endif
+endif
+
+#--------------------------------------------------------------------
 # LLVM Capable Compiler
 #--------------------------------------------------------------------
 
@@ -570,12 +590,7 @@ ifeq ($(HOST_OS),Darwin)
     SharedLinkOptions += -mmacosx-version-min=$(DARWIN_VERSION)
   endif
 else
-  ifeq ($(HOST_OS),Cygwin)
-    SharedLinkOptions=-shared -nostdlib -Wl,--export-all-symbols \
-                      -Wl,--enable-auto-import -Wl,--enable-auto-image-base
-  else
-    SharedLinkOptions=-shared
-  endif
+  SharedLinkOptions=-shared
 endif
 
 ifeq ($(TARGET_OS),Darwin)
@@ -585,11 +600,13 @@ ifeq ($(TARGET_OS),Darwin)
 endif
 
 ifdef SHARED_LIBRARY
+ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
 ifneq ($(HOST_OS),Darwin)
   LD.Flags += $(RPATH) -Wl,'$$ORIGIN'
 else
 ifneq ($(DARWIN_MAJVERS),4)
-  LD.Flags += $(RPATH) -Wl,$(LibDir)
+  LD.Flags += $(RPATH) -Wl,$(SharedLibDir)
+endif
 endif
 endif
 endif
@@ -960,6 +977,13 @@ LLVMUsedLibs    := $(patsubst %.a.o, lib%.a, $(addsuffix .o, $(LLVMLIBS)))
 LLVMLibsPaths   := $(addprefix $(LLVMLibDir)/,$(LLVMUsedLibs))
 endif
 
+# Win32.DLL may refer to other components.
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
+  ifdef LOADABLE_MODULE
+    LINK_COMPONENTS := all
+  endif
+endif
+
 ifndef IS_CLEANING_TARGET
 ifdef LINK_COMPONENTS
 
@@ -972,8 +996,13 @@ $(LLVM_CONFIG):
 $(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT): $(LLVM_CONFIG)
 
 ifeq ($(ENABLE_SHARED), 1)
+# We can take the "auto-import" feature to get rid of using dllimport.
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
+LLVMLibsOptions += -Wl,--enable-auto-import,--enable-runtime-pseudo-reloc \
+                   -L $(SharedLibDir)
+endif
 LLVMLibsOptions += -lLLVM-$(LLVMVersion)
-LLVMLibsPaths += $(LibDir)/libLLVM-$(LLVMVersion)$(SHLIBEXT)
+LLVMLibsPaths += $(SharedLibDir)/$(SharedPrefix)LLVM-$(LLVMVersion)$(SHLIBEXT)
 else
 LLVMLibsOptions += $(shell $(LLVM_CONFIG) --libs     $(LINK_COMPONENTS))
 LLVMLibsPaths   += $(LLVM_CONFIG) \
@@ -1018,6 +1047,21 @@ ifeq ($(HOST_OS),Darwin)
 LLVMLibsOptions += -Wl,-exported_symbols_list,$(NativeExportsFile)
 endif
 
+# GNU ld Win32 accepts .DEF files that contain "DATA" entries.
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
+NativeExportsFile := $(ObjDir)/$(notdir $(EXPORTED_SYMBOL_FILE:.exports=.def))
+
+# LLVMLibsOptions is invalidated at processing tools/llvm-shlib.
+SharedLinkOptions += $(NativeExportsFile)
+
+$(NativeExportsFile): $(EXPORTED_SYMBOL_FILE) $(ObjDir)/.dir
+	$(Echo) Generating $(notdir $@)
+	$(Verb) $(ECHO) "EXPORTS" > $@
+	$(Verb) $(CAT) $< >> $@
+clean-local::
+	-$(Verb) $(RM) -f $(NativeExportsFile)
+else
+
 # gold, bfd ld, etc.
 ifeq ($(HAVE_LINK_VERSION_SCRIPT),1)
 LLVMLibsOptions += -Wl,--version-script,$(NativeExportsFile)
@@ -1025,6 +1069,8 @@ endif
 
 endif
 
+endif
+
 ###############################################################################
 # Library Build Rules: Four ways to build a library
 ###############################################################################
@@ -1097,10 +1143,10 @@ ifdef LIBRARYNAME
 LIBRARYNAME := $(strip $(LIBRARYNAME))
 ifdef LOADABLE_MODULE
 LibName.A  := $(LibDir)/$(LIBRARYNAME).a
-LibName.SO := $(LibDir)/$(LIBRARYNAME)$(SHLIBEXT)
+LibName.SO := $(SharedLibDir)/$(LIBRARYNAME)$(SHLIBEXT)
 else
 LibName.A  := $(LibDir)/lib$(LIBRARYNAME).a
-LibName.SO := $(LibDir)/lib$(LIBRARYNAME)$(SHLIBEXT)
+LibName.SO := $(SharedLibDir)/$(SharedPrefix)$(LIBRARYNAME)$(SHLIBEXT)
 endif
 LibName.O  := $(LibDir)/$(LIBRARYNAME).o
 LibName.BCA:= $(LibDir)/lib$(LIBRARYNAME).bca
@@ -1125,13 +1171,13 @@ SharedLibKindMessage := "Loadable Module"
 else
 SharedLibKindMessage := "Shared Library"
 endif
-$(LibName.SO): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths) $(LibDir)/.dir
+$(LibName.SO): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths) $(SharedLibDir)/.dir
 	$(Echo) Linking $(BuildMode) $(SharedLibKindMessage) \
 	  $(notdir $@)
 	$(Verb) $(Link) $(SharedLinkOptions) -o $@ $(ObjectsO) \
 	  $(ProjLibsOptions) $(LLVMLibsOptions) $(LIBS)
 else
-$(LibName.SO): $(ObjectsO) $(LibDir)/.dir
+$(LibName.SO): $(ObjectsO) $(SharedLibDir)/.dir
 	$(Echo) Linking $(BuildMode) Shared Library $(notdir $@)
 	$(Verb) $(Link) $(SharedLinkOptions) -o $@ $(ObjectsO)
 endif
@@ -1148,21 +1194,23 @@ uninstall-local::
 	$(Echo) Uninstall circumvented with NO_INSTALL
 else
 
-ifdef LOADABLE_MODULE
-DestSharedLib = $(DESTDIR)$(PROJ_libdir)/$(LIBRARYNAME)$(SHLIBEXT)
+# Win32.DLL prefers to be located on the "PATH" of binaries.
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
+DestSharedLibDir := $(DESTDIR)$(PROJ_bindir)
 else
-DestSharedLib = $(DESTDIR)$(PROJ_libdir)/lib$(LIBRARYNAME)$(SHLIBEXT)
+DestSharedLibDir := $(DESTDIR)$(PROJ_libdir)
 endif
+DestSharedLib := $(DestSharedLibDir)/$(SharedPrefix)$(LIBRARYNAME)$(SHLIBEXT)
 
 install-local:: $(DestSharedLib)
 
-$(DestSharedLib): $(LibName.SO) $(DESTDIR)$(PROJ_libdir)
+$(DestSharedLib): $(LibName.SO) $(DestSharedLibDir)
 	$(Echo) Installing $(BuildMode) Shared Library $(DestSharedLib)
 	$(Verb) $(INSTALL) $(LibName.SO) $(DestSharedLib)
 
 uninstall-local::
 	$(Echo) Uninstalling $(BuildMode) Shared Library $(DestSharedLib)
-	-$(Verb) $(RM) -f $(DESTDIR)$(PROJ_libdir)/lib$(LIBRARYNAME).*
+	-$(Verb) $(RM) -f $(DestSharedLibDir)/$(SharedPrefix)$(LIBRARYNAME).*
 endif
 endif
 
diff --git a/tools/llvm-shlib/Makefile b/tools/llvm-shlib/Makefile
index 899406c..5238130 100644
--- a/tools/llvm-shlib/Makefile
+++ b/tools/llvm-shlib/Makefile
@@ -15,6 +15,17 @@ NO_BUILD_ARCHIVE = 1
 LINK_LIBS_IN_SHARED = 1
 SHARED_LIBRARY = 1
 
+include $(LEVEL)/Makefile.config
+
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
+    EXPORTED_SYMBOL_FILE = $(ObjDir)/$(LIBRARYNAME).exports
+
+    # It is needed to force static-stdc++.a linked.
+    # FIXME: It should be omitted when configure detects system's stdc++.dll.
+    SHLIB_FRAG_NAMES += stdc++.a.o
+
+endif
+
 include $(LEVEL)/Makefile.common
 
 # Include all archives in libLLVM.(so|dylib) except the ones that have
@@ -57,3 +68,44 @@ ifeq ($(HOST_OS), Linux)
     # Don't allow unresolved symbols.
     LLVMLibsOptions += -Wl,--no-undefined
 endif
+
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
+
+SHLIB_STUBS := $(addprefix $(ObjDir)/, $(SHLIB_FRAG_NAMES))
+SHLIB_FRAGS := $(patsubst %.a.o, $(ObjDir)/%.syms.txt, $(LIBRARYNAME).a.o $(SHLIB_FRAG_NAMES))
+LLVMLibsOptions := $(SHLIB_STUBS) $(LLVMLibsOptions)
+
+$(LibName.SO): $(SHLIB_STUBS)
+
+%.syms.txt: %.a.o
+	$(Echo) Collecting global symbols of $(notdir $*)
+	$(Verb) $(NM_PATH) -g $< > $@
+
+$(ObjDir)/$(LIBRARYNAME).exports: $(SHLIB_FRAGS) $(ObjDir)/.dir
+	$(Echo) Generating exports for $(LIBRARYNAME)
+	$(Verb) ($(SED) -n \
+			-e "s/^.* T _\([^.][^.]*\)$$/\1/p" \
+			-e "s/^.* [BDR] _\([^.][^.]*\)$$/\1 DATA/p" \
+			$(SHLIB_FRAGS) \
+		 | sort -u) > $@
+
+$(ObjDir)/$(LIBRARYNAME).a.o: $(LLVMLibsPaths) $(ObjDir)/.dir
+	$(Echo) Linking all LLVMLibs together for $(LIBRARYNAME)
+	$(Verb) $(Link) -nostartfiles -Wl,-r -nodefaultlibs -o $@ \
+			-Wl,--whole-archive $(LLVMLibsPaths) \
+			-Wl,--no-whole-archive
+
+$(ObjDir)/stdc++.a.o: $(ObjDir)/.dir
+	$(Echo) Linking all libs together for static libstdc++.a
+	$(Verb) $(Link) -nostartfiles -Wl,-r -nodefaultlibs -o $@ \
+			-Wl,--whole-archive -lstdc++ \
+			-Wl,--no-whole-archive
+# FIXME: workaround to invalidate -lstdc++
+	$(Echo) Making dummy -lstdc++ to lib
+	$(Verb) $(AR) rc $(ToolDir)/libstdc++.dll.a
+# FIXME: Is install-local needed?
+
+clean-local::
+	$(Verb) $(RM) -f $(ToolDir)/libstdc++.dll.a
+
+endif


More information about the llvm-dev mailing list