[commit: ghc] master: Add short library names support to Windows linker (5d84110)
git at git.haskell.org
git at git.haskell.org
Sat Oct 10 13:22:08 UTC 2015
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/5d841108acef950fed6a5e608ac9b18e7431aa87/ghc
>---------------------------------------------------------------
commit 5d841108acef950fed6a5e608ac9b18e7431aa87
Author: Tamar Christina <tamar at zhox.com>
Date: Sat Oct 10 15:21:09 2015 +0200
Add short library names support to Windows linker
Make Linker.hs try asking gcc for lib%s.dll as well, also changed tryGcc
to pass -L to all components by using -B instead. These two fix
shortnames linking on windows.
re-enabled tests: ghcilink003, ghcilink006 and T3333
Added two tests: load_short_name and enabled T1407 on windows.
Reviewed By: thomie, bgamari
Differential Revision: https://phabricator.haskell.org/D1310
GHC Trac Issues: #9878, #1407, #1883, #5289
>---------------------------------------------------------------
5d841108acef950fed6a5e608ac9b18e7431aa87
compiler/ghci/Linker.hs | 10 +++++++---
testsuite/tests/ghci/linking/Makefile | 8 ++++++++
testsuite/tests/ghci/linking/T1407.script | 4 ----
testsuite/tests/ghci/linking/all.T | 8 +-------
testsuite/tests/ghci/linking/dyn/A.c | 17 +++++++++++++++++
testsuite/tests/ghci/linking/dyn/Makefile | 23 +++++++++++++++++++++++
testsuite/tests/ghci/linking/dyn/T1407.script | 4 ++++
testsuite/tests/ghci/linking/dyn/all.T | 12 ++++++++++++
testsuite/tests/ghci/scripts/all.T | 3 +--
9 files changed, 73 insertions(+), 16 deletions(-)
diff --git a/compiler/ghci/Linker.hs b/compiler/ghci/Linker.hs
index 8c2a07c..29968f5 100644
--- a/compiler/ghci/Linker.hs
+++ b/compiler/ghci/Linker.hs
@@ -1200,7 +1200,7 @@ locateLib dflags is_hs dirs lib
-- for a dynamic library (#5289)
-- otherwise, assume loadDLL can find it
--
- = findDll `orElse` findArchive `orElse` tryGcc `orElse` assumeDll
+ = findDll `orElse` findArchive `orElse` tryGcc `orElse` tryGccPrefixed `orElse` assumeDll
| not dynamicGhc
-- When the GHC package was not compiled as dynamic library
@@ -1221,6 +1221,7 @@ locateLib dflags is_hs dirs lib
hs_dyn_lib_file = mkHsSOName platform hs_dyn_lib_name
so_name = mkSOName platform lib
+ lib_so_name = "lib" ++ so_name
dyn_lib_file = case (arch, os) of
(ArchX86_64, OSSolaris2) -> "64" </> so_name
_ -> so_name
@@ -1230,7 +1231,8 @@ locateLib dflags is_hs dirs lib
findArchive = liftM (fmap Archive) $ findFile dirs arch_file
findHSDll = liftM (fmap DLLPath) $ findFile dirs hs_dyn_lib_file
findDll = liftM (fmap DLLPath) $ findFile dirs dyn_lib_file
- tryGcc = liftM (fmap DLLPath) $ searchForLibUsingGcc dflags so_name dirs
+ tryGcc = liftM (fmap DLLPath) $ searchForLibUsingGcc dflags so_name dirs
+ tryGccPrefixed = liftM (fmap DLLPath) $ searchForLibUsingGcc dflags lib_so_name dirs
assumeDll = return (DLL lib)
infixr `orElse`
@@ -1242,7 +1244,9 @@ locateLib dflags is_hs dirs lib
searchForLibUsingGcc :: DynFlags -> String -> [FilePath] -> IO (Maybe FilePath)
searchForLibUsingGcc dflags so dirs = do
- str <- askCc dflags (map (FileOption "-L") dirs
+ -- GCC does not seem to extend the library search path (using -L) when using
+ -- --print-file-name. So instead pass it a new base location.
+ str <- askCc dflags (map (FileOption "-B") dirs
++ [Option "--print-file-name", Option so])
let file = case lines str of
[] -> ""
diff --git a/testsuite/tests/ghci/linking/Makefile b/testsuite/tests/ghci/linking/Makefile
index 5b8e23c..c833454 100644
--- a/testsuite/tests/ghci/linking/Makefile
+++ b/testsuite/tests/ghci/linking/Makefile
@@ -40,7 +40,11 @@ ghcilink002 :
.PHONY: ghcilink003
ghcilink003 :
+ifeq "$(WINDOWS)" "YES"
+ echo ":q" | "$(TEST_HC)" --interactive -ignore-dot-ghci -v0 -lstdc++-6
+else
echo ":q" | "$(TEST_HC)" --interactive -ignore-dot-ghci -v0 -lstdc++
+endif
# Test 4:
# package P
@@ -114,7 +118,11 @@ ghcilink006 :
echo "version: 1.0" >>$(PKG006)
echo "id: test-XXX" >>$(PKG006)
echo "key: test-1.0" >>$(PKG006)
+ifeq "$(WINDOWS)" "YES"
+ echo "extra-libraries: stdc++-6" >>$(PKG006)
+else
echo "extra-libraries: stdc++" >>$(PKG006)
+endif
'$(GHC_PKG)' init $(LOCAL_PKGCONF006)
'$(GHC_PKG)' --no-user-package-db -f $(LOCAL_PKGCONF006) register $(PKG006) -v0
#
diff --git a/testsuite/tests/ghci/linking/T1407.script b/testsuite/tests/ghci/linking/T1407.script
deleted file mode 100644
index 9716435..0000000
--- a/testsuite/tests/ghci/linking/T1407.script
+++ /dev/null
@@ -1,4 +0,0 @@
-:set -ldl
-import Foreign
-import Foreign.C.String
-foreign import ccall "dlerror" dle :: IO CString
diff --git a/testsuite/tests/ghci/linking/all.T b/testsuite/tests/ghci/linking/all.T
index 4d05b8f..fc3516a 100644
--- a/testsuite/tests/ghci/linking/all.T
+++ b/testsuite/tests/ghci/linking/all.T
@@ -12,8 +12,6 @@ test('ghcilink002',
test('ghcilink003',
[
- # still cannot load libstdc++ on Windows. See also #4468.
- when(opsys('mingw32'), expect_broken(5289)),
unless(doing_ghci, skip),
extra_clean(['dir003/*','dir003'])
],
@@ -36,8 +34,6 @@ test('ghcilink005',
test('ghcilink006',
[
- # still cannot load libstdc++ on Windows. See also #4468.
- when(opsys('mingw32'), expect_broken(5289)),
unless(doing_ghci, skip),
extra_clean(['dir006/ghcilink006.package.conf/*', 'dir006/*','dir006'])
],
@@ -47,9 +43,7 @@ test('ghcilink006',
test('T3333',
[extra_clean(['T3333.o']),
unless(doing_ghci, skip),
- unless(opsys('linux') or ghci_dynamic(), expect_broken(3333))],
+ unless(ghci_dynamic(), expect_broken(3333))],
run_command,
['$MAKE -s --no-print-directory T3333'])
-test('T1407', when(opsys('mingw32'), expect_broken(1407)),
- ghci_script, ['T1407.script'])
diff --git a/testsuite/tests/ghci/linking/dyn/A.c b/testsuite/tests/ghci/linking/dyn/A.c
new file mode 100644
index 0000000..fec94f2
--- /dev/null
+++ b/testsuite/tests/ghci/linking/dyn/A.c
@@ -0,0 +1,17 @@
+#if defined(_MSC_VER)
+ // Microsoft
+ #define EXPORT __declspec(dllexport)
+#elif defined(_GCC)
+ // GCC
+ #define EXPORT __attribute__((visibility("default")))
+#else
+ // do nothing and hope for the best?
+ #define EXPORT
+#endif
+
+extern EXPORT int foo();
+
+EXPORT int foo()
+{
+ return 2;
+}
diff --git a/testsuite/tests/ghci/linking/dyn/Makefile b/testsuite/tests/ghci/linking/dyn/Makefile
new file mode 100644
index 0000000..8a3b736
--- /dev/null
+++ b/testsuite/tests/ghci/linking/dyn/Makefile
@@ -0,0 +1,23 @@
+TOP=../../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+ifeq "$(WINDOWS)" "YES"
+DLL = lib$1.dll
+else ifeq "$(DARWIN)" "YES"
+DLL = lib$1.dylib
+else
+DLL = lib$1.so
+endif
+
+
+.PHONY: load_short_name
+load_short_name:
+ rm -rf bin_short
+ mkdir bin_short
+ gcc -shared A.c -o "bin_short/$(call DLL,A)"
+ echo ":q" | "$(TEST_HC)" --interactive -L"$(PWD)/bin_short" -lA -v0
+
+.PHONY: compile_libAS
+compile_libAS:
+ gcc -shared A.c -o $(call DLL,AS)
diff --git a/testsuite/tests/ghci/linking/dyn/T1407.script b/testsuite/tests/ghci/linking/dyn/T1407.script
new file mode 100644
index 0000000..0274f82
--- /dev/null
+++ b/testsuite/tests/ghci/linking/dyn/T1407.script
@@ -0,0 +1,4 @@
+:set -lAS
+import Foreign
+import Foreign.C.Types
+foreign import ccall "foo" dle :: IO CInt
diff --git a/testsuite/tests/ghci/linking/dyn/all.T b/testsuite/tests/ghci/linking/dyn/all.T
new file mode 100644
index 0000000..2810c7f
--- /dev/null
+++ b/testsuite/tests/ghci/linking/dyn/all.T
@@ -0,0 +1,12 @@
+test('load_short_name',
+ [unless(doing_ghci, skip),
+ extra_clean(['bin_short/*', 'bin_short'])],
+ run_command,
+ ['$MAKE -s --no-print-directory load_short_name'])
+
+test('T1407',
+ [unless(doing_ghci, skip),
+ extra_clean(['libAS.*']),
+ pre_cmd('$MAKE -s --no-print-directory compile_libAS'),
+ extra_hc_opts('-L.')],
+ ghci_script, ['T1407.script'])
diff --git a/testsuite/tests/ghci/scripts/all.T b/testsuite/tests/ghci/scripts/all.T
index d2244c1..faf3f1d 100755
--- a/testsuite/tests/ghci/scripts/all.T
+++ b/testsuite/tests/ghci/scripts/all.T
@@ -208,8 +208,7 @@ test('T9878',
[extra_clean(['T9878.hi','T9878.o'])],
ghci_script, ['T9878.script'])
test('T9878b',
- [ when(opsys('mingw32'), expect_broken(9878)),
- extra_run_opts('-fobject-code'),
+ [ extra_run_opts('-fobject-code'),
extra_clean(['T9878b.hi','T9878b.o'])],
ghci_script, ['T9878b.script'])
test('T10018', normal, ghci_script, ['T10018.script'])
More information about the ghc-commits
mailing list