summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamar Christina <tamar@zhox.com>2016-10-31 21:03:14 +0000
committerTamar Christina <tamar@zhox.com>2016-10-31 21:03:14 +0000
commit795be0ea60fc81aefdaf6ecb1dc9b03c4a5c9f86 (patch)
treec1b71a9a55e6395c21308bb243094d5163178281
parent80d4a03332e09064e5542924f2897d7eb573f19e (diff)
downloadhaskell-795be0ea60fc81aefdaf6ecb1dc9b03c4a5c9f86.tar.gz
Align GHCi's library search order more closely with LDs
Summary: Given a static library and an import library in the same folder. e.g. ``` libfoo.a libfoo.dll.a ``` running `ghci -lfoo` we should prefer the import library `libfoo.dll.a` over `libfoo.a` because we prefer having to just load the DLL. And not having to do any linking. This also more closely emulated the behaviour of LD, which has a search order of ``` libxxx.dll.a xxx.dll.a libxxx.a cygxxx.dll (*) libxxx.dll xxx.dll ``` Test Plan: ./validate Reviewers: RyanGlScott, austin, hvr, bgamari, erikd, simonmar Reviewed By: RyanGlScott Subscribers: thomie, #ghc_windows_task_force Differential Revision: https://phabricator.haskell.org/D2651 GHC Trac Issues: #12771
-rw-r--r--compiler/ghci/Linker.hs7
-rw-r--r--testsuite/tests/rts/T12771/Makefile10
-rw-r--r--testsuite/tests/rts/T12771/T12771.stdout1
-rw-r--r--testsuite/tests/rts/T12771/all.T5
-rw-r--r--testsuite/tests/rts/T12771/foo.c6
-rw-r--r--testsuite/tests/rts/T12771/foo_dll.c4
-rw-r--r--testsuite/tests/rts/T12771/main.hs5
7 files changed, 35 insertions, 3 deletions
diff --git a/compiler/ghci/Linker.hs b/compiler/ghci/Linker.hs
index a2ca1b514b..73d0fac1f5 100644
--- a/compiler/ghci/Linker.hs
+++ b/compiler/ghci/Linker.hs
@@ -1281,7 +1281,8 @@ loadFrameworks hsc_env platform pkg
-- If it isn't present, we assume that addDLL in the RTS can find it,
-- which generally means that it should be a dynamic library in the
-- standard system search path.
-
+-- For GHCi we tend to prefer dynamic libraries over static ones as
+-- they are easier to load and manage, have less overhead.
locateLib :: HscEnv -> Bool -> [FilePath] -> String -> IO LibrarySpec
locateLib hsc_env is_hs dirs lib
| not is_hs
@@ -1290,16 +1291,16 @@ locateLib hsc_env is_hs dirs lib
-- then look in library-dirs for a static library (libfoo.a)
-- then look in library-dirs and inplace GCC for a dynamic library (libfoo.so)
-- then check for system dynamic libraries (e.g. kernel32.dll on windows)
- -- then try "gcc --print-file-name" to search gcc's search path
-- then try looking for import libraries on Windows (.dll.a, .lib)
+ -- then try "gcc --print-file-name" to search gcc's search path
-- then look in library-dirs and inplace GCC for a static library (libfoo.a)
-- for a dynamic library (#5289)
-- otherwise, assume loadDLL can find it
--
= findDll `orElse`
findSysDll `orElse`
- tryGcc `orElse`
tryImpLib `orElse`
+ tryGcc `orElse`
findArchive `orElse`
assumeDll
diff --git a/testsuite/tests/rts/T12771/Makefile b/testsuite/tests/rts/T12771/Makefile
new file mode 100644
index 0000000000..d6960a022a
--- /dev/null
+++ b/testsuite/tests/rts/T12771/Makefile
@@ -0,0 +1,10 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+T12771:
+ '$(TEST_CC)' -c foo.c -o foo.o
+ '$(AR)' rsc libfoo.a foo.o
+ '$(TEST_HC)' -shared foo_dll.c -o libfoo-1.dll
+ mv libfoo-1.dll.a libfoo.dll.a
+ echo main | '$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) main.hs -lfoo -L"$(PWD)"
diff --git a/testsuite/tests/rts/T12771/T12771.stdout b/testsuite/tests/rts/T12771/T12771.stdout
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/testsuite/tests/rts/T12771/T12771.stdout
@@ -0,0 +1 @@
+1
diff --git a/testsuite/tests/rts/T12771/all.T b/testsuite/tests/rts/T12771/all.T
new file mode 100644
index 0000000000..50933d5e67
--- /dev/null
+++ b/testsuite/tests/rts/T12771/all.T
@@ -0,0 +1,5 @@
+test('T12771', [ extra_clean(['libfoo.a', 'libfoo-1.dll', 'foo.o', 'main.o'])
+ , extra_files(['foo.c', 'main.hs', 'foo_dll.c'])
+ , unless(opsys('mingw32'), skip)
+ ],
+ run_command, ['$MAKE -s --no-print-directory T12771'])
diff --git a/testsuite/tests/rts/T12771/foo.c b/testsuite/tests/rts/T12771/foo.c
new file mode 100644
index 0000000000..af8ad9cb50
--- /dev/null
+++ b/testsuite/tests/rts/T12771/foo.c
@@ -0,0 +1,6 @@
+extern int bar();
+
+int foo ()
+{
+ return bar();
+}
diff --git a/testsuite/tests/rts/T12771/foo_dll.c b/testsuite/tests/rts/T12771/foo_dll.c
new file mode 100644
index 0000000000..8ea6c22735
--- /dev/null
+++ b/testsuite/tests/rts/T12771/foo_dll.c
@@ -0,0 +1,4 @@
+int foo()
+{
+ return 1;
+}
diff --git a/testsuite/tests/rts/T12771/main.hs b/testsuite/tests/rts/T12771/main.hs
new file mode 100644
index 0000000000..fbc8f5603c
--- /dev/null
+++ b/testsuite/tests/rts/T12771/main.hs
@@ -0,0 +1,5 @@
+module Main where
+
+foreign import ccall "foo" c_foo :: Int
+
+main = print c_foo