require "./context.cr" require "./recipe.cr" extend Package # FIXME: recipe.clean? context autoclean? context = Context.new() context.packaging_backend = "apk" recipes = [] of Package::Recipe # FIXME: context.new_recipe? context.recipe? recipes << Recipe.new(context, "hello", "2.10").tap do |recipe| recipe.sources << "https://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz" # This is a voluntary mix of automatic and manual build # instructions. # Also, installing in /package makes testing with a real-life # package manager trivial and reduces the damage done in case # of… containment failure. ]:-> recipe.instructions.configure << "cd hello-#{recipe.version} && ./configure --prefix=/usr" recipe.url = "https://www.gnu.org/software/hello/" recipe.description = "The GNU Hello program produces a familiar, friendly greeting." recipe.dependencies << "gettext" # Should be automatic now. #recipe.packages << Package::Package.new(recipe).tap do |package| # package.name = "#{recipe.name}-man" # package.files = ["/package/share/man"] #end end recipes << Recipe.new(context, "automake", "1.16").tap do |recipe| recipe.sources << "https://ftp.gnu.org/gnu/automake/automake-#{recipe.version}.tar.gz" end recipes << Recipe.new(context, "autoconf", "2.69").tap do |recipe| recipe.sources << "https://ftp.gnu.org/gnu/autoconf/autoconf-#{recipe.version}.tar.gz" recipe.dependencies << "m4" << "perl" end recipes << Recipe.new(context, "libtool", "2.4.6").tap do |recipe| recipe.sources << "http://ftpmirror.gnu.org/libtool/libtool-#{recipe.version}.tar.gz" end recipes << Recipe.new(context, "m4", "1.4.18").tap do |recipe| recipe.sources << "https://ftp.gnu.org/gnu/m4/m4-#{recipe.version}.tar.gz" recipe.dependencies << "perl" end recipes << Recipe.new(context, "bzip2", "1.0.6").tap do |recipe| recipe.sources << "https://downloads.sourceforge.net/project/bzip2/bzip2-#{recipe.version}.tar.gz" recipe.instructions.configure << "sed -i.orig -e '/^CFLAGS=/s/.*/CFLAGS = -O2 -fPIC/' #{recipe.dirname}/Makefile" recipe.options["make install"] = "PREFIX='#{recipe.fake_root_directory}/usr'" end recipes << Recipe.new(context, "perl", "5.30.0").tap do |recipe| recipe.sources << "https://www.cpan.org/src/5.0/perl-#{recipe.version}.tar.gz" recipe.dependencies << "zlib" << "bzip2" recipe.instructions.build << %( set -e -x; cd #{recipe.dirname}; BUILD_ZLIB=0; BUILD_BZIP2=0; BZIP2_LIB=/usr/lib; BZIP2_INCLUDE=/usr/inculde; export BUILD_ZLIB BUILD_BZIP2 BZIP2_LIB BZIP2_INCLUDE; ./Configure -des \ -Dcccdlflags='-fPIC' \ -Dcccdlflags='-fPIC' \ -Dccdlflags='-rdynamic' \ -Dprefix=/usr \ -Uprivlib=$_privlib \ -Darchlib=$_archlib \ -Dvendorprefix=/usr \ -Dvendorlib=/usr/share/perl5/vendor_perl \ -Dvendorarch=/usr/lib/perl5/vendor_perl \ -Dsiteprefix=/usr/local \ -Dsitelib=/usr/local/share/perl5/site_perl \ -Dsitearch=/usr/local/lib/perl5/site_perl \ -Dlocincpth=' ' \ -Dcc=gcc \ -Uoptimize="$CFLAGS" \ -Duselargefiles \ -Dusethreads \ -Duseshrplib \ -Dd_semctl_semun \ -Dman1dir=/usr/share/man/man1 \ -Dman3dir=/usr/share/man/man3 \ -Dinstallman1dir=/usr/share/man/man1 \ -Dinstallman3dir=/usr/share/man/man3 \ -Dman1ext='1' \ -Dman3ext='3pm' \ -Dcf_by='Alpine' \ -Ud_csh \ -Dusenm \ || return 1 make libperl.so && make || return 1 ) end recipes << Recipe.new(context, "apk-tools", "2.10.4").tap do |recipe| recipe.sources << "https://dev.alpinelinux.org/archive/apk-tools/apk-tools-#{recipe.version}.tar.xz" recipe.options["make"] = "LUAAPK= static" recipe.instructions.install << "mkdir -p '#{recipe.fake_root_directory}/sbin'" recipe.instructions.install << "cp apk-tools-#{recipe.version}/src/apk.static '#{recipe.fake_root_directory}/sbin/apk'" [ "/var/lib/apk", "/var/cache/misc", "/etc/apk/keys", "/etc/apk/protected_paths.d" ].each do |dir| recipe.instructions.install << "mkdir -p '#{recipe.fake_root_directory}#{dir}'" end #recipe.build_dependencies << "zlib-dev" << "openssl-dev" << "linux-dev" end recipes << Recipe.new(context, "abuild", "3.4.0").tap do |recipe| recipe.sources << "https://dev.alpinelinux.org/archive/abuild/abuild-#{recipe.version}.tar.xz" end recipes << Recipe.new(context, "pkg-config", "0.29.2").tap do |recipe| recipe.sources << "http://pkgconfig.freedesktop.org/releases/pkg-config-#{recipe.version}.tar.gz" # FIXME: We’ll want to remove this at some point. recipe.options["configure"] = "--with-internal-glib" end recipes << Recipe.new(context, "tar", "1.32").tap do |recipe| recipe.sources << "http://ftp.gnu.org/gnu/tar/tar-#{recipe.version}.tar.gz" recipe.options["configure"] = "FORCE_UNSAFE_CONFIGURE=1" end recipes << Recipe.new(context, "libarchive", "3.3.3").tap do |recipe| recipe.sources << "https://www.libarchive.org/downloads/libarchive-#{recipe.version}.tar.gz" # Conflicts with “tar” (gnu tar) #recipe.instructions.install << "cd #{recipe.dirname} && make DESTDIR='#{recipe.fake_root_directory}' install" #recipe.instructions.install << "cd '#{recipe.fake_root_directory}' && ln -s /usr/bin/bsdtar usr/bin/tar" end # FIXME: Build and install the actual kernel. recipes << Recipe.new(context, "linux", "5.2.4").tap do |recipe| recipe.sources << "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-#{recipe.version}.tar.xz" recipe.instructions.build << "true" recipe.instructions.install << "mkdir -p '#{recipe.fake_root_directory}/usr'" recipe.instructions.install << "cd '#{recipe.dirname}' && make headers_install ARCH=x86_64 INSTALL_HDR_PATH='#{recipe.fake_root_directory}/usr'" end recipes << Recipe.new(context, "make", "4.2").tap do |recipe| recipe.sources << "https://ftp.gnu.org/gnu/make/make-#{recipe.version}.tar.gz" end recipes << Recipe.new(context, "zlib", "1.2.11").tap do |recipe| recipe.sources << "https://www.zlib.net/zlib-#{recipe.version}.tar.gz" end # Be careful with that one. It’s not configured to use proper prefixes. # (Not sure that it should though. It’s gotta put things in /sbin anyway.) recipes << Recipe.new(context, "sysvinit", "2.95").tap do |recipe| recipe.sources << "https://git.savannah.nongnu.org/cgit/sysvinit.git/snapshot/sysvinit-#{recipe.version}.tar.gz" recipe.url = "https://savannah.nongnu.org/projects/sysvinit" recipe.description = "System V-like init system." recipe.dependencies << "util-linux" recipe.instructions.install << "cd sysvinit-#{recipe.version} && make ROOT='#{recipe.fake_root_directory}' install" end recipes << Recipe.new(context, "musl", "1.1.23").tap do |recipe| recipe.sources << "https://www.musl-libc.org/releases/musl-#{recipe.version}.tar.gz" recipe.url = "https://www.musl-libc.org/" recipe.description = "The musl c library (libc) implementation." recipe.options["configure"] = "--prefix=/usr --libdir=/lib --syslibdir=/lib --enable-shared --enable-static" # FIXME: We need to make a few symlinks (libm.so, libpthread.so, librt.so, libdl.so.) # FIXME: We should probably add a ldd script too. end recipes << Recipe.new(context, "libffi", "3.2.1").tap do |recipe| recipe.sources << "ftp://sourceware.org/pub/libffi/libffi-#{recipe.version}.tar.gz" recipe.instructions.install << %{ set -e; cd #{recipe.dirname}; make DESTDIR="#{recipe.fake_root_directory}" install; cd "#{recipe.fake_root_directory}"; mv usr/lib/libffi-#{recipe.version}/include usr; nuke usr/lib/libffi-#{recipe.version} } end recipes << Recipe.new(context, "python", "3.7.4").tap do |recipe| recipe.sources << "https://www.python.org/ftp/python/#{recipe.version}/Python-#{recipe.version}.tgz" recipe.dirname = "Python-#{recipe.version}" end recipes << Recipe.new(context, "crystal", "0.29.9").tap do |recipe| # FIXME: Arrows, ASAP. #recipe.sources << "https://github.com/crystal-lang/crystal/archive/#{recipe.version}.tar.gz" recipe.dirname = "crystal-8b3dba72bd681118b2b761c68d7d2fdcbbbfceb2" recipe.sources << "https://github.com/crystal-lang/crystal/archive/8b3dba72bd681118b2b761c68d7d2fdcbbbfceb2.zip" recipe.dependencies << "libyaml" << "libevent" << "pcre" << "openssl" recipe.options["make"] = "release=1 LLVM_CONFIG=/usr/bad/llvm-6/bin/llvm-config" recipe.instructions.install << %{ set -e cd #{recipe.dirname}; PKG="#{recipe.fake_root_directory}"; mkdir -p "$PKG/usr/bin"; mkdir -p "$PKG/usr/lib/crystal/core"; mkdir -p "$PKG/usr/share/man/man1"; install -D -m 755 .build/crystal "$PKG"/usr/bin/crystal; install -D -m 644 man/crystal.1 "$PKG"/usr/share/man/man1/crystal.1; cp -r src/* "$PKG/usr/lib/crystal/core"; cd "$PKG/usr/lib/crystal/core"; nuke ext/sigfault.* llvm/ext/llvm_ext.o } end [{"6", "6.0.1"}, {"7", "7.1.0"},{"8", "8.0.0"}].each do |branch, version| recipes << Recipe.new(context, "llvm-#{branch}", version).tap do |recipe| recipe.sources << "http://releases.llvm.org/#{recipe.version}/llvm-#{recipe.version}.src.tar.xz" recipe.url = "http://llvm.org" recipe.description = "The LLVM Project is a collection of modular and reusable compiler and toolchain technologies." recipe.dependencies << "libffi" # Build-deps. #recipe.build_dependencies << "cmake" #recipe.build_dependencies << "make" #recipe.build_dependencies << "libffi-dev" #recipe.build_dependencies << "musl-dev" recipe.instructions.configure << "mkdir #{recipe.name}-#{recipe.version}" # FIXME: BROKEN recipe.instructions.configure << <<-EOF cd #{recipe.name}-#{recipe.version} && \ cmake ../llvm-#{recipe.version}.src \ -DCMAKE_INSTALL_PREFIX=/usr/bad/llvm-#{branch} \ -DLLVM_BUILD_DOCS=OFF \ -DLLVM_BUILD_EXAMPLES=OFF \ -DLLVM_BUILD_EXTERNAL_COMPILER_RT=ON \ -DLLVM_BUILD_LLVM_DYLIB=ON \ -DLLVM_ENABLE_ASSERTIONS=OFF \ -DLLVM_ENABLE_CXX1Y=ON \ -DLLVM_ENABLE_FFI=ON \ -DLLVM_ENABLE_LIBCXX=OFF \ -DLLVM_ENABLE_PIC=ON \ -DLLVM_ENABLE_RTTI=ON \ -DLLVM_ENABLE_SPHINX=OFF \ -DLLVM_ENABLE_TERMINFO=ON \ -DLLVM_ENABLE_ZLIB=ON \ -DLLVM_INCLUDE_EXAMPLES=OFF \ -DLLVM_LINK_LLVM_DYLIB=ON \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_CXX_FLAGS="-fPIC -O2" \ -DCMAKE_C_FLAGS="-fPIC -O2" EOF recipe.instructions.build << "pwd && ls && cd #{recipe.name}-#{recipe.version} && make" recipe.instructions.install << "cd #{recipe.name}-#{recipe.version} && make DESTDIR='#{recipe.fake_root_directory}' install" end end recipes << Recipe.new(context, "cmake", "3.15.1").tap do |recipe| recipe.sources << "https://github.com/Kitware/CMake/releases/download/v3.15.1/cmake-#{recipe.version}.tar.gz" end recipes << Recipe.new(context, "gmp", "6.1.2").tap do |recipe| recipe.sources << "https://gmplib.org/download/gmp/gmp-#{recipe.version}.tar.xz" end recipes << Recipe.new(context, "mpfr", "4.0.2").tap do |recipe| recipe.sources << "https://www.mpfr.org/mpfr-current/mpfr-#{recipe.version}.tar.xz" end recipes << Recipe.new(context, "mpc", "1.1.0").tap do |recipe| recipe.sources << "https://ftp.gnu.org/gnu/mpc/mpc-#{recipe.version}.tar.gz" end recipes << Recipe.new(context, "gcc", "9.1.0").tap do |recipe| recipe.sources << "https://ftp.gnu.org/gnu/gcc/gcc-9.1.0/gcc-#{recipe.version}.tar.xz" recipe.dependencies << "gmp" << "mpfr" << "mpc" << "binutils" recipe.dirname = "build" recipe.instructions.configure << %( set -e; mkdir build; cd build; sed -e '/m64=/s/lib64/lib/' \ -i.orig ../gcc-#{recipe.version}/gcc/config/i386/t-linux64; ../gcc-#{recipe.version}/configure \ --prefix=/usr \ --libdir=/usr/lib \ --disable-multilib \ --disable-libssp \ --disable-libmpx \ --disable-libmudflap \ --disable-libsanitizer \ --disable-nls \ --disable-werror \ --enable-languages=c,c++ \ --target=x86_64-junk-linux-musl \ --build=x86_64-junk-linux-musl \ --host=x86_64-junk-linux-musl ) end recipes << Recipe.new(context, "zsh", "5.7.1").tap do |recipe| recipe.sources << "https://downloads.sourceforge.net/project/zsh/zsh/#{recipe.version}/zsh-#{recipe.version}.tar.xz" recipe.url = "https://zsh.org" recipe.description = "Zsh is a shell designed for interactive use, although it is also a powerful scripting language." recipe.dependencies << "ncurses" recipe.options["configure"] = "--with-tcsetpgrp" # Build-deps. #recipe.build_dependencies << "ncurses-dev" end recipes << Recipe.new(context, "ncurses", "6.1").tap do |recipe| recipe.sources << "ftp://ftp.invisible-island.net/ncurses/ncurses-#{recipe.version}.tar.gz" recipe.url = "https://www.gnu.org/software/ncurses/" recipe.options["configure"] = "--enable-widec --without-ada --with-shared --enable-pc-files --disable-termcap" recipe.instructions.install << "cd ncurses-#{recipe.version} && make 'DESTDIR=#{recipe.fake_root_directory}' install" # Already provided bu busybox. recipe.instructions.install << "cd '#{recipe.fake_root_directory}' && rm usr/bin/clear usr/bin/reset" end recipes << Recipe.new(context, "busybox", "1.31.0").tap do |recipe| recipe.sources << "https://busybox.net/downloads/busybox-#{recipe.version}.tar.bz2" recipe.instructions.configure << "cd busybox-#{recipe.version} && make defconfig" recipe.instructions.configure << "sed -i -e 's/.*CONFIG_STATIC.*/CONFIG_STATIC=y/' busybox-#{recipe.version}/.config" recipe.instructions.install << "mkdir -p '#{recipe.fake_root_directory}/bin'" recipe.instructions.install << "mkdir -p '#{recipe.fake_root_directory}/sbin'" recipe.instructions.install << "mkdir -p '#{recipe.fake_root_directory}/usr/bin'" recipe.instructions.install << "mkdir -p '#{recipe.fake_root_directory}/usr/sbin'" recipe.instructions.install << "cp busybox-#{recipe.version}/busybox '#{recipe.fake_root_directory}/bin/busybox'" recipe.instructions.install << "chroot '#{recipe.fake_root_directory}' /bin/busybox --install -s" #recipe.build_dependencies << "linux-dev" end recipes << Recipe.new(context, "rc", "0.0.1").tap do |recipe| recipe.sources << "https://git.karchnu.fr/JunkOS/rc/archive/579e431144e33b2510260b1bce5505fd328d2961.tar.gz" # Those two are required due to a lack of robustness in our current backends. recipe.instructions.configure << "true" recipe.instructions.build << "true" recipe.instructions.install << "mkdir -p '#{recipe.fake_root_directory}/etc'" recipe.instructions.install << "cp rc/* '#{recipe.fake_root_directory}/etc/'" end recipes << Recipe.new(context, "libyaml", "0.2.2").tap do |recipe| recipe.sources << "https://github.com/yaml/libyaml/archive/#{recipe.version}.tar.gz" recipe.instructions.configure << "cd libyaml-#{recipe.version} && ./bootstrap && ./configure --prefix=/usr" # recipe.build_dependencies << "autoconf" << "libtool" end # FIXME: This one will fail on non-x86_64 platforms. Also on non-linux # platforms. This build script is total shit. recipes << Recipe.new(context, "openssl", "1.1.1c").tap do |recipe| recipe.sources << "https://www.openssl.org/source/openssl-#{recipe.version}.tar.gz" recipe.instructions.configure << "cd openssl-#{recipe.version} && ./Configure --prefix=/usr linux-x86_64" end recipes << Recipe.new(context, "libevent", "2.1.10").tap do |recipe| recipe.sources << "https://github.com/libevent/libevent/releases/download/release-#{recipe.version}-stable/libevent-#{recipe.version}-stable.tar.gz" recipe.dirname = "libevent-#{recipe.version}-stable" end recipes << Recipe.new(context, "pcre2", "10.33").tap do |recipe| recipe.sources << "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-#{recipe.version}.tar.gz" end recipes << Recipe.new(context, "pcre", "8.43").tap do |recipe| recipe.sources << "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-#{recipe.version}.tar.gz" recipe.options["configure"] = %( \ --enable-utf8 \ --enable-unicode-properties \ --enable-pcre8 \ --enable-pcre16 \ --enable-pcre32 \ --with-match-limit-recursion=8192 ) end recipes << Recipe.new(context, "binutils", "2.32").tap do |recipe| recipe.sources << "https://ftp.gnu.org/gnu/binutils/binutils-#{recipe.version}.tar.xz" recipe.options["configure"] = %( \ --disable-multilib \ --with-pic --disable-nls ) recipe.options["make"] = "tooldir=/usr" recipe.instructions.install << "cd #{recipe.dirname} && make 'DESTDIR=#{recipe.fake_root_directory}' tooldir=/usr install && rm '#{recipe.fake_root_directory}/usr/bin/strings'" end recipes << Recipe.new(context, "readline", "8.0").tap do |recipe| recipe.sources << "ftp://ftp.gnu.org/gnu/readline/readline-#{recipe.version}.tar.gz" end recipes << Recipe.new(context, "gc", "8.0.4").tap do |recipe| recipe.sources << "https://github.com/ivmai/bdwgc/releases/download/v#{recipe.version}/gc-#{recipe.version}.tar.gz" end recipes << Recipe.new(context, "clang", "8.0.1").tap do |recipe| recipe.sources << "https://github.com/llvm/llvm-project/releases/download/llvmorg-#{recipe.version}/cfe-#{recipe.version}.src.tar.xz" recipe.dirname = "build" recipe.instructions.configure << "mkdir build && cd build && cmake ../cfe-#{recipe.version}.src -DCMAKE_PREFIX_PATH=/usr/bad/llvm-8 -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release" end recipes << Recipe.new(context, "service", "0.0.1").tap do |recipe| recipe.sources << "" # FIXME end if ARGV.size == 0 || ARGV[0]? == "-h" pp recipes.map &.name exit 0 end selected_recipes = ARGV.map do |name| recipes.find(&.name.==(name)) || name end if selected_recipes.any? &.is_a?(String) puts "At least one of the requested recipes is not known." selected_recipes.select! &.is_a?(String) pp! selected_recipes end # Getting rid of Strings. selected_recipes = selected_recipes.compact_map do |recipe| if recipe.is_a? String nil else recipe end end selected_recipes.each do |recipe| pp recipe raise "oh no, download failed" unless recipe.download raise "oh no, extraction failed" unless recipe.extract raise "oh no, build failed" unless recipe.build raise "oh no, packaging failed" unless recipe.package recipe.clean end