dash/contrib/devtools/test-symbol-check.py

180 lines
5.9 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# Copyright (c) 2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Test script for symbol-check.py
'''
import os
import subprocess
from typing import List
import unittest
from utils import determine_wellknown_cmd
def call_symbol_check(cc: List[str], source, executable, options):
# This should behave the same as AC_TRY_LINK, so arrange well-known flags
# in the same order as autoconf would.
#
# See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for
# reference.
env_flags: List[str] = []
for var in ['CFLAGS', 'CPPFLAGS', 'LDFLAGS']:
env_flags += filter(None, os.environ.get(var, '').split(' '))
subprocess.run([*cc,source,'-o',executable] + env_flags + options, check=True)
p = subprocess.run(['./contrib/devtools/symbol-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
os.remove(source)
os.remove(executable)
return (p.returncode, p.stdout.rstrip())
def get_machine(cc: List[str]):
p = subprocess.run([*cc,'-dumpmachine'], stdout=subprocess.PIPE, universal_newlines=True)
return p.stdout.rstrip()
class TestSymbolChecks(unittest.TestCase):
def test_ELF(self):
source = 'test1.c'
executable = 'test1'
cc = determine_wellknown_cmd('CC', 'gcc')
# -lutil is part of the libc6 package so a safe bet that it's installed
# it's also out of context enough that it's unlikely to ever become a real dependency
source = 'test2.c'
executable = 'test2'
with open(source, 'w', encoding="utf8") as f:
f.write('''
#include <utmp.h>
int main()
{
login(0);
return 0;
}
''')
self.assertEqual(call_symbol_check(cc, source, executable, ['-lutil']),
(1, executable + ': libutil.so.1 is not in ALLOWED_LIBRARIES!\n' +
executable + ': failed LIBRARY_DEPENDENCIES'))
Merge bitcoin/bitcoin#22645: scripts: prevent GCC optimising test symbols in test-symbol-check 5449d44e37982fcd5251fd47873c5f7d34c39fc9 scripts: prevent GCC optimising test symbols in test-symbol-check (fanquake) Pull request description: I noticed in #22381 that when the test-symbol-check target was being built with Clang and run in the CI it would fail due to using a too-new version of `pow` (used [here](https://github.com/bitcoin/bitcoin/blob/d67330d11245b11fbdd5e2dd5343ee451186931e/contrib/devtools/test-symbol-check.py#L85)). Our CIs use Focal (glibc 2.31) and the version of `pow` was the optimized version introduced in [glibc 2.29](https://lwn.net/Articles/778286/): ```bash * Optimized generic exp, exp2, log, log2, pow, sinf, cosf, sincosf and tanf. ``` This made sense, except for that if it was failing when built using Clang, why hadn't it also been failing when being built with GCC? Turns out GCC is optimizing away that call to `pow` at all optimization levels, including `-O0`, see: https://godbolt.org/z/53MhzMxT7, and this has been the case forever, or at least since GCC 5.x. Clang on the other hand, will only optimize away the `pow` call at `-O1` and `-O2`, not `-O0`: https://godbolt.org/z/Wbnqj3q6c. Thus when this test was built with Clang (we don't pass `-O` so we default to `-O0`) it was failing in the CI environment, because it would actually have a call to the "new" `pow`. Avoid this issue by using a symbol that won't be optimized away, or that we are unlikely to ever have versioning issues with. ACKs for top commit: laanwj: ACK 5449d44e37982fcd5251fd47873c5f7d34c39fc9 Tree-SHA512: 3a26c5c3a5f2905fd0dd90892470e241ba625c0af3be2629d06d5da3a97534c1d6a55b796bbdd41e2e6a26a8fab7d981b98c45d4238565b0eb7edf3c5da02007
2021-08-18 17:16:02 +02:00
# finally, check a simple conforming binary
source = 'test3.c'
executable = 'test3'
with open(source, 'w', encoding="utf8") as f:
f.write('''
Merge bitcoin/bitcoin#22645: scripts: prevent GCC optimising test symbols in test-symbol-check 5449d44e37982fcd5251fd47873c5f7d34c39fc9 scripts: prevent GCC optimising test symbols in test-symbol-check (fanquake) Pull request description: I noticed in #22381 that when the test-symbol-check target was being built with Clang and run in the CI it would fail due to using a too-new version of `pow` (used [here](https://github.com/bitcoin/bitcoin/blob/d67330d11245b11fbdd5e2dd5343ee451186931e/contrib/devtools/test-symbol-check.py#L85)). Our CIs use Focal (glibc 2.31) and the version of `pow` was the optimized version introduced in [glibc 2.29](https://lwn.net/Articles/778286/): ```bash * Optimized generic exp, exp2, log, log2, pow, sinf, cosf, sincosf and tanf. ``` This made sense, except for that if it was failing when built using Clang, why hadn't it also been failing when being built with GCC? Turns out GCC is optimizing away that call to `pow` at all optimization levels, including `-O0`, see: https://godbolt.org/z/53MhzMxT7, and this has been the case forever, or at least since GCC 5.x. Clang on the other hand, will only optimize away the `pow` call at `-O1` and `-O2`, not `-O0`: https://godbolt.org/z/Wbnqj3q6c. Thus when this test was built with Clang (we don't pass `-O` so we default to `-O0`) it was failing in the CI environment, because it would actually have a call to the "new" `pow`. Avoid this issue by using a symbol that won't be optimized away, or that we are unlikely to ever have versioning issues with. ACKs for top commit: laanwj: ACK 5449d44e37982fcd5251fd47873c5f7d34c39fc9 Tree-SHA512: 3a26c5c3a5f2905fd0dd90892470e241ba625c0af3be2629d06d5da3a97534c1d6a55b796bbdd41e2e6a26a8fab7d981b98c45d4238565b0eb7edf3c5da02007
2021-08-18 17:16:02 +02:00
#include <stdio.h>
int main()
{
Merge bitcoin/bitcoin#22645: scripts: prevent GCC optimising test symbols in test-symbol-check 5449d44e37982fcd5251fd47873c5f7d34c39fc9 scripts: prevent GCC optimising test symbols in test-symbol-check (fanquake) Pull request description: I noticed in #22381 that when the test-symbol-check target was being built with Clang and run in the CI it would fail due to using a too-new version of `pow` (used [here](https://github.com/bitcoin/bitcoin/blob/d67330d11245b11fbdd5e2dd5343ee451186931e/contrib/devtools/test-symbol-check.py#L85)). Our CIs use Focal (glibc 2.31) and the version of `pow` was the optimized version introduced in [glibc 2.29](https://lwn.net/Articles/778286/): ```bash * Optimized generic exp, exp2, log, log2, pow, sinf, cosf, sincosf and tanf. ``` This made sense, except for that if it was failing when built using Clang, why hadn't it also been failing when being built with GCC? Turns out GCC is optimizing away that call to `pow` at all optimization levels, including `-O0`, see: https://godbolt.org/z/53MhzMxT7, and this has been the case forever, or at least since GCC 5.x. Clang on the other hand, will only optimize away the `pow` call at `-O1` and `-O2`, not `-O0`: https://godbolt.org/z/Wbnqj3q6c. Thus when this test was built with Clang (we don't pass `-O` so we default to `-O0`) it was failing in the CI environment, because it would actually have a call to the "new" `pow`. Avoid this issue by using a symbol that won't be optimized away, or that we are unlikely to ever have versioning issues with. ACKs for top commit: laanwj: ACK 5449d44e37982fcd5251fd47873c5f7d34c39fc9 Tree-SHA512: 3a26c5c3a5f2905fd0dd90892470e241ba625c0af3be2629d06d5da3a97534c1d6a55b796bbdd41e2e6a26a8fab7d981b98c45d4238565b0eb7edf3c5da02007
2021-08-18 17:16:02 +02:00
printf("42");
return 0;
}
''')
Merge bitcoin/bitcoin#22645: scripts: prevent GCC optimising test symbols in test-symbol-check 5449d44e37982fcd5251fd47873c5f7d34c39fc9 scripts: prevent GCC optimising test symbols in test-symbol-check (fanquake) Pull request description: I noticed in #22381 that when the test-symbol-check target was being built with Clang and run in the CI it would fail due to using a too-new version of `pow` (used [here](https://github.com/bitcoin/bitcoin/blob/d67330d11245b11fbdd5e2dd5343ee451186931e/contrib/devtools/test-symbol-check.py#L85)). Our CIs use Focal (glibc 2.31) and the version of `pow` was the optimized version introduced in [glibc 2.29](https://lwn.net/Articles/778286/): ```bash * Optimized generic exp, exp2, log, log2, pow, sinf, cosf, sincosf and tanf. ``` This made sense, except for that if it was failing when built using Clang, why hadn't it also been failing when being built with GCC? Turns out GCC is optimizing away that call to `pow` at all optimization levels, including `-O0`, see: https://godbolt.org/z/53MhzMxT7, and this has been the case forever, or at least since GCC 5.x. Clang on the other hand, will only optimize away the `pow` call at `-O1` and `-O2`, not `-O0`: https://godbolt.org/z/Wbnqj3q6c. Thus when this test was built with Clang (we don't pass `-O` so we default to `-O0`) it was failing in the CI environment, because it would actually have a call to the "new" `pow`. Avoid this issue by using a symbol that won't be optimized away, or that we are unlikely to ever have versioning issues with. ACKs for top commit: laanwj: ACK 5449d44e37982fcd5251fd47873c5f7d34c39fc9 Tree-SHA512: 3a26c5c3a5f2905fd0dd90892470e241ba625c0af3be2629d06d5da3a97534c1d6a55b796bbdd41e2e6a26a8fab7d981b98c45d4238565b0eb7edf3c5da02007
2021-08-18 17:16:02 +02:00
self.assertEqual(call_symbol_check(cc, source, executable, []),
(0, ''))
def test_MACHO(self):
source = 'test1.c'
executable = 'test1'
cc = determine_wellknown_cmd('CC', 'clang')
with open(source, 'w', encoding="utf8") as f:
f.write('''
#include <expat.h>
int main()
{
XML_ExpatVersion();
return 0;
}
''')
self.assertEqual(call_symbol_check(cc, source, executable, ['-lexpat', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']),
(1, 'libexpat.1.dylib is not in ALLOWED_LIBRARIES!\n' +
f'{executable}: failed DYNAMIC_LIBRARIES MIN_OS SDK'))
source = 'test2.c'
executable = 'test2'
with open(source, 'w', encoding="utf8") as f:
f.write('''
#include <CoreGraphics/CoreGraphics.h>
int main()
{
CGMainDisplayID();
return 0;
}
''')
self.assertEqual(call_symbol_check(cc, source, executable, ['-framework', 'CoreGraphics', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']),
(1, f'{executable}: failed MIN_OS SDK'))
source = 'test3.c'
executable = 'test3'
with open(source, 'w', encoding="utf8") as f:
f.write('''
int main()
{
return 0;
}
''')
self.assertEqual(call_symbol_check(cc, source, executable, ['-Wl,-platform_version','-Wl,macos', '-Wl,11.0', '-Wl,11.4']),
(1, f'{executable}: failed SDK'))
def test_PE(self):
source = 'test1.c'
executable = 'test1.exe'
cc = determine_wellknown_cmd('CC', 'x86_64-w64-mingw32-gcc')
with open(source, 'w', encoding="utf8") as f:
f.write('''
#include <pdh.h>
int main()
{
PdhConnectMachineA(NULL);
return 0;
}
''')
self.assertEqual(call_symbol_check(cc, source, executable, ['-lpdh', '-Wl,--major-subsystem-version', '-Wl,6', '-Wl,--minor-subsystem-version', '-Wl,1']),
(1, 'pdh.dll is not in ALLOWED_LIBRARIES!\n' +
executable + ': failed DYNAMIC_LIBRARIES'))
source = 'test2.c'
executable = 'test2.exe'
with open(source, 'w', encoding="utf8") as f:
f.write('''
int main()
{
return 0;
}
''')
self.assertEqual(call_symbol_check(cc, source, executable, ['-Wl,--major-subsystem-version', '-Wl,9', '-Wl,--minor-subsystem-version', '-Wl,9']),
(1, executable + ': failed SUBSYSTEM_VERSION'))
source = 'test3.c'
executable = 'test3.exe'
with open(source, 'w', encoding="utf8") as f:
f.write('''
Merge bitcoin/bitcoin#24491: contrib: fix implicit function decleration in win symbol check e4e9dd3a287f134356044f636e189da704de8ed4 contrib: fix implicit function decleration in win symbol check (fanquake) Pull request description: ```bash test3.c: In function 'main': test3.c:6:21: warning: implicit declaration of function 'CoFreeUnusedLibrariesEx' [-Wimplicit-function-declaration] 6 | CoFreeUnusedLibrariesEx(0,0); ``` ```bash bash-5.1# find guix-build-$(git rev-parse --short=12 HEAD)/output/ -type f -print0 | env LC_ALL=C sort -z | xargs -r0 sha256sum 1907745369f13b0b01583795e395b7e8ecda174a8a3b6309184b14609bfdcb20 guix-build-e4e9dd3a287f/output/dist-archive/bitcoin-e4e9dd3a287f.tar.gz 6973025bd46acdbc327118541f26d36885434305d20a7fa33e0db61f66f8b930 guix-build-e4e9dd3a287f/output/x86_64-w64-mingw32/SHA256SUMS.part 4cdc4efc0d27b3fcfb8f36244dfd956d19ae5df0414dcc23e733c88188f1f93a guix-build-e4e9dd3a287f/output/x86_64-w64-mingw32/bitcoin-e4e9dd3a287f-win-unsigned.tar.gz 022e9743b13f5366cd0f4b52ff8350b42d8c6a506c98363071501a6c4ac735f1 guix-build-e4e9dd3a287f/output/x86_64-w64-mingw32/bitcoin-e4e9dd3a287f-win64-debug.zip 62e65f04fdcacb3d3fbcffbea5204f723f2b27a5f9a62a77abaf0b7ee7de3744 guix-build-e4e9dd3a287f/output/x86_64-w64-mingw32/bitcoin-e4e9dd3a287f-win64-setup-unsigned.exe d773f5ba6afe456b7b5286f0cf98bcb711da8087b96a31f2e38f9c43af44fe96 guix-build-e4e9dd3a287f/output/x86_64-w64-mingw32/bitcoin-e4e9dd3a287f-win64.zip ``` ACKs for top commit: laanwj: Code review ACK e4e9dd3a287f134356044f636e189da704de8ed4 hebasto: ACK e4e9dd3a287f134356044f636e189da704de8ed4, tested on Ubuntu 22.04. Tree-SHA512: e075b052f848a654ed11fb8bc29e2a7b015ab2b44878535d84ac61ecec507410d68e866526c5e0acd1b1b99e65c9d738231208cbb676c8d3f73691317c94c9e0
2022-03-13 09:23:07 +01:00
#include <combaseapi.h>
int main()
{
CoFreeUnusedLibrariesEx(0,0);
return 0;
}
''')
self.assertEqual(call_symbol_check(cc, source, executable, ['-lole32', '-Wl,--major-subsystem-version', '-Wl,6', '-Wl,--minor-subsystem-version', '-Wl,1']),
(0, ''))
if __name__ == '__main__':
unittest.main()