Skip to content

Commit

Permalink
Add support for cross-compiling via the Makefile (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
athre0z authored and rockdaboot committed Aug 7, 2024
1 parent 4b72935 commit b0907ff
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 67 deletions.
23 changes: 14 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ FROM debian:testing

WORKDIR /agent

ARG arch=amd64

RUN apt-get update -y && apt-get dist-upgrade -y && apt-get install -y \
curl wget cmake dwz lsb-release software-properties-common gnupg git clang-16 llvm \
golang unzip jq && apt-get clean autoclean && apt-get autoremove --yes

RUN wget -qO- https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.56.2

# cross_debian_arch: amd64 or arm64
# cross_pkg_arch: x86-64 or aarch64
RUN cross_debian_arch=$(uname -m | sed -e 's/aarch64/amd64/' -e 's/x86_64/arm64/'); \
cross_pkg_arch=$(uname -m | sed -e 's/aarch64/x86-64/' -e 's/x86_64/aarch64/'); \
apt-get update -y && \
apt-get dist-upgrade -y && \
apt-get install -y wget make git clang-16 golang unzip \
gcc-${cross_pkg_arch}-linux-gnu libc6-${cross_debian_arch}-cross && \
apt-get clean autoclean && \
apt-get autoremove --yes

RUN wget -qO- https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh \
| sh -s -- -b $(go env GOPATH)/bin v1.56.2

# gRPC dependencies
RUN go install google.golang.org/protobuf/cmd/[email protected]
Expand All @@ -20,7 +25,7 @@ RUN
PB_FILE="protoc-24.4-linux-x86_64.zip"; \
INSTALL_DIR="/usr/local"; \
\
curl -LO "$PB_URL/$PB_FILE" \
wget -q "$PB_URL/$PB_FILE" \
&& unzip "$PB_FILE" -d "$INSTALL_DIR" 'bin/*' 'include/*' \
&& chmod +xr "$INSTALL_DIR/bin/protoc" \
&& find "$INSTALL_DIR/include" -type d -exec chmod +x {} \; \
Expand Down
56 changes: 38 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,48 @@

SHELL := /usr/bin/env bash

# Detect native architecture and translate to GOARCH.
NATIVE_ARCH := $(shell uname -m)
ifeq ($(NATIVE_ARCH),x86_64)
NATIVE_ARCH := amd64
else ifneq (,$(filter $(NATIVE_ARCH),aarch64 arm64))
NATIVE_ARCH := arm64
else
$(error Unsupported architecture: $(NATIVE_ARCH))
endif

# Valid values are: amd64, arm64.
TARGET_ARCH ?= $(NATIVE_ARCH)

ifeq ($(NATIVE_ARCH),$(TARGET_ARCH))
ARCH_PREFIX :=
else ifeq ($(TARGET_ARCH),arm64)
ARCH_PREFIX := aarch64-linux-gnu-
else ifeq ($(TARGET_ARCH),amd64)
ARCH_PREFIX := x86_64-linux-gnu-
else
$(error Unsupported architecture: $(TARGET_ARCH))
endif

export TARGET_ARCH
export CGO_ENABLED = 1
export GOARCH = $(TARGET_ARCH)
export CC = $(ARCH_PREFIX)gcc
export OBJCOPY = $(ARCH_PREFIX)objcopy

BRANCH = $(shell git rev-parse --abbrev-ref HEAD | tr -d '-' | tr '[:upper:]' '[:lower:]')
COMMIT_SHORT_SHA = $(shell git rev-parse --short=8 HEAD)

VERSION ?= v0.0.0
BUILD_TIMESTAMP ?= $(shell date +%s)
REVISION ?= $(BRANCH)-$(COMMIT_SHORT_SHA)

VC_LDFLAGS := -X github.com/elastic/otel-profiling-agent/vc.version=$(VERSION) \
LDFLAGS := -X github.com/elastic/otel-profiling-agent/vc.version=$(VERSION) \
-X github.com/elastic/otel-profiling-agent/vc.revision=$(REVISION) \
-X github.com/elastic/otel-profiling-agent/vc.buildTimestamp=$(BUILD_TIMESTAMP)
-X github.com/elastic/otel-profiling-agent/vc.buildTimestamp=$(BUILD_TIMESTAMP) \
-extldflags=-static

GO_FLAGS := -buildvcs=false -ldflags="$(LDFLAGS)" -tags osusergo,netgo

all: generate ebpf binary

Expand All @@ -25,11 +57,10 @@ clean:
@rm -rf go .cache

generate:
go install github.com/florianl/[email protected]
go generate ./...

binary:
go build -buildvcs=false -ldflags="$(VC_LDFLAGS) -extldflags=-static" -tags osusergo,netgo
go build $(GO_FLAGS)

ebpf:
$(MAKE) -j$(shell nproc) -C support/ebpf
Expand All @@ -40,7 +71,7 @@ lint: generate
golangci-lint run --timeout 10m

test: generate ebpf test-deps
go test ./...
go test $(GO_FLAGS) ./...

TESTDATA_DIRS:= \
nativeunwind/elfunwindinfo/testdata \
Expand All @@ -62,23 +93,12 @@ integration-test-binaries: generate ebpf
./$(test_name)) || exit ; \
)

# Detect native architecture.
UNAME_NATIVE_ARCH:=$(shell uname -m)

ifeq ($(UNAME_NATIVE_ARCH),x86_64)
NATIVE_ARCH:=amd64
else ifneq (,$(filter $(UNAME_NATIVE_ARCH),aarch64 arm64))
NATIVE_ARCH:=arm64
else
$(error Unsupported architecture: $(UNAME_NATIVE_ARCH))
endif

docker-image:
docker build -t profiling-agent --build-arg arch=$(NATIVE_ARCH) -f Dockerfile .
docker build -t profiling-agent -f Dockerfile .

agent:
docker run -v "$$PWD":/agent -it --rm --user $(shell id -u):$(shell id -g) profiling-agent \
make VERSION=$(VERSION) REVISION=$(REVISION) BUILD_TIMESTAMP=$(BUILD_TIMESTAMP)
"make TARGET_ARCH=$(TARGET_ARCH) VERSION=$(VERSION) REVISION=$(REVISION) BUILD_TIMESTAMP=$(BUILD_TIMESTAMP)"

legal:
@go install go.elastic.co/go-licence-detector@latest
Expand Down
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
> [!NOTE]
>
> [!NOTE]
>
> Please be aware that we currently won't merge 3rd party PRs because this repository
> is temporary. We are waiting for the decision of the OpenTelemetry technical
> commitee on the donation of this repository.
Expand Down Expand Up @@ -42,8 +42,8 @@ agent to OpenTelementry.

## Building

