Last active
July 9, 2025 07:11
-
-
Save viktorholk/1a0f94cb0fec1fc4526336c5e8078aa8 to your computer and use it in GitHub Desktop.
The semacode-ruby19 gem v0.7.4 contains C extensions that fail to compile on modern macOS systems due to compatibility issues. This script builds the gem in a compatible Docker environment and creates a precompiled version that works with both direct Ruby usage and Bundler. Using Rbenv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -e # Exit on any error | |
| # Configuration | |
| GEM_NAME="semacode-ruby19" | |
| GEM_VERSION="0.7.4" | |
| CONTAINER_NAME="semacode-builder" | |
| # Colors for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| NC='\033[0m' # No Color | |
| # Logging functions | |
| log() { echo -e "${GREEN}[$(date +'%H:%M:%S')] $1${NC}"; } | |
| error() { echo -e "${RED}[ERROR] $1${NC}" >&2; } | |
| warn() { echo -e "${YELLOW}[WARNING] $1${NC}"; } | |
| # Clean existing installations | |
| cleanup_existing() { | |
| log "Cleaning existing semacode installations..." | |
| gem uninstall semacode-ruby19 --force >/dev/null 2>&1 || true | |
| rm -rf ~/.rbenv/versions/*/lib/ruby/gems/*/gems/semacode-ruby19-* 2>/dev/null || true | |
| rm -rf ~/.rbenv/versions/*/lib/ruby/gems/*/specifications/semacode-ruby19-* 2>/dev/null || true | |
| rm -rf ~/.rbenv/versions/*/lib/ruby/gems/*/extensions/*/semacode-ruby19-* 2>/dev/null || true | |
| rm -rf ~/.rbenv/versions/*/lib/ruby/gems/*/cache/semacode-ruby19-* 2>/dev/null || true | |
| log "✓ Existing installations cleaned" | |
| } | |
| # Check if Docker is running | |
| check_docker() { | |
| if ! docker info >/dev/null 2>&1; then | |
| error "Docker is not running. Please start Docker and try again." | |
| exit 1 | |
| fi | |
| } | |
| # Build gem in Docker | |
| build_in_docker() { | |
| log "Building Docker image..." | |
| cat > Dockerfile.semacode << 'EOF' | |
| FROM ruby:2.5-slim | |
| RUN apt-get update && apt-get install -y build-essential wget && rm -rf /var/lib/apt/lists/* | |
| WORKDIR /build | |
| EOF | |
| docker build -f Dockerfile.semacode -t semacode-builder --platform=linux/arm64 . >/dev/null | |
| log "Downloading and compiling gem in container..." | |
| docker run --name ${CONTAINER_NAME} --platform=linux/arm64 -d semacode-builder tail -f /dev/null >/dev/null | |
| docker exec ${CONTAINER_NAME} bash -c " | |
| gem fetch ${GEM_NAME} --version ${GEM_VERSION} | |
| gem install ${GEM_NAME}-${GEM_VERSION}.gem --local --no-document | |
| gem unpack ${GEM_NAME}-${GEM_VERSION}.gem | |
| " >/dev/null | |
| log "✓ Gem compiled successfully in Docker" | |
| } | |
| # Copy compiled files from container | |
| copy_from_container() { | |
| log "Copying compiled files..." | |
| mkdir -p output | |
| # Get gem directory paths | |
| local gem_dir=$(docker exec ${CONTAINER_NAME} ruby -e "puts Gem.dir") | |
| # Copy the installed gem (with compiled extensions) | |
| docker cp ${CONTAINER_NAME}:${gem_dir}/gems/${GEM_NAME}-${GEM_VERSION} output/ >/dev/null | |
| docker cp ${CONTAINER_NAME}:${gem_dir}/specifications/${GEM_NAME}-${GEM_VERSION}.gemspec output/ >/dev/null | |
| log "✓ Files copied from container" | |
| } | |
| # Create precompiled gem | |
| create_precompiled_gem() { | |
| log "Creating Bundler-compatible gem..." | |
| # Use the installed gem (has compiled extensions) and remove ext directory | |
| cp -r output/${GEM_NAME}-${GEM_VERSION} precompiled/ | |
| rm -rf precompiled/ext | |
| # Fix gemspec - remove extensions line and update files list | |
| cp output/${GEM_NAME}-${GEM_VERSION}.gemspec precompiled/ | |
| sed -i '' '/s\.extensions/d' precompiled/${GEM_NAME}-${GEM_VERSION}.gemspec | |
| sed -i '' 's/"ext\/extconf\.rb"/"lib\/semacode_native.so", "lib\/semacode.rb"/' precompiled/${GEM_NAME}-${GEM_VERSION}.gemspec | |
| # Build and install the fixed gem | |
| cd precompiled | |
| gem build ${GEM_NAME}-${GEM_VERSION}.gemspec >/dev/null | |
| gem install ${GEM_NAME}-${GEM_VERSION}.gem --local --no-document >/dev/null | |
| cd .. | |
| log "✓ Precompiled gem installed" | |
| } | |
| # Test installation | |
| test_gem() { | |
| log "Testing gem functionality..." | |
| if ruby -e "require 'semacode'; sema = DataMatrix::Encoder.new('test'); puts \"Size: #{sema.width}x#{sema.height}\"" >/dev/null 2>&1; then | |
| log "✓ Gem works perfectly!" | |
| return 0 | |
| else | |
| error "Gem test failed" | |
| return 1 | |
| fi | |
| } | |
| # Cleanup Docker | |
| cleanup_docker() { | |
| docker stop ${CONTAINER_NAME} >/dev/null 2>&1 || true | |
| docker rm ${CONTAINER_NAME} >/dev/null 2>&1 || true | |
| docker rmi semacode-builder >/dev/null 2>&1 || true | |
| rm -f Dockerfile.semacode | |
| rm -rf precompiled | |
| } | |
| # Main execution | |
| main() { | |
| log "🚀 Starting semacode-ruby19 build process..." | |
| # Setup cleanup trap | |
| trap cleanup_docker EXIT | |
| # Execute build steps | |
| cleanup_existing | |
| check_docker | |
| build_in_docker | |
| copy_from_container | |
| create_precompiled_gem | |
| if test_gem; then | |
| log "🎉 SUCCESS! Semacode gem is ready to use!" | |
| log " - Works with: require 'semacode'" | |
| log " - Works with: bundle install" | |
| log " - Built gem saved: ./precompiled/${GEM_NAME}-${GEM_VERSION}.gem" | |
| else | |
| error "Build completed but gem test failed" | |
| exit 1 | |
| fi | |
| } | |
| # Run if script is executed directly | |
| if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then | |
| main "$@" | |
| fi |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is the error when installing on newer MacOS.
Previous fix was to downgrade XCode to 11.5, but this is no longer a solution.