From c05f529a19cb76f4e08d7400db57cb308e7c0e40 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 4 Mar 2021 21:14:29 -0500 Subject: Replace Travis CI with Github workflow --- .github/calcrom/calcrom.pl | 166 ++++++++++++++++++++++++++++++++++++++++++++ .github/calcrom/webhook.sh | 16 +++++ .github/workflows/build.yml | 40 +++++++++++ .travis.yml | 39 ----------- .travis/calcrom/calcrom.pl | 166 -------------------------------------------- .travis/calcrom/webhook.sh | 16 ----- 6 files changed, 222 insertions(+), 221 deletions(-) create mode 100755 .github/calcrom/calcrom.pl create mode 100755 .github/calcrom/webhook.sh create mode 100644 .github/workflows/build.yml delete mode 100644 .travis.yml delete mode 100755 .travis/calcrom/calcrom.pl delete mode 100755 .travis/calcrom/webhook.sh diff --git a/.github/calcrom/calcrom.pl b/.github/calcrom/calcrom.pl new file mode 100755 index 000000000..4858babb9 --- /dev/null +++ b/.github/calcrom/calcrom.pl @@ -0,0 +1,166 @@ +#!/usr/bin/perl + +use IPC::Cmd qw[ run ]; + +(@ARGV == 1) + or die "ERROR: no map file specified.\n"; +open(my $file, $ARGV[0]) + or die "ERROR: could not open file '$ARGV[0]'.\n"; + +my $src = 0; +my $asm = 0; +my $srcdata = 0; +my $data = 0; +while (my $line = <$file>) +{ + if ($line =~ /^ \.(\w+)\s+0x[0-9a-f]+\s+(0x[0-9a-f]+) (\w+)\/.+\.o/) + { + my $section = $1; + my $size = hex($2); + my $dir = $3; + + if ($section =~ /text/) + { + if ($dir eq 'src') + { + $src += $size; + } + elsif ($dir eq 'asm') + { + $asm += $size; + } + } + elsif ($section =~ /rodata/) + { + if ($dir eq 'src') + { + $srcdata += $size; + } + elsif ($dir eq 'data') + { + $data += $size; + } + } + } +} + +(my $elffname = $ARGV[0]) =~ s/\.map/.elf/; + +# Note that the grep filters out all branch labels. It also requires a minimum +# line length of 5, to filter out a ton of generated symbols (like AcCn). No +# settings to nm seem to remove these symbols. Finally, nm prints out a separate +# entry for whenever a name appears in a file, not just where it's defined. uniq +# removes all the duplicate entries. +# +# +# You'd expect this to take a while, because of uniq. It runs in under a second, +# though. Uniq is pretty fast! +my $base_cmd = "nm $elffname | awk '{print \$3}' | grep '^[^_].\\{4\\}' | uniq"; + +# This looks for Unknown_, Unknown_, or sub_, followed by just numbers. Note that +# it matches even if stuff precedes the unknown, like sUnknown/gUnknown. +my $undoc_cmd = "grep '[Uu]nknown_[0-9a-fA-F]*\\|sub_[0-9a-fA-F]*'"; + +# This looks for every symbol with an address at the end of it. Some things are +# given a name based on their type / location, but still have an unknown purpose. +# For example, FooMap_EventScript_FFFFFFF. +my $partial_doc_cmd = "grep '_[0-28][0-9a-fA-F]\\{5,6\\}'"; + +my $count_cmd = "wc -l"; + +# It sucks that we have to run this three times, but I can't figure out how to get +# stdin working for subcommands in perl while still having a timeout. It's decently +# fast anyway. +my $total_syms_as_string; +(run ( + command => "$base_cmd | $count_cmd", + buffer => \$total_syms_as_string, + timeout => 60 +)) + or die "ERROR: Error while getting all symbols: $?"; + +my $undocumented_as_string; +(run ( + command => "$base_cmd | $undoc_cmd | $count_cmd", + buffer => \$undocumented_as_string, + timeout => 60 +)) + or die "ERROR: Error while filtering for undocumented symbols: $?"; + +my $partial_documented_as_string; +(run ( + command => "$base_cmd | $partial_doc_cmd | $count_cmd", + buffer => \$partial_documented_as_string, + timeout => 60 +)) + or die "ERROR: Error while filtering for partial symbols: $?"; + +# Performing addition on a string converts it to a number. Any string that fails +# to convert to a number becomes 0. So if our converted number is 0, but our string +# is nonzero, then the conversion was an error. +my $undocumented = $undocumented_as_string + 0; +(($undocumented != 0) and ($undocumented_as_string ne "0")) + or die "ERROR: Cannot convert string to num: '$undocumented_as_string'"; + +my $partial_documented = $partial_documented_as_string + 0; +(($partial_documented != 0) and ($partial_documented_as_string ne "0")) + or die "ERROR: Cannot convert string to num: '$partial_documented_as_string'"; + +my $total_syms = $total_syms_as_string + 0; +(($total_syms != 0) and ($total_syms_as_string ne "0")) + or die "ERROR: Cannot convert string to num: '$total_syms_as_string'"; + +($total_syms != 0) + or die "ERROR: No symbols found."; + +my $total = $src + $asm; +my $srcPct = sprintf("%.4f", 100 * $src / $total); +my $asmPct = sprintf("%.4f", 100 * $asm / $total); + +# partial_documented is double-counting the unknown_* and sub_* symbols. +$partial_documented = $partial_documented - $undocumented; + +my $documented = $total_syms - ($undocumented + $partial_documented); +my $docPct = sprintf("%.4f", 100 * $documented / $total_syms); +my $partialPct = sprintf("%.4f", 100 * $partial_documented / $total_syms); +my $undocPct = sprintf("%.4f", 100 * $undocumented / $total_syms); + +if ($asm == 0) +{ + print "Code decompilation is 100% complete\n" +} +else +{ + print "$total total bytes of code\n"; + print "$src bytes of code in src ($srcPct%)\n"; + print "$asm bytes of code in asm ($asmPct%)\n"; +} +print "\n"; + +if ($partial_documented == 0 && $undocumented == 0) +{ + print "Documentation is 100% complete\n" +} +else +{ + print "$total_syms total symbols\n"; + print "$documented symbols documented ($docPct%)\n"; + print "$partial_documented symbols partially documented ($partialPct%)\n"; + print "$undocumented symbols undocumented ($undocPct%)\n"; +} + +print "\n"; +my $dataTotal = $srcdata + $data; +my $srcDataPct = sprintf("%.4f", 100 * $srcdata / $dataTotal); +my $dataPct = sprintf("%.4f", 100 * $data / $dataTotal); + +if ($data == 0) +{ + print "Data porting to C is 100% complete\n" +} +else +{ + print "$dataTotal total bytes of data\n"; + print "$srcdata bytes of data in src ($srcDataPct%)\n"; + print "$data bytes of data in data ($dataPct%)\n"; +} diff --git a/.github/calcrom/webhook.sh b/.github/calcrom/webhook.sh new file mode 100755 index 000000000..5dd65a75f --- /dev/null +++ b/.github/calcrom/webhook.sh @@ -0,0 +1,16 @@ +#!/bin/bash -ex + +# Only run this script if it's the master branch build. +if [[ "$GITHUB_REF" != "refs/heads/master" || "$GITHUB_EVENT_NAME" != "false" ]]; then + exit 0 +fi + +build_name=$1 +map_file=$build_name.map +if [ ! -f $map_file ]; then + echo "$map_file does not exist!" + exit 1 +fi + +output=$(perl $(dirname "$0")/calcrom.pl $build_name.map | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g') +curl -d "{\"username\": \"$CALCROM_DISCORD_WEBHOOK_USERNAME\", \"avatar_url\": \"$CALCROM_DISCORD_WEBHOOK_AVATAR_URL\", \"content\":\"\`\`\`$build_name progress:\\n$output\`\`\`\"}" -H "Content-Type: application/json" -X POST "$CALCROM_DISCORD_WEBHOOK_URL" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..220b14da3 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,40 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + +env: + CALCROM_DISCORD_WEBHOOK_USERNAME: ${{ secrets.CALCROM_DISCORD_WEBHOOK_USERNAME }} + CALCROM_DISCORD_WEBHOOK_AVATAR_URL: ${{ secrets.CALCROM_DISCORD_WEBHOOK_AVATAR_URL }} + CALCROM_DISCORD_WEBHOOK_URL: ${{ secrets.CALCROM_DISCORD_WEBHOOK_URL }} + +jobs: + build: + runs-on: ubuntu-18.04 + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Install binutils + run: sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi + # build-essential, git, and libpng-dev are already installed + # gcc-arm-none-eabi is only needed for the modern build + # as an alternative to dkP + + - name: Install agbcc + run: | + git clone https://github.com/pret/agbcc.git + cd agbcc + ./build.sh + ./install.sh ../ + + - name: Compare + run: make -j${nproc} compare + + - name: Modern + run: make -j${nproc} modern + + - name: Webhook + run: sh .github/calcrom/webhook.sh pokeemerald diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8d39be503..000000000 --- a/.travis.yml +++ /dev/null @@ -1,39 +0,0 @@ -language: generic -dist: bionic -sudo: false -env: - global: - - DEVKITPRO=$HOME - - DEVKITARM=$DEVKITPRO/devkitARM -addons: - apt: - packages: - - gcc-multilib - - linux-libc-dev -cache: - apt: true -install: - - pushd $HOME - - travis_retry wget https://github.com/devkitPro/buildscripts/releases/download/devkitARM_r52/devkitARM_r52-linux.tar.xz - - tar xJf devkitARM*.tar.xz - - travis_retry wget https://github.com/devkitPro/devkitarm-rules/releases/download/v1.0.0/devkitarm-rules-1.0.0.tar.xz - - tar xJf devkitarm-rules-*.tar.xz -C $DEVKITARM - - travis_retry git clone https://github.com/pret/agbcc.git - - cd agbcc && ./build.sh && ./install.sh $TRAVIS_BUILD_DIR - - popd -matrix: - include: - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-7 - env: _="Build" - script: - - make -j2 tools CXX=g++-7 - - make -j2 compare - - make -j2 modern -after_success: - - .travis/calcrom/webhook.sh pokeemerald diff --git a/.travis/calcrom/calcrom.pl b/.travis/calcrom/calcrom.pl deleted file mode 100755 index 4858babb9..000000000 --- a/.travis/calcrom/calcrom.pl +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -use IPC::Cmd qw[ run ]; - -(@ARGV == 1) - or die "ERROR: no map file specified.\n"; -open(my $file, $ARGV[0]) - or die "ERROR: could not open file '$ARGV[0]'.\n"; - -my $src = 0; -my $asm = 0; -my $srcdata = 0; -my $data = 0; -while (my $line = <$file>) -{ - if ($line =~ /^ \.(\w+)\s+0x[0-9a-f]+\s+(0x[0-9a-f]+) (\w+)\/.+\.o/) - { - my $section = $1; - my $size = hex($2); - my $dir = $3; - - if ($section =~ /text/) - { - if ($dir eq 'src') - { - $src += $size; - } - elsif ($dir eq 'asm') - { - $asm += $size; - } - } - elsif ($section =~ /rodata/) - { - if ($dir eq 'src') - { - $srcdata += $size; - } - elsif ($dir eq 'data') - { - $data += $size; - } - } - } -} - -(my $elffname = $ARGV[0]) =~ s/\.map/.elf/; - -# Note that the grep filters out all branch labels. It also requires a minimum -# line length of 5, to filter out a ton of generated symbols (like AcCn). No -# settings to nm seem to remove these symbols. Finally, nm prints out a separate -# entry for whenever a name appears in a file, not just where it's defined. uniq -# removes all the duplicate entries. -# -# -# You'd expect this to take a while, because of uniq. It runs in under a second, -# though. Uniq is pretty fast! -my $base_cmd = "nm $elffname | awk '{print \$3}' | grep '^[^_].\\{4\\}' | uniq"; - -# This looks for Unknown_, Unknown_, or sub_, followed by just numbers. Note that -# it matches even if stuff precedes the unknown, like sUnknown/gUnknown. -my $undoc_cmd = "grep '[Uu]nknown_[0-9a-fA-F]*\\|sub_[0-9a-fA-F]*'"; - -# This looks for every symbol with an address at the end of it. Some things are -# given a name based on their type / location, but still have an unknown purpose. -# For example, FooMap_EventScript_FFFFFFF. -my $partial_doc_cmd = "grep '_[0-28][0-9a-fA-F]\\{5,6\\}'"; - -my $count_cmd = "wc -l"; - -# It sucks that we have to run this three times, but I can't figure out how to get -# stdin working for subcommands in perl while still having a timeout. It's decently -# fast anyway. -my $total_syms_as_string; -(run ( - command => "$base_cmd | $count_cmd", - buffer => \$total_syms_as_string, - timeout => 60 -)) - or die "ERROR: Error while getting all symbols: $?"; - -my $undocumented_as_string; -(run ( - command => "$base_cmd | $undoc_cmd | $count_cmd", - buffer => \$undocumented_as_string, - timeout => 60 -)) - or die "ERROR: Error while filtering for undocumented symbols: $?"; - -my $partial_documented_as_string; -(run ( - command => "$base_cmd | $partial_doc_cmd | $count_cmd", - buffer => \$partial_documented_as_string, - timeout => 60 -)) - or die "ERROR: Error while filtering for partial symbols: $?"; - -# Performing addition on a string converts it to a number. Any string that fails -# to convert to a number becomes 0. So if our converted number is 0, but our string -# is nonzero, then the conversion was an error. -my $undocumented = $undocumented_as_string + 0; -(($undocumented != 0) and ($undocumented_as_string ne "0")) - or die "ERROR: Cannot convert string to num: '$undocumented_as_string'"; - -my $partial_documented = $partial_documented_as_string + 0; -(($partial_documented != 0) and ($partial_documented_as_string ne "0")) - or die "ERROR: Cannot convert string to num: '$partial_documented_as_string'"; - -my $total_syms = $total_syms_as_string + 0; -(($total_syms != 0) and ($total_syms_as_string ne "0")) - or die "ERROR: Cannot convert string to num: '$total_syms_as_string'"; - -($total_syms != 0) - or die "ERROR: No symbols found."; - -my $total = $src + $asm; -my $srcPct = sprintf("%.4f", 100 * $src / $total); -my $asmPct = sprintf("%.4f", 100 * $asm / $total); - -# partial_documented is double-counting the unknown_* and sub_* symbols. -$partial_documented = $partial_documented - $undocumented; - -my $documented = $total_syms - ($undocumented + $partial_documented); -my $docPct = sprintf("%.4f", 100 * $documented / $total_syms); -my $partialPct = sprintf("%.4f", 100 * $partial_documented / $total_syms); -my $undocPct = sprintf("%.4f", 100 * $undocumented / $total_syms); - -if ($asm == 0) -{ - print "Code decompilation is 100% complete\n" -} -else -{ - print "$total total bytes of code\n"; - print "$src bytes of code in src ($srcPct%)\n"; - print "$asm bytes of code in asm ($asmPct%)\n"; -} -print "\n"; - -if ($partial_documented == 0 && $undocumented == 0) -{ - print "Documentation is 100% complete\n" -} -else -{ - print "$total_syms total symbols\n"; - print "$documented symbols documented ($docPct%)\n"; - print "$partial_documented symbols partially documented ($partialPct%)\n"; - print "$undocumented symbols undocumented ($undocPct%)\n"; -} - -print "\n"; -my $dataTotal = $srcdata + $data; -my $srcDataPct = sprintf("%.4f", 100 * $srcdata / $dataTotal); -my $dataPct = sprintf("%.4f", 100 * $data / $dataTotal); - -if ($data == 0) -{ - print "Data porting to C is 100% complete\n" -} -else -{ - print "$dataTotal total bytes of data\n"; - print "$srcdata bytes of data in src ($srcDataPct%)\n"; - print "$data bytes of data in data ($dataPct%)\n"; -} diff --git a/.travis/calcrom/webhook.sh b/.travis/calcrom/webhook.sh deleted file mode 100755 index 86da74c87..000000000 --- a/.travis/calcrom/webhook.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -ex - -# Only run this script if it's the master branch build. -if [[ "$TRAVIS_BRANCH" != "master" || "$TRAVIS_PULL_REQUEST" != "false" ]]; then - exit 0 -fi - -build_name=$1 -map_file=$build_name.map -if [ ! -f $map_file ]; then - echo "$map_file does not exist!" - exit 1 -fi - -output=$(perl $(dirname "$0")/calcrom.pl $build_name.map | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g') -curl -d "{\"username\": \"$CALCROM_DISCORD_WEBHOOK_USERNAME\", \"avatar_url\": \"$CALCROM_DISCORD_WEBHOOK_AVATAR_URL\", \"content\":\"\`\`\`$build_name progress:\\n$output\`\`\`\"}" -H "Content-Type: application/json" -X POST $CALCROM_DISCORD_WEBHOOK_URL -- cgit v1.2.3