Skip to content

[WIP] bazel/autotools: Add some testing for built tools #2783

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
66 changes: 45 additions & 21 deletions bazel/autotools/archives.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,21 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("//:versions.bzl", "VERSIONS")

def _autotools_archive(name, arch):
"""Create an autotools archive repository."""
http_archive(
name = name,
urls = ["https://github.com/envoyproxy/toolshed/releases/download/bazel-bins-v0.1.11/autotools-%s-%s-%s-%s-%s.tar.xz" % (
VERSIONS["m4"],
VERSIONS["autoconf"],
VERSIONS["automake"],
VERSIONS["libtool"],
arch
)],
sha256 = VERSIONS["autotools_%s_sha256" % arch],
build_file_content = """
_AUTOTOOLS_BUILD_FILE = """
package(default_visibility = ["//visibility:public"])

filegroup(
name = "all",
srcs = glob(["**/*"]),
)

# Export all binaries
exports_files(glob(["bin/*"]))
# Export all binaries
exports_files(glob(["autotools-x86_64/bin/*", "autotools-aarch64/bin/*"]))

# Individual tool aliases
[alias(
name = tool,
actual = "bin/" + tool,
actual = "autotools-x86_64/bin/" + tool,
) for tool in [
"m4",
"autoconf",
Expand All @@ -44,10 +32,46 @@ exports_files(glob(["bin/*"]))
"libtool",
"libtoolize",
]]
""",
"""

def _local_autotools_archive(name, tarball_path):
"""Create an autotools archive repository from a local tarball."""
# Use http_archive with a file:// URL for local tarballs
http_archive(
name = name,
urls = ["file://" + tarball_path],
build_file_content = _AUTOTOOLS_BUILD_FILE,
)

def _autotools_archive(name, arch):
"""Create an autotools archive repository from GitHub releases."""
http_archive(
name = name,
urls = ["https://github.com/envoyproxy/toolshed/releases/download/bazel-bins-v%s/autotools-%s-%s-%s-%s-%s.tar.xz" % (
VERSIONS["bins_release"],
VERSIONS["m4"],
VERSIONS["autoconf"],
VERSIONS["automake"],
VERSIONS["libtool"],
arch
)],
sha256 = VERSIONS["autotools_%s_sha256" % arch],
build_file_content = _AUTOTOOLS_BUILD_FILE,
)

def setup_autotools_archives():
"""Set up autotools archives for both architectures."""
_autotools_archive("autotools_x86_64", "x86_64")
_autotools_archive("autotools_aarch64", "aarch64")
def setup_autotools_archives(local_tarball_path = None):
"""Set up autotools archives for both architectures.

Args:
local_tarball_path: Optional path to a local autotools tarball. If provided,
this will be used instead of downloading from GitHub releases.
The same tarball will be used for both architectures.
"""
if local_tarball_path:
# Use the same local tarball for both architectures
_local_autotools_archive("autotools_x86_64", local_tarball_path)
_local_autotools_archive("autotools_aarch64", local_tarball_path)
else:
# Download from GitHub releases
_autotools_archive("autotools_x86_64", "x86_64")
_autotools_archive("autotools_aarch64", "aarch64")
10 changes: 7 additions & 3 deletions bazel/autotools/setup.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ load("//autotools:archives.bzl", "setup_autotools_archives")
load("//autotools:autotools_repo.bzl", "setup_autotools_repo")
load("//toolchains:register.bzl", "toolshed_toolchains")

def setup_autotools(register_toolchains = True):
def setup_autotools(register_toolchains = True, local_tarball_path = None):
"""Set up autotools for use in external repositories.

This function:
1. Downloads the prebuilt autotools archives
1. Downloads the prebuilt autotools archives OR uses a local tarball
2. Creates the @autotools repository
3. Registers the toolchains

Expand All @@ -19,9 +19,13 @@ def setup_autotools(register_toolchains = True):

Args:
register_toolchains: Whether to register the autotools toolchains (default: True)
local_tarball_path: Optional path to a local autotools tarball for testing.
If provided, this will be used instead of downloading from
GitHub releases. This is useful for testing without going
through the release cycle.
"""
# Set up the archives
setup_autotools_archives()
setup_autotools_archives(local_tarball_path = local_tarball_path)

# Create the @autotools repo
setup_autotools_repo()
Expand Down
6 changes: 6 additions & 0 deletions bazel/autotools/test/.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Inherit from parent .bazelrc if needed
try-import ../../.bazelrc

# Basic build options for testing
build --color=yes
build --curses=yes
1 change: 1 addition & 0 deletions bazel/autotools/test/.bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7.6.0
233 changes: 233 additions & 0 deletions bazel/autotools/test/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
load("@rules_foreign_cc//foreign_cc:defs.bzl", "configure_make")

sh_test(
name = "test_autotools",
srcs = ["test_autotools.sh"],
data = ["@autotools_x86_64//:all"],
)

genrule(
name = "prepare_autotools_files",
outs = [
"configure.ac",
"Makefile.am",
"src/Makefile.am",
"src/hello.c",
"src/hello.h",
"src/main.c",
],
cmd = """
mkdir -p src m4 build-aux
cat > $(@D)/configure.ac <<'EOF'
AC_INIT([libhello], [1.0], [[email protected]])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
# AC_CONFIG_HEADERS([src/hello.h])
LT_INIT
AC_CONFIG_FILES([
Makefile
src/Makefile
])
AC_OUTPUT
EOF

cat > $(@D)/Makefile.am <<'EOF'
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src
EOF

cat > $(@D)/src/Makefile.am <<'EOF'
lib_LTLIBRARIES = libhello.la
libhello_la_SOURCES = hello.c
libhello_la_LDFLAGS = -version-info 1:0:0

bin_PROGRAMS = hello_test
hello_test_SOURCES = main.c
hello_test_LDADD = libhello.la

include_HEADERS = hello.h
EOF

cat > $(@D)/src/hello.c <<'EOF'
#include <stdio.h>
#include "hello.h"

void hello_world(const char *name) {
printf("Hello, %s from autotools!\\n", name);
}

int get_version(void) {
return 42;
}
EOF

cat > $(@D)/src/hello.h <<'EOF'
#ifndef HELLO_H
#define HELLO_H

void hello_world(const char *name);
int get_version(void);

#endif
EOF

cat > $(@D)/src/main.c <<'EOF'
#include <stdio.h>
#include "hello.h"

int main(int argc, char *argv[]) {
hello_world(argc > 1 ? argv[1] : "World");
printf("Library version: %d\\n", get_version());
return 0;
}
EOF
""",
)


filegroup(
name = "hellolib",
srcs = [
"configure.ac",
"Makefile.am",
"src/Makefile.am",
"src/hello.c",
"src/hello.h",
"src/main.c",
],
)

# Build the autotools project using the toolchain
configure_make(
name = "build_libhello",
lib_source = "hellolib",
configure_in_place = True,
configure_prefix = """
find .

# Skip common ancestor logic for now, just copy files
for f in $(locations :hellolib); do
if [[ -f "$$EXT_BUILD_ROOT/$$f" ]]; then
mkdir -p "$$(dirname "$$f")"
cp $$EXT_BUILD_ROOT/$$f ./
fi
done

# Parse autotools base directory from locations

for f in $(locations @autotools_x86_64//:all); do
if echo "$$f" | grep -q "/bin/autoreconf$$"; then
AUTOTOOLS_DIR=$$EXT_BUILD_ROOT/$$(dirname $$(dirname $$f))
break
fi
done

# Also need perl
for f in $(locations @perl_linux_amd64//:runtime); do
if echo "$$f" | grep -q "/bin/perl$$"; then
PERL_DIR=$$EXT_BUILD_ROOT/$$(dirname $$(dirname $$f))
break
fi
done


# Set up PATH
export PATH="$$AUTOTOOLS_DIR/bin:$$PERL_DIR/bin:$$PATH"

# Tool binaries
export M4="$$AUTOTOOLS_DIR/bin/m4 "
export AUTOCONF="$$AUTOTOOLS_DIR/bin/autoconf "
export AUTOHEADER="$$AUTOTOOLS_DIR/bin/autoheader "
export AUTORECONF="$$AUTOTOOLS_DIR/bin/autoreconf "
export AUTOMAKE="$$AUTOTOOLS_DIR/bin/automake "
export ACLOCAL="$$AUTOTOOLS_DIR/bin/aclocal "
export LIBTOOLIZE="$$AUTOTOOLS_DIR/bin/libtoolize "
export LIBTOOL="$$AUTOTOOLS_DIR/bin/libtool "
# dumb perl shit needs a space after path
export AUTOM4TE="$$AUTOTOOLS_DIR/bin/autom4te "
export PERL="$$PERL_DIR/bin/perl"

# Autoconf paths
export autom4te_perllibdir="$$AUTOTOOLS_DIR/share/autoconf"
export AC_MACRODIR="$$AUTOTOOLS_DIR/share/autoconf"
export AUTOM4TE_CFG="$$AUTOTOOLS_DIR/share/autoconf/autom4te.cfg"
export trailer_m4="$$AUTOTOOLS_DIR/share/autoconf/autoconf/trailer.m4"
export autom4te_buildauxdir="$$AUTOTOOLS_DIR/share/autoconf/build-aux"

# Automake paths
export automake_incdir="$$AUTOTOOLS_DIR/share/automake-1.16"
export AUTOMAKE_LIBDIR="$$AUTOTOOLS_DIR/share/automake-1.16"
export ACLOCAL_PATH="$$AUTOTOOLS_DIR/share/aclocal-1.16:$$AUTOTOOLS_DIR/share/aclocal"

export AUTOMAKE_SHARE="$$AUTOTOOLS_DIR/share/automake-1.16"
export ACLOCAL_AUTOMAKE_DIR="$$AUTOTOOLS_DIR/share/aclocal-1.16"

# Libtool paths
export pkgauxdir="$$AUTOTOOLS_DIR/share/libtool/build-aux"
export pkgdatadir="$$AUTOTOOLS_DIR/share/libtool"


# Create m4 directory
mkdir -p m4 build-aux

pwd
ls -l .
cat Makefile.am
cat configure.ac


# Fix autom4te.cfg paths
sed -i "s|--prepend-include '[^']*share/autoconf'|--prepend-include '$${AUTOTOOLS_DIR}/share/autoconf'|g" \
"$$AUTOM4TE_CFG"

cat "$$AUTOM4TE_CFG"

# Debug aclocal
echo "=== Adding debug to aclocal ==="
cp $$ACLOCAL aclocal.debug
sed -i '/^my @automake_includes = /a\\print STDERR "DEBUG: Initial automake_includes = @automake_includes\\n";' aclocal.debug
sed -i '/@automake_includes = (\\$$ENV{"ACLOCAL_AUTOMAKE_DIR"})/a\\print STDERR "DEBUG: automake_includes after env override = @automake_includes\\n";' aclocal.debug
sed -i '/if (! opendir (DIR, \\$$m4dir))/i\\ print STDERR "DEBUG: Trying to open directory: \\$$m4dir\\n";' aclocal.debug
sed -i '/my \\$$fullfile = File::Spec->canonpath/a\\ print STDERR "DEBUG: Examining file: \\$$fullfile\\n";' aclocal.debug
sed -i '/verb "found macro \\$macro in \\$file"/a\\ print STDERR "DEBUG: Found macro \\$macro in \\$file\\n";' aclocal.debug

echo "Running debug aclocal"
./aclocal.debug -I m4 --verbose || {
echo "aclocal.debug failed"
exit 1
}

# autom4te --language=autoconf --trace=AC_CONFIG_FILES configure.ac
cat src/Makefile.am
# cat src/configure.ac

# $$AUTOM4TE --language=autoconf --trace=AM_INIT_AUTOMAKE configure.ac


AUTOMAKE="automake --add-missing --copy --force-missing --verbose --warnings=all,no-error" \
autoreconf -fiv


# Continue with autoreconf
$$AUTORECONF -fivm || {
exit 1
}

""",
out_binaries = ["hello_test"],
out_shared_libs = ["libhello.so"],
out_static_libs = ["libhello.a"],
build_data = [
"@autotools_x86_64//:all",
"@perl_linux_amd64//:runtime",
":hellolib",
],
visibility = ["//visibility:public"],
)

# Test that the built binary works
sh_test(
name = "test_built_binary",
srcs = ["test_built_binary.sh"],
data = [":build_libhello"],
)
23 changes: 23 additions & 0 deletions bazel/autotools/test/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
workspace(name = "autotools_test")

local_repository(
name = "envoy_toolshed",
path = "../..",
)

load("@envoy_toolshed//:archives.bzl", "load_archives")
load_archives()

load("@envoy_toolshed//:deps.bzl", "resolve_dependencies")
resolve_dependencies(
autotools_local_tarball_path = "/tmp/autotools-18.tar.xz",
)

load("@envoy_toolshed//:toolchains.bzl", "load_toolchains")
load_toolchains()

load("@envoy_toolshed//:packages.bzl", "load_packages")
load_packages()

load("@toolshed_pip3//:requirements.bzl", "install_deps")
install_deps()
Loading
Loading