Skip to content

Commit d00e6ca

Browse files
authored
On Windows only build library with major soversion (#97)
* On Windows only build library with major soversion * Automatically get from Makefile the name of the library file * Debug: verbose linker * On Windows link to `-lblastrampoline-<MAJOR_VERSION>` * Revert "Debug: verbose linker" This reverts commit d9e47b9. * Install only shared libraries in `$(binlib)` This avoids installing a duplicate import library on Windows.
1 parent 1eb1fd3 commit d00e6ca

File tree

4 files changed

+54
-19
lines changed

4 files changed

+54
-19
lines changed

src/Make.inc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ ifneq (,$(findstring MINGW,$(OS))$(findstring MSYS,$(OS))$(findstring CYGWIN,$(O
2424
endif
2525

2626
LBT_SOVERSION_MAJOR := 5
27-
LBT_SOVERSION_MINOR := 3
27+
LBT_SOVERSION_MINOR := 4
2828
LBT_SOVERSION_PATCH := 0
2929

3030
ifeq ($(OS), WINNT)
@@ -112,3 +112,14 @@ endif
112112
# Default installation location; we expect you to be overriding this
113113
prefix ?= prefix
114114
builddir ?= build
115+
116+
define newline # a literal \n
117+
118+
119+
endef
120+
121+
# Makefile debugging trick:
122+
# call print-VARIABLE to see the runtime value of any variable
123+
# (hardened against any special characters appearing in the output)
124+
print-%:
125+
@echo '$*=$(subst ','\'',$(subst $(newline),\n,$($*)))'

src/Makefile

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ endif
3030
# Place the `.o` files into `$(builddir)`
3131
MAIN_OBJS := $(addprefix $(builddir)/,$(MAIN_OBJS))
3232

33+
ifeq ($(OS),WINNT)
34+
# On Windows only build the library with the major soversion, all other copies
35+
# are useless and error prone.
36+
TARGET_LIBRARIES = $(builddir)/$(LIB_MAJOR_VERSION)
37+
else
38+
TARGET_LIBRARIES = $(builddir)/$(LIB_MAJOR_VERSION) $(builddir)/$(LIB_FULL_VERSION) $(builddir)/libblastrampoline.$(SHLIB_EXT)
39+
endif
40+
3341
$(builddir) $(builddir)/trampolines:
3442
@mkdir -p $@
3543

@@ -42,22 +50,26 @@ dump-trampolines: trampolines/trampolines_$(ARCH).S
4250
$(CC) $< -S | sed -E 's/ ((%%)|;) /\n/g' | sed -E 's/.global/\n.global/g'
4351

4452

45-
$(builddir)/$(LIB_FULL_VERSION): $(MAIN_OBJS)
46-
@$(call PRINT_CC,$(CC) -o "$@" $(call IMPLIB_FLAGS,$(builddir)/$(LIB_MAJOR_VERSION)) $(LBT_CFLAGS) $(SONAME_FLAG) $^ -shared $(LBT_LDFLAGS))
53+
$(builddir)/$(LIB_MAJOR_VERSION): $(MAIN_OBJS)
54+
@$(call PRINT_CC,$(CC) -o "$@" $(call IMPLIB_FLAGS,$@) $(LBT_CFLAGS) $(SONAME_FLAG) $^ -shared $(LBT_LDFLAGS))
4755

48-
$(builddir)/$(LIB_MAJOR_VERSION): | $(builddir)/$(LIB_FULL_VERSION)
49-
ln -sf "$(LIB_FULL_VERSION)" "$@"
56+
ifneq ($(OS),WINNT)
57+
$(builddir)/$(LIB_FULL_VERSION): | $(builddir)/$(LIB_MAJOR_VERSION)
58+
ln -sf "$(LIB_MAJOR_VERSION)" "$@"
5059

5160
$(builddir)/libblastrampoline.$(SHLIB_EXT): | $(builddir)/$(LIB_MAJOR_VERSION)
5261
ln -sf "$(LIB_MAJOR_VERSION)" "$@"
62+
endif
5363

5464
# Install both libraries and our headers
55-
install: $(builddir)/libblastrampoline.$(SHLIB_EXT)
65+
install: $(TARGET_LIBRARIES)
5666
@mkdir -p $(DESTDIR)$(prefix)/include/libblastrampoline
5767
-@cp -Ra $(LBT_ROOT)/include/* $(DESTDIR)$(prefix)/include/libblastrampoline
5868
@cp -a $(LBT_ROOT)/src/libblastrampoline.h $(DESTDIR)$(prefix)/include/
5969
@mkdir -p $(DESTDIR)$(prefix)/$(binlib)
60-
@cp -a $(builddir)/libblastrampoline*$(SHLIB_EXT)* $(DESTDIR)$(prefix)/$(binlib)/
70+
@for lib in $(TARGET_LIBRARIES); do \
71+
cp -a $${lib} $(DESTDIR)$(prefix)/$(binlib)/; \
72+
done
6173
ifeq ($(OS),WINNT)
6274
@mkdir -p $(DESTDIR)$(prefix)/lib
6375
@cp -a $(builddir)/$(LIB_MAJOR_VERSION).a $(DESTDIR)$(prefix)/lib

test/runtests.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,28 +121,28 @@ lbt_dir = joinpath(lbt_dir, binlib)
121121

122122
@testset "LBT -> OpenBLAS_jll ($(openblas_interface))" begin
123123
libdirs = unique(vcat(lbt_dir, OpenBLAS_jll.LIBPATH_list..., CompilerSupportLibraries_jll.LIBPATH_list...))
124-
run_all_tests("blastrampoline", libdirs, openblas_interface, OpenBLAS_jll.libopenblas_path, tests=[dgemm, sgesv, sdot, zdotc])
124+
run_all_tests(blastrampoline_link_name(), libdirs, openblas_interface, OpenBLAS_jll.libopenblas_path, tests=[dgemm, sgesv, sdot, zdotc])
125125
end
126126

127127
# And again, but this time with OpenBLAS32_jll
128128
@testset "LBT -> OpenBLAS32_jll (LP64)" begin
129129
libdirs = unique(vcat(lbt_dir, OpenBLAS32_jll.LIBPATH_list..., CompilerSupportLibraries_jll.LIBPATH_list...))
130-
run_all_tests("blastrampoline", libdirs, :LP64, OpenBLAS32_jll.libopenblas_path, tests=[dgemm, sgesv, sdot, zdotc])
130+
run_all_tests(blastrampoline_link_name(), libdirs, :LP64, OpenBLAS32_jll.libopenblas_path, tests=[dgemm, sgesv, sdot, zdotc])
131131
end
132132

133133
# Test against MKL_jll using `libmkl_rt`, which is :LP64 by default
134134
if MKL_jll.is_available()
135135
@testset "LBT -> MKL_jll (LP64)" begin
136136
libdirs = unique(vcat(lbt_dir, MKL_jll.LIBPATH_list..., CompilerSupportLibraries_jll.LIBPATH_list...))
137-
run_all_tests("blastrampoline", libdirs, :LP64, MKL_jll.libmkl_rt_path)
137+
run_all_tests(blastrampoline_link_name(), libdirs, :LP64, MKL_jll.libmkl_rt_path)
138138
end
139139

140140
# Test that we can set MKL's interface via an environment variable to select ILP64, and LBT detects it properly
141141
if Sys.WORD_SIZE == 64
142142
@testset "LBT -> MKL_jll (ILP64, via env)" begin
143143
withenv("MKL_INTERFACE_LAYER" => "ILP64") do
144144
libdirs = unique(vcat(lbt_dir, MKL_jll.LIBPATH_list..., CompilerSupportLibraries_jll.LIBPATH_list...))
145-
run_all_tests("blastrampoline", libdirs, :ILP64, MKL_jll.libmkl_rt_path)
145+
run_all_tests(blastrampoline_link_name(), libdirs, :ILP64, MKL_jll.libmkl_rt_path)
146146
end
147147
end
148148
end
@@ -155,13 +155,13 @@ veclib_blas_path = "/System/Library/Frameworks/Accelerate.framework/Versions/A/F
155155
if dlopen_e(veclib_blas_path) != C_NULL
156156
# Test that we can run BLAS-only tests without LAPACK loaded (`sgesv` test requires LAPACK symbols)
157157
@testset "LBT -> vecLib/libBLAS" begin
158-
run_all_tests("blastrampoline", [lbt_dir], :LP64, veclib_blas_path; tests=[dgemm, sdot, zdotc])
158+
run_all_tests(blastrampoline_link_name(), [lbt_dir], :LP64, veclib_blas_path; tests=[dgemm, sdot, zdotc])
159159
end
160160

161161
# With LAPACK as well, run all tests except `dgemmt`
162162
veclib_lapack_path = "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/libLAPACK.dylib"
163163
@testset "LBT -> vecLib/libLAPACK" begin
164-
run_all_tests("blastrampoline", [lbt_dir], :LP64, string(veclib_blas_path, ";", veclib_lapack_path), tests=[dgemm, sgesv, sdot, zdotc])
164+
run_all_tests(blastrampoline_link_name(), [lbt_dir], :LP64, string(veclib_blas_path, ";", veclib_lapack_path), tests=[dgemm, sgesv, sdot, zdotc])
165165
end
166166
end
167167

@@ -171,14 +171,14 @@ blas64 = dlopen("libblas64", throw_error=false)
171171
if blas64 !== nothing
172172
# Test that we can run BLAS-only tests without LAPACK loaded (`sgesv` test requires LAPACK symbols, blas64 doesn't have CBLAS)
173173
@testset "LBT -> libblas64 (ILP64, BLAS)" begin
174-
run_all_tests("blastrampoline", [lbt_dir], :ILP64, dlpath(blas64); tests=[dgemm, sdot])
174+
run_all_tests(blastrampoline_link_name(), [lbt_dir], :ILP64, dlpath(blas64); tests=[dgemm, sdot])
175175
end
176176

177177
# Check if we have a `liblapack` and if we do, run again, this time including `sgesv`
178178
lapack = dlopen("liblapack64", throw_error=false)
179179
if lapack !== nothing
180180
@testset "LBT -> libblas64 + liblapack64 (ILP64, BLAS+LAPACK)" begin
181-
run_all_tests("blastrampoline", [lbt_dir], :ILP64, "$(dlpath(blas64));$(dlpath(lapack))"; tests=[dgemm, sdot, sgesv])
181+
run_all_tests(blastrampoline_link_name(), [lbt_dir], :ILP64, "$(dlpath(blas64));$(dlpath(lapack))"; tests=[dgemm, sdot, sgesv])
182182
end
183183
end
184184
end

test/utils.jl

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@ end
5353

5454
needs_m32() = startswith(last(capture_output(`$(cc) -dumpmachine`)), "x86_64") && Sys.WORD_SIZE == 32
5555

56+
function blastrampoline_major_version()
57+
srcdir = joinpath(dirname(@__DIR__), "src")
58+
return split(readchomp(`$(make) -sC $(pathesc(srcdir)) print-LIB_MAJOR_VERSION`), "=")[end]
59+
end
60+
61+
function blastrampoline_link_name()
62+
@static if Sys.iswindows()
63+
# On Windows we need to link to `-lblastrampoline-<MAJOR_VERSION>`
64+
return replace(splitext(blastrampoline_major_version())[begin], r"^lib" => "")
65+
end
66+
return "blastrampoline"
67+
end
68+
5669

5770
# Build blastrampoline into a temporary directory, and return that
5871
blastrampoline_build_dir = nothing
@@ -64,15 +77,14 @@ function build_libblastrampoline()
6477
cflags_add = "-Werror" * (needs_m32() ? " -m32" : "")
6578
dir = mktempdir()
6679
srcdir = joinpath(dirname(@__DIR__), "src")
67-
run(`$(make) -sC $(pathesc(srcdir)) CFLAGS="$(cflags_add)" ARCH=$(Sys.ARCH) clean`)
68-
run(`$(make) -sC $(pathesc(srcdir)) CFLAGS="$(cflags_add)" ARCH=$(Sys.ARCH) install builddir=$(pathesc(dir))/build prefix=$(pathesc(dir))/output`)
69-
7080
global blastrampoline_build_dir = joinpath(dir, "output")
81+
run(`$(make) -sC $(pathesc(srcdir)) CFLAGS="$(cflags_add)" ARCH=$(Sys.ARCH) clean`)
82+
run(`$(make) -sC $(pathesc(srcdir)) CFLAGS="$(cflags_add)" ARCH=$(Sys.ARCH) install builddir=$(pathesc(dir))/build prefix=$(pathesc(blastrampoline_build_dir))`)
7183

7284
# Give LBT a fake linking name so that we can test from within Julia versions that actually load LBT natively.
7385
link_name = "blastramp-dev"
7486
cp(
75-
joinpath(blastrampoline_build_dir, binlib, "libblastrampoline.$(shlib_ext)"),
87+
joinpath(blastrampoline_build_dir, binlib, blastrampoline_major_version()),
7688
joinpath(blastrampoline_build_dir, binlib, "lib$(link_name).$(shlib_ext)"),
7789
)
7890
println("$(blastrampoline_build_dir)/$(binlib)")

0 commit comments

Comments
 (0)