> [!NOTE]
>
> [!NOTE]
>
> If you simply wish to take the agent for a spin with minimal effort, you can
> also immediately jump to the ["Visualizing data locally"
> section](#visualizing-data-locally), launch devfiler and follow the download
Expand All @@ -60,7 +60,11 @@ make docker-image

Then, you can build the agent:
```sh
# Build for architecture of current machine:
make agent

# OR, cross-compile an agent for another architecture:
make agent TARGET_ARCH=arm64 # accepted: amd64, arm64
```

The resulting binary will be in the current directory as `otel-profiling-agent`.
Expand All @@ -86,7 +90,7 @@ captured traces to the backend.
## Visualizing data locally

We created a desktop application called "devfiler" that allows visualizing the
profiling agent's output locally, making it very convenient for development use.
profiling agent's output locally, making it very convenient for development use.
devfiler spins up a local server that listens on `0.0.0.0:11000`.

![Screenshot of devfiler UI](./doc/devfiler.png)
Expand All @@ -104,7 +108,7 @@ The archive contains a build for each of the following platforms:
- Linux AppImage (x86_64)
- Linux AppImage (aarch64)

> [!NOTE]
> [!NOTE]
> devfiler is currently in an experimental preview stage.
### macOS
Expand Down
17 changes: 10 additions & 7 deletions libpf/pfelf/testdata/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
.PHONY: all

CC ?= cc
OBJCOPY ?= objcopy

BINARIES=fixed-address \
go-binary \
kernel-image \
Expand All @@ -15,18 +18,18 @@ clean:
rm -f $(BINARIES)

with-debug-syms: test.c
gcc $< -g -o $@
$(CC) $< -g -o $@

without-debug-syms: test.c
gcc $< -s -o $@
$(CC) $< -s -o $@

separate-debug-file: with-debug-syms
objcopy --only-keep-debug $< $@
$(OBJCOPY) --only-keep-debug $< $@

fixed-address: fixed-address.c fixed-address.ld
# The following command will likely print a warning (about a missing -T option), which should be ignored.
# Removing the warning would require passing a fully-fledged linker script to bypass gcc's default.
gcc $^ -o $@
$(CC) $^ -o $@

# Write an ELF notes file with a build ID
the_notorious_build_id:
Expand All @@ -36,12 +39,12 @@ the_notorious_build_id:
bash -c "echo -en 'somedata\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00_notorious_build_id_\x00somedata' > $@"

kernel-image: test.c
gcc $< -s -o $@ -DLINUX_VERSION="\"Linux version 1.2.3\\n\""
$(CC) $< -s -o $@ -DLINUX_VERSION="\"Linux version 1.2.3\\n\""

ubuntu-kernel-image: test.c
gcc $< -s -o $@ -DLINUX_VERSION="\"Linux version 1.2.3 (Ubuntu 4.5.6)\\n\""
$(CC) $< -s -o $@ -DLINUX_VERSION="\"Linux version 1.2.3 (Ubuntu 4.5.6)\\n\""

# A fake go binary (with a .gopclntab section)
go-binary: without-debug-syms
objcopy --add-section .gopclntab=/dev/null $< $@
$(OBJCOPY) --add-section .gopclntab=/dev/null $< $@

4 changes: 2 additions & 2 deletions reporter/testdata/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.PHONY: all

CC=gcc
CFLAGS=-Wl,--build-id
CC ?= cc
CFLAGS = -Wl,--build-id

all: test

Expand Down
40 changes: 18 additions & 22 deletions support/ebpf/Makefile
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
SHELL ?= bash

CLANG ?= clang-16
LINK ?= llvm-link-16
BPF_CLANG ?= clang-16
BPF_LINK ?= llvm-link-16
LLC ?= llc-16

DEBUG_FLAGS = -DOPTI_DEBUG -g

# Detect native architecture.
NATIVE_ARCH:=$(shell uname -m)

# Detect native architecture and translate to GOARCH.
NATIVE_ARCH := $(shell uname -m)
ifeq ($(NATIVE_ARCH),x86_64)
NATIVE_ARCH:=x86
else ifeq ($(NATIVE_ARCH),aarch64)
NATIVE_ARCH:=arm64
NATIVE_ARCH := amd64
else ifneq (,$(filter $(NATIVE_ARCH),aarch64 arm64))
NATIVE_ARCH := arm64
else
$(error Unsupported architecture: $(NATIVE_ARCH))
endif

# This can be passed-in, valid values are: x86, arm64.
target_arch ?= $(NATIVE_ARCH)
# Valid values are: amd64, arm64.
TARGET_ARCH ?= $(NATIVE_ARCH)

# Set default values.
TARGET_ARCH = $(target_arch)
TRACER_NAME = tracer.ebpf.$(TARGET_ARCH)
TRACER_NAME ?= tracer.ebpf.$(TARGET_ARCH)

ifeq ($(TARGET_ARCH),arm64)
TARGET_FLAGS = -target aarch64-linux-gnu
Expand Down Expand Up @@ -53,28 +49,28 @@ all: $(TRACER_NAME)
debug: TARGET_FLAGS+=$(DEBUG_FLAGS)
debug: all

x86:
$(MAKE) target_arch=x86 all
amd64:
$(MAKE) TARGET_ARCH=amd64 all

arm64:
$(MAKE) target_arch=arm64 all
$(MAKE) TARGET_ARCH=arm64 all

debug-x86:
$(MAKE) target_arch=x86 debug
debug-amd64:
$(MAKE) TARGET_ARCH=amd64 debug

debug-arm64:
$(MAKE) target_arch=arm64 debug
$(MAKE) TARGET_ARCH=arm64 debug

errors.h: ../../tools/errors-codegen/errors.json
go run ../../tools/errors-codegen/main.go bpf $@

%.ebpf.c: errors.h ;

%.ebpf.$(TARGET_ARCH).o: %.ebpf.c
$(CLANG) $(FLAGS) -o $@
$(BPF_CLANG) $(FLAGS) -o $@

$(TRACER_NAME): $(OBJS)
$(LINK) $^ -o - | $(LLC) -march=bpf -mcpu=v2 -filetype=obj -o $@
$(BPF_LINK) $^ -o - | $(LLC) -march=bpf -mcpu=v2 -filetype=obj -o $@
@./print_instruction_count.sh $@

baseline: $(TRACER_NAME)
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion support/support_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ import (
_ "embed"
)

//go:embed ebpf/tracer.ebpf.x86
//go:embed ebpf/tracer.ebpf.amd64
var tracerData []byte
6 changes: 4 additions & 2 deletions tools/fake-apm-agent/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
.PHONY: clean all

CC ?= cc

ARCH=$(shell uname -m)
LIB_NAME=elastic-jvmti-linux-$(ARCH).so

Expand All @@ -12,10 +14,10 @@ endif
all: fake-apm-agent $(LIB_NAME)

$(LIB_NAME): fake-apm-agent-lib.c
cc $< -g -shared -fPIC -mtls-dialect=$(TLS_DIALECT) -ftls-model=global-dynamic -o $@
$(CC) $< -g -shared -fPIC -mtls-dialect=$(TLS_DIALECT) -ftls-model=global-dynamic -o $@

fake-apm-agent: fake-apm-agent.c
cc $< -g -DLIB_NAME='"$(LIB_NAME)"' -o $@
$(CC) $< -g -DLIB_NAME='"$(LIB_NAME)"' -o $@

clean:
rm elastic-jvmti-linux-$(ARCH).so
Expand Down

0 comments on commit b0907ff

Please sign in to comment.