Skip to content

Commit 8d917f9

Browse files
eschnettgiordano
authored andcommitted
Iterate over readmeta results (#1308)
* Iterate over `readmeta` results * Correct get_soname * Require ObjectFile 0.4 * Update Manifest.toml
1 parent e60fa99 commit 8d917f9

File tree

9 files changed

+105
-90
lines changed

9 files changed

+105
-90
lines changed

Manifest.toml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
julia_version = "1.7.2"
44
manifest_format = "2.0"
5-
project_hash = "1e87134dc5853b26c2f65af5a46eb0a2d987da86"
5+
project_hash = "37b1c77f30c4c87e9820261f70d049fd61c325f2"
66

77
[[deps.ArgParse]]
88
deps = ["Logging", "TextWrap"]
@@ -38,7 +38,7 @@ uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
3838

3939
[[deps.BinaryBuilderBase]]
4040
deps = ["Bzip2_jll", "CodecZlib", "Downloads", "Gzip_jll", "HistoricalStdlibVersions", "InteractiveUtils", "JLLWrappers", "JSON", "LibGit2", "LibGit2_jll", "Libdl", "Logging", "OrderedCollections", "OutputCollectors", "Pkg", "Printf", "ProgressMeter", "REPL", "Random", "SHA", "Scratch", "SimpleBufferStream", "TOML", "Tar", "Tar_jll", "UUIDs", "XZ_jll", "Zstd_jll", "p7zip_jll", "pigz_jll", "unzip_jll"]
41-
git-tree-sha1 = "b6e70b712721dea3f586d97aa05e7b5eba96309c"
41+
git-tree-sha1 = "6f8c4fb870b394c018455d05c2f6f9097f80175b"
4242
repo-rev = "master"
4343
repo-url = "https://github.com/JuliaPackaging/BinaryBuilderBase.jl.git"
4444
uuid = "7f725544-6523-48cd-82d1-3fa08ff4056e"
@@ -62,10 +62,10 @@ uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
6262
version = "0.7.3"
6363

6464
[[deps.Compat]]
65-
deps = ["Dates", "LinearAlgebra", "UUIDs"]
66-
git-tree-sha1 = "886826d76ea9e72b35fcd000e535588f7b60f21d"
65+
deps = ["Dates", "LinearAlgebra", "TOML", "UUIDs"]
66+
git-tree-sha1 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b"
6767
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
68-
version = "4.10.1"
68+
version = "4.12.0"
6969

7070
[[deps.CompilerSupportLibraries_jll]]
7171
deps = ["Artifacts", "Libdl"]
@@ -96,14 +96,14 @@ deps = ["Random", "Serialization", "Sockets"]
9696
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
9797

9898
[[deps.Downloads]]
99-
deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
99+
deps = ["ArgTools", "LibCURL", "NetworkOptions"]
100100
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
101101

102102
[[deps.ExceptionUnwrapping]]
103103
deps = ["Test"]
104-
git-tree-sha1 = "e90caa41f5a86296e014e148ee061bd6c3edec96"
104+
git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a"
105105
uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4"
106-
version = "0.1.9"
106+
version = "0.1.10"
107107

108108
[[deps.ExprTools]]
109109
git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec"
@@ -112,9 +112,9 @@ version = "0.1.10"
112112

113113
[[deps.FileIO]]
114114
deps = ["Pkg", "Requires", "UUIDs"]
115-
git-tree-sha1 = "299dc33549f68299137e51e6d49a13b5b1da9673"
115+
git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc"
116116
uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
117-
version = "1.16.1"
117+
version = "1.16.2"
118118

119119
[[deps.FileWatching]]
120120
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
@@ -171,9 +171,9 @@ version = "1.0.0"
171171

172172
[[deps.JLD2]]
173173
deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"]
174-
git-tree-sha1 = "c2d0f45afcb5f6209155670bffd100c3b4937ea3"
174+
git-tree-sha1 = "853b9e0b876e8c7093a824c4f83c619d23525e64"
175175
uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
176-
version = "0.4.40"
176+
version = "0.4.43"
177177

178178
[[deps.JLLWrappers]]
179179
deps = ["Artifacts", "Preferences"]
@@ -288,9 +288,9 @@ uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
288288

289289
[[deps.ObjectFile]]
290290
deps = ["Reexport", "StructIO"]
291-
git-tree-sha1 = "55ce61d43409b1fb0279d1781bf3b0f22c83ab3b"
291+
git-tree-sha1 = "195e0a19842f678dd3473ceafbe9d82dfacc583c"
292292
uuid = "d8793406-e978-5875-9003-1fc021f44a92"
293-
version = "0.3.7"
293+
version = "0.4.1"
294294

295295
[[deps.OpenBLAS_jll]]
296296
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
@@ -555,10 +555,10 @@ deps = ["Artifacts", "Libdl"]
555555
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
556556

557557
[[deps.pigz_jll]]
558-
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
559-
git-tree-sha1 = "3c0c0b0c133b6ab53e1af05dc526091ce8781f16"
558+
deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"]
559+
git-tree-sha1 = "cb56f0446caa6138418ee28132024e2c3911d19b"
560560
uuid = "1bc43ea1-30af-5bc8-a9d4-c018457e6e3e"
561-
version = "2.7.0+0"
561+
version = "2.8.0+0"
562562

563563
[[deps.unzip_jll]]
564564
deps = ["Artifacts", "JLLWrappers", "Libdl"]

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ JLD2 = "0.1.6, 0.2, 0.3, 0.4"
4141
JLLWrappers = "1.2.0"
4242
JSON = "0.21"
4343
LoggingExtras = "0.4, 1"
44-
ObjectFile = "0.3.6, 0.4"
44+
ObjectFile = "0.4"
4545
OutputCollectors = "0.1"
4646
PkgLicenses = "0.2"
4747
Registrator = "1.1"

src/Auditor.jl

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -81,38 +81,40 @@ function audit(prefix::Prefix, src_name::AbstractString = "";
8181

8282
# Peel this binary file open like a delicious tangerine
8383
try
84-
readmeta(f) do oh
85-
if !is_for_platform(oh, platform)
86-
if verbose
87-
@warn("Skipping binary analysis of $(relpath(f, prefix.path)) (incorrect platform)")
88-
end
89-
else
90-
# Check that the ISA isn't too high
91-
all_ok &= check_isa(oh, platform, prefix; verbose, silent)
92-
# Check that the OS ABI is set correctly (often indicates the wrong linker was used)
93-
all_ok &= check_os_abi(oh, platform; verbose)
94-
# Make sure all binary files are executables, if libraries aren't
95-
# executables Julia may not be able to dlopen them:
96-
# https://github.com/JuliaLang/julia/issues/38993. In principle this
97-
# should be done when autofix=true, but we have to run this fix on MKL
98-
# for Windows, for which however we have to set autofix=false:
99-
# https://github.com/JuliaPackaging/Yggdrasil/pull/922.
100-
all_ok &= ensure_executability(oh; verbose, silent)
101-
102-
# If this is a dynamic object, do the dynamic checks
103-
if isdynamic(oh)
104-
# Check that the libgfortran version matches
105-
all_ok &= check_libgfortran_version(oh, platform; verbose, has_csl)
106-
# Check whether the library depends on any of the most common
107-
# libraries provided by `CompilerSupportLibraries_jll`.
108-
all_ok &= check_csl_libs(oh, platform; verbose, has_csl)
109-
# Check that the libstdcxx string ABI matches
110-
all_ok &= check_cxxstring_abi(oh, platform; verbose)
111-
# Check that this binary file's dynamic linkage works properly. Note to always
112-
# DO THIS ONE LAST as it can actually mutate the file, which causes the previous
113-
# checks to freak out a little bit.
114-
all_ok &= check_dynamic_linkage(oh, prefix, bin_files;
115-
platform, silent, verbose, autofix, src_name)
84+
readmeta(f) do ohs
85+
foreach(ohs) do oh
86+
if !is_for_platform(oh, platform)
87+
if verbose
88+
@warn("Skipping binary analysis of $(relpath(f, prefix.path)) (incorrect platform)")
89+
end
90+
else
91+
# Check that the ISA isn't too high
92+
all_ok &= check_isa(oh, platform, prefix; verbose, silent)
93+
# Check that the OS ABI is set correctly (often indicates the wrong linker was used)
94+
all_ok &= check_os_abi(oh, platform; verbose)
95+
# Make sure all binary files are executables, if libraries aren't
96+
# executables Julia may not be able to dlopen them:
97+
# https://github.com/JuliaLang/julia/issues/38993. In principle this
98+
# should be done when autofix=true, but we have to run this fix on MKL
99+
# for Windows, for which however we have to set autofix=false:
100+
# https://github.com/JuliaPackaging/Yggdrasil/pull/922.
101+
all_ok &= ensure_executability(oh; verbose, silent)
102+
103+
# If this is a dynamic object, do the dynamic checks
104+
if isdynamic(oh)
105+
# Check that the libgfortran version matches
106+
all_ok &= check_libgfortran_version(oh, platform; verbose, has_csl)
107+
# Check whether the library depends on any of the most common
108+
# libraries provided by `CompilerSupportLibraries_jll`.
109+
all_ok &= check_csl_libs(oh, platform; verbose, has_csl)
110+
# Check that the libstdcxx string ABI matches
111+
all_ok &= check_cxxstring_abi(oh, platform; verbose)
112+
# Check that this binary file's dynamic linkage works properly. Note to always
113+
# DO THIS ONE LAST as it can actually mutate the file, which causes the previous
114+
# checks to freak out a little bit.
115+
all_ok &= check_dynamic_linkage(oh, prefix, bin_files;
116+
platform, silent, verbose, autofix, src_name)
117+
end
116118
end
117119
end
118120
end

src/auditor/compiler_abi.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ function detect_libstdcxx_version(oh::ObjectHandle, platform::AbstractPlatform)
120120

121121
# Extract all pieces of `.gnu.version_d` from libstdc++.so, find the `GLIBCXX_*`
122122
# symbols, and use the maximum version of that to find the GLIBCXX ABI version number
123-
version_symbols = readmeta(first(libstdcxx_libs)) do oh
124-
unique(vcat((x -> x.names).(ELFVersionData(oh))...))
123+
version_symbols = readmeta(first(libstdcxx_libs)) do ohs
124+
unique(vcat((x -> x.names).(vcat(ELFVersionData.(ohs)...))...))
125125
end
126126
version_symbols = filter(x -> startswith(x, "GLIBCXX_"), version_symbols)
127127
if isempty(version_symbols)

src/auditor/dynamic_linkage.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ function platform_for_object(oh::ObjectHandle)
6868
end
6969

7070
function _rpaths(file::AbstractString)
71-
readmeta(file) do oh
72-
rpaths(RPath(oh))
71+
readmeta(file) do ohs
72+
vcat(rpaths.(RPath.(ohs))...)
7373
end
7474
end
7575

7676
function _canonical_rpaths(file::AbstractString)
77-
readmeta(file) do oh
78-
canonical_rpaths(RPath(oh))
77+
readmeta(file) do ohs
78+
vcat(canonical_rpaths.(RPath.(ohs))...)
7979
end
8080
end
8181

src/auditor/soname_matching.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ get_soname(oh::ObjectHandle) = nothing
44
# Auto-open a path into an ObjectHandle
55
function get_soname(path::AbstractString)
66
try
7-
readmeta(get_soname, path)
7+
only(readmeta(ns -> get_soname.(ns), path))
88
catch e
99
@warn "Could not probe $(path) for an SONAME!" exception=(e, catch_backtrace())
1010
return nothing

src/wizard/interactive_build.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,16 @@ function step4(state::WizardState, ur::Runner, platform::AbstractPlatform,
3434

3535
# Check if we can load them as an object file
3636
files = filter(files) do f
37-
readmeta(f) do oh
38-
return Auditor.is_for_platform(oh, platform)
37+
readmeta(f) do ohs
38+
return any(Auditor.is_for_platform(oh, platform) for oh in ohs)
3939
end
4040
end
4141

4242
# Strip out the prefix from filenames
4343
state.files = map(file->replace(file, "$(destdir_path)/" => ""), files)
4444
state.file_kinds = map(files) do f
45-
readmeta(f) do oh
45+
readmeta(f) do ohs
46+
oh = first(ohs)
4647
if isexecutable(oh)
4748
return :executable
4849
elseif islibrary(oh)

src/wizard/utils.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ from `ObjectFile`.
8585
function filter_object_files(files)
8686
return filter(files) do f
8787
try
88-
readmeta(f) do oh
88+
readmeta(f) do ohs
8989
return true
9090
end
9191
catch e
@@ -121,8 +121,8 @@ function match_files(state::WizardState, prefix::Prefix,
121121
prefix_files = filter_object_files(prefix_files)
122122
# Check if we can load them as an object file
123123
prefix_files = filter(prefix_files) do f
124-
readmeta(f) do oh
125-
if !Auditor.is_for_platform(oh, platform)
124+
readmeta(f) do ohs
125+
if !any(Auditor.is_for_platform(oh, platform) for oh in ohs)
126126
if !silent
127127
@warn("Skipping binary `$f` with incorrect platform")
128128
end

test/auditing.jl

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,11 @@ end
8686
prefix = Prefix(testdir)
8787

8888
# Run ISA test
89-
readmeta(locate(product, prefix)) do oh
90-
detected_isa = Auditor.analyze_instruction_set(oh, platform; verbose=true)
91-
@test detected_isa == "avx512"
89+
readmeta(locate(product, prefix)) do ohs
90+
foreach(ohs) do oh
91+
detected_isa = Auditor.analyze_instruction_set(oh, platform; verbose=true)
92+
@test detected_isa == "avx512"
93+
end
9294
end
9395
end
9496
end
@@ -133,9 +135,11 @@ end
133135
prefix = Prefix(testdir)
134136

135137
# Run ISA test
136-
readmeta(locate(product, prefix)) do oh
137-
detected_march = Auditor.analyze_instruction_set(oh, platform; verbose=true)
138-
@test detected_march == "avx"
138+
readmeta(locate(product, prefix)) do ohs
139+
foreach(ohs) do oh
140+
detected_march = Auditor.analyze_instruction_set(oh, platform; verbose=true)
141+
@test detected_march == "avx"
142+
end
139143
end
140144
end
141145
end
@@ -182,14 +186,16 @@ end
182186
prefix = Prefix(testdir)
183187

184188
# Run ISA test
185-
readmeta(locate(product, prefix)) do oh
186-
detected_march = Auditor.analyze_instruction_set(oh, platform; verbose=true)
187-
if march == "avx2"
188-
# Detecting the ISA isn't 100% reliable and it's even less
189-
# accurate when looking for AVX2 features
190-
@test_broken march == detected_march
191-
else
192-
@test march == detected_march
189+
readmeta(locate(product, prefix)) do ohs
190+
foreach(ohs) do oh
191+
detected_march = Auditor.analyze_instruction_set(oh, platform; verbose=true)
192+
if march == "avx2"
193+
# Detecting the ISA isn't 100% reliable and it's even less
194+
# accurate when looking for AVX2 features
195+
@test_broken march == detected_march
196+
else
197+
@test march == detected_march
198+
end
193199
end
194200
end
195201
end
@@ -243,9 +249,11 @@ end
243249
prefix = Prefix(testdir)
244250

245251
# Ensure that the library detects as the correct cxxstring_abi:
246-
readmeta(locate(libcxxstringabi_test, prefix)) do oh
247-
detected_cxxstring_abi = Auditor.detect_cxxstring_abi(oh, platform)
248-
@test detected_cxxstring_abi == cxxstring_abi(platform)
252+
readmeta(locate(libcxxstringabi_test, prefix)) do ohs
253+
foreach(ohs) do oh
254+
detected_cxxstring_abi = Auditor.detect_cxxstring_abi(oh, platform)
255+
@test detected_cxxstring_abi == cxxstring_abi(platform)
256+
end
249257
end
250258

251259
# Explicitly test cxx string abi mismatches
@@ -404,11 +412,13 @@ end
404412
prefix = Prefix(testdir)
405413

406414
# Helper to extract the dylib id of a path
407-
function get_dylib_id(path)
408-
return readmeta(path) do oh
409-
dylib_id_lcs = [lc for lc in MachOLoadCmds(oh) if isa(lc, MachOIdDylibCmd)]
410-
@test !isempty(dylib_id_lcs)
411-
return dylib_name(first(dylib_id_lcs))
415+
function get_dylib_ids(path)
416+
return readmeta(path) do ohs
417+
map(ohs) do oh
418+
dylib_id_lcs = [lc for lc in MachOLoadCmds(oh) if isa(lc, MachOIdDylibCmd)]
419+
@test !isempty(dylib_id_lcs)
420+
return dylib_name(first(dylib_id_lcs))
421+
end
412422
end
413423
end
414424

@@ -419,7 +429,7 @@ end
419429
right_id_path = locate(right_id, prefix; platform=platform)
420430
for p in (no_id_path, abs_id_path, right_id_path)
421431
@test any(startswith.(p, libdirs(prefix)))
422-
@test get_dylib_id(p) == "@rpath/$(basename(p))"
432+
@test all(get_dylib_ids(p) .== "@rpath/$(basename(p))")
423433
end
424434

425435
# Only if it already has an `@rpath/`-ified ID, it doesn't get touched.
@@ -534,10 +544,12 @@ end
534544
# audit should warn us.
535545
libgfortran_versions = (3, 4, 5)
536546
other_libgfortran_version = libgfortran_versions[findfirst(v -> v != our_libgfortran_version.major, libgfortran_versions)]
537-
@test_logs (:warn, Regex("but we are supposedly building for libgfortran$(other_libgfortran_version)")) (:warn, r"Linked library libgfortran.so.5") (:warn, r"Linked library libquadmath.so.0") (:warn, r"Linked library libgcc_s.so.1") readmeta(hello_world_path) do oh
538-
p = deepcopy(platform)
539-
p["libgfortran_version"] = "$(other_libgfortran_version).0.0"
540-
@test !Auditor.audit(Prefix(testdir); platform=p, autofix=false)
547+
@test_logs (:warn, Regex("but we are supposedly building for libgfortran$(other_libgfortran_version)")) (:warn, r"Linked library libgfortran.so.5") (:warn, r"Linked library libquadmath.so.0") (:warn, r"Linked library libgcc_s.so.1") readmeta(hello_world_path) do ohs
548+
foreach(ohs) do oh
549+
p = deepcopy(platform)
550+
p["libgfortran_version"] = "$(other_libgfortran_version).0.0"
551+
@test !Auditor.audit(Prefix(testdir); platform=p, autofix=false)
552+
end
541553
end
542554
end
543555
end

0 commit comments

Comments
 (0)