Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: Port Go build wrapper from Shell to Python & support externaly defined build options #1031

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions completion/meson.build
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
generate_completions_program = find_program('generate_completions.py')

if bash_completion.found()
bash_comp_dir = bash_completion.get_pkgconfig_variable('completionsdir')
bash_comp_dir = bash_completion.get_variable(pkgconfig: 'completionsdir')
else
bash_comp_dir = get_option('datadir') / 'bash-completion' / 'completions'
message('bash-completion not found: using', get_option('prefix') / bash_comp_dir, 'as a falback install directory')
endif

if fish.found()
fish_comp_dir = fish.get_pkgconfig_variable('completionsdir')
fish_comp_dir = fish.get_variable(pkgconfig: 'completionsdir')
else
fish_comp_dir = get_option('datadir') / 'fish' / 'completions'
message('fish not found: using', get_option('prefix') / fish_comp_dir, 'as a fallback install directory')
Expand Down
24 changes: 1 addition & 23 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,11 @@ if not skopeo.found()
message('Running system tests requires Skopeo for OCI image manipulation.')
endif

install_subdir(
'test',
install_dir: join_paths(get_option('datadir'), meson.project_name()),
exclude_files: [
'system/libs/bats-assert/.git',
'system/libs/bats-assert/.gitignore',
'system/libs/bats-assert/.travis.yml',
'system/libs/bats-assert/package.json',
'system/libs/bats-support/.git',
'system/libs/bats-support/.gitignore',
'system/libs/bats-support/.travis.yml',
'system/libs/bats-support/package.json'
],
exclude_directories: [
'system/libs/bats-assert/.git',
'system/libs/bats-assert/script',
'system/libs/bats-assert/test',
'system/libs/bats-support/.git',
'system/libs/bats-support/script',
'system/libs/bats-support/test'
]
)

subdir('data')
subdir('doc')
subdir('profile.d')
subdir('src')
subdir('test')
if get_option('install_completions')
subdir('completion')
endif
Expand Down
6 changes: 6 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@ option(
type: 'boolean',
value: true,
)

option(
'go_build_flags',
description: 'Options passed to \'go build\' during build',
type: 'string',
)
79 changes: 0 additions & 79 deletions src/go-build-wrapper

This file was deleted.

109 changes: 109 additions & 0 deletions src/go-build-wrapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env python3
#
# Copyright © 2022 Ondřej Míchal
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import os
import shlex
import subprocess
import sys

prog_name = os.path.basename(sys.argv[0])


def get_canonical_libc_dirname(cc):
try:
libc_path = subprocess.run(
[cc, '--print-file-name=libc.so'],
capture_output=True, check=True, text=True).stdout.strip()
except subprocess.CalledProcessError as e:
print(f'{prog_name}: failed to read the path to libc.so', file=sys.stderr)
print(e.stderr, file=sys.stderr)
sys.exit(1)

libc_path_canonical = os.path.realpath(libc_path)

return os.path.dirname(libc_path_canonical)


def create_rpath(libc_path_dirname):
return '/run/host' + libc_path_dirname


def alter_dynamic_linker_path(dynamic_linker):
dynamic_linker_basename = os.path.basename(dynamic_linker)
dynamic_linker_canonical = os.path.realpath(dynamic_linker)
dynamic_linker_canonical_dirname = os.path.dirname(
dynamic_linker_canonical)

return f'/run/host{dynamic_linker_canonical_dirname}/{dynamic_linker_basename}'


if len(sys.argv) != 8:
print('{}: wrong arguments'.format(prog_name), file=sys.stderr)
print('''Usage: {} [SOURCE DIR]
[OUTPUT DIR]
[VERSION]
[C COMPILER]
[DYNAMIC LINKER]
[MIGRATION PATH FORCOREOS/TOOLBOX]
[BUILD FLAGS]'''.format(prog_name), file=sys.stderr)
sys.exit(1)

source_dir = sys.argv[1]
output_dir = sys.argv[2]
version = sys.argv[3]
cc = sys.argv[4]
dynamic_linker = sys.argv[5]
# Boolean is passed from Meson as a string
coreos_migration = True if sys.argv[6] == "true" else False
build_flags = sys.argv[7]

try:
os.chdir(source_dir)
except OSError as e:
print(f'{prog_name}: failed to change directory to {source_dir}',
file=sys.stderr)
print(e, file=sys.stderr)
sys.exit(1)

libc_path_dirname = get_canonical_libc_dirname(cc)
dynamic_linker = alter_dynamic_linker_path(dynamic_linker)
rpath = create_rpath(libc_path_dirname)

# Write overriden binary values to a file for testing
go_build_override_values_file = os.path.join(output_dir, 'go-build-overrides')
with open(go_build_override_values_file, mode='w') as f:
f.write(f'{dynamic_linker} {rpath}')

build_cmd = [
'go', 'build',
'-trimpath',
'-o', os.path.join(output_dir, 'toolbox')
]

if coreos_migration:
build_cmd.extend(['-tags', 'migration_path_for_coreos_toolbox'])

if build_flags:
build_cmd.extend(shlex.split(build_flags))

build_cmd.extend([
'-ldflags',
f'-extldflags \'-Wl,-dynamic-linker,{dynamic_linker} -Wl,-rpath,{rpath}\' -linkmode external -X github.com/containers/toolbox/pkg/version.currentVersion={version}'
])

go_build = subprocess.run(build_cmd)
sys.exit(go_build.returncode)
17 changes: 9 additions & 8 deletions src/meson.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
go_build_wrapper_file = files('go-build-wrapper')
go_build_wrapper_program = find_program('go-build-wrapper')
go_build_wrapper_program = find_program('go-build-wrapper.py')

meson_go_fmt_program = find_program('meson_go_fmt.py')

Expand Down Expand Up @@ -47,7 +46,7 @@ endif

message('Host machine dynamic linker:', dynamic_linker)

custom_target(
toolbox = custom_target(
'toolbox',
build_by_default: true,
command: [
Expand All @@ -58,16 +57,18 @@ custom_target(
cc.cmd_array().get(-1),
dynamic_linker,
migration_path_for_coreos_toolbox.to_string(),
get_option('go_build_flags'),
],
input: sources,
install: true,
install_dir: get_option('bindir'),
output: 'toolbox',
)

if shellcheck.found()
test('shellcheck go-build-wrapper', shellcheck, args: [go_build_wrapper_file])
endif

test('go fmt', meson_go_fmt_program, args: [meson.current_source_dir()])
test('toolbox go unit tests', go, args: ['test', '-v', './...'], workdir: meson.current_source_dir())
test('toolbox go unit tests',
go,
args: ['test', '-v', './...'],
depends: toolbox,
workdir: meson.current_source_dir()
)
23 changes: 23 additions & 0 deletions test/binary/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Binary tests

These tests test the Toolbx binary if it is properly set up (e.g., rpath, path
to dynamic linker)

## Dependencies

- `go`

## How to run the tests

The tests are best run using the build system that takes care of passing proper
values to them.

In case you want/need to run them manually run this command in this directory:

```shell
$ go test ./... -args <path-to-toolbx-binary> <path-to-file-with-build-overrides>
```

The tests read the tested values from a file where the build script wrote the
values it embeded into the binary. The values are space-separated on a single
line.
Loading