Commit 5d841108 authored by Tamar Christina's avatar Tamar Christina Committed by thomie

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
parent e331392e
......@@ -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
[] -> ""
......
......@@ -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
#
......
:set -ldl
import Foreign
import Foreign.C.String
foreign import ccall "dlerror" dle :: IO CString
......@@ -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'])
#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;
}
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)
:set -lAS
import Foreign
import Foreign.C.Types
foreign import ccall "foo" dle :: IO CInt
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'])
......@@ -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'])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment