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

add toolchain shims here #175

Merged
merged 16 commits into from
Sep 29, 2023
Merged
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
22 changes: 12 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ jobs:
- catb.org/wumpus
- c-ares.org
- vim.org
- tea.xyz/gx/cc
# FIXME? requires a darwin platform to run, and needs
# macOS 12 to test. That'll require a more complex matrix
# using get-platform.
Expand All @@ -29,32 +28,35 @@ jobs:
- uses: actions/checkout@v3
- uses: teaxyz/setup@v0

- name: configure PATH
run: echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH
- run: |
find ~/.tea/tea.xyz/var/pantry -name 'package.yml' -exec sed -i '/tea\.xyz\/gx\/cc: c99/d' {} \;

- uses: actions/cache@v3
with:
path: ${{ env.HOME }}/.cache/deno
key: deno-get-platform-${{ hashFiles('deno.jsonc')}}
# prefetch dneo deps to make the output from the build step more legible
- run: deno cache **/*.ts

- name: prefetch deno deps
# this makes the output from the build step more legible
run: deno cache **/*.ts
- name: install brewkit
run: |
mkdir -p "$HOME/.tea/tea.xyz/brewkit/v*"
mv * "$HOME/.tea/tea.xyz/brewkit/v*"
echo "$HOME/.tea/tea.xyz/brewkit/v*/bin" >> $GITHUB_PATH

- run: pkg build ${{matrix.pkgs}}
id: build

- run: test -n '${{ steps.build.outputs.pkgs }}'
- run: test -n '${{ steps.build.outputs.relative-paths }}'

- run: |
if pkg query ${{ steps.build.outputs.pkgs }} --src 2>&1 | grep -E '^warn: pkg has no srcs:'; then
echo "srcs=false" >> $GITHUB_OUTPUT
else
echo "srcs=true" >> $GITHUB_OUTPUT
fi
id: srcs

- run: test -n '${{ steps.build.outputs.srcs }}'
if: steps.srcs.outputs.srcs == 'true'

- run: test -n '${{ steps.build.outputs.srcs-relative-paths }}'
if: steps.srcs.outputs.srcs == 'true'

Expand Down
4 changes: 4 additions & 0 deletions lib/usePantry.getScript.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import useConfig from "libtea/hooks/useConfig.ts"
import { SupportedPlatforms } from "https://raw.githubusercontent.com/teaxyz/lib/v0.4.2/src/utils/host.ts"
import { isArray, isString, isPlainObject, PlainObject } from "is-what"
import { Package, Installation, hooks, utils, semver } from "libtea"
Expand All @@ -13,6 +14,9 @@ export const getScript = async (pkg: Package, key: 'build' | 'test', deps: Insta
const mm = useMoustaches()
const script = (input: unknown) => {
const tokens = mm.tokenize.all(pkg, deps)
tokens.push({
from: "build.root", to: useConfig().prefix.string
})
if (isArray(input)) input = input.map(obj => {
if (isPlainObject(obj)) {

Expand Down
5 changes: 5 additions & 0 deletions libexec/stage-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ if (!yml.test) throw "no `test` node in package.yml"
env['PATH'] ??= []
env['PATH'].push("/usr/bin:/bin")

if (!deps.find(({pkg}) => pkg.project == 'llvm.org' || pkg.project == 'gnu.org/gcc')) {
/// add our helper cc toolchain unless the package has picked its own toolchain
env['PATH'].push(new Path(new URL(import.meta.url).pathname).parent().parent().join("share/toolchain/bin").string)
}

let text = undent`
#!/usr/bin/env bash

Expand Down
9 changes: 7 additions & 2 deletions libexec/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@ const pkg = await pantry.resolve(parse(pkgname))

/// assemble build script
const pantry_sh = await pantry.getScript(pkg, 'build', deps)
const brewkit = new Path(new URL(import.meta.url).pathname).parent().parent().join("share/brewkit")
const sup_PATH = [new Path(new URL(import.meta.url).pathname).parent().parent().join("share/brewkit")]

if (!deps.find(({pkg}) => pkg.project == 'llvm.org' || pkg.project == 'gnu.org/gcc')) {
/// add our helper cc toolchain unless the package has picked its own toolchain
sup_PATH.push(new Path(new URL(import.meta.url).pathname).parent().parent().join("share/toolchain/bin"))
}

/// calc env
const sh = useShellEnv()
Expand Down Expand Up @@ -86,7 +91,7 @@ const text = undent`

mkdir -p "$HOME"

export PATH=${brewkit}:"$PATH"
export PATH=${sup_PATH.map(x => x.string).join(':')}:"$PATH"
export CFLAGS="-w $CFLAGS" # warnings are noise

${pantry_sh}
Expand Down
Binary file added share/.DS_Store
Binary file not shown.
9 changes: 4 additions & 5 deletions share/TEMPLATE.pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,13 @@ dependencies:

build:
dependencies:
tea.xyz/gx/cc: c99
tea.xyz/gx/make: '*'
# ^^ often packages need dependencies to build, it is very common for
# packages to need a C compiler and make, the above provide those
cmake.org: ^3
# ^^ we provide a c compiler and make by default, other deps you’ll need to add yourself

script: |
./configure $ARGS
make --jobs {{ hw.concurrency }} install
# it’s extremely common for packages to require the above
# ^^ it’s extremely common for packages to require the above

# script also supports a list of commands, which is useful for complex builds
# or if you want to run a command in a different directory
Expand Down
Binary file added share/toolchain/.DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions share/toolchain/bin/ar
1 change: 1 addition & 0 deletions share/toolchain/bin/as
1 change: 1 addition & 0 deletions share/toolchain/bin/c++
1 change: 1 addition & 0 deletions share/toolchain/bin/cc
1 change: 1 addition & 0 deletions share/toolchain/bin/clang
1 change: 1 addition & 0 deletions share/toolchain/bin/clang++
1 change: 1 addition & 0 deletions share/toolchain/bin/cpp
1 change: 1 addition & 0 deletions share/toolchain/bin/g++
1 change: 1 addition & 0 deletions share/toolchain/bin/gcc
1 change: 1 addition & 0 deletions share/toolchain/bin/ld
1 change: 1 addition & 0 deletions share/toolchain/bin/ld64.lld
1 change: 1 addition & 0 deletions share/toolchain/bin/lld
1 change: 1 addition & 0 deletions share/toolchain/bin/lld-link
7 changes: 7 additions & 0 deletions share/toolchain/bin/make
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

if [ $(uname) = Darwin ]; then
exec /usr/bin/make "$@"
else
exec tea +gnu.org/make make "$@"
fi
1 change: 1 addition & 0 deletions share/toolchain/bin/nm
1 change: 1 addition & 0 deletions share/toolchain/bin/objcopy
1 change: 1 addition & 0 deletions share/toolchain/bin/ranlib
1 change: 1 addition & 0 deletions share/toolchain/bin/readelf
1 change: 1 addition & 0 deletions share/toolchain/bin/strings
1 change: 1 addition & 0 deletions share/toolchain/bin/strip
85 changes: 85 additions & 0 deletions share/toolchain/shim
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/bin/sh

tool=$(basename $0)

if [ $(uname) != Darwin ]; then
d="$(cd "$(dirname "$0")/.." && pwd)"
exec "$TEA_PREFIX/tea.xyz/v*/bin/tea" +llvm.org $d/symlinks/$tool "$@"
fi

case $tool in
cc|gcc|clang|c++|g++|clang++)
exec ruby $0 "$@"
;;
ld|lld|lld-link|ld64.lld)
for word in "$@"; do
if test "$word" = -r; then
exec /usr/bin/"$tool" "$@"
fi
done

exec /usr/bin/$tool "$@" -rpath "${TEA_PREFIX:-$HOME/.tea}"
;;
*)
exec /usr/bin/$tool "$@"
;;
esac


#!/usr/bin/ruby

# - we inject our rpath to ensure our libs our found
# - for bottles we replace that in fix-machos.rb with a relocatable prefix
# - in general usage we don’t, so if the user needs to distribute their artifacts,
# they will need to fix them first, but that's typical anyway.

$tea_prefix = ENV['TEA_PREFIX'] || (ENV['HOME'] + "/.tea")
exe = File.basename($0)

# remove duplicates since this in fact embeds the rpath multiple times
# and omit -nodefaultrpaths since it is not a valid flag for clang
args = ARGV.map do |arg|
arg unless arg == "-Wl,-rpath,#$tea_prefix" or arg == "-nodefaultrpaths"
end.compact

def is_tea? path
path = File.realpath path while File.symlink? path
return File.basename(path) == "tea"
end

# find next example of ourselves
# this will either pick the Apple provided clang or the tea one
exe_path = ENV['PATH'].split(":").filter { |path|
if path == File.dirname(__FILE__)
false
elsif path == File.join($tea_prefix, ".local/bin")
false
elsif is_tea?(path)
false
else
true
end
}.map { |path|
"#{path}/#{exe}"
}.reject { |path|
# if the user created a symlink of `cc` to `tea` don’t use it
File.symlink? path and File.basename(File.readlink(path)) == "tea"
}.find { |path|
File.exist?(path)
}

abort "couldn’t find #{exe} in `PATH`" unless exe_path

for arg in args do
# figuring out what “mode” we are operating in is hard
# we don’t want to add this linker command always because it causes a warning to be
# output if we are not outputing executables/dylibs and this warning can break
# configure scripts, however the below is not fully encompassing
# we aren't sure what the rules are TBH, possibly it is as simple as if the output (`-o`)
# is a .o then we don’t add the rpath
if arg.start_with? '-l' or arg.end_with? '.dylib'
exec exe_path, *args, "-Wl,-rpath,#$tea_prefix"
end
end

exec exe_path, *args
1 change: 1 addition & 0 deletions share/toolchain/symlinks/ar
1 change: 1 addition & 0 deletions share/toolchain/symlinks/as
1 change: 1 addition & 0 deletions share/toolchain/symlinks/c++
1 change: 1 addition & 0 deletions share/toolchain/symlinks/cc
1 change: 1 addition & 0 deletions share/toolchain/symlinks/clang
1 change: 1 addition & 0 deletions share/toolchain/symlinks/clang++
1 change: 1 addition & 0 deletions share/toolchain/symlinks/cpp
1 change: 1 addition & 0 deletions share/toolchain/symlinks/g++
1 change: 1 addition & 0 deletions share/toolchain/symlinks/gcc
1 change: 1 addition & 0 deletions share/toolchain/symlinks/ld
1 change: 1 addition & 0 deletions share/toolchain/symlinks/ld64.lld
1 change: 1 addition & 0 deletions share/toolchain/symlinks/lld
1 change: 1 addition & 0 deletions share/toolchain/symlinks/lld-link
1 change: 1 addition & 0 deletions share/toolchain/symlinks/nm
1 change: 1 addition & 0 deletions share/toolchain/symlinks/objcopy
1 change: 1 addition & 0 deletions share/toolchain/symlinks/ranlib
1 change: 1 addition & 0 deletions share/toolchain/symlinks/readelf
1 change: 1 addition & 0 deletions share/toolchain/symlinks/strings
1 change: 1 addition & 0 deletions share/toolchain/symlinks/strip
Loading