├── .gitignore ├── framework ├── os │ ├── unknown_os.rb │ ├── mac.rb │ ├── os_spec.rb │ ├── os_dsl.rb │ ├── os.rb │ ├── fedora.rb │ ├── centos.rb │ ├── deepin.rb │ ├── redhat.rb │ └── ubuntu.rb ├── utils │ ├── pwd.rb │ ├── rm.rb │ ├── cp.rb │ ├── system_command.rb │ ├── ln.rb │ ├── mv.rb │ ├── mpi.rb │ ├── mkdir.rb │ ├── add_env.rb │ ├── ssh.rb │ ├── sed.rb │ ├── work_in.rb │ ├── which.rb │ ├── cd.rb │ ├── write_file.rb │ ├── append_file.rb │ ├── patch.rb │ ├── set_compile_env.rb │ ├── std_cmake_args.rb │ ├── load_package.rb │ ├── set_compile_flags.rb │ ├── append_env.rb │ ├── decompress.rb │ ├── inreplace.rb │ ├── run.rb │ ├── curl.rb │ └── cli.rb ├── compiler │ ├── pgi.rb │ ├── gcc.rb │ ├── clang.rb │ ├── intel.rb │ ├── compiler_spec.rb │ ├── compiler_dsl.rb │ ├── compiler.rb │ └── compiler_set.rb ├── package │ ├── package_special_labels.rb │ ├── package_downloader.rb │ ├── package_linker.rb │ ├── package_spec.rb │ ├── package_dsl.rb │ └── package_loader.rb ├── db │ ├── tables.sql │ └── history.rb ├── commands │ ├── edit.rb │ ├── update.rb │ ├── list.rb │ ├── link.rb │ ├── unlink.rb │ ├── fix.rb │ ├── uninstall.rb │ ├── command_parser.rb │ ├── pack.rb │ ├── setup.rb │ ├── config.rb │ └── load.rb ├── runtime.rb └── settings.rb ├── test └── docker │ ├── run.sh │ ├── entrypoint.sh │ ├── build.sh │ └── Dockerfile ├── packages ├── gsl.rb ├── bzip2.rb ├── utf8proc.rb ├── blosc.rb ├── netcdf.rb ├── papi.rb ├── expat.rb ├── m4.rb ├── wgrib2.rb ├── giflib.rb ├── geos.rb ├── zlib.rb ├── mct.rb ├── fox.rb ├── openjpeg.rb ├── libaec.rb ├── jpeg.rb ├── szip.rb ├── uuid.rb ├── json-c.rb ├── readline.rb ├── udunits.rb ├── julia.rb ├── openblas.rb ├── yacc.rb ├── libtiff.rb ├── libxml2.rb ├── xz.rb ├── mpfr.rb ├── openarray.rb ├── gmp.rb ├── hwloc.rb ├── icu4c.rb ├── flex.rb ├── opencoarrays.rb ├── antlr2.rb ├── emoslib.rb ├── tmux.rb ├── bufrlib.rb ├── pmix.rb ├── libgeotiff.rb ├── cmake.rb ├── csv-fortran.rb ├── lapack.rb ├── libgd.rb ├── mongoc.rb ├── ofed.rb ├── g2clib.rb ├── json-fortran.rb ├── petsc.rb ├── grads.rb ├── libpng.rb ├── jasper@2.0.4.rb ├── libuuid.rb ├── netcdf-cxx.rb ├── hdf-eos2@2.19.rb ├── fftw.rb ├── suite-sparse.rb ├── gettext.rb ├── netcdf-cxx4.rb ├── ncurses.rb ├── gptl.rb ├── cmor.rb ├── hdf4.rb ├── mpich.rb ├── gdbm.rb ├── jasper.rb ├── pcre2.rb ├── webp.rb ├── libffi.rb ├── nco.rb ├── hdf-eos2.rb ├── scalapack.rb ├── boost.rb ├── openmpi@4.0.1.rb ├── cdo.rb ├── proj.rb ├── sqlite3.rb ├── cdo@1.9.6.rb ├── libevent.rb ├── pnetcdf.rb ├── munge.rb ├── odb-api.rb ├── met.rb ├── openmpi.rb ├── eccodes.rb ├── mvapich2.rb ├── hdf5.rb ├── netcdf-c.rb ├── netcdf-fortran.rb ├── cartopy.rb ├── openssl.rb ├── metis.rb ├── magics.rb ├── nvhpc.rb ├── slurm.rb ├── gdal.rb ├── lua.rb ├── pio.rb ├── intel-oneapi.rb ├── gcc.rb ├── python3@3.6.rb ├── esmf.rb ├── python3.rb └── vim.rb ├── setup ├── zshrc ├── bashrc ├── install_sqlite.sh └── install_ruby.sh ├── starman ├── framework.rb └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .byebug_history 2 | .runtime 3 | ruby 4 | sqlite 5 | -------------------------------------------------------------------------------- /framework/os/unknown_os.rb: -------------------------------------------------------------------------------- 1 | class UnknownOS < OS 2 | type :unknown 3 | end 4 | -------------------------------------------------------------------------------- /framework/utils/pwd.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def pwd 3 | FileUtils.pwd 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /framework/utils/rm.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def rm path 3 | FileUtils.rm_rf path 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /framework/utils/cp.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def cp src, dst 3 | FileUtils.cp src, dst 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /framework/utils/system_command.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def system_command? cmd 3 | which cmd 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/docker/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker run --name starman-test -v /tmp/starman:/tmp/starman -it dongli/starman-test:0.0.1 4 | -------------------------------------------------------------------------------- /framework/utils/ln.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def ln src, dst 3 | Dir.glob src do |src_file| 4 | FileUtils.ln_sf src_file, dst 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /framework/utils/mv.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def mv src, dst 3 | Dir.glob src do |src_file| 4 | FileUtils.mv src_file, dst.to_s 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /framework/utils/mpi.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | class MPI 3 | def self.openmpi? 4 | `#{File.dirname ENV['MPICC']}/mpiexec --version`.match('OpenRTE') 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /framework/compiler/pgi.rb: -------------------------------------------------------------------------------- 1 | class PgiCompiler < Compiler 2 | vendor :pgi 3 | 4 | version do |language| 5 | `#{Settings.compilers[language]} -V 2>&1`.match(/\s+(\d+\.\d+)/)[1] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /framework/compiler/gcc.rb: -------------------------------------------------------------------------------- 1 | class GccCompiler < Compiler 2 | vendor :gcc 3 | 4 | version do |language| 5 | `#{Settings.compilers[language]} -v 2>&1`.match(/^gcc\s+.+\s+(\d+\.\d+\.\d+)/)[1] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /framework/utils/mkdir.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def mkdir name, &block 3 | FileUtils.mkdir_p name 4 | return unless block_given? 5 | work_in name do 6 | yield 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /framework/compiler/clang.rb: -------------------------------------------------------------------------------- 1 | class ClangCompiler < Compiler 2 | vendor :clang 3 | 4 | version do |language| 5 | `#{Settings.compilers[language]} -v 2>&1`.match(/version\s*(\d+\.\d+\.\d+)/)[1] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /framework/utils/add_env.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def add_env key, val 3 | @@added_env ||= {} 4 | @@added_env[key] = val 5 | end 6 | 7 | def added_env 8 | @@added_env rescue {} 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd /opt 4 | 5 | git clone https://github.com/dongli/starman && \ 6 | . starman/setup/bashrc && \ 7 | starman setup --install-root /opt/software 8 | 9 | bash 10 | -------------------------------------------------------------------------------- /framework/os/mac.rb: -------------------------------------------------------------------------------- 1 | class Mac < OS 2 | type :mac 3 | 4 | version do 5 | `sw_vers`.match(/ProductVersion:\s*(.*)$/)[1] 6 | end 7 | 8 | def arm? 9 | `uname -m`.chomp == 'arm64' 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /framework/utils/ssh.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def ssh cmd, options = {} 3 | user = options[:user] || ENV['USER'] 4 | res = `ssh #{user}@#{options[:host]} #{cmd}` 5 | return { status: $?, output: res } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /test/docker/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION=0.0.1 4 | 5 | sed -i "s/version \".*\"/version \"$VERSION\"/" Dockerfile 6 | 7 | docker build --rm -t dongli/starman-test:$VERSION . && \ 8 | docker push dongli/starman-test:$VERSION 9 | -------------------------------------------------------------------------------- /framework/package/package_special_labels.rb: -------------------------------------------------------------------------------- 1 | class PackageSpecialLabels 2 | def self.check label 3 | case label 4 | when :mpi 5 | ENV['MPICC'] != nil and ENV['MPICXX'] != nil and ENV['MPIFC'] != nil 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /framework/compiler/intel.rb: -------------------------------------------------------------------------------- 1 | class IntelCompiler < Compiler 2 | vendor :intel 3 | 4 | version do |language| 5 | `#{Settings.compilers[language]} -v 2>&1`.match(/^icc\s*(\(ICC\)|version)*\s*(\d+\.\d+(\.\d+)?)/)[2] rescue nil 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /framework/utils/sed.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def sed file_path, sed_cmd 3 | if OS.linux? 4 | run "sed -i #{sed_cmd} #{file_path}" 5 | elsif OS.mac? 6 | run "sed -i '' #{sed_cmd} #{file_path}" 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /framework/db/tables.sql: -------------------------------------------------------------------------------- 1 | create table install( 2 | id integer primary key, 3 | name varchar(30), 4 | version varchar(30), 5 | prefix varchar(512), 6 | compiler_set varchar(30), 7 | options varchar(2048), 8 | time datetime 9 | ); 10 | -------------------------------------------------------------------------------- /framework/utils/work_in.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def work_in dir 3 | CLI.error 'No work block is given!' if not block_given? 4 | CLI.error "Directory #{CLI.red dir} does not exist!" if not Dir.exist? dir 5 | cd dir 6 | yield 7 | cd :back 8 | end 9 | end -------------------------------------------------------------------------------- /framework/os/os_spec.rb: -------------------------------------------------------------------------------- 1 | class OsSpec 2 | attr_accessor :type, :version, :commands 3 | 4 | def initialize 5 | @commands = {} 6 | end 7 | 8 | def eval 9 | self.version = Version.new self.version.call if self.version.class == Proc 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /framework/compiler/compiler_spec.rb: -------------------------------------------------------------------------------- 1 | class CompilerSpec 2 | attr_accessor :vendor, :version, :active_language, :command 3 | 4 | def eval language 5 | self.version = Version.new self.version.call(language.to_s) if self.version.class == Proc 6 | self.command = Settings.compilers[language.to_s] 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /framework/utils/which.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def which cmd 3 | begin 4 | `which #{cmd} 2> /dev/null`.chomp 5 | rescue 6 | ENV['PATH'].split(':').each do |dir| 7 | path = "#{dir}/#{cmd}" 8 | return path if Dir.exist? dir and File.exist? path 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /packages/gsl.rb: -------------------------------------------------------------------------------- 1 | class Gsl < Package 2 | url 'https://mirrors.sjtug.sjtu.edu.cn/gnu/gsl/gsl-2.7.tar.gz' 3 | sha256 '' 4 | 5 | def install 6 | run './configure', '--disable-dependency-tracking', "--prefix=#{prefix}" 7 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 8 | run 'make', 'install' 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | RUN yum -y install gcc gcc-c++ gcc-gfortran git vim-enhanced which ruby make bzip2 m4 4 | 5 | ADD entrypoint.sh / 6 | 7 | ENTRYPOINT /entrypoint.sh 8 | 9 | LABEL description "Test environment for STARMAN" 10 | LABEL maintainer "Li Dong " 11 | LABEL version "0.0.1" 12 | -------------------------------------------------------------------------------- /framework/utils/cd.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def cd dir, *options 3 | if dir == :back 4 | FileUtils.chdir @@cd_dir_stack.last 5 | @@cd_dir_stack.pop 6 | else 7 | @@cd_dir_stack ||= [] 8 | @@cd_dir_stack << FileUtils.pwd if not options.include? :not_record 9 | FileUtils.chdir dir 10 | end 11 | end 12 | end -------------------------------------------------------------------------------- /framework/utils/write_file.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def write_file file_path, content = nil, &block 3 | dir = File.dirname file_path 4 | mkdir_p dir if not Dir.exist? dir 5 | file = File.new file_path, 'w' 6 | if block_given? 7 | content ||= '' 8 | yield content 9 | end 10 | file << content 11 | file.close 12 | end 13 | end -------------------------------------------------------------------------------- /packages/bzip2.rb: -------------------------------------------------------------------------------- 1 | class Bzip2 < Package 2 | url 'https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz' 3 | sha256 'ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269' 4 | 5 | def install 6 | inreplace 'Makefile', '$(PREFIX)/man', '$(PREFIX)/share/man' 7 | run 'make', 'install', "PREFIX=#{prefix}", "CFLAGS=-fPIC" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /framework/utils/append_file.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def append_file file_path, content = nil, &block 3 | dir = File.dirname file_path 4 | mkdir_p dir if not Dir.exist? dir 5 | file = File.open file_path, 'a' 6 | if block_given? 7 | content ||= '' 8 | yield content 9 | end 10 | file << content 11 | file.close 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /packages/utf8proc.rb: -------------------------------------------------------------------------------- 1 | class Utf8proc < Package 2 | url 'https://github.com/JuliaStrings/utf8proc/archive/refs/tags/v2.9.0.tar.gz' 3 | sha256 '18c1626e9fc5a2e192311e36b3010bfc698078f692888940f1fa150547abb0c1' 4 | file_name 'utf8proc-2.9.0.tar.gz' 5 | 6 | label :common 7 | 8 | def install 9 | run 'make', 'install', "prefix=#{prefix}" 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /packages/blosc.rb: -------------------------------------------------------------------------------- 1 | class Blosc < Package 2 | url 'https://github.com/Blosc/c-blosc/archive/v1.21.1.tar.gz' 3 | sha256 'f387149eab24efa01c308e4cba0f59f64ccae57292ec9c794002232f7903b55b' 4 | file_name 'blosc-1.21.1.tar.gz' 5 | 6 | depends_on :cmake 7 | 8 | def install 9 | run 'cmake', '.', *std_cmake_args 10 | run 'make', 'install' 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /packages/netcdf.rb: -------------------------------------------------------------------------------- 1 | class Netcdf < Package 2 | version '4.9.2' 3 | label :group 4 | 5 | option 'with-cxx', 'Disable C++ bindings.' 6 | 7 | depends_on 'netcdf-c', version: '4.9.2' 8 | depends_on 'netcdf-cxx', version: '4.2' if with_cxx? 9 | depends_on 'netcdf-cxx4', version: '4.3.1' if with_cxx? 10 | depends_on 'netcdf-fortran', version: '4.6.1' 11 | end 12 | -------------------------------------------------------------------------------- /packages/papi.rb: -------------------------------------------------------------------------------- 1 | class Papi < Package 2 | url 'http://icl.utk.edu/projects/papi/downloads/papi-7.0.1.tar.gz' 3 | sha256 'c105da5d8fea7b113b0741a943d467a06c98db959ce71bdd9a50b9f03eecc43e' 4 | 5 | def install 6 | work_in 'src' do 7 | run './configure', "--prefix=#{prefix}" 8 | run 'make' 9 | run 'make', 'install' 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /packages/expat.rb: -------------------------------------------------------------------------------- 1 | class Expat < Package 2 | url 'https://github.com/libexpat/libexpat/releases/download/R_2_4_1/expat-2.4.1.tar.xz' 3 | sha256 'cf032d0dba9b928636548e32b327a2d66b1aab63c4f4a13dd132c2d1d2f2fb6a' 4 | 5 | label :common 6 | 7 | def install 8 | run './configure', "--prefix=#{prefix} --without-docbook" 9 | run 'make', 'install' 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /packages/m4.rb: -------------------------------------------------------------------------------- 1 | class M4 < Package 2 | url 'https://mirrors.nju.edu.cn/gnu/m4/m4-1.4.19.tar.xz' 3 | sha256 '63aede5c6d33b6d9b13511cd0be2cac046f2e70fd0a07aa9573a04a82783af96' 4 | 5 | label :common 6 | label :skip_if_exist, binary_file: 'm4' 7 | 8 | def install 9 | run './configure', "--prefix=#{prefix}" 10 | run 'make' 11 | run 'make', 'install' 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /packages/wgrib2.rb: -------------------------------------------------------------------------------- 1 | class Wgrib2 < Package 2 | url 'https://www.ftp.cpc.ncep.noaa.gov/wd51we/wgrib2/wgrib2.tgz.v3.1.1' 3 | sha256 '9236f6afddad76d868c2cfdf5c4227f5bdda5e85ae40c18bafb37218e49bc04a' 4 | file_name 'wgrib2-3.1.1.tar.gz' 5 | version '3.1.1' 6 | 7 | label :common 8 | 9 | def install 10 | run 'make' 11 | mkdir bin 12 | cp './wgrib2/wgrib2', bin 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /packages/giflib.rb: -------------------------------------------------------------------------------- 1 | class Giflib < Package 2 | url 'https://downloads.sourceforge.net/project/giflib/giflib-5.1.4.tar.bz2' 3 | sha256 'df27ec3ff24671f80b29e6ab1c4971059c14ac3db95406884fc26574631ba8d5' 4 | 5 | def install 6 | args = %W[ 7 | --prefix=#{prefix} 8 | --disable-dependency-tracking 9 | ] 10 | run './configure', *args 11 | run 'make', 'install' 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /packages/geos.rb: -------------------------------------------------------------------------------- 1 | class Geos < Package 2 | url 'https://download.osgeo.org/geos/geos-3.7.2.tar.bz2' 3 | sha256 '2166e65be6d612317115bfec07827c11b403c3f303e0a7420a2106bc999d7707' 4 | 5 | def install 6 | args = %W[ 7 | --prefix=#{prefix} 8 | --disable-dependency-tracking 9 | --disable-python 10 | ] 11 | 12 | run './configure', *args 13 | run 'make', 'install' 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /packages/zlib.rb: -------------------------------------------------------------------------------- 1 | class Zlib < Package 2 | url 'https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz' 3 | sha256 'b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30' 4 | 5 | label :skip_if_exist, library_file: 'libz.so' 6 | 7 | def install 8 | ENV['CFLAGS'] = '-O3 -fPIC' 9 | run './configure', "--prefix=#{prefix}" 10 | run 'make', 'install' 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /packages/mct.rb: -------------------------------------------------------------------------------- 1 | class Mct < Package 2 | url 'https://github.com/MCSclimate/MCT/archive/refs/tags/MCT_2.11.0.zip' 3 | sha256 'baa1554ca3ccd0a2378b5b09bbd401ef458f967f0deb450049aea65c02db58da' 4 | version '2.11.0' 5 | 6 | depends_on :mpi 7 | 8 | def install 9 | args = %W[ 10 | --prefix=#{prefix} 11 | ] 12 | run './configure', *args 13 | run 'make' 14 | run 'make', 'install' 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /framework/commands/edit.rb: -------------------------------------------------------------------------------- 1 | class EditCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman edit 9 | EOS 10 | @parser.parse! 11 | Settings.init 12 | end 13 | 14 | def run 15 | cmd = system_command?('vim') ? 'vim' : 'vi' 16 | system "#{cmd} -c 'set filetype=ruby' #{ENV['STARMAN_ROOT']}/packages/#{ARGV.last}.rb" 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /packages/fox.rb: -------------------------------------------------------------------------------- 1 | class Fox < Package 2 | url 'http://homepages.see.leeds.ac.uk/~earawa/FoX/source/FoX-4.1.2.tar.gz' 3 | sha256 '3b749138229e7808d0009a97e2ac47815ad5278df6879a9cc64351a7921ba06f' 4 | 5 | def install 6 | args = %W[ 7 | --prefix=#{prefix} 8 | --enable-fast 9 | ] 10 | run './configure', *args 11 | run 'make' 12 | run 'make', 'install' 13 | run 'mv', "#{prefix}/finclude", "#{prefix}/include" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /packages/openjpeg.rb: -------------------------------------------------------------------------------- 1 | class Openjpeg < Package 2 | url 'https://github.com/uclouvain/openjpeg/archive/v2.3.0.tar.gz' 3 | sha256 '3dc787c1bb6023ba846c2a0d9b1f6e179f1cd255172bde9eb75b01f1e6c7d71a' 4 | file_name 'openjpeg-2.3.0.tar.gz' 5 | 6 | depends_on :cmake 7 | 8 | def install 9 | args = std_cmake_args 10 | mkdir 'build' do 11 | run 'cmake', '..', *args 12 | run 'make' 13 | run 'make', 'install' 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /packages/libaec.rb: -------------------------------------------------------------------------------- 1 | class Libaec < Package 2 | url 'https://gitlab.dkrz.de/k202009/libaec/-/archive/v1.1.3/libaec-v1.1.3.tar.bz2' 3 | sha256 '46216f9d2f2d3ffea4c61c9198fe0236f7f316d702f49065c811447186d18222' 4 | version '1.1.3' 5 | 6 | def install 7 | mkdir 'build' do 8 | run 'cmake', '..', *std_cmake_args, '-DBUILD_TESTING=ON' 9 | run 'make' 10 | run 'make', 'test' unless skip_test? 11 | run 'make', 'install' 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /packages/jpeg.rb: -------------------------------------------------------------------------------- 1 | class Jpeg < Package 2 | url 'http://www.ijg.org/files/jpegsrc.v9d.tar.gz' 3 | sha256 '2303a6acfb6cc533e0e86e8a9d29f7e6079e118b9de3f96e07a71a11c082fa6a' 4 | version 'v9b' 5 | 6 | label :conflict_with_system if OS.mac? 7 | 8 | def install 9 | args = %W[ 10 | --prefix=#{prefix} 11 | --disable-dependency-tracking 12 | --disable-silent-rules 13 | ] 14 | run './configure', *args 15 | run 'make', 'install' 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /framework/utils/patch.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def patch_data data 3 | file = File.open('patch.diff', 'w') 4 | file << data 5 | file.close 6 | system 'patch --ignore-whitespace -N -p1 < patch.diff' 7 | CLI.error 'Failed to apply patch!' unless $?.success? 8 | end 9 | 10 | def patch_file path, options={} 11 | system "patch --ignore-whitespace -N -p#{options[:strip] || 0} < #{path}" 12 | CLI.error 'Failed to apply patch!' unless $?.success? 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /packages/szip.rb: -------------------------------------------------------------------------------- 1 | class Szip < Package 2 | url 'https://support.hdfgroup.org/ftp/lib-external/szip/2.1.1/src/szip-2.1.1.tar.gz' 3 | sha256 '21ee958b4f2d4be2c9cabfa5e1a94877043609ce86fde5f286f105f7ff84d412' 4 | 5 | def install 6 | ENV['CFLAGS'] = '-fPIC' if CompilerSet.c.intel? 7 | args = %W[ 8 | --prefix=#{prefix} 9 | --disable-debug 10 | --disable-dependency-tracking 11 | ] 12 | run './configure', *args 13 | run 'make', 'install' 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /framework/commands/update.rb: -------------------------------------------------------------------------------- 1 | class UpdateCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman update 9 | EOS 10 | @parser.parse! 11 | end 12 | 13 | def run 14 | work_in ENV['STARMAN_ROOT'] do 15 | if Dir.exist? '.git' 16 | system 'git', 'pull' 17 | else 18 | CLI.error "Sorry, you haven't installed STARMAN using #{CLI.red 'git'}!" 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /packages/uuid.rb: -------------------------------------------------------------------------------- 1 | class Uuid < Package 2 | url 'https://mirrors.ocf.berkeley.edu/debian/pool/main/o/ossp-uuid/ossp-uuid_1.6.2.orig.tar.gz' 3 | sha256 '11a615225baa5f8bb686824423f50e4427acd3f70d394765bdff32801f0fd5b0' 4 | version '1.6.2' 5 | 6 | def install 7 | args = %W[ 8 | --prefix=#{prefix} 9 | --without-perl 10 | --without-php 11 | --without-pgsql 12 | ] 13 | run './configure', *args 14 | run 'make' 15 | run 'make', 'install' 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /packages/json-c.rb: -------------------------------------------------------------------------------- 1 | class JsonC < Package 2 | url 'https://github.com/json-c/json-c/archive/json-c-0.13.1-20180305.tar.gz' 3 | sha256 '5d867baeb7f540abe8f3265ac18ed7a24f91fe3c5f4fd99ac3caba0708511b90' 4 | version '0.13.1' 5 | 6 | depends_on :cmake 7 | 8 | def install 9 | args = std_cmake_args 10 | mkdir 'build' do 11 | run 'cmake', '..', *args 12 | run 'make' 13 | run 'make', 'install' 14 | end 15 | cp 'json_object_iterator.h', inc + '/json-c' 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /framework/utils/set_compile_env.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def set_compile_env 3 | # FIXME: Only a package depends on mpi should set CC to MPICC. 4 | ENV['CC'] = c_compiler 5 | ENV['CXX'] = cxx_compiler 6 | ENV['FC'] = fortran_compiler 7 | ENV['F77'] = fortran_compiler 8 | ENV['MPICC'] = mpi_c_compiler 9 | ENV['MPICXX'] = mpi_cxx_compiler 10 | ENV['MPIFC'] = mpi_fortran_compiler 11 | ENV['MPIF77'] = mpi_fortran_compiler 12 | ENV['MPIF90'] = mpi_fortran_compiler 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /packages/readline.rb: -------------------------------------------------------------------------------- 1 | class Readline < Package 2 | url 'https://ftp.gnu.org/gnu/readline/readline-8.2.tar.gz' 3 | sha256 '3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35' 4 | version '8.2' 5 | 6 | label :common 7 | label :alone 8 | label :skip_if_exist, include_file: 'readline/readline.h' 9 | 10 | def install 11 | run './configure', "--prefix=#{prefix}" 12 | inreplace 'readline.pc', /^(Requires.private: .*)$/, "# \\1" if OS.mac? 13 | run 'make', 'install' 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /packages/udunits.rb: -------------------------------------------------------------------------------- 1 | class Udunits < Package 2 | url 'https://artifacts.unidata.ucar.edu/repository/downloads-udunits/2.2.28/udunits-2.2.28.tar.gz' 3 | sha256 '590baec83161a3fd62c00efa66f6113cec8a7c461e3f61a5182167e0cc5d579e' 4 | 5 | label :common 6 | 7 | depends_on :expat 8 | 9 | def install 10 | args = %W[ 11 | --prefix=#{prefix} 12 | CPPFLAGS='-I#{link_inc}' 13 | LDFLAGS='-L#{link_lib}' 14 | ] 15 | run './configure', *args 16 | run 'make', 'install' 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /setup/zshrc: -------------------------------------------------------------------------------- 1 | export STARMAN_ROOT=$(cd $(dirname $0) && cd .. && pwd) 2 | export PATH=$STARMAN_ROOT:$PATH 3 | 4 | if [[ -d $STARMAN_ROOT/ruby/bin ]]; then 5 | export PATH=$STARMAN_ROOT/ruby/bin:$PATH 6 | fi 7 | 8 | function before_command { 9 | if [[ "$1" =~ .*starman[[:space:]]+(load) ]]; then 10 | res=$(eval "$1 --print") 11 | if [[ ! "$res" =~ Warning && ! "$res" =~ Error ]]; then 12 | $(echo $res) 13 | fi 14 | fi 15 | } 16 | autoload -Uz add-zsh-hook 17 | add-zsh-hook preexec before_command 18 | -------------------------------------------------------------------------------- /packages/julia.rb: -------------------------------------------------------------------------------- 1 | class Julia < Package 2 | if OS.linux? 3 | url 'https://julialang-s3.julialang.org/bin/linux/x64/1.8/julia-1.8.5-linux-x86_64.tar.gz' 4 | sha256 'e71a24816e8fe9d5f4807664cbbb42738f5aa9fe05397d35c81d4c5d649b9d05' 5 | end 6 | version '1.8.5' 7 | 8 | label :common 9 | 10 | def install 11 | mkdir prefix 12 | mv 'bin', prefix 13 | mv 'etc', prefix 14 | mv 'include', prefix 15 | mv 'lib', prefix 16 | mv 'libexec', prefix 17 | mv 'share', prefix 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /packages/openblas.rb: -------------------------------------------------------------------------------- 1 | class Openblas < Package 2 | url 'https://github.com/xianyi/OpenBLAS/archive/refs/tags/v0.3.24.tar.gz' 3 | sha256 'ceadc5065da97bd92404cac7254da66cc6eb192679cf1002098688978d4d5132' 4 | file_name 'openblas-0.3.24.tar.gz' 5 | 6 | def install 7 | ENV['DYNAMIC_ARCH'] = '1' 8 | ENV['USE_OPENMP'] = '1' 9 | ENV['NUM_THREADS'] = '56' 10 | run 'make', "CC=#{ENV['CC']}", "FC=#{ENV['FC']}", 'libs', 'netlib', 'shared' 11 | run 'make', "PREFIX=#{prefix}", 'install' 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /packages/yacc.rb: -------------------------------------------------------------------------------- 1 | class Yacc < Package 2 | url 'https://invisible-mirror.net/archives/byacc/byacc-20170709.tgz' 3 | sha256 '27cf801985dc6082b8732522588a7b64377dd3df841d584ba6150bc86d78d9eb' 4 | version '2017.07.09' 5 | 6 | label :common 7 | label :skip_if_exist, binary_file: 'yacc' 8 | 9 | def install 10 | args = %W[ 11 | --prefix=#{prefix} 12 | --disable-debug 13 | --disable-dependency-tracking 14 | ] 15 | run './configure', *args 16 | run 'make', 'install' 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /packages/libtiff.rb: -------------------------------------------------------------------------------- 1 | class Libtiff < Package 2 | url 'https://download.osgeo.org/libtiff/tiff-4.6.0.tar.gz' 3 | sha256 '88b3979e6d5c7e32b50d7ec72fb15af724f6ab2cbf7e10880c360a77e4b5d99a' 4 | 5 | depends_on :jpeg 6 | 7 | def install 8 | args = %W[ 9 | --prefix=#{prefix} 10 | --disable-dependency-tracking 11 | --disable-lzma 12 | --with-jpeg-include-dir=#{Jpeg.inc} 13 | --with-jpeg-lib-dir=#{Jpeg.lib} 14 | ] 15 | run './configure', *args 16 | run 'make', 'install' 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /framework/compiler/compiler_dsl.rb: -------------------------------------------------------------------------------- 1 | module CompilerDSL 2 | def self.included base 3 | base.extend self 4 | end 5 | 6 | def spec 7 | return self.class_variable_get "@@#{self}_spec" if self.class_variable_defined? "@@#{self}_spec" 8 | self.class_variable_set "@@#{self}_spec", CompilerSpec.new 9 | end 10 | 11 | def vendor val 12 | if val != nil 13 | spec.vendor = val.to_sym 14 | end 15 | end 16 | 17 | def version &block 18 | if block_given? 19 | spec.version = block 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /packages/libxml2.rb: -------------------------------------------------------------------------------- 1 | class Libxml2 < Package 2 | url 'http://xmlsoft.org/sources/libxml2-2.9.7.tar.gz' 3 | sha256 'f63c5e7d30362ed28b38bfa1ac6313f9a80230720b7fb6c80575eeab3ff5900c' 4 | 5 | label :common 6 | 7 | depends_on :zlib 8 | 9 | def install 10 | args = %W[ 11 | --prefix=#{prefix} 12 | --disable-dependency-tracking 13 | --without-python 14 | --without-lzma 15 | --with-zlib=#{Zlib.prefix} 16 | ] 17 | run './configure', *args 18 | run 'make' 19 | run 'make', 'install' 20 | end 21 | end -------------------------------------------------------------------------------- /packages/xz.rb: -------------------------------------------------------------------------------- 1 | class Xz < Package 2 | url 'https://downloads.sourceforge.net/project/lzmautils/xz-5.2.5.tar.gz' 3 | sha256 'f6f4910fd033078738bd82bfba4f49219d03b17eb0794eb91efbae419f4aba10' 4 | 5 | label :common 6 | 7 | def install 8 | args = %W[ 9 | --prefix=#{prefix} 10 | --disable-debug 11 | --disable-dependency-tracking 12 | --disable-silent-rules 13 | ] 14 | run './configure', *args 15 | run 'make' 16 | run 'make', 'check' unless skip_test? 17 | run 'make', 'install' 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /packages/mpfr.rb: -------------------------------------------------------------------------------- 1 | class Mpfr < Package 2 | url 'http://mirrors.aliyun.com/gnu/mpfr/mpfr-4.2.0.tar.xz' 3 | sha256 '06a378df13501248c1b2db5aa977a2c8126ae849a9d9b7be2546fb4a9c26d993' 4 | 5 | depends_on :gmp 6 | 7 | def install 8 | args = %W[ 9 | --prefix=#{prefix} 10 | --disable-dependency-tracking 11 | --disable-silent-rules 12 | --with-gmp=#{Gmp.link_root} 13 | ] 14 | run './configure', *args 15 | run 'make' 16 | run 'make', 'check' unless skip_test? 17 | run 'make', 'install' 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /packages/openarray.rb: -------------------------------------------------------------------------------- 1 | class Openarray < Package 2 | url 'https://github.com/hxmhuang/OpenArray/archive/1.0.1.tar.gz' 3 | sha256 '3a21246ab9ca2e569304437fe05f504bb2778fbd1ed8a43a61692a0c0be6150e' 4 | file_name 'openarray-1.0.1.tar.gz' 5 | 6 | depends_on :pnetcdf 7 | depends_on :mpi 8 | 9 | def install 10 | args = %W[ 11 | --prefix=#{prefix} 12 | PNETCDF_DIR=#{Pnetcdf.link_root} 13 | ] 14 | run './configure', *args 15 | run 'make' 16 | run 'make', 'test' unless skip_test? 17 | run 'make', 'install' 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /framework/compiler/compiler.rb: -------------------------------------------------------------------------------- 1 | class Compiler 2 | include CompilerDSL 3 | 4 | extend Forwardable 5 | def_delegators :@spec, :vendor, :version, :command 6 | 7 | def initialize language 8 | @spec = self.class.class_variable_get("@@#{self.class}_spec").clone 9 | @spec.eval language 10 | end 11 | 12 | def gcc? 13 | @spec.vendor == :gcc 14 | end 15 | 16 | def intel? 17 | @spec.vendor == :intel 18 | end 19 | 20 | def pgi? 21 | @spec.vendor == :pgi 22 | end 23 | 24 | def clang? 25 | @spec.vendor == :clang 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /framework/runtime.rb: -------------------------------------------------------------------------------- 1 | class Runtime 2 | extend Utils 3 | 4 | @@runtime = {} 5 | 6 | def self.runtime_file 7 | ENV['STARMAN_ROOT'] + '/.runtime' 8 | end 9 | 10 | def self.rc_root 11 | @@runtime['rc_root'] 12 | end 13 | 14 | def self.init 15 | if File.exist? runtime_file 16 | @@runtime = YAML.load(open(runtime_file).read) 17 | end 18 | end 19 | 20 | def self.write options 21 | @@runtime['rc_root'] = options[:rc_root] 22 | write_file runtime_file, <<-EOS 23 | --- 24 | rc_root: #{@@runtime['rc_root']} 25 | EOS 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /framework/commands/list.rb: -------------------------------------------------------------------------------- 1 | class ListCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman list 9 | EOS 10 | # Parse package names and load them. 11 | parse_packages relax: true 12 | @parser.parse! 13 | Settings.init 14 | end 15 | 16 | def run 17 | PackageLoader.loaded_packages.keys.map(&:to_s).sort.map(&:to_sym).each do |name| 18 | package = PackageLoader.loaded_packages[name] 19 | print "#{CLI.blue name}@#{package.version}\n" 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /packages/gmp.rb: -------------------------------------------------------------------------------- 1 | class Gmp < Package 2 | url 'https://ftp.gnu.org/gnu/gmp/gmp-6.3.0.tar.xz' 3 | sha256 'a3c2b80201b89e68616f4ad30bc66aee4927c3ce50e33929ca819d5c43538898' 4 | 5 | label :skip_if_exist, library_file: "libgmp.#{OS.soname}" 6 | 7 | def install 8 | args = %W[ 9 | --prefix=#{prefix} 10 | --disable-debug 11 | --disable-dependency-tracking 12 | --enable-cxx 13 | --with-pic 14 | ] 15 | run './configure', *args 16 | run 'make' 17 | run 'make', 'check' unless skip_test? 18 | run 'make', 'install' 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /framework/commands/link.rb: -------------------------------------------------------------------------------- 1 | class LinkCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman link ... [options] 9 | EOS 10 | parse_packages 11 | @parser.parse! 12 | end 13 | 14 | def run 15 | PackageLoader.loaded_packages.each do |name, package| 16 | next if not PackageLoader.from_cmd_line? package or package.has_label? :not_link 17 | CLI.notice "Link package #{CLI.green package.name} ..." 18 | PackageLinker.link package 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /packages/hwloc.rb: -------------------------------------------------------------------------------- 1 | class Hwloc < Package 2 | url 'https://download.open-mpi.org/release/hwloc/v2.10/hwloc-2.10.0.tar.bz2' 3 | sha256 '0305dd60c9de2fbe6519fe2a4e8fdc6d3db8de574a0ca7812b92e80c05ae1392' 4 | 5 | label :common 6 | 7 | option 'without-rocm', 'Build without ROCM.' 8 | 9 | def install 10 | args = %W[ 11 | --prefix=#{prefix} 12 | --disable-debug 13 | --disable-dependency-tracking 14 | --without-x 15 | ] 16 | args << '--without-rocm' if without_rocm? 17 | run './configure', *args 18 | run 'make', 'install' 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /setup/bashrc: -------------------------------------------------------------------------------- 1 | # This file should be sourced before call starman in any bashrc files! 2 | 3 | export STARMAN_ROOT=$(cd $(dirname $BASH_SOURCE) && cd .. && pwd) 4 | export PATH=$STARMAN_ROOT:$PATH 5 | 6 | if [[ -d $STARMAN_ROOT/ruby/bin ]]; then 7 | export PATH=$STARMAN_ROOT/ruby/bin:$PATH 8 | fi 9 | 10 | function before_command { 11 | if [[ "$BASH_COMMAND" =~ .*starman[[:space:]]+(load) ]]; then 12 | res=$($BASH_COMMAND --print) 13 | if [[ ! "$res" =~ Warning && ! "$res" =~ Error ]]; then 14 | $(echo $res) 15 | fi 16 | fi 17 | } 18 | trap before_command DEBUG 19 | -------------------------------------------------------------------------------- /packages/icu4c.rb: -------------------------------------------------------------------------------- 1 | class Icu4c < Package 2 | url 'https://ssl.icu-project.org/files/icu4c/62.1/icu4c-62_1-src.tgz' 3 | sha256 '3dd9868d666350dda66a6e305eecde9d479fb70b30d5b55d78a1deffb97d5aa3' 4 | version '62.1' 5 | 6 | label :common 7 | 8 | def install 9 | args = %W[ 10 | --prefix=#{prefix} 11 | --disable-samples 12 | --disable-tests 13 | --enable-static 14 | --with-library-bits=64 15 | ] 16 | 17 | cd 'source' do 18 | run './configure', *args 19 | run 'make' 20 | run 'make', 'install' 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /framework/commands/unlink.rb: -------------------------------------------------------------------------------- 1 | class UnlinkCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman unlink ... [options] 9 | EOS 10 | parse_packages 11 | @parser.parse! 12 | end 13 | 14 | def run 15 | PackageLoader.loaded_packages.each do |name, package| 16 | next if not PackageLoader.from_cmd_line? package or package.has_label? :alone 17 | CLI.notice "Unlink package #{CLI.green package.name} ..." 18 | PackageLinker.unlink package 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /packages/flex.rb: -------------------------------------------------------------------------------- 1 | class Flex < Package 2 | url 'https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz' 3 | sha256 'e87aae032bf07c26f85ac0ed3250998c37621d95f8bd748b31f15b33c45ee995' 4 | 5 | label :common 6 | label :skip_if_exist, binary_file: 'flex' 7 | 8 | depends_on :gettext 9 | depends_on :m4 10 | 11 | def install 12 | args = %W[ 13 | --prefix=#{prefix} 14 | --disable-dependency-tracking 15 | --disable-silent-rules 16 | --enable-shared 17 | ] 18 | run './configure', *args 19 | run 'make', 'install' 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /packages/opencoarrays.rb: -------------------------------------------------------------------------------- 1 | class Opencoarrays < Package 2 | url 'https://github.com/sourceryinstitute/OpenCoarrays/releases/download/2.10.1/OpenCoarrays-2.10.1.tar.gz' 3 | sha256 'b04b8fa724e7e4e5addbab68d81d701414e713ab915bafdf1597ec5dd9590cd4' 4 | 5 | depends_on :cmake 6 | depends_on :mpi 7 | 8 | def install 9 | if CompilerSet.c.vendor != :gcc 10 | CLI.error 'OpenCoarrays only works with GNU compilers!' 11 | end 12 | mkdir 'build' do 13 | run 'cmake', '..', *std_cmake_args 14 | run 'make' 15 | run 'make', 'install' 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /framework/utils/std_cmake_args.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def std_cmake_args options = {} 3 | args = %W[ 4 | -DCMAKE_SYSTEM_PREFIX_PATH=#{Settings.link_root} 5 | -DCMAKE_C_FLAGS_RELEASE=-DNDEBUG 6 | -DCMAKE_CXX_FLAGS_RELEASE=-DNDEBUG 7 | -DCMAKE_INSTALL_PREFIX=#{prefix} 8 | -DCMAKE_BUILD_TYPE=Release 9 | -DCMAKE_FIND_FRAMEWORK=LAST 10 | -DCMAKE_VERBOSE_MAKEFILE=ON 11 | -Wno-dev 12 | ] 13 | args << "-DCMAKE_PREFIX_PATH=#{options[:search_paths].join}" if options[:search_paths] and not options[:search_paths].empty? 14 | args 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /packages/antlr2.rb: -------------------------------------------------------------------------------- 1 | class Antlr2 < Package 2 | url 'https://www.antlr2.org/download/antlr-2.7.7.tar.gz' 3 | sha256 '853aeb021aef7586bda29e74a6b03006bcb565a755c86b66032d8ec31b67dbb9' 4 | 5 | label :common 6 | 7 | def install 8 | inreplace 'lib/cpp/antlr/CharScanner.hpp', { 9 | '#include ' => "#include \n#include " 10 | } 11 | args = %W[ 12 | --prefix=#{prefix} 13 | --disable-debug 14 | --disable-csharp 15 | --disable-java 16 | --disable-python 17 | ] 18 | run './configure', *args 19 | run 'make' 20 | run 'make', 'install' 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /packages/emoslib.rb: -------------------------------------------------------------------------------- 1 | class Emoslib < Package 2 | url 'https://software.ecmwf.int/wiki/download/attachments/3473472/libemos-4.5.5-Source.tar.gz?api=v2' 3 | sha256 '88e3ca91268df5ae2db1909460445ed43e95de035d62b02cab26ce159851a4c1' 4 | 5 | depends_on :eccodes 6 | depends_on :fftw 7 | 8 | def install 9 | args = std_cmake_args 10 | args << "-DECCODES_PATH=#{Eccodes.link_root}" 11 | args << "-DFFTW_ROOT=#{Fftw.link_root}" 12 | mkdir 'build' do 13 | run 'cmake', '..', *args 14 | run 'make' 15 | run 'make', 'test' unless skip_test? 16 | run 'make', 'install' 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /packages/tmux.rb: -------------------------------------------------------------------------------- 1 | class Tmux < Package 2 | url 'https://github.com/tmux/tmux/releases/download/3.3a/tmux-3.3a.tar.gz' 3 | sha256 'e4fd347843bd0772c4f48d6dde625b0b109b7a380ff15db21e97c11a4dcdf93f' 4 | 5 | label :common 6 | 7 | depends_on :libevent 8 | depends_on :ncurses 9 | depends_on :utf8proc 10 | 11 | def install 12 | args = %W[ 13 | --prefix=#{prefix} 14 | --disable-dependency-tracking 15 | --enable-utf8proc 16 | CPPFLAGS='-I#{Utf8proc.link_inc}' 17 | LDFLAGS='-L#{Utf8proc.link_lib} -lresolv' 18 | ] 19 | run './configure', *args 20 | run 'make', 'install' 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /packages/bufrlib.rb: -------------------------------------------------------------------------------- 1 | class Bufrlib < Package 2 | url 'https://www.emc.ncep.noaa.gov/BUFRLIB/docs/BUFRLIB_v11-3-0.tar' 3 | sha256 '122bc2accfca5a572eaf26e2267d1d40efe1d8d60907a1b99c921f875757e94a' 4 | version '11.3.0' 5 | 6 | def install 7 | flags = CompilerSet.fortran.gcc? ? '-fno-second-underscore -fallow-argument-mismatch' : '' 8 | run '$CC -DUNDERSCORE -c `./getdefflags_C.sh` *.c' 9 | run '$FC -c `./getdefflags_F.sh` modv*.F moda*.F `ls -1 *.F *.f | grep -v "mod[av]_"`', flags 10 | run 'ar crv libbufr.a *.o' 11 | mkdir inc 12 | mkdir lib 13 | mv '*.h', inc 14 | mv 'libbufr.a', lib 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /packages/pmix.rb: -------------------------------------------------------------------------------- 1 | class Pmix < Package 2 | url 'https://github.com/openpmix/openpmix/releases/download/v5.0.2/pmix-5.0.2.tar.bz2' 3 | sha256 '28227ff2ba925da2c3fece44502f23a91446017de0f5a58f5cea9370c514b83c' 4 | 5 | label :common 6 | 7 | depends_on :munge 8 | depends_on :libevent 9 | 10 | def install 11 | args = %W[ 12 | --prefix=#{prefix} 13 | --disable-man-pages 14 | --with-libevent=#{Libevent.link_root} 15 | ] 16 | args << "--with-munge=#{Munge.link_root}" unless Munge.skipped? 17 | run './configure', *args 18 | run 'make', "-j#{jobs_number}" 19 | run 'make', 'install' 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /packages/libgeotiff.rb: -------------------------------------------------------------------------------- 1 | class Libgeotiff < Package 2 | url 'https://github.com/OSGeo/libgeotiff/releases/download/1.5.1/libgeotiff-1.5.1.tar.gz' 3 | sha256 'f9e99733c170d11052f562bcd2c7cb4de53ed405f7acdde4f16195cd3ead612c' 4 | 5 | depends_on 'jpeg' 6 | depends_on 'libtiff' 7 | depends_on 'proj' 8 | 9 | def install 10 | args = %W[ 11 | --prefix=#{prefix} 12 | --disable-dependency-tracking 13 | --with-jpeg=#{Jpeg.link_root} 14 | --with-libtiff=#{Libtiff.link_root} 15 | --with-proj=#{Proj.link_root} 16 | ] 17 | run './configure', *args 18 | run 'make' 19 | run 'make', 'install' 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /framework/utils/load_package.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def load_package package 3 | return if package.has_label? :alone and CommandParser.command != :install 4 | append_path package.bin if Dir.exist? package.bin 5 | append_ld_library_path package.lib if Dir.exist? package.lib 6 | append_ld_library_path package.lib64 if Dir.exist? package.lib64 7 | append_pkg_config_path package.lib + '/pkgconfig' if Dir.exist? package.lib + '/pkgconfig' 8 | append_pkg_config_path package.lib64 + '/pkgconfig' if Dir.exist? package.lib64 + '/pkgconfig' 9 | append_manpath package.man if Dir.exist? package.man 10 | package.export_env 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /packages/cmake.rb: -------------------------------------------------------------------------------- 1 | class Cmake < Package 2 | url 'https://github.com/Kitware/CMake/releases/download/v3.24.2/cmake-3.24.2.tar.gz' 3 | sha256 '0d9020f06f3ddf17fb537dc228e1a56c927ee506b486f55fe2dc19f69bf0c8db' 4 | 5 | label :common 6 | label :skip_if_exist, version: lambda { `cmake --version`.match(/(\d+\.\d+\.\d+(\.\d+)?)/)[1] rescue nil }, condition: '>= 3.20' 7 | 8 | def install 9 | CLI.error 'Use Clang compilers to build CMake!' if OS.mac? and CompilerSet.c.gcc? 10 | run './bootstrap', "--prefix=#{prefix}", '--', '-DCMAKE_BUILD_TYPE=Release', '-DCMAKE_USE_OPENSSL=OFF' 11 | run 'make' 12 | run 'make', 'install' 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /framework/utils/set_compile_flags.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def set_compile_flags package, level = 0 3 | if level == 0 4 | ENV['CPPFLAGS'] = '' 5 | ENV['FCFLAGS'] = '' 6 | ENV['LDFLAGS'] = '' 7 | end 8 | if package 9 | package.dependencies.each_key do |depend_name| 10 | depend_package = PackageLoader.loaded_packages[depend_name] 11 | next if depend_package.skipped? 12 | flag = " -Wl,-rpath,#{depend_package.link_lib}" 13 | ENV['LDFLAGS'] += flag if depend_package.link_lib and not ENV['LDFLAGS'].include? flag 14 | set_compile_flags depend_package, level + 1 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /packages/csv-fortran.rb: -------------------------------------------------------------------------------- 1 | class CsvFortran < Package 2 | url 'https://github.com/jacobwilliams/fortran-csv-module/archive/refs/tags/1.3.1.zip' 3 | sha256 '3b379adb7fe52a6680302f4a91ca328ae6260bb4590c1da54afe6983cda452f9' 4 | file_name 'csv-fortran-1.3.1.zip' 5 | 6 | depends_on :cmake 7 | 8 | def install 9 | args = std_cmake_args 10 | 11 | mkdir 'build' do 12 | run 'cmake', '..', *args 13 | run 'make' 14 | run 'make', 'install' 15 | end 16 | 17 | # Remove or rename directories. 18 | work_in prefix do 19 | rm 'bin' 20 | rm 'files' 21 | rm 'doc' 22 | mv 'finclude', 'include' 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /packages/lapack.rb: -------------------------------------------------------------------------------- 1 | class Lapack < Package 2 | url 'https://www.netlib.org/lapack/lapack-3.8.0.tar.gz' 3 | sha256 'deb22cc4a6120bff72621155a9917f485f96ef8319ac074a7afbc68aab88bcf6' 4 | 5 | depends_on :cmake 6 | 7 | def install 8 | inreplace 'SRC/dsytrf_aa_2stage.f', 'DLACGV, ', '' 9 | inreplace 'SRC/ssytrf_aa_2stage.f', 'SLACGV, ', '' 10 | 11 | mkdir 'build' do 12 | run 'cmake', '..', 13 | '-DBUILD_SHARED_LIBS:BOOL=ON', 14 | '-DLAPACKE:BOOL=ON', 15 | *std_cmake_args 16 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 17 | run 'make', 'install' 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /packages/libgd.rb: -------------------------------------------------------------------------------- 1 | class Libgd < Package 2 | url 'https://github.com/libgd/libgd/releases/download/gd-2.3.3/libgd-2.3.3.tar.xz' 3 | sha256 '3fe822ece20796060af63b7c60acb151e5844204d289da0ce08f8fdf131e5a61' 4 | 5 | depends_on :zlib 6 | depends_on :libpng 7 | depends_on :jpeg 8 | depends_on :libtiff 9 | 10 | def install 11 | args = %W[ 12 | --prefix=#{prefix} 13 | --with-zlib=#{Zlib.link_root} 14 | --with-png=#{Libpng.link_root} 15 | --with-jpeg=#{Jpeg.link_root} 16 | --with-tiff=#{Libtiff.link_root} 17 | --with-x 18 | ] 19 | run './configure', *args 20 | run 'make' 21 | run 'make', 'install' 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /packages/mongoc.rb: -------------------------------------------------------------------------------- 1 | class Mongoc < Package 2 | url 'https://github.com/mongodb/mongo-c-driver/releases/download/1.17.5/mongo-c-driver-1.17.5.tar.gz' 3 | sha256 '4b15b7e73a8b0621493e4368dc2de8a74af381823ae8f391da3d75d227ba16be' 4 | 5 | label :common 6 | 7 | depends_on :cmake 8 | 9 | def install 10 | run 'cmake', '.', *std_cmake_args 11 | run 'make', 'install' 12 | if Dir.exist? lib64 13 | ['libbson-1.0.pc', 'libbson-static-1.0.pc', 'libmongoc-1.0.pc', 'libmongoc-static-1.0.pc'].each do |pc| 14 | inreplace lib64 + '/pkgconfig/' + pc, { 15 | '${prefix}/lib' => '${prefix}/lib64' 16 | } 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /packages/ofed.rb: -------------------------------------------------------------------------------- 1 | class Ofed < Package 2 | url 'http://www.mellanox.com/downloads/ofed/MLNX_OFED-4.4-2.0.7.0/MLNX_OFED_SRC-4.4-2.0.7.0.tgz' 3 | sha256 '206ea006aac540f9704b2e4153769046c6a69e8984ca68e8debf1ddccb6ccc7a' 4 | 5 | label :wild 6 | 7 | option 'mode', 'Install mode.', type: :string, choices: ['all', 'hpc', 'basic'], default: 'hpc' 8 | 9 | def install 10 | CLI.error 'OFED is only supported in CentOS now!' if not OS.centos? 11 | CLI.error "Invalid mode #{CLI.red mode}!" unless ['all', 'basic', 'hpc'].include? mode 12 | run './install.pl', "--#{mode}", '--enable-opensm' 13 | CLI.warning 'OFED RPMs are installed in /usr and /opt.' 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /packages/g2clib.rb: -------------------------------------------------------------------------------- 1 | class G2clib < Package 2 | url 'http://www.nco.ncep.noaa.gov/pmb/codes/GRIB2/g2clib-1.6.0.tar' 3 | sha256 'afec1ea29979b84369d0f46f305ed12f73f1450ec2db737664ec7f75c1163add' 4 | 5 | depends_on :jasper 6 | depends_on :libpng 7 | depends_on :zlib 8 | 9 | def install 10 | inreplace 'makefile', { 11 | 'INC=-I/nwprod/lib/include/' => "INC=-I#{link_inc} -I#{Libpng.inc}", 12 | 'CC=gcc' => "CC=#{CompilerSet.c.command}", 13 | '-D__64BIT__' => '' 14 | } 15 | run 'make' 16 | mkdir inc 17 | cp 'grib2.h', inc 18 | mkdir lib 19 | cp 'libg2c_v1.6.0.a', lib 20 | cp 'libg2c_v1.6.0.a', lib + '/libgrib2c.a' 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /packages/json-fortran.rb: -------------------------------------------------------------------------------- 1 | class JsonFortran < Package 2 | url 'https://github.com/jacobwilliams/json-fortran/archive/refs/tags/8.2.5.tar.gz' 3 | sha256 '16eec827f64340c226ba9a8463f001901d469bc400a1e88b849f258f9ef0d100' 4 | file_name 'json-fortran-8.2.5.tar.gz' 5 | 6 | depends_on :cmake 7 | 8 | option 'disable-unicode', 'Disable Unicode support so that CK=1' 9 | 10 | def install 11 | mkdir 'build' do 12 | args = %W[ 13 | -DUSE_GNU_INSTALL_CONVENTION:BOOL=TRUE 14 | -DENABLE_UNICODE:BOOL=#{disable_unicode? ? 'FALSE' : 'TRUE'} 15 | ] 16 | run 'cmake', '..', *std_cmake_args, *args 17 | run 'make', 'install' 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /packages/petsc.rb: -------------------------------------------------------------------------------- 1 | class Petsc < Package 2 | url 'https://web.cels.anl.gov/projects/petsc/download/release-snapshots/petsc-3.20.2.tar.gz' 3 | sha256 '2a2d08b5f0e3d0198dae2c42ce1fd036f25c153ef2bb4a2d320ca141ac7cd30b' 4 | 5 | depends_on :mpi 6 | depends_on :hdf5 7 | depends_on :netcdf 8 | depends_on :metis 9 | depends_on :openblas 10 | depends_on :scalapack 11 | depends_on 'suite-sparse' 12 | 13 | def install 14 | ENV.delete 'PETSC_DIR' 15 | args = %W[ 16 | --prefix=#{prefix} 17 | --with-debugging=0 18 | --with-scalar-type=real 19 | --with-x=0 20 | ] 21 | run './configure', *args 22 | run 'make', 'all' 23 | run 'make', 'install' 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /packages/grads.rb: -------------------------------------------------------------------------------- 1 | class Grads < Package 2 | url 'http://cola.gmu.edu/grads/2.2/grads-2.2.1-src.tar.gz' 3 | sha256 '695e2066d7d131720d598bac0beb61ac3ae5578240a5437401dc0ffbbe516206' 4 | version '2.2.1' 5 | 6 | label :common 7 | 8 | depends_on :hdf5 9 | depends_on :netcdf 10 | depends_on :udunits 11 | depends_on :libgeotiff 12 | depends_on :libgd 13 | 14 | def install 15 | args = %W[ 16 | --prefix=#{prefix} 17 | --with-hdf5=#{Hdf5.link_root} 18 | --with-netcdf=#{Netcdf.link_root} 19 | --with-udunits=#{Udunits.link_root} 20 | --with-geotiff=#{Libgeotiff.link_root} 21 | ] 22 | run './configure', *args 23 | run 'make' 24 | run 'make', 'install' 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /packages/libpng.rb: -------------------------------------------------------------------------------- 1 | class Libpng < Package 2 | url 'https://downloads.sourceforge.net/libpng/libpng-1.6.35.tar.xz' 3 | sha256 '23912ec8c9584917ed9b09c5023465d71709dce089be503c7867fec68a93bcd7' 4 | 5 | if OS.mac? 6 | label :alone 7 | elsif OS.linux? 8 | label :skip_if_exist, library_file: 'libpng.so' 9 | end 10 | 11 | depends_on :zlib 12 | 13 | def install 14 | args = %W[ 15 | --prefix=#{prefix} 16 | --disable-dependency-tracking 17 | --disable-silent-rules 18 | CPPFLAGS='-I#{Zlib.link_inc}' 19 | LDFLAGS='-L#{Zlib.link_lib}' 20 | ] 21 | run './configure', *args 22 | run 'make' 23 | run 'make', 'test' unless skip_test? 24 | run 'make', 'install' 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /packages/jasper@2.0.4.rb: -------------------------------------------------------------------------------- 1 | class Jasper < Package 2 | url 'https://codeload.github.com/mdadams/jasper/tar.gz/version-2.0.14' 3 | sha256 '85266eea728f8b14365db9eaf1edc7be4c348704e562bb05095b9a077cf1a97b' 4 | file_name 'jasper-2.0.14.tar.gz' 5 | 6 | depends_on :cmake 7 | depends_on :jpeg 8 | 9 | option 'disable-opengl', 'Disable OpenGL dependencies.' 10 | 11 | def install 12 | args = std_cmake_args 13 | args << '-DJAS_ENABLE_OPENGL=Off' if disable_opengl? 14 | args << '-DJAS_ENABLE_DOC=Off' 15 | mkdir 'build' do 16 | run 'cmake', '..', *args 17 | run 'make' 18 | # FIXME: Some tests need openjpeg. 19 | #run 'make', 'test' unless skip_test? 20 | run 'make', 'install' 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /packages/libuuid.rb: -------------------------------------------------------------------------------- 1 | class Libuuid < Package 2 | url 'https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.34/util-linux-2.34.tar.gz' 3 | sha256 'b62c92e5e1629642113cd41cec1ee86d1ee7e36b8ffe8ec3ac89c11797e9ac25' 4 | 5 | def install 6 | args = %W[ 7 | --prefix=#{prefix} 8 | --disable-dependency-tracking 9 | --enable-silent-rules 10 | --disable-all-programs 11 | --enable-libuuid 12 | ] 13 | run './configure', *args 14 | inreplace 'Makefile', { 15 | 'am__append_439 = bash-completion/uuidgen' => '#am__append_439 = bash-completion/uuidgen' 16 | } 17 | run 'make' 18 | run 'make', 'check' unless skip_test? 19 | run 'make', 'install' 20 | rm bin 21 | rm sbin 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /framework/os/os_dsl.rb: -------------------------------------------------------------------------------- 1 | module OsDSL 2 | def self.included base 3 | base.extend self 4 | end 5 | 6 | def spec 7 | return self.class_variable_get "@@#{self}_spec" if self.class_variable_defined? "@@#{self}_spec" 8 | self.class_variable_set "@@#{self}_spec", OsSpec.new 9 | end 10 | 11 | def type val = nil 12 | if val != nil 13 | spec.type = val.to_sym 14 | else 15 | @@os.type 16 | end 17 | end 18 | 19 | def version &block 20 | if block_given? 21 | spec.version = block 22 | else 23 | @@os.version 24 | end 25 | end 26 | 27 | def command name, &block 28 | if block_given? 29 | spec.commands[name.to_sym] = block 30 | else 31 | @@os.commands[name.to_sym] 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /framework/utils/append_env.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | @@appended_env = {} 3 | 4 | def append_path path 5 | append_env 'PATH', path 6 | end 7 | 8 | def append_ld_library_path path 9 | append_env OS.ld_library_path, path 10 | end 11 | 12 | def append_pkg_config_path path 13 | append_env 'PKG_CONFIG_PATH', path 14 | end 15 | 16 | def append_manpath path 17 | append_env 'MANPATH', path 18 | end 19 | 20 | def append_env key, val, sep=':' 21 | @@appended_env[key] = ENV[key] if not @@appended_env.has_key? key 22 | @@appended_env[key] = "#{val}#{sep}#{@@appended_env[key].gsub(val, '') if @@appended_env[key]}".gsub('::', ':') 23 | ENV[key] = @@appended_env[key] 24 | end 25 | 26 | def appended_env 27 | @@appended_env rescue {} 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /packages/netcdf-cxx.rb: -------------------------------------------------------------------------------- 1 | class NetcdfCxx < Package 2 | url 'https://www.unidata.ucar.edu/downloads/netcdf/ftp/netcdf-cxx-4.2.tar.gz' 3 | sha256 '95ed6ab49a0ee001255eac4e44aacb5ca4ea96ba850c08337a3e4c9a0872ccd1' 4 | 5 | grouped_by :netcdf 6 | 7 | depends_on 'netcdf-c' 8 | 9 | def install 10 | return false if CompilerSet.cxx.pgi? and OS.mac? 11 | ENV['CPPFLAGS'] += " -I#{link_inc}" 12 | ENV['LDFLAGS'] += " -L#{link_lib}" 13 | args = %W[ 14 | --prefix=#{prefix} 15 | --disable-dependency-tracking 16 | --disable-dap-remote-tests 17 | --enable-static 18 | --enable-shared 19 | ] 20 | run './configure', *args 21 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 22 | run 'make', 'check' unless skip_test? 23 | run 'make', 'install' 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /packages/hdf-eos2@2.19.rb: -------------------------------------------------------------------------------- 1 | class HdfEos2 < Package 2 | url 'https://observer.gsfc.nasa.gov/ftp/edhs/hdfeos/previous_releases/HDF-EOS2.19v1.00.tar.Z' 3 | sha256 '3fffa081466e85d2b9436d984bc44fe97bbb33ad9d8b7055a322095dc4672e31' 4 | version '2.19' 5 | 6 | depends_on :hdf4 7 | depends_on :jpeg 8 | depends_on :szip 9 | depends_on :zlib 10 | 11 | def install 12 | args = %W[ 13 | --prefix=#{prefix} 14 | --with-hdf4=#{link_root} 15 | --with-zlib=#{link_root} 16 | --with-szlib=#{link_root} 17 | CC='#{link_bin}/h4cc -Df2cFortran' 18 | ] 19 | args << "--with-jpeg=#{OS.mac? ? Jpeg.prefix : link_root}" 20 | run './configure', *args 21 | run 'make' 22 | run 'make', 'install' 23 | work_in 'include' do 24 | run 'make', 'install' 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /packages/fftw.rb: -------------------------------------------------------------------------------- 1 | class Fftw < Package 2 | url 'http://www.fftw.org/fftw-3.3.8.tar.gz' 3 | sha256 '6113262f6e92c5bd474f2875fa1b01054c4ad5040f6b0da7c03c98821d9ae303' 4 | 5 | option 'with-openmp', 'Use OpenMP compiler directives in order to induce parallelism.' 6 | option 'with-mpi', 'Enable compilation and installation of the FFTW MPI library.' 7 | 8 | depends_on :mpi if with_mpi? 9 | 10 | def install 11 | args = %W[ 12 | --prefix=#{prefix} 13 | --enable-fortran 14 | --enable-shared 15 | --disable-debug 16 | --disable-dependency-tracking 17 | ] 18 | args << '--enable-openmp' if with_openmp? 19 | args << '--enable-mpi' if with_mpi? 20 | run './configure', *args 21 | run 'make' 22 | run 'make', 'check' unless skip_test? 23 | run 'make', 'install' 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /packages/suite-sparse.rb: -------------------------------------------------------------------------------- 1 | class SuiteSparse < Package 2 | url 'https://github.com/DrTimothyAldenDavis/SuiteSparse/archive/refs/tags/v7.1.0.tar.gz' 3 | sha256 '4cd3d161f9aa4f98ec5fa725ee5dc27bca960a3714a707a7d12b3d0abb504679' 4 | file_name 'SuiteSparse-7.1.0.tar.gz' 5 | 6 | depends_on :cmake 7 | depends_on :metis 8 | depends_on :openblas 9 | depends_on :mpfr 10 | 11 | def install 12 | args = %W[ 13 | INSTALL=#{prefix} 14 | BLAS='-L#{Openblas.lib} -lopenblas' 15 | LAPACK='-L#{Openblas.lib} -lopenblas' 16 | MY_METIS_LIB='-L#{Metis.lib} -lmetis' 17 | MY_METIS_INC=#{Metis.inc} 18 | CMAKE_OPTIONS='#{std_cmake_args.join(' ')} -DMPFR_ROOT=#{Mpfr.prefix}' 19 | JOBS=#{jobs_number} 20 | ] 21 | run 'make', 'library', *args 22 | run 'make', 'install', *args 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /packages/gettext.rb: -------------------------------------------------------------------------------- 1 | class Gettext < Package 2 | url 'https://ftp.gnu.org/gnu/gettext/gettext-0.19.8.1.tar.xz' 3 | sha256 '105556dbc5c3fbbc2aa0edb46d22d055748b6f5c7cd7a8d99f8e7eb84e938be4' 4 | 5 | label :common 6 | label :skip_if_exist, library_file: 'libgettextpo.so.0' if OS.linux? 7 | 8 | depends_on :libxml2 9 | 10 | def install 11 | args = %W[ 12 | --disable-dependency-tracking 13 | --disable-silent-rules 14 | --disable-debug 15 | --prefix=#{prefix} 16 | --with-included-gettext 17 | --with-included-glib 18 | --with-included-libcroco 19 | --with-included-libunistring 20 | --disable-java 21 | --disable-csharp 22 | --without-git 23 | --without-cvs 24 | --without-xz 25 | ] 26 | run './configure', *args 27 | run 'make' 28 | run 'make', 'install' 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /packages/netcdf-cxx4.rb: -------------------------------------------------------------------------------- 1 | class NetcdfCxx4 < Package 2 | url 'https://github.com/Unidata/netcdf-cxx4/archive/v4.3.1.tar.gz' 3 | sha256 'e3fe3d2ec06c1c2772555bf1208d220aab5fee186d04bd265219b0bc7a978edc' 4 | version '4.3.1' 5 | file_name 'netcdf-cxx4-4.3.1.tar.gz' 6 | 7 | grouped_by :netcdf 8 | 9 | depends_on 'netcdf-c' 10 | 11 | def install 12 | return false if CompilerSet.cxx.pgi? and OS.mac? 13 | ENV['CPPFLAGS'] += " -I#{link_inc}" 14 | ENV['LDFLAGS'] += " -L#{link_lib}" 15 | args = %W[ 16 | --prefix=#{prefix} 17 | --disable-dependency-tracking 18 | --disable-dap-remote-tests 19 | --enable-static 20 | --enable-shared 21 | ] 22 | run './configure', *args 23 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 24 | run 'make', 'check' unless skip_test? 25 | run 'make', 'install' 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /packages/ncurses.rb: -------------------------------------------------------------------------------- 1 | class Ncurses < Package 2 | url 'https://ftp.gnu.org/gnu/ncurses/ncurses-6.1.tar.gz' 3 | mirror 'https://ftpmirror.gnu.org/ncurses/ncurses-6.1.tar.gz' 4 | sha256 'aa057eeeb4a14d470101eff4597d5833dcef5965331be3528c08d99cebaa0d17' 5 | 6 | label :common 7 | label :alone 8 | label :skip_if_exist, library_file: "libncursesw.#{OS.soname}.6" 9 | 10 | def install 11 | args = %W[ 12 | --prefix=#{prefix} 13 | --enable-pc-files 14 | --with-pkg-config-libdir=#{lib}/pkgconfig 15 | --enable-sigwinch 16 | --enable-symlinks 17 | --enable-widec 18 | --with-shared 19 | --with-gpm=no 20 | ] 21 | run './configure', *args 22 | run 'make', 'install' 23 | # Why there is no libncurses.so file? 24 | run 'ln -s', lib + '/libncursesw.' + OS.soname, lib + '/libncurses.' + OS.soname 25 | end 26 | end 27 | 28 | -------------------------------------------------------------------------------- /packages/gptl.rb: -------------------------------------------------------------------------------- 1 | class Gptl < Package 2 | url 'https://github.com/jmrosinski/GPTL/releases/download/v8.1.1/gptl-8.1.1.tar.gz' 3 | sha256 'b8ee26f7aeedd2a31d565789634e7c380023fe6b65bbf59030884f4dcbce94a5' 4 | 5 | depends_on :mpi 6 | depends_on :papi unless OS.mac? 7 | 8 | def install 9 | ENV['CC'] = ENV['MPICC'] 10 | ENV['FC'] = ENV['MPIFC'] 11 | if CompilerSet.c.intel? 12 | ENV['CFLAGS'] = '-std=gnu99' 13 | end 14 | args = %W[ 15 | --prefix=#{prefix} 16 | --enable-pmpi 17 | ] 18 | if not OS.mac? 19 | args << '--enable-papi' 20 | ENV['CPPFLAGS'] = "-I#{Papi.inc}" 21 | ENV['LDFLAGS'] = "-L#{Papi.lib}" 22 | end 23 | args << '--disable-shared' if CompilerSet.c.intel? 24 | run './configure', *args 25 | run 'make' 26 | run 'make', 'check' unless skip_test? 27 | run 'make', 'install' 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /packages/cmor.rb: -------------------------------------------------------------------------------- 1 | class Cmor < Package 2 | url 'https://github.com/PCMDI/cmor/archive/3.6.1.tar.gz' 3 | sha256 '991035a41424f72ea6f0f85653fc13730eb035e63c7dff6ca740aa7a70976fb4' 4 | file_name 'cmor-3.6.1.tar.gz' 5 | 6 | option 'with-python3', 'Enable support for Python3.' 7 | 8 | depends_on 'json-c' 9 | depends_on :netcdf 10 | depends_on :udunits 11 | depends_on :libuuid 12 | 13 | def install 14 | args = %W[ 15 | --prefix=#{prefix} 16 | --disable-shared 17 | --with-json-c=#{JsonC.link_root} 18 | --with-netcdf=#{Netcdf.link_root} 19 | --with-udunits2=#{Udunits.link_root} 20 | --with-uuid=#{Libuuid.link_root} 21 | ] 22 | args << "--with-python=#{`python3-config --prefix`}" if with_python3? 23 | run './configure', *args 24 | run 'make' 25 | run 'make', 'test' unless skip_test? 26 | run 'make', 'install' 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /packages/hdf4.rb: -------------------------------------------------------------------------------- 1 | class Hdf4 < Package 2 | url 'https://support.hdfgroup.org/ftp/HDF/HDF_Current/src/hdf-4.2.13.tar.bz2' 3 | sha256 '55d3a42313bda0aba7b0463687caf819a970e0ba206f5ed2c23724f80d2ae0f3' 4 | 5 | depends_on :yacc 6 | depends_on :flex 7 | depends_on :jpeg 8 | depends_on :szip 9 | depends_on :zlib 10 | 11 | def install 12 | args = %W[ 13 | --prefix=#{prefix} 14 | --with-zlib=#{link_root} 15 | --with-szlib=#{link_root} 16 | --disable-netcdf 17 | --enable-fortran 18 | --enable-static 19 | ] 20 | args << "--with-jpeg=#{OS.mac? ? Jpeg.prefix : link_root}" 21 | args << '--disable-fortran' unless CompilerSet.fortran 22 | run './configure', *args 23 | run 'make', 'install' 24 | end 25 | 26 | def post_install 27 | mv bin + '/ncdump', bin + '/ncdump_hdf4' 28 | mv bin + '/ncgen', bin + '/ncgen_hdf4' 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /packages/mpich.rb: -------------------------------------------------------------------------------- 1 | class Mpich < Package 2 | url 'https://www.mpich.org/static/downloads/3.2.1/mpich-3.2.1.tar.gz' 3 | sha256 '5db53bf2edfaa2238eb6a0a5bc3d2c2ccbfbb1badd79b664a1a919d2ce2330f1' 4 | 5 | label :mpi 6 | 7 | conflicts_with :openmpi, :mvapich2 8 | 9 | option 'enable-fast', 'Get fastest performance at the expense of error reporting and other program development aids.' 10 | 11 | def export_env 12 | ENV['MPICC'] = "#{bin}/mpicc" 13 | ENV['MPICXX'] = "#{bin}/mpic++" 14 | ENV['MPIFC'] = "#{bin}/mpifort" 15 | end 16 | 17 | def install 18 | args = %W[ 19 | --prefix=#{prefix} 20 | --disable-dependency-tracking 21 | --disable-silent-rules 22 | ] 23 | args << '--enable-fast=all,O3' if enable_fast? 24 | run './configure', *args 25 | run 'make' 26 | run 'make', 'check' unless skip_test? 27 | run 'make', 'install' 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /packages/gdbm.rb: -------------------------------------------------------------------------------- 1 | class Gdbm < Package 2 | url 'https://ftp.gnu.org/gnu/gdbm/gdbm-1.18.1.tar.gz' 3 | mirror 'https://ftpmirror.gnu.org/gdbm/gdbm-1.18.1.tar.gz' 4 | sha256 '86e613527e5dba544e73208f42b78b7c022d4fa5a6d5498bf18c8d6f745b91dc' 5 | 6 | label :common 7 | 8 | option 'with-libgdbm-compat', 'Build libgdbm_compat, a compatibility layer which provides UNIX-like dbm and ndbm interfaces.' 9 | 10 | def install 11 | args = %W[ 12 | --disable-dependency-tracking 13 | --disable-silent-rules 14 | --prefix=#{prefix} 15 | ] 16 | # Use --without-readline because readline detection is broken in 1.13 17 | # https://github.com/Homebrew/homebrew-core/pull/10903 18 | args << '--without-readline' if OS.mac? 19 | 20 | args << '--enable-libgdbm-compat' if with_libgdbm_compat? 21 | 22 | run './configure', *args 23 | run 'make', 'install' 24 | end 25 | end 26 | 27 | -------------------------------------------------------------------------------- /packages/jasper.rb: -------------------------------------------------------------------------------- 1 | class Jasper < Package 2 | url 'http://www.ece.uvic.ca/~mdadams/jasper/software/jasper-1.900.1.zip' 3 | sha256 '6b905a9c2aca2e275544212666eefc4eb44d95d0a57e4305457b407fe63f9494' 4 | 5 | depends_on :jpeg 6 | 7 | def install 8 | inreplace 'src/libjasper/jpc/jpc_qmfb.c', { 9 | 'int jpc_ft_synthesize(int *a' => 'int jpc_ft_synthesize(jpc_fix_t *a' 10 | } 11 | inreplace 'src/libjasper/jpc/jpc_qmfb.h', { 12 | 'int (*analyze)(int *' => 'int (*analyze)(long *', 13 | 'int (*synthesize)(int *' => 'int (*synthesize)(long *' 14 | } 15 | args = %W[ 16 | --disable-debug 17 | --disable-dependency-tracking 18 | --enable-shared 19 | --prefix=#{prefix} 20 | CFLAGS='-std=c90' 21 | CPPFLAGS='-I#{Jpeg.inc}' 22 | LDFLAGS='-L#{Jpeg.lib}' 23 | ] 24 | run './configure', *args 25 | run 'make', 'install' 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /packages/pcre2.rb: -------------------------------------------------------------------------------- 1 | class Pcre2 < Package 2 | url 'https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.40/pcre2-10.40.tar.bz2' 3 | sha256 '14e4b83c4783933dc17e964318e6324f7cae1bc75d8f3c79bc6969f00c159d68' 4 | 5 | depends_on :zlib 6 | depends_on :bzip2 7 | 8 | def install 9 | args = %W[ 10 | --disable-dependency-tracking 11 | --prefix=#{prefix} 12 | --enable-pcre2-16 13 | --enable-pcre2-32 14 | --enable-pcre2grep-libz 15 | --enable-pcre2grep-libbz2 16 | --enable-jit 17 | ] 18 | append_env 'CPPFLAGS', "-I#{Zlib.link_inc}", sep=' ' 19 | append_env 'LDFLAGS', "-L#{Zlib.link_lib}", sep=' ' 20 | unless Bzip2.skipped? 21 | append_env 'CPPFLAGS', "-I#{Bzip2.link_inc}", sep=' ' 22 | append_env 'LDFLAGS', "-L#{Bzip2.link_lib}", sep=' ' 23 | end 24 | run './configure', *args 25 | run 'make' 26 | run 'make', 'install' 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /packages/webp.rb: -------------------------------------------------------------------------------- 1 | class Webp < Package 2 | url 'https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.3.tar.gz' 3 | sha256 'e20a07865c8697bba00aebccc6f54912d6bc333bb4d604e6b07491c1a226b34f' 4 | 5 | depends_on 'jpeg' 6 | depends_on 'libpng' 7 | depends_on 'libtiff' 8 | 9 | def install 10 | args = %W[ 11 | --prefix=#{prefix} 12 | --disable-dependency-tracking 13 | --disable-gif 14 | --disable-gl 15 | --enable-libwebpdecoder 16 | --enable-libwebpdemux 17 | --enable-libwebpmux 18 | --with-pngincludedir=#{Libpng.link_inc} 19 | --with-pnglibdir=#{Libpng.link_lib} 20 | --with-jpegincludedir=#{Jpeg.link_inc} 21 | --with-jpeglibdir=#{Jpeg.link_lib} 22 | --with-tiffincludedir=#{Libtiff.link_inc} 23 | --with-tifflibdir=#{Libtiff.link_lib} 24 | ] 25 | run './configure', *args 26 | run 'make', 'install' 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /packages/libffi.rb: -------------------------------------------------------------------------------- 1 | # NOTE: If libffi is updated, python3 should be reinstalled too! 2 | 3 | class Libffi < Package 4 | url 'https://github.com/libffi/libffi/releases/download/v3.4.2/libffi-3.4.2.tar.gz' 5 | sha256 '540fb721619a6aba3bdeef7d940d8e9e0e6d2c193595bc243241b77ff9e93620' 6 | 7 | label :common 8 | label :skip_if_exist, include_file: 'ffi.h' 9 | 10 | def install 11 | args = %W[ 12 | --prefix=#{prefix} 13 | --disable-debug 14 | --disable-dependency-tracking 15 | ] 16 | run './configure', *args 17 | run 'make', 'install' 18 | # Move header files into normal path. 19 | CLI.notice 'Fix bad header location.' 20 | mkdir inc 21 | mv "#{lib}/libffi-#{version}/include/*", inc 22 | inreplace "#{lib}/pkgconfig/libffi.pc", 23 | "includedir=${libdir}/libffi-#{version}/include", 24 | "includedir=${exec_prefix}/include" 25 | rm "#{lib}/libffi-#{version}" 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /packages/nco.rb: -------------------------------------------------------------------------------- 1 | class Nco < Package 2 | url 'https://github.com/nco/nco/archive/5.0.3.tar.gz' 3 | sha256 '61b45cdfbb772718f00d40da1a4ce268201fd00a61ebb9515460b8dda8557bdb' 4 | file_name 'nco-5.0.3.tar.gz' 5 | 6 | label :common 7 | 8 | depends_on :antlr2 9 | depends_on :flex 10 | depends_on :gsl 11 | depends_on :netcdf 12 | depends_on :udunits 13 | 14 | def install 15 | args = %W[ 16 | --prefix=#{prefix} 17 | --enable-netcdf4 18 | --enable-dap 19 | --enable-ncap2 20 | --enable-udunits2 21 | --enable-optimize-custom 22 | --disable-doc 23 | NETCDF_INC=#{Netcdf.link_inc} 24 | NETCDF_LIB=#{Netcdf.link_lib} 25 | NETCDF4_ROOT=#{Netcdf.link_root} 26 | NETCDF_ROOT=#{Netcdf.link_root} 27 | UDUNITS2_PATH=#{Udunits.link_root} 28 | ANTLR_ROOT=#{Antlr2.link_root} 29 | ] 30 | run './configure', *args 31 | run 'make' 32 | run 'make', 'check' if not skip_test? 33 | run 'make', 'install' 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /packages/hdf-eos2.rb: -------------------------------------------------------------------------------- 1 | class HdfEos2 < Package 2 | url 'https://git.earthdata.nasa.gov/rest/git-lfs/storage/DAS/hdfeos/cb0f900d2732ab01e51284d6c9e90d0e852d61bba9bce3b43af0430ab5414903?response-content-disposition=attachment%3B%20filename%3D%22HDF-EOS2.20v1.00.tar.Z%22%3B%20filename*%3Dutf-8%27%27HDF-EOS2.20v1.00.tar.Z' 3 | sha256 'cb0f900d2732ab01e51284d6c9e90d0e852d61bba9bce3b43af0430ab5414903' 4 | version '2.20' 5 | file_name 'HDF-EOS2.20v1.00.tar.Z' 6 | 7 | depends_on :hdf4 8 | depends_on :jpeg 9 | depends_on :szip 10 | depends_on :zlib 11 | 12 | def install 13 | args = %W[ 14 | --prefix=#{prefix} 15 | --with-hdf4=#{link_root} 16 | --with-zlib=#{link_root} 17 | --with-szlib=#{link_root} 18 | CC='#{link_bin}/h4cc -Df2cFortran' 19 | ] 20 | args << "--with-jpeg=#{OS.mac? ? Jpeg.prefix : link_root}" 21 | run './configure', *args 22 | run 'make' 23 | run 'make', 'install' 24 | work_in 'include' do 25 | run 'make', 'install' 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /framework/utils/decompress.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def decompress path, options = {} 3 | args = [] 4 | case path 5 | when /\.tar.Z$/i 6 | args << "--strip-components #{options[:strip_leading_dirs]}" if options[:strip_leading_dirs] 7 | system "tar xzf #{path} #{args.join(' ')}" 8 | when /\.(tar(\..*)?|tgz|tbz2)$/i 9 | args << "--strip-components #{options[:strip_leading_dirs]}" if options[:strip_leading_dirs] 10 | system "tar xf #{path} #{args.join(' ')}" 11 | when /\.(gz)$/i 12 | system "gzip -d #{path}" 13 | when /\.(bz2)$/i 14 | system "bzip2 -d #{path}" 15 | when /\.(zip)$/i 16 | CLI.error 'No unzip is installed by system! Please install one by apt-get or yum according to your OS.' if not system_command? 'unzip' 17 | system "unzip -o #{path} 1> /dev/null" 18 | if options[:strip_leading_dirs] 19 | system 'mv ./*/* .' 20 | end 21 | else 22 | CLI.error "Unknown compression type of #{CLI.red path}!" if options[:exit] 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /packages/scalapack.rb: -------------------------------------------------------------------------------- 1 | class Scalapack < Package 2 | url 'https://netlib.org/scalapack/scalapack-2.2.0.tgz' 3 | sha256 '40b9406c20735a9a3009d863318cb8d3e496fb073d201c5463df810e01ab2a57' 4 | 5 | depends_on :cmake 6 | depends_on :mpi 7 | depends_on :openblas 8 | 9 | def install 10 | inreplace 'CMakeLists.txt', { 11 | 'target_link_libraries( scalapack ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES})' => 12 | 'target_link_libraries( scalapack ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES} ${MPI_Fortran_LIBRARIES})' 13 | } 14 | inreplace 'CMakeLists.txt', 16, <<-EOS 15 | if ("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "GNU") 16 | set( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fallow-argument-mismatch" ) 17 | endif () 18 | EOS 19 | mkdir 'build' do 20 | blas = "'-L#{Openblas.lib} -lopenblas'" 21 | run 'cmake', '..', *std_cmake_args, '-DBUILD_SHARED_LIBS=ON', 22 | "-DBLAS_LIBRARIES=#{blas}", "-DLAPACK_LIBRARIES=#{blas}" 23 | run 'make', 'all' 24 | run 'make', 'install' 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /starman: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV['STARMAN_ROOT'] = File.absolute_path(File.dirname __FILE__) 4 | 5 | require "#{ENV['STARMAN_ROOT']}/framework" 6 | 7 | begin 8 | command_name = ARGV.shift.to_sym 9 | rescue 10 | CLI.error 'No command is provided!' 11 | end 12 | 13 | aliases = { 14 | i: :install, 15 | rm: :uninstall, 16 | c: :config, 17 | e: :edit, 18 | u: :update, 19 | ls: :list 20 | } 21 | 22 | commands = { 23 | setup: SetupCommand, 24 | list: ListCommand, 25 | install: InstallCommand, 26 | uninstall: UninstallCommand, 27 | load: LoadCommand, 28 | debug_load: LoadCommand, 29 | config: ConfigCommand, 30 | edit: EditCommand, 31 | link: LinkCommand, 32 | unlink: UnlinkCommand, 33 | pack: PackCommand, 34 | update: UpdateCommand, 35 | fix: FixCommand 36 | } 37 | 38 | OS.init 39 | Runtime.init 40 | 41 | CLI.error "Unknown command #{CLI.red command_name}!" unless commands.has_key? command_name or aliases.has_key? command_name 42 | command = (commands[command_name] || commands[aliases[command_name]]).new 43 | 44 | command.run 45 | -------------------------------------------------------------------------------- /packages/boost.rb: -------------------------------------------------------------------------------- 1 | class Boost < Package 2 | url 'https://jaist.dl.sourceforge.net/project/boost/boost/1.68.0/boost_1_68_0.tar.bz2' 3 | sha256 '7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7' 4 | version '1.68.0' 5 | 6 | depends_on :icu4c 7 | 8 | def install 9 | append_file 'user-config.jam' do |content| 10 | if OS.mac? 11 | content << "using darwin : : #{ENV['CXX']} ;\n" 12 | elsif OS.linux? 13 | content << "using gcc : : #{ENV['CXX']} ;\n" 14 | end 15 | end 16 | 17 | args = %W[ 18 | --prefix=#{prefix} 19 | --with-icu=#{Icu4c.link_root} 20 | --without-libraries=python,mpi 21 | ] 22 | run './bootstrap.sh', *args 23 | 24 | run './b2', 'headers' 25 | 26 | args = %W[ 27 | --prefix=#{prefix} 28 | -d2 29 | -j#{CommandParser.args[:make_jobs]} 30 | --user-config=user-config.jam 31 | -sNO_LZMA=1 32 | install 33 | threading=multi 34 | link=shared 35 | cxxflags=-std=c++11 36 | ] 37 | run './b2', *args 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /packages/openmpi@4.0.1.rb: -------------------------------------------------------------------------------- 1 | class Openmpi < Package 2 | url 'https://download.open-mpi.org/release/open-mpi/v4.0/openmpi-4.0.1.tar.bz2' 3 | sha256 'cce7b6d20522849301727f81282201d609553103ac0b09162cf28d102efb9709' 4 | 5 | label :mpi 6 | 7 | conflicts_with :mpich, :mvapich2 8 | 9 | option 'with-ucx', 'Use UCX library.' 10 | option 'with-verbs', 'Use VERBS library.' 11 | 12 | def export_env 13 | ENV['MPICC'] = "#{bin}/mpicc" 14 | ENV['MPICXX'] = "#{bin}/mpic++" 15 | ENV['MPIFC'] = "#{bin}/mpifort" 16 | end 17 | 18 | def install 19 | args = %W[ 20 | --prefix=#{prefix} 21 | --disable-dependency-tracking 22 | --disable-silent-rules 23 | --disable-debug 24 | --enable-shared 25 | --with-hwloc=internal 26 | ] 27 | args << '--with-ucx' if with_ucx? 28 | args << '--with-verbs' if with_verbs? 29 | ENV['lt_cv_ld_force_load'] = 'no' if OS.mac? 30 | run './configure', *args 31 | run 'make', 'all', '-j', '8' 32 | run 'make', 'check' if not skip_test? 33 | run 'make', 'install' 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /framework/utils/inreplace.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def inreplace file_paths, before = nil, after = nil, &block 3 | Array(file_paths).each do |file_path| 4 | tmp = File.readlines(file_path) 5 | lines = {} 6 | tmp.each_with_index do |line, idx| 7 | if not line.valid_encoding? 8 | lines[idx+1] = line.encode('UTF-16be', invalid: :replace, replace: '?').encode('UTF-8') 9 | else 10 | lines[idx+1] = line 11 | end 12 | end 13 | content = lines.values.join '' 14 | if block_given? 15 | block.call content 16 | elsif before.class == Hash and not after 17 | before.each do |key, value| 18 | content.gsub! key, value 19 | end 20 | elsif (before.class == String or before.class == Regexp) and after.class == String 21 | content.gsub! before, after 22 | elsif before.class == Fixnum and after.class == String 23 | lines[before] += after + "\n" 24 | content = lines.values.join '' 25 | end 26 | write_file file_path, content 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /packages/cdo.rb: -------------------------------------------------------------------------------- 1 | class Cdo < Package 2 | url 'https://code.mpimet.mpg.de/attachments/download/29019/cdo-2.3.0.tar.gz' 3 | sha256 '10c878227baf718a6917837527d4426c2d0022cfac4457c65155b9c57f091f6b' 4 | 5 | label :common 6 | 7 | depends_on :eccodes 8 | depends_on :hdf5 9 | depends_on :libaec 10 | depends_on :netcdf 11 | depends_on :proj 12 | 13 | def install 14 | ENV['LDFLAGS'] = "-L#{Eccodes.lib64}" 15 | if Hdf5.enable_parallel? 16 | ENV['CC'] = ENV['MPICC'] 17 | ENV['CXX'] = ENV['MPICXX'] 18 | ENV['FC'] = ENV['MPIFC'] 19 | end 20 | args = %W[ 21 | --prefix=#{prefix} 22 | --with-hdf5=#{Hdf5.prefix} 23 | --with-netcdf=#{Netcdf.prefix} 24 | --with-zlib=#{Zlib.prefix} 25 | --with-szlib=#{Szip.prefix} 26 | --with-eccodes=#{Eccodes.prefix} 27 | --with-proj=#{Proj.prefix} 28 | --disable-dependency-tracking 29 | --disable-debug 30 | LIBS='-lz' 31 | ] 32 | run './configure', *args 33 | run 'make' 34 | run 'make', 'check' unless skip_test? 35 | run 'make', 'install' 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /packages/proj.rb: -------------------------------------------------------------------------------- 1 | class Proj < Package 2 | url 'https://github.com/OSGeo/PROJ/releases/download/8.2.0/proj-8.2.0.tar.gz' 3 | sha256 'de93df9a4aa88d09459ead791f2dbc874b897bf67a5bbb3e4b68de7b1bdef13c' 4 | 5 | depends_on :sqlite3 6 | depends_on :libtiff 7 | 8 | def install 9 | if CompilerSet.c.vendor == :gcc and CompilerSet.c.version >= '13' 10 | inreplace 'src/proj_json_streaming_writer.hpp', { 11 | '#include ' => "#include \n#include " 12 | } 13 | inreplace 'src/projections/s2.cpp', { 14 | '#include ' => "#include \n#include " 15 | } 16 | end 17 | args = %W[ 18 | --prefix=#{prefix} 19 | --disable-dependency-tracking 20 | TIFF_CFLAGS='-I#{Libtiff.inc}' 21 | TIFF_LIBS='-L#{Libtiff.lib} -ltiff' 22 | --without-curl 23 | ] 24 | args << "SQLITE3_CFLAGS='-I#{Sqlite3.inc}'" 25 | args << "SQLITE3_LIBS='-L#{Sqlite3.lib} -lsqlite3'" 26 | run './configure', *args 27 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 28 | run 'make', 'install' 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /framework/utils/run.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | def run cmd, *options 3 | cmd_line = "#{cmd} #{options.select { |option| option.class == String }.join(' ')}" 4 | if CommandParser.args[:verbose] or options.include? :verbose 5 | CLI.blue_arrow cmd_line 6 | system cmd_line 7 | else 8 | CLI.blue_arrow cmd_line, :truncate 9 | system "#{cmd_line} 1>#{Settings.cache_root}/stdout.#{Process.pid} 2>#{Settings.cache_root}/stderr.#{Process.pid}" 10 | end 11 | if not $?.success? and not options.include? :allow_failure 12 | CLI.error "Failed to run #{cmd_line}!" + 13 | "#{CommandParser.args[:verbose] || " Check logs:\n#{Settings.cache_root}/stdout.#{Process.pid}\n#{Settings.cache_root}/stderr.#{Process.pid}"}" 14 | else 15 | FileUtils.rm_f "#{Settings.cache_root}/stdout.#{Process.pid}" 16 | FileUtils.rm_f "#{Settings.cache_root}/stderr.#{Process.pid}" 17 | end 18 | end 19 | 20 | def success? cmd, *options 21 | cmd_line = "#{cmd} #{options.select { |option| option.class == String }.join(' ')}" 22 | system "#{cmd_line} &> /dev/null" 23 | $?.success? 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /packages/sqlite3.rb: -------------------------------------------------------------------------------- 1 | class Sqlite3 < Package 2 | url 'https://sqlite.org/2020/sqlite-autoconf-3310100.tar.gz' 3 | sha256 '62284efebc05a76f909c580ffa5c008a7d22a1287285d68b7825a2b6b51949ae' 4 | version ' 3.31.1' 5 | 6 | label :common 7 | label :alone 8 | 9 | depends_on :readline 10 | 11 | def install 12 | append_env 'CPPFLAGS', '-DSQLITE_ENABLE_COLUMN_METADATA=1', sep=' ' 13 | # Default value of MAX_VARIABLE_NUMBER is 999 which is too low for many 14 | # applications. Set to 250000 (Same value used in Debian and Ubuntu). 15 | append_env 'CPPFLAGS', '-DSQLITE_MAX_VARIABLE_NUMBER=250000', sep=' ' 16 | append_env 'CPPFLAGS', '-DSQLITE_ENABLE_RTREE=1', sep=' ' 17 | append_env 'CPPFLAGS', '-DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1', sep=' ' 18 | append_env 'CPPFLAGS', '-DSQLITE_ENABLE_JSON1=1', sep=' ' 19 | args = %W[ 20 | --prefix=#{prefix} 21 | --disable-dependency-tracking 22 | --enable-dynamic-extensions 23 | --enable-readline 24 | --disable-editline 25 | --enable-session 26 | ] 27 | run './configure', *args 28 | run 'make', 'install' 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /packages/cdo@1.9.6.rb: -------------------------------------------------------------------------------- 1 | class Cdo < Package 2 | url 'https://code.mpimet.mpg.de/attachments/download/19299/cdo-1.9.6.tar.gz' 3 | sha256 'b31474c94548d21393758caa33f35cf7f423d5dfc84562ad80a2bdcb725b5585' 4 | 5 | label :common 6 | 7 | depends_on :eccodes 8 | depends_on :hdf5 9 | depends_on :libxml2 10 | depends_on :netcdf 11 | depends_on :jasper 12 | depends_on :proj 13 | depends_on :udunits 14 | 15 | def install 16 | args = %W[ 17 | --prefix=#{prefix} 18 | --with-hdf5=#{Hdf5.prefix} 19 | --with-netcdf=#{Netcdf.prefix} 20 | --with-zlib=#{Zlib.prefix} 21 | --with-szlib=#{Szip.prefix} 22 | --with-jasper=#{Jasper.prefix} 23 | --with-eccodes=#{Eccodes.prefix} 24 | --with-udunits2=#{Udunits.prefix} 25 | --with-proj=#{Proj.prefix} 26 | --with-libxml2=#{Libxml2.prefix} 27 | --disable-dependency-tracking 28 | --disable-debug 29 | ] 30 | run './configure', *args 31 | run 'make' 32 | inreplace 'test/tsformat.test', 'test -n "$CDO" || CDO=cdo', 'CDO="../src/cdo -L"' 33 | run 'make', 'check' unless skip_test? 34 | run 'make', 'install' 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /packages/libevent.rb: -------------------------------------------------------------------------------- 1 | # The libevent API provides a mechanism to execute a callback function when a 2 | # specific event occurs on a file descriptor or after a timeout has been 3 | # reached. Furthermore, libevent also support callbacks due to signals or 4 | # regular timeouts. 5 | # 6 | # libevent is meant to replace the event loop found in event driven network 7 | # servers. An application just needs to call event_dispatch() and then add or 8 | # remove events dynamically without having to change the event loop. 9 | 10 | class Libevent < Package 11 | url 'https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz' 12 | sha256 '92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb' 13 | 14 | label :common 15 | 16 | depends_on :openssl 17 | 18 | def install 19 | if not Openssl.skipped? 20 | ENV['CPPFLAGS'] += " -I#{Openssl.inc}" 21 | ENV['LDFLAGS'] += " -L#{Openssl.lib}" 22 | end 23 | args = %W[ 24 | --prefix=#{prefix} 25 | --disable-dependency-tracking 26 | --disable-debug-mode 27 | ] 28 | run './configure', *args 29 | run 'make' 30 | run 'make', 'install' 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /packages/pnetcdf.rb: -------------------------------------------------------------------------------- 1 | class Pnetcdf < Package 2 | url 'https://parallel-netcdf.github.io/Release/pnetcdf-1.13.0.tar.gz' 3 | sha256 'aba0f1c77a51990ba359d0f6388569ff77e530ee574e40592a1e206ed9b2c491' 4 | 5 | option 'without-cxx', 'Disable C++ bindings' 6 | option 'without-fortran', 'Disable Fortran bindings' 7 | 8 | depends_on :mpi 9 | 10 | def install 11 | args = %W[ 12 | --prefix=#{prefix} 13 | CC=#{ENV['MPICC']} 14 | CXX=#{ENV['MPICXX']} 15 | FC=#{ENV['MPIFC']} 16 | ] 17 | args << '--disable-cxx' if without_cxx? 18 | args << '--disable-fortran' if without_fortran? 19 | # Script configure will reset them to blank somehow, so hardcode them! 20 | inreplace './configure', { 21 | /(if test "x\$\{MPICC\}" = x ; then)/ => "MPICC=#{ENV['MPICC']}\n\\1", 22 | /(if test "x\$\{MPICXX\}" = x ; then)/ => "MPICXX=#{ENV['MPICXX']}\n\\1", 23 | /(if test "x\$\{MPIF90\}" = x ; then)/ => "MPIF90=#{ENV['MPIFC']}\n\\1", 24 | /(if test "x\$\{MPIF77\}" = x ; then)/ => "MPIF77=#{ENV['MPIFC']}\n\\1" 25 | } 26 | run './configure', *args 27 | run 'make' 28 | run 'make', 'check' unless skip_test? 29 | run 'make', 'install' 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /framework/package/package_downloader.rb: -------------------------------------------------------------------------------- 1 | class PackageDownloader 2 | extend Utils 3 | 4 | def self.downloaded? package 5 | path = "#{Settings.cache_root}/#{package.file_name}" 6 | package.sha256 == Digest::SHA256.hexdigest(File.read(path)) if File.file? path 7 | end 8 | 9 | def self.download package 10 | if not downloaded? package 11 | if CommandParser.args[:http_cache] 12 | url = "#{CommandParser.args[:http_cache]}/#{package.file_name}" 13 | else 14 | url = package.url 15 | end 16 | if not url.nil? 17 | CLI.notice "Downloading #{url} ..." 18 | FileUtils.mkdir_p Settings.cache_root if not File.directory? Settings.cache_root 19 | curl url, Settings.cache_root, rename: package.file_name 20 | end 21 | end 22 | # Download patches if exist. 23 | package.patches.each_with_index do |patch, index| 24 | case patch 25 | when PackageSpec 26 | next if downloaded? patch 27 | if CommandParser.args[:http_cache] 28 | url = "#{CommandParser.args[:http_cache]}/#{patch.file_name}" 29 | else 30 | url = patch.url 31 | end 32 | CLI.notice "Downloading #{url} ..." 33 | curl url, Settings.cache_root, rename: patch.file_name 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /packages/munge.rb: -------------------------------------------------------------------------------- 1 | # MUNGE (MUNGE Uid 'N' Gid Emporium) is an authentication service for creating 2 | # and validating credentials. It is designed to be highly scalable for use in 3 | # an HPC cluster environment. It allows a process to authenticate the UID and 4 | # GID of another local or remote process within a group of hosts having common 5 | # users and groups. These hosts form a security realm that is defined by a 6 | # shared cryptographic key. Clients within this security realm can create and 7 | # validate credentials without the use of root privileges, reserved ports, or 8 | # platform-specific methods. 9 | 10 | class Munge < Package 11 | url 'https://github.com/dun/munge/archive/refs/tags/munge-0.5.16.tar.gz' 12 | sha256 'fa27205d6d29ce015b0d967df8f3421067d7058878e75d0d5ec3d91f4d32bb57' 13 | 14 | label :common 15 | label :skip_if_exist, binary_file: 'munge' 16 | 17 | depends_on :openssl 18 | 19 | def install 20 | args = %W[ 21 | --prefix=#{prefix} 22 | --with-crypto-lib=openssl 23 | ] 24 | args << "--with-openssl-prefix=#{Openssl.prefix}" if not Openssl.skipped? 25 | run './bootstrap' 26 | run './configure', *args 27 | run 'make' 28 | run 'make', 'check' if not skip_test? 29 | run 'make', 'install' 30 | run "chmod 0600 #{prefix}/etc/munge/munge.key" 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /packages/odb-api.rb: -------------------------------------------------------------------------------- 1 | class OdbApi < Package 2 | url 'https://confluence.ecmwf.int/download/attachments/61117379/odb_api_bundle-0.18.1-Source.tar.gz?api=v2' 3 | sha256 '7a01968be0d6f55004d6203a4b9ee06b91accec9078da4103cf71d2879ca2aad' 4 | 5 | depends_on :cmake 6 | depends_on :yacc 7 | depends_on :flex 8 | depends_on :ncurses 9 | depends_on :eccodes 10 | depends_on :netcdf 11 | 12 | option 'with-python', 'Build Python2 bindings.' 13 | 14 | def install 15 | args = std_cmake_args search_paths: [Eccodes.link_root] 16 | args << '-DENABLE_NETCDF=On' 17 | args << '-DENABLE_FORTRAN=On' 18 | args << "-DENABLE_PYTHON=#{with_python? ? 'On' : 'Off'}" 19 | args << "-DNETCDF_PATH='#{link_inc}'" 20 | if OS.mac? 21 | inreplace 'odb_api/CMakeLists.txt', 'ecbuild_add_cxx_flags("-fPIC -Wl,--as-needed")', 'ecbuild_add_cxx_flags("-fPIC")' 22 | end 23 | if not Ncurses.skipped? 24 | args << "-DCURSES_INCLUDE_PATH=#{Ncurses.inc}" 25 | args << "-DCURSES_LIBRARY=#{Ncurses.lib}/libncursesw.#{OS.soname}" 26 | inreplace 'eckit/src/eckit/cmd/term.c', { 27 | '' => '', 28 | '' => '' 29 | } 30 | end 31 | mkdir 'build' do 32 | run 'cmake', '..', *args 33 | run 'make', 'install' 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /framework/commands/fix.rb: -------------------------------------------------------------------------------- 1 | class FixCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman fix 9 | EOS 10 | Settings.init 11 | end 12 | 13 | def run 14 | fix_history_db_compiler_set 15 | end 16 | 17 | def fix_history_db_compiler_set 18 | # Fix history.db to add 'compiler_set' column. 19 | res = `echo 'select id, name, prefix, compiler_set from install;' | #{History.db_cmd} #{History.db_path}`.split("\n") 20 | if $?.exitstatus != 0 21 | res = `echo 'alter table install add compiler_set varchar(30);' | #{History.db_cmd} #{History.db_path}` 22 | if $?.exitstatus != 0 23 | p res 24 | exit 1 25 | end 26 | else 27 | res.map! { |record| record.split('|') } 28 | res.each do |columns| 29 | if columns.length == 3 30 | compiler_set = columns[2].gsub(Settings.install_root + '/', '').split('/').first 31 | if compiler_set != 'common' 32 | res = `echo 'update install set compiler_set = "#{compiler_set}" where id = "#{columns[0]}";' | #{History.db_cmd} #{History.db_path}` 33 | if $?.exitstatus != 0 34 | p res 35 | exit 1 36 | end 37 | end 38 | end 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /packages/met.rb: -------------------------------------------------------------------------------- 1 | class Met < Package 2 | url 'https://github.com/dtcenter/MET/releases/download/v10.1.2/met-10.1.2.20220516.tar.gz' 3 | sha256 'f0ef0de116495c91128ca6a267bb4f93088220f33d4b9d2cf57f014be6fd9742' 4 | version '10.1.2' 5 | 6 | label :common 7 | 8 | option 'with-sat', 'Enable functionality for satellite' 9 | 10 | depends_on :nceplibs 11 | depends_on :bufrlib 12 | depends_on :hdf4 if with_sat? 13 | depends_on 'hdf-eos2' if with_sat? 14 | depends_on 'netcdf-cxx4' 15 | depends_on :gsl 16 | depends_on :zlib 17 | 18 | def install 19 | args = %W[ 20 | --prefix=#{prefix} 21 | --disable-dependency-tracking 22 | --enable-grib2 23 | --disable-mode_graphics 24 | MET_NETCDF=#{NetcdfCxx4.link_root} 25 | MET_GRIB2C=#{Nceplibs.prefix}/g2c-1.6.2 26 | GRIB2CLIB_NAME=-lg2c 27 | MET_GSL=#{Gsl.link_root} 28 | MET_BUFRLIB=#{Bufrlib.link_root} 29 | MET_HDF5=#{Hdf5.link_root} 30 | LDFLAGS='-L#{Netcdf.link_lib} #{OS.mac? ? "-L#{Libpng.lib}" : ''}' 31 | CPPFLAGS='-D__64BIT__' 32 | ] 33 | if with_sat? 34 | args << "MET_HDF=#{Hdf4.link_root}" 35 | args << "MET_HDFEOS=#{HdfEos2.link_root}" 36 | end 37 | if OS.mac? 38 | inreplace 'src/basic/vx_config/config_util.cc', /(#include )/, "\\1\n#include \n" 39 | end 40 | run './configure', *args 41 | run 'make', 'install', multiple_jobs? ? "-j#{jobs_number}" : '' 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /packages/openmpi.rb: -------------------------------------------------------------------------------- 1 | class Openmpi < Package 2 | url 'https://download.open-mpi.org/release/open-mpi/v5.0/openmpi-5.0.3.tar.bz2' 3 | sha256 '990582f206b3ab32e938aa31bbf07c639368e4405dca196fabe7f0f76eeda90b' 4 | 5 | label :mpi 6 | 7 | conflicts_with :mpich, :mvapich2 8 | 9 | option 'with-external-libs', 'Use STARMAN built libraries (libevent, hwloc, pmix, ucx).' 10 | 11 | depends_on :zlib 12 | if with_external_libs? 13 | depends_on :hwloc 14 | depends_on :pmix 15 | depends_on :libevent 16 | depends_on :ucx 17 | end 18 | 19 | def export_env 20 | ENV['MPICC'] = "#{bin}/mpicc" 21 | ENV['MPICXX'] = "#{bin}/mpic++" 22 | ENV['MPIFC'] = "#{bin}/mpifort" 23 | end 24 | 25 | def install 26 | args = %W[ 27 | --prefix=#{prefix} 28 | --disable-dependency-tracking 29 | --disable-silent-rules 30 | --disable-debug 31 | --disable-sphinx 32 | --enable-shared 33 | --with-zlib=#{Zlib.prefix} 34 | --with-prrte=internal 35 | ] 36 | if with_external_libs? 37 | args << "--with-libevent=#{Libevent.prefix}" 38 | args << "--with-hwloc=#{Hwloc.prefix}" 39 | args << "--with-pmix=#{Pmix.prefix}" 40 | args << "--with-ucx=#{Ucx.prefix}" 41 | end 42 | ENV['lt_cv_ld_force_load'] = 'no' if OS.mac? 43 | run './configure', *args 44 | run 'make', 'all', multiple_jobs? ? "-j#{jobs_number}" : '' 45 | run 'make', 'check' if not skip_test? 46 | run 'make', 'install' 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /packages/eccodes.rb: -------------------------------------------------------------------------------- 1 | class Eccodes < Package 2 | url 'https://confluence.ecmwf.int/download/attachments/45757960/eccodes-2.34.1-Source.tar.gz' 3 | sha256 'f9b8680122e3ccec26e6ed24a81f1bc50ed9f2232b431e05e573678aac4d9734' 4 | 5 | depends_on :cmake 6 | depends_on :libaec 7 | depends_on :libpng 8 | depends_on :netcdf 9 | depends_on :openjpeg 10 | 11 | option 'with-python3', 'Build Python 3 bindings.' 12 | 13 | def export_env 14 | if Dir.exist? lib + '/python*' 15 | append_env 'PYTHONPATH', "#{Dir.glob(lib + '/python*').first}/site-packages" 16 | end 17 | end 18 | 19 | def install 20 | args = std_cmake_args search_paths: [link_root] 21 | args << '-DENABLE_FORTRAN=On' 22 | args << '-DENABLE_NETCDF=On' 23 | args << "-DNETCDF_PATH='#{link_root}'" 24 | args << '-DENABLE_JPG=On' 25 | args << "-DOPENJPEG_PATH='#{link_root}'" 26 | args << '-DENABLE_JPG_LIBOPENJPEG=ON' 27 | args << '-DENABLE_JPG_LIBJASPER=OFF' 28 | args << '-DENABLE_ECCODES_THREADS=ON' 29 | if with_python3? 30 | args << "-DENABLE_PYTHON=On" 31 | args << "-DPYTHON_EXECUTABLE=#{which 'python3'}" 32 | CLI.warning "Ignore #{CLI.red '--with-python2'} option." if with_python2? 33 | else 34 | args << "-DENABLE_PYTHON=Off" 35 | end 36 | mkdir 'build' do 37 | run 'cmake', '..', *args 38 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 39 | run 'ctest' unless skip_test? 40 | run 'make', 'install' 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /framework/compiler/compiler_set.rb: -------------------------------------------------------------------------------- 1 | class CompilerSet 2 | def self.init 3 | command_patterns = { 4 | gcc: { 5 | c: /\bgcc(-\d+)?$/, 6 | cxx: /\bg\+\+(-\d+)?$/, 7 | fortran: /\bgfortran(-\d+)?$/ 8 | }, 9 | clang: { 10 | c: /\bclang$/, 11 | cxx: /\bclang\+\+$/ 12 | }, 13 | pgi: { 14 | c: /\bnvcc$/, 15 | cxx: /\bnvc\+\+$/, 16 | fortran: /\bnvfortran$/ 17 | }, 18 | intel: { 19 | c: /(icc|icx)$/, 20 | cxx: /(icpc|icpx)$/, 21 | fortran: /(ifort|ifx)$/ 22 | } 23 | } 24 | [:c, :cxx, :fortran].each do |language| 25 | next unless Settings.compilers[language.to_s] 26 | case Settings.compilers[language.to_s] 27 | when command_patterns[:gcc][language] 28 | self.class_variable_set :"@@#{language}_compiler", GccCompiler.new(language) 29 | when command_patterns[:clang][language] 30 | self.class_variable_set :"@@#{language}_compiler", ClangCompiler.new(language) 31 | when command_patterns[:pgi][language] 32 | self.class_variable_set :"@@#{language}_compiler", PgiCompiler.new(language) 33 | when command_patterns[:intel][language] 34 | self.class_variable_set :"@@#{language}_compiler", IntelCompiler.new(language) 35 | end 36 | end 37 | end 38 | 39 | def self.c 40 | @@c_compiler 41 | end 42 | 43 | def self.cxx 44 | @@cxx_compiler 45 | end 46 | 47 | def self.fortran 48 | @@fortran_compiler 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /packages/mvapich2.rb: -------------------------------------------------------------------------------- 1 | class Mvapich2 < Package 2 | url 'http://mvapich.cse.ohio-state.edu/download/mvapich/mv2/mvapich2-2.2.tar.gz' 3 | sha256 '791a6fc2b23de63b430b3e598bf05b1b25b82ba8bf7e0622fc81ba593b3bb131' 4 | 5 | label :mpi 6 | 7 | conflicts_with :openmpi, :mpich 8 | 9 | option 'enable-debug', 'Enable debug messages, may impact performance.' 10 | # TODO: Should we add slurm dependency? 11 | option 'enable-slurm-1', 'Enable PMI-1 support in SLURM.' 12 | option 'enable-slurm-2', 'Enable PMI-2 support in SLURM.' 13 | option 'with-omni-path', 'Build for Intel Omni-Path devices.' 14 | option 'with-truescale', 'Build for Intel TrueScale devices.' 15 | 16 | depends_on :yacc 17 | depends_on :hwloc 18 | 19 | def install 20 | args = %W[ 21 | --prefix=#{prefix} 22 | --enable-fortran=all 23 | CPPFLAGS='-I#{common_inc}' 24 | LDFLAGS='-L#{common_lib}' 25 | ] 26 | # NOTE: IB library from vendors should already been installed. 27 | if with_omni_path? 28 | args << '--with-device=ch3:psm' 29 | elsif with_truescale? 30 | args << '--with-device=ch3:psm' 31 | else 32 | args << '--with-device=ch3:mrail --with-rdma=gen2' 33 | end 34 | args << '--enable-g=all --enable-error-messages=all' if enable_debug? 35 | if enable_slurm_1? 36 | args << '--with-pmi=pmi1 --with-pm=slurm' 37 | elsif enable_slurm_2? 38 | args << '--with-pmi=pmi2 --with-pm=slurm' 39 | end 40 | run './configure', *args 41 | run 'make' 42 | run 'make', 'install' 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /packages/hdf5.rb: -------------------------------------------------------------------------------- 1 | class Hdf5 < Package 2 | url 'https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.14/hdf5-1.14.3/src/hdf5-1.14.3.tar.bz2' 3 | sha256 '9425f224ed75d1280bb46d6f26923dd938f9040e7eaebf57e66ec7357c08f917' 4 | 5 | depends_on :szip 6 | depends_on :zlib 7 | depends_on :cmake 8 | depends_on :mpi 9 | 10 | option 'without-cxx', 'Disable C++ bindings.' 11 | option 'without-fortran', 'Disable Fortran bindings.' 12 | option 'enable-parallel', 'Enable parallel IO.' 13 | 14 | def install 15 | ENV['LDFLAGS'] = '' if CompilerSet.c.pgi? 16 | ENV['CFLAGS'] = '-fPIC' 17 | 18 | args = std_cmake_args 19 | args << "-DHDF5_BUILD_CPP_LIB=#{(without_cxx? ? 'OFF' : 'ON')}" 20 | args << "-DHDF5_BUILD_FORTRAN=#{(without_fortran? ? 'OFF' : 'ON')}" 21 | if enable_parallel? 22 | args << '-DHDF5_ENABLE_PARALLEL=ON' 23 | args << '-DALLOW_UNSUPPORTED=ON' 24 | end 25 | args << '-DHDF5_ENABLE_THREADSAFE=OFF' 26 | 27 | args << "-DZLIB_DIR=#{install_root}" 28 | args << "-DSZIP_DIR=#{install_root}" 29 | args << '-DHDF5_ENABLE_Z_LIB_SUPPORT=ON' 30 | args << '-DHDF5_ENABLE_SZIP_SUPPORT=ON' 31 | 32 | if OS.mac? 33 | # Shared fortran is not supported, build static (according to release_docs/INSTALL_CMake.txt) 34 | args << '-DBUILD_SHARED_LIBS=OFF' 35 | end 36 | 37 | mkdir 'build' do 38 | run 'cmake', '..', *args 39 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 40 | run 'ctest' unless skip_test? 41 | run 'make', 'install' 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /packages/netcdf-c.rb: -------------------------------------------------------------------------------- 1 | class NetcdfC < Package 2 | url 'https://github.com/Unidata/netcdf-c/archive/refs/tags/v4.9.2.tar.gz' 3 | file_name 'netcdf-c-4.9.2.tar.gz' 4 | sha256 'bc104d101278c68b303359b3dc4192f81592ae8640f1aee486921138f7f88cb7' 5 | 6 | grouped_by :netcdf 7 | 8 | depends_on :m4 9 | depends_on :hdf5 10 | # depends_on :blosc if OS.mac? 11 | depends_on :mpi 12 | 13 | option 'disable-netcdf-4', 'Disable NetCDF4 interfaces.' 14 | option 'enable-parallel', 'Enable parallel IO.' 15 | 16 | def install 17 | # Fix a bug for PGI compiler. 18 | inreplace 'nc_test4/test_filter_misc.c', '#define DBLVAL 12345678.12345678d', '#define DBLVAL 12345678.12345678' 19 | inreplace 'nc_test4/tst_filterparser.c', '#define DBLVAL 12345678.12345678d', '#define DBLVAL 12345678.12345678' 20 | ENV['CPPFLAGS'] += " -I#{link_inc} -DNDEBUG" 21 | ENV['LDFLAGS'] += " -L#{link_lib} -lsz" 22 | ENV['CC'] = ENV['MPICC'] if enable_parallel? 23 | args = %W[ 24 | --prefix=#{prefix} 25 | --enable-utilities 26 | --enable-shared 27 | --enable-static 28 | --disable-dap-remote-tests 29 | --disable-doxygen 30 | --disable-dap 31 | ] 32 | args << '--disable-netcdf-4' if disable_netcdf_4? 33 | args << '--enable-parallel-tests' if enable_parallel? 34 | ENV['lt_cv_ld_force_load'] = 'no' if OS.mac? 35 | run './configure', *args 36 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 37 | run 'make', 'check' if not skip_test? and not CompilerSet.c.intel? 38 | run 'make', 'install' 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /framework/utils/curl.rb: -------------------------------------------------------------------------------- 1 | module Utils 2 | CONTENT_TYPES = { 3 | json: 'application/json', 4 | octet_stream: 'application/octet-stream' 5 | }.freeze 6 | 7 | def curl url, root, options = {} 8 | if system_command? :curl 9 | options[:method] ||= :get 10 | case options[:method] 11 | when :get 12 | filename = options[:rename] ? options[:rename] : File.basename(URI.parse(url).path) 13 | system "curl --insecure -f#L -C - -o #{root}/#{filename} #{url}" 14 | unless $?.success? 15 | if $?.exitstatus == 33 16 | rm "#{root}/#{filename}" 17 | curl url, root, options 18 | end 19 | CLI.error "Failed to download #{CLI.red url}!" 20 | end 21 | when :put, :post 22 | args = ["-X #{options[:method].upcase}"] 23 | args << "-u '#{options[:username]}:#{options[:password]}'" if options[:username] and options[:password] 24 | args << "-d '#{options[:payload]}'" if options[:payload] 25 | args << "--data-binary '@#{root}'" if root 26 | args << "-H 'Content-Type: #{CONTENT_TYPES[options[:content_type]]}'" if options[:content_type] 27 | system "curl #{args.join(' ')} #{url}" 28 | when :delete 29 | args = ["-X #{options[:method].upcase}"] 30 | args << "-u '#{options[:username]}:#{options[:password]}'" if options[:username] and options[:password] 31 | system "curl #{args.join(' ')} #{url}" 32 | end 33 | else 34 | CLI.error "There is no #{CLI.red 'curl'} installed! Install it with system package manager or else." 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /packages/netcdf-fortran.rb: -------------------------------------------------------------------------------- 1 | class NetcdfFortran < Package 2 | url 'https://github.com/Unidata/netcdf-fortran/archive/refs/tags/v4.6.1.tar.gz' 3 | file_name 'netcdf-fortran-4.6.1.tar.gz' 4 | sha256 '40b534e0c81b853081c67ccde095367bd8a5eead2ee883431331674e7aa9509f' 5 | 6 | grouped_by :netcdf 7 | 8 | depends_on 'netcdf-c' 9 | 10 | option 'enable-parallel', 'Enable parallel IO.' 11 | 12 | def install 13 | ENV['CPPFLAGS'] += " -I#{link_inc}" 14 | ENV['LDFLAGS'] += " -L#{link_lib}" 15 | if OS.mac? and CompilerSet.fortran.intel? 16 | ENV['LDFLAGS'] += ' -Wl,-flat_namespace' 17 | ENV['FFLAGS'] = '-assume no2underscore' 18 | end 19 | ENV['FC'] = "#{enable_parallel? ? ENV['MPIFC'] : ENV['FC']} -fPIC" 20 | args = %W[ 21 | --prefix=#{prefix} 22 | --disable-dependency-tracking 23 | --disable-dap-remote-tests 24 | --enable-static 25 | --enable-shared 26 | ] 27 | ENV['lt_cv_ld_force_load'] = 'no' if OS.mac? 28 | run './configure', *args 29 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 30 | run 'make', 'check' unless skip_test? 31 | run 'make', 'install' 32 | 33 | # Fix RPATH! 34 | # dyld[68316]: Library not loaded: @rpath/libhdf5_hl.310.dylib 35 | # Referenced from: .../libnetcdff.7.dylib 36 | if OS.mac? 37 | {'hdf5_hl.310' => Hdf5.lib, 'hdf5.310' => Hdf5.lib, 'sz.2' => Szip.lib}.each do |key, value| 38 | run 'install_name_tool', '-change', "@rpath/lib#{key}.dylib", "#{value}/lib#{key}.dylib", "#{lib}/libnetcdff.dylib" 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /packages/cartopy.rb: -------------------------------------------------------------------------------- 1 | class Cartopy < Package 2 | url 'https://pypi.tuna.tsinghua.edu.cn/packages/46/c1/04e50c9986842f00f7db0e7a65caa896840050d7328f74e5b7437aa01179/Cartopy-0.18.0.tar.gz' 3 | sha256 '7ffa317e8f8011e0d965a3ef1179e57a049f77019867ed677d49dcc5c0744434' 4 | 5 | label :common 6 | 7 | depends_on :proj 8 | depends_on :geos 9 | depends_on :python3 10 | 11 | resource :shapely do 12 | url 'https://pypi.tuna.tsinghua.edu.cn/packages/42/f3/0e1bc2c4f15e05e30c6b99322b9ddaa2babb3f43bc7df2698efdc1553439/Shapely-1.7.1.tar.gz' 13 | sha256 '1641724c1055459a7e2b8bbe47ba25bdc89554582e62aec23cb3f3ca25f9b129' 14 | end 15 | 16 | resource :pyshp do 17 | url 'https://pypi.tuna.tsinghua.edu.cn/packages/ca/1f/e9cc2c3fce32e2926581f8b6905831165235464c858ba550b6e9b8ef78c3/pyshp-2.1.2.tar.gz' 18 | sha256 'a0aa668cd0fc09b873f10facfe96971c0496b7fe4f795684d96cc7306ac5841c' 19 | end 20 | 21 | def install 22 | site_packages = "python#{Version.new(`python3 --version`.split[1]).major_minor}/site-packages" 23 | ENV['PYTHONPATH'] = "#{lib64}/#{site_packages}:#{lib}/#{site_packages}" 24 | install_resource :shapely, '.' 25 | work_in 'shapely' do 26 | run 'python3', 'setup.py', 'install', "--prefix=#{prefix}" 27 | end 28 | install_resource :pyshp, '.' 29 | work_in 'pyshp' do 30 | run 'python3', 'setup.py', 'install', "--prefix=#{prefix}" 31 | end 32 | args = %W[ 33 | -I#{Proj.inc} 34 | -I#{Geos.inc} 35 | -L#{Proj.lib} 36 | -L#{Geos.lib} 37 | ] 38 | run 'python3', 'setup.py', 'build_ext', *args 39 | run 'python3', 'setup.py', 'install', "--prefix=#{prefix}" 40 | CLI.caveat "Add export PYTHONPATH=#{ENV['PYTHONPATH']}:$PYTHONPATH into your ~/.bashrc!" 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /framework/os/os.rb: -------------------------------------------------------------------------------- 1 | class OS 2 | extend Utils 3 | include OsDSL 4 | 5 | extend Forwardable 6 | def_delegators :@spec, :type, :version, :commands 7 | 8 | def initialize 9 | @spec = self.class.class_variable_get "@@#{self.class}_spec" 10 | @spec.eval 11 | end 12 | 13 | def self.init 14 | sys = `uname`.strip.to_sym 15 | case sys 16 | when :Darwin 17 | @@os = Mac.new 18 | when :Linux 19 | case `cat /etc/*release` 20 | when /Fedora/ 21 | @@os = Fedora.new 22 | when /CentOS/ 23 | @@os = CentOS.new 24 | when /Deepin/ 25 | @@os = Deepin.new 26 | when /Red Hat Enterprise Linux Server/ 27 | @@os = RedHatOS.new 28 | when /Ubuntu/ 29 | @@os = Ubuntu.new 30 | else 31 | @@os = UnknownOS.new 32 | end 33 | else 34 | CLI.error "Unknown OS #{CLI.red sys}!" 35 | end 36 | # Delegate commands of OS instance. 37 | class << self 38 | @@os.commands.each do |name, block| 39 | self.send :define_method, name do |*args| 40 | block.call *args 41 | end 42 | end 43 | end 44 | end 45 | 46 | def self.mac? 47 | @@os.type == :mac 48 | end 49 | 50 | def self.arm? 51 | @@os.arm? 52 | end 53 | 54 | def self.linux? 55 | [:centos, :fedora, :redhat, :ubuntu, :unknown].include? @@os.type 56 | end 57 | 58 | def self.centos? 59 | @@os.type == :centos 60 | end 61 | 62 | def self.fedora? 63 | @@os.type == :fedora 64 | end 65 | 66 | def self.redhat? 67 | @@os.type == :redhat 68 | end 69 | 70 | def self.ld_library_path 71 | mac? ? 'DYLD_LIBRARY_PATH' : 'LD_LIBRARY_PATH' 72 | end 73 | 74 | def self.soname 75 | mac? ? 'dylib' : 'so' 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /packages/openssl.rb: -------------------------------------------------------------------------------- 1 | class Openssl < Package 2 | url 'https://www.openssl.org/source/openssl-1.0.2n.tar.gz' 3 | sha256 '370babb75f278c39e0c50e8c4e7493bc0f18db6867478341a832a982fd15a8fe' 4 | version '1.0.2n' 5 | 6 | label :common 7 | label :alone 8 | label :skip_if_exist, library_file: 'libssl.so' 9 | 10 | depends_on :zlib 11 | 12 | def install 13 | # OpenSSL will prefer the PERL environment variable if set over $PATH 14 | # which can cause some odd edge cases & isn't intended. Unset for safety, 15 | # along with perl modules in PERL5LIB. 16 | ENV.delete 'PERL' 17 | ENV.delete 'PERL5LIB' 18 | 19 | # Load zlib from an explicit path instead of relying on dyld's fallback 20 | # path, which is empty in a SIP context. This patch will be unnecessary 21 | # when we begin building openssl with no-comp to disable TLS compression. 22 | # https://langui.sh/2015/11/27/sip-and-dlopen 23 | if OS.mac? 24 | inreplace 'crypto/comp/c_zlib.c', 25 | 'zlib_dso = DSO_load(NULL, "z", NULL, 0);', 26 | 'zlib_dso = DSO_load(NULL, "/usr/lib/libz.dylib", NULL, DSO_FLAG_NO_NAME_TRANSLATION);' 27 | end 28 | 29 | inreplace 'Configure', 'if $cc eq "gcc"', 'if $cc =~ /gcc$/' 30 | 31 | args = %W[ 32 | --prefix=#{prefix} 33 | --with-zlib-include=#{Zlib.inc} 34 | no-ssl2 35 | zlib-dynamic 36 | shared 37 | enable-cms 38 | ] 39 | if OS.linux? 40 | args << 'linux-x86_64' 41 | elsif OS.mac? 42 | args << 'darwin64-x86_64-cc' 43 | args << 'enable-ec_nistp_64_gcc_128' 44 | end 45 | run 'perl', './Configure', *args 46 | run 'make', 'depend' 47 | run 'make' 48 | run 'make', 'test' unless skip_test? 49 | run 'make', 'install' 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /packages/metis.rb: -------------------------------------------------------------------------------- 1 | class Metis < Package 2 | url 'https://github.com/KarypisLab/METIS/archive/refs/tags/v5.2.1.tar.gz' 3 | sha256 '1a4665b2cd07edc2f734e30d7460afb19c1217c2547c2ac7bf6e1848d50aff7a' 4 | file_name 'metis-5.2.1.tar.gz' 5 | 6 | resource :gklib do 7 | url 'https://codeload.github.com/KarypisLab/GKlib/zip/8bd6bad750b2b0d90800c632cf18e8ee93ad72d7' 8 | sha256 '6a76af30d708e2d2ad11cdac224aa50d7f58abff24963fffa4ef5250fc4c39de' 9 | file_name 'gklib-8bd6ba.zip' 10 | end 11 | 12 | def install 13 | args = %W[ 14 | shared=1 15 | cc=#{CompilerSet.c.command} 16 | gklib_path=#{prefix} 17 | prefix=#{prefix} 18 | ] 19 | # Install GKLib. 20 | install_resource :gklib, '.' 21 | if OS.mac? and CompilerSet.c.vendor == :gcc 22 | ['conf/gkbuild.cmake', 'gklib/GKlibSystem.cmake'].each do |file| 23 | inreplace file, '-std=c99' => '-std=gnu11' 24 | end 25 | end 26 | work_in 'gklib' do 27 | if OS.centos? 28 | inreplace 'GKlibSystem.cmake', { 29 | '# Finally set the official C flags.' => 30 | 'set(GKlib_COPTIONS "${GKlib_COPTIONS} -D_POSIX_C_SOURCE=199309L")' 31 | } 32 | end 33 | inreplace 'CMakeLists.txt', { 34 | 'project(GKlib C)' => "project(GKlib C)\nset(CMAKE_C_FLAGS -fPIC)" 35 | } 36 | run 'make', 'config', *args 37 | run 'make', 'install' 38 | end 39 | inreplace 'CMakeLists.txt', { 40 | 'project(METIS C)' => "project(GKlib C)\nset(CMAKE_C_FLAGS -fPIC)" 41 | } 42 | inreplace 'libmetis/CMakeLists.txt', { 43 | 'add_library(metis ${METIS_LIBRARY_TYPE} ${metis_sources})' => 44 | "add_library(metis ${METIS_LIBRARY_TYPE} ${metis_sources})\ntarget_link_libraries(metis GKlib)" 45 | } 46 | run 'make', 'config', *args 47 | run 'make', 'install' 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /packages/magics.rb: -------------------------------------------------------------------------------- 1 | class Magics < Package 2 | url 'https://confluence.ecmwf.int/download/attachments/3473464/Magics-4.0.2-Source.tar.gz' 3 | sha256 '2cf7bfdaac4b6921a86d1090bf61258862d5ff47ee8770a42af3436820ea7868' 4 | 5 | label :common 6 | 7 | depends_on :cmake 8 | depends_on :proj 9 | depends_on :netcdf 10 | depends_on :eccodes 11 | depends_on :emoslib 12 | depends_on 'odb-api' 13 | 14 | def install 15 | args = std_cmake_args 16 | args << '-DENABLE_METVIEW=On' 17 | args << '-DENABLE_NETCDF=On' 18 | args << "-DNETCDF_PATH=#{Netcdf.link_root}" 19 | args << '-DENABLE_GRIB=On' 20 | args << '-DENABLE_ECCODES=On' 21 | args << "-DECCODES_PATH=#{Eccodes.link_root}" 22 | args << '-DENABLE_BUFR=On' 23 | args << "-DEMOS_PATH=#{Emoslib.link_root}" 24 | args << '-DENABLE_ODB=On' 25 | args << "-DODB_API_PATH=#{OdbApi.link_root}" 26 | args << "-DPROJ4_PATH=#{Proj.link_root}" 27 | args << "-DPYTHON_EXECUTABLE=$(which python3)" 28 | # FIXME: We assume user installed Qt by using Homebrew. 29 | if OS.mac? 30 | CLI.error 'Install libffi first!' if not Dir.exist? '/usr/local/opt/libffi/lib/pkgconfig' 31 | ENV['PKG_CONFIG_PATH'] = '/usr/local/opt/libffi/lib/pkgconfig' 32 | CLI.error 'Install qt first!' if not Dir.exist? '/usr/local/Cellar/qt' 33 | args << "-DCMAKE_PREFIX_PATH=#{Dir.glob('/usr/local/Cellar/qt/*').first}" 34 | inreplace 'src/terralib/kernel/TeUtils.cpp', '#include ', "#define _Atomic volatile\n#include " 35 | end 36 | ['tools/xml2cc_mv.py', 'tools/xml2cc.py'].each do |file| 37 | inreplace file, '#!/usr/bin/env python', '#!/usr/bin/env python3' 38 | end 39 | mkdir 'build' do 40 | run 'cmake', '..', *args 41 | run 'make' 42 | run 'MAGPLUS=$(pwd)/..', 'make', 'check' unless skip_test? 43 | run 'make', 'install' 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /packages/nvhpc.rb: -------------------------------------------------------------------------------- 1 | class Nvhpc < Package 2 | if OS.linux? 3 | url 'https://developer.download.nvidia.com/hpc-sdk/23.7/nvhpc_2023_237_Linux_x86_64_cuda_12.2.tar.gz' 4 | sha256 '5606fc0c282c345d8039cd44b552e609da1147043857fe232c10d31846a4e64d' 5 | end 6 | version '23.7' 7 | 8 | label :compiler 9 | label :mpi 10 | label :alone 11 | 12 | def root 13 | "#{prefix}/#{`uname -s`.chomp}_#{`uname -m`.chomp}/#{version}" 14 | end 15 | 16 | def bin 17 | "#{root}/compilers/bin" 18 | end 19 | 20 | def mpi_bin 21 | "#{root}/comm_libs/mpi/bin" 22 | end 23 | 24 | def lib 25 | "#{root}/compilers/lib" 26 | end 27 | 28 | def mpi_lib 29 | "#{root}/comm_libs/mpi/lib" 30 | end 31 | 32 | def install 33 | ENV['NVHPC_SILENT'] = 'true' 34 | ENV['NVHPC_INSTALL_DIR'] = prefix 35 | ENV['NVPHC_INSTALL_TYPE'] = 'single' 36 | run './install' 37 | end 38 | 39 | def post_install 40 | # Update conf file to add this new compiler set. 41 | Settings.settings['compiler_sets']["nvhpc_#{version}"] = { 42 | 'c' => "#{bin}/nvcc", 43 | 'mpi_c' => "#{mpi_bin}/mpicc", 44 | 'cxx' => "#{bin}/nvc++", 45 | 'mpi_cxx' => "#{mpi_bin}/mpic++", 46 | 'fortran' => "#{bin}/nvfortran", 47 | 'mpi_fortran' => "#{mpi_bin}/mpif90" 48 | } 49 | Settings.write 50 | CLI.caveat <<-EOS 51 | Please add the following lines into your ~/.bashrc: 52 | export NVARCH=`uname -s`_`uname -m` 53 | export NVCOMPILERS=#{prefix} 54 | export MANPATH=$MANPATH:$NVCOMPILERS/$NVARCH/23.7/compilers/man 55 | export PATH=$NVCOMPILERS/$NVARCH/23.7/compilers/bin:$PATH 56 | export PATH=$NVCOMPILERS/$NVARCH/23.7/comm_libs/mpi/bin:$PATH 57 | export MANPATH=$MANPATH:$NVCOMPILERS/$NVARCH/23.7/comm_libs/mpi/man 58 | EOS 59 | end 60 | 61 | def export_env 62 | append_path bin 63 | append_path mpi_bin 64 | append_manpath "#{root}/compilers/man" 65 | append_manpath "#{root}/comm_libs/mpi/share/man" 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /packages/slurm.rb: -------------------------------------------------------------------------------- 1 | class Slurm < Package 2 | url 'https://download.schedmd.com/slurm/slurm-21.08.2.tar.bz2' 3 | sha256 '6cfea3ae89021dd5986109ef0bda5ad1418f88b61a446631bea576fd6c3399f3' 4 | 5 | label :common 6 | 7 | depends_on :munge 8 | depends_on :pmix 9 | 10 | def install 11 | args = %W[ 12 | --prefix=#{prefix} 13 | --sysconfdir=#{link_root}/etc 14 | --with-pmix=#{link_root} 15 | --with-hdf5=no 16 | ] 17 | args << "--with-munge=#{link_root}" unless Munge.skipped? 18 | run './configure', *args 19 | run 'make', "-j#{jobs_number}" 20 | run 'make', 'check' 21 | run 'make', 'install' 22 | end 23 | 24 | # def post_install 25 | # # Create slurm system user. 26 | # OS.add_user 'slurm', system_user: true, all_nodes: true 27 | # # Generate slurm.conf file. 28 | # conf_file = "#{link_root}/etc/slurm.conf" 29 | # if not File.exist? conf_file 30 | # write_file conf_file, <<-EOS 31 | #ClusterName=cluster 32 | #ControlMachine=#{Settings.master_node} 33 | #ControlAddr=#{Settings.master_node} 34 | #SlurmUser=slurm 35 | #SlurmctldPort=6817 36 | #SlurmdPort=6818 37 | #AuthType=auth/munge 38 | #StateSaveLocation=/var/spool/slurm/ctld 39 | #SlurmdSpoolDir=/var/spool/slurm/d 40 | #SwitchType=switch/none 41 | #MpiDefault=none 42 | #SlurmctldPidFile=/var/run/slurmctld.pid 43 | #SlurmdPidFile=/var/run/slurmd.pid 44 | #ProctrackType=proctrack/cgroup 45 | #SlurmctldTimeout=300 46 | #SlurmdTimeout=300 47 | #InactiveLimit=0 48 | #MinJobAge=300 49 | #KillWait=30 50 | #Waittime=0 51 | #SchedulerType=sched/backfill 52 | #FastSchedule=1 53 | #SlurmctldDebug=3 54 | #SlurmctldLogFile=/var/log/slurmctld.log 55 | #SlurmdDebug=3 56 | #SlurmdLogFile=/var/log/slurmd.log 57 | #JobCompType=jobcomp/none 58 | #NodeName=#{Settings.nodes} Procs=1 State=UNKNOWN 59 | #PartitionName=debug Nodes=ALL Default=YES MaxTime=INFINITE State=UP 60 | #EOS 61 | # end 62 | # CLI.warning "You should revise #{CLI.red conf_file} before start slurm." 63 | # end 64 | end 65 | -------------------------------------------------------------------------------- /packages/gdal.rb: -------------------------------------------------------------------------------- 1 | class Gdal < Package 2 | url 'http://download.osgeo.org/gdal/3.5.3/gdal-3.5.3.tar.xz' 3 | sha256 'd32223ddf145aafbbaec5ccfa5dbc164147fb3348a3413057f9b1600bb5b3890' 4 | 5 | label :common 6 | 7 | depends_on 'expat' 8 | depends_on 'geos' 9 | depends_on 'giflib' 10 | depends_on 'hdf5' 11 | depends_on 'jpeg' 12 | depends_on 'json-c' 13 | depends_on 'libgeotiff' 14 | depends_on 'libpng' 15 | depends_on 'libtiff' 16 | depends_on 'libxml2' 17 | depends_on 'netcdf' 18 | depends_on 'pcre2' 19 | depends_on 'proj' 20 | depends_on 'webp' 21 | 22 | def install 23 | args = %W[ 24 | --prefix=#{prefix} 25 | --disable-debug 26 | --with-libtool 27 | --with-local=#{prefix} 28 | --without-opencl 29 | --with-threads 30 | --with-pam 31 | --with-pcidsk=internal 32 | --with-pcraster=internal 33 | --with-expat=#{Expat.prefix} 34 | --with-geos=#{Geos.bin}/geos-config 35 | --with-geotiff=#{Libgeotiff.prefix} 36 | --with-gif=#{Giflib.prefix} 37 | --with-jpeg=#{Jpeg.prefix} 38 | --with-libjson-c=#{JsonC.prefix} 39 | --with-libtiff=#{Libtiff.prefix} 40 | --with-png=#{Libpng.prefix} 41 | --with-proj=#{Proj.prefix} 42 | --with-hdf5=#{Hdf5.prefix} 43 | --with-netcdf=#{Netcdf.prefix} 44 | --with-webp=#{Webp.prefix} 45 | --with-armadillo=no 46 | --with-qhull=no 47 | --without-jpeg12 48 | --without-mysql 49 | --without-python 50 | --without-gta 51 | --without-ogdi 52 | --without-hdf4 53 | --without-openjpeg 54 | --without-fgdb 55 | --without-ecw 56 | --without-kakadu 57 | --without-mrsid 58 | --without-jp2mrsid 59 | --without-msg 60 | --without-oci 61 | --without-idb 62 | --without-podofo 63 | --without-rasdaman 64 | --without-sosi 65 | ] 66 | run './configure', *args 67 | run 'make' 68 | run 'make', 'install' 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /packages/lua.rb: -------------------------------------------------------------------------------- 1 | class Lua < Package 2 | url 'https://www.lua.org/ftp/lua-5.4.4.tar.gz' 3 | sha256 '164c7849653b80ae67bec4b7473b884bf5cc8d2dca05653475ec2ed27b9ebf61' 4 | 5 | label :common 6 | label :skip_if_exist, include_file: 'lua5.4/lua.h' 7 | 8 | if not CompilerSet.c.clang? 9 | depends_on :readline 10 | depends_on :ncurses 11 | end 12 | 13 | def install 14 | inreplace 'src/Makefile', { 15 | /^\s*CC\s*=.*$/ => "CC = #{CompilerSet.c.command}", 16 | } 17 | if not OS.mac? and not CompilerSet.c.clang? 18 | inreplace 'src/Makefile', { 19 | /^\s*CFLAGS\s*=(.*)$/ => "CFLAGS = \\1 -fPIE -I#{Readline.inc} -I#{Ncurses.inc}", 20 | /^\s*LDFLAGS\s*=(.*)$/ => "LDFLAGS = \\1 -L#{Readline.lib} -L#{Ncurses.lib}", 21 | /^\s*LIBS\s*=(.*)$/ => "LIBS = \\1 -lncursesw" 22 | } 23 | end 24 | inreplace 'src/luaconf.h', { 25 | /#define LUA_ROOT.*/ => "#define LUA_ROOT \"#{prefix}\"" 26 | } 27 | if OS.linux? 28 | platform = 'linux' 29 | elsif OS.mac? 30 | platform = 'macosx' 31 | else 32 | platform = 'generic' 33 | end 34 | run 'make', platform, "INSTALL_TOP=#{prefix}", "INSTALL_MAN=#{man}/man1" 35 | run 'make', 'install', "INSTALL_TOP=#{prefix}", "INSTALL_MAN=#{man}/man1" 36 | mkdir "#{lib}/pkgconfig" 37 | File.open("#{lib}/pkgconfig/lua.pc", 'w') do |file| 38 | file << <<-EOT 39 | V= #{Version.new(version).major_minor} 40 | R= #{version} 41 | prefix=#{prefix} 42 | INSTALL_BIN= ${prefix}/bin 43 | INSTALL_INC= ${prefix}/include 44 | INSTALL_LIB= ${prefix}/lib 45 | INSTALL_MAN= ${prefix}/share/man/man1 46 | INSTALL_LMOD= ${prefix}/share/lua/${V} 47 | INSTALL_CMOD= ${prefix}/lib/lua/${V} 48 | exec_prefix=${prefix} 49 | libdir=${exec_prefix}/lib 50 | includedir=${prefix}/include 51 | 52 | Name: Lua 53 | Description: An Extensible Extension Language 54 | Version: #{version} 55 | Requires: 56 | Libs: -L${libdir} -llua -lm 57 | Cflags: -I${includedir} 58 | EOT 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /packages/pio.rb: -------------------------------------------------------------------------------- 1 | class Pio < Package 2 | url 'https://github.com/NCAR/ParallelIO/archive/refs/tags/pio2_5_10.zip' 3 | sha256 '6c5d7369922422541f43e089802eb6e3e4b83569bb7c23c09ca040036eeb7947' 4 | version '2.5.10' 5 | file_name 'ParallelIO-pio2_5_10.zip' 6 | 7 | option 'with-pnetcdf', 'Use PnetCDF library.' 8 | 9 | depends_on :mpi 10 | depends_on :cmake 11 | depends_on :netcdf 12 | depends_on :pnetcdf if with_pnetcdf? 13 | 14 | resource :cmake_fortran_utils do 15 | url 'https://github.com/CESM-Development/CMake_Fortran_utils/archive/refs/tags/CMake_Fortran_utils_150308.tar.gz' 16 | sha256 '4f22073e0142494c421a21a059a861f55965ed6e730fd186ef25302a75e6cfb8' 17 | end 18 | 19 | resource :genf90 do 20 | url 'https://github.com/PARALLELIO/genf90/archive/refs/tags/genf90_200608.zip' 21 | sha256 'db269c0cde55fab83d1da26cdf2b81fe27905540a660b4c78bfa39159dc2e397' 22 | end 23 | 24 | def install 25 | ENV['CC'] = ENV['MPICC'] 26 | ENV['CXX'] = ENV['MPICXX'] 27 | ENV['FC'] = ENV['MPIFC'] 28 | install_resource :genf90, '.' 29 | args = std_cmake_args 30 | args << "-DBUILD_SHARED_LIBS=ON" 31 | args << "-DLIBZ_PATH=#{link_root}" 32 | args << "-DSZIP_PATH=#{link_root}" 33 | args << "-DHDF5_PATH=#{link_root}" 34 | args << "-DNetCDF_C_PATH=#{link_root}" 35 | args << "-DNetCDF_Fortran_PATH=#{link_root}" 36 | args << "-DUSER_CMAKE_MODULE_PATH=#{pwd}/cmake_fortran_utils" 37 | args << "-DGENF90_PATH=#{pwd}/genf90" 38 | args << "-DPIO_ENABLE_TIMING=OFF" 39 | if with_pnetcdf? 40 | args << "-DPnetCDF_PATH=#{link_root}" 41 | else 42 | args << "-DWITH_PNETCDF=OFF" 43 | end 44 | if skip_test? 45 | args << "-DPIO_ENABLE_TESTS=OFF" 46 | end 47 | args << "-DMPIEXEC_PREFLAGS='--oversubscribe'" if MPI.openmpi? 48 | mkdir 'build' do 49 | install_resource :cmake_fortran_utils, '.' 50 | run 'cmake', '..', *args 51 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 52 | run 'make', 'check' unless skip_test? 53 | run 'make', 'install' 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /framework/commands/uninstall.rb: -------------------------------------------------------------------------------- 1 | class UninstallCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman uninstall ... [options] 9 | EOS 10 | @parser.on '-cNAME', '--compiler-set NAME', 'Set the active compiler set by its name set in conf file.' do |compiler_set| 11 | @@args[:compiler_set] = compiler_set 12 | end 13 | @parser.on '--with-deps', 'Also uninstall dependency packages.' do 14 | @@args[:with_deps] = true 15 | end 16 | @parser.on '--all', 'Remove all packages.' do 17 | @@args[:all] = true 18 | end 19 | parse_packages empty_is_ok: true, relax: true 20 | @parser.parse! 21 | end 22 | 23 | def run 24 | @@package_group = nil 25 | if CommandParser.args[:all] 26 | History.installed_packages.each do |name, package| 27 | remove package 28 | end 29 | else 30 | PackageLoader.loaded_packages.each do |name, package| 31 | next if not PackageLoader.from_cmd_line? package and not CommandParser.args[:with_deps] 32 | remove package 33 | end 34 | end 35 | end 36 | 37 | def remove package 38 | if package.has_label? :group and History.installed? package 39 | CLI.notice "Package group #{CLI.green package.name} is uninstalled." 40 | @@package_group = package.name 41 | elsif not History.installed? package and not package.skipped? and (not package.group or not package.group == @@package_group) 42 | CLI.warning "Package #{CLI.red package.name} has not been installed." 43 | else 44 | if not @@package_group or not package.group == @@package_group 45 | CLI.notice "Uninstall package #{CLI.green package.name} #{CLI.blue package.version} ..." 46 | end 47 | PackageLinker.unlink package 48 | if Dir.exist? package.prefix 49 | FileUtils.rm_rf package.prefix 50 | # Remove empty directory. 51 | FileUtils.rmdir File.dirname(package.prefix) if Dir.glob("#{File.dirname(package.prefix)}/*").size == 0 52 | end 53 | History.remove_install package 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /framework/os/fedora.rb: -------------------------------------------------------------------------------- 1 | class Fedora < OS 2 | type :fedora 3 | 4 | version do 5 | # Fedora release 30 (Thirty) 6 | `cat /etc/fedora-release`.match(/Fedora.*release \d+/)[1] 7 | end 8 | 9 | command :add_user do |name, options = {}| 10 | if options[:all_nodes] 11 | uid = [] 12 | Settings.nodes.each do |node| 13 | # First check if user exists. 14 | next if ssh("id #{name} 2>&1", host: node, user: 'root')[:status].success? 15 | # Then we can add user in each node. 16 | args = [] 17 | if options[:system_user] 18 | args << '--system' 19 | args << '--no-create-home' 20 | end 21 | if not ssh("useradd #{args.join(' ')} #{name} 2>&1", host: node, user: 'root')[:status].success? 22 | # Try to delete already added user. 23 | delete_user name, options 24 | CLI.error "Failed to add user #{CLI.blue name} on node #{CLI.red node}!" 25 | end 26 | # Record uid for later check. 27 | res = ssh("id #{name} 2>&1", host: node, user: 'root')[:output] 28 | uid << res.match(/uid=(\d+)/)[1] 29 | CLI.notice "Add user #{CLI.blue name} on node #{CLI.green node} with uid #{uid.last}." 30 | end 31 | # Check if uid is the same across nodes. 32 | if uid.uniq.size > 1 33 | CLI.error "Add user #{CLI.blue name} successfully, but uids are not all the same!" 34 | end 35 | else 36 | CLI.error 'Under construction!' 37 | end 38 | end 39 | 40 | command :delete_user do |name, options = {}| 41 | if options[:all_nodes] 42 | Settings.nodes.each do |node| 43 | # First check if user exists. 44 | next unless ssh("id #{name} 2>&1", host: node, user: 'root')[:status].success? 45 | args = %W[--selinux-user] 46 | if not ssh("userdel #{args.join(' ')} #{name} 2>&1", host:node, user: 'root')[:status].success? 47 | CLI.error "Failed to delete user #{CLI.blue name} on host #{CLI.red node}!" 48 | end 49 | CLI.notice "Delete user #{CLI.blue name} on node #{CLI.green node}." 50 | end 51 | else 52 | CLI.error 'Under construction!' 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /framework/os/centos.rb: -------------------------------------------------------------------------------- 1 | class CentOS < OS 2 | type :centos 3 | 4 | version do 5 | # CentOS Linux release 7.4.1708 (Core) 6 | `cat /etc/centos-release`.match(/CentOS.*release ([\d\.]+)/)[1] 7 | end 8 | 9 | command :add_user do |name, options = {}| 10 | if options[:all_nodes] 11 | uid = [] 12 | Settings.nodes.each do |node| 13 | # First check if user exists. 14 | next if ssh("id #{name} 2>&1", host: node, user: 'root')[:status].success? 15 | # Then we can add user in each node. 16 | args = [] 17 | if options[:system_user] 18 | args << '--system' 19 | args << '--no-create-home' 20 | end 21 | if not ssh("useradd #{args.join(' ')} #{name} 2>&1", host: node, user: 'root')[:status].success? 22 | # Try to delete already added user. 23 | delete_user name, options 24 | CLI.error "Failed to add user #{CLI.blue name} on node #{CLI.red node}!" 25 | end 26 | # Record uid for later check. 27 | res = ssh("id #{name} 2>&1", host: node, user: 'root')[:output] 28 | uid << res.match(/uid=(\d+)/)[1] 29 | CLI.notice "Add user #{CLI.blue name} on node #{CLI.green node} with uid #{uid.last}." 30 | end 31 | # Check if uid is the same across nodes. 32 | if uid.uniq.size > 1 33 | CLI.error "Add user #{CLI.blue name} successfully, but uids are not all the same!" 34 | end 35 | else 36 | CLI.error 'Under construction!' 37 | end 38 | end 39 | 40 | command :delete_user do |name, options = {}| 41 | if options[:all_nodes] 42 | Settings.nodes.each do |node| 43 | # First check if user exists. 44 | next unless ssh("id #{name} 2>&1", host: node, user: 'root')[:status].success? 45 | args = %W[--selinux-user] 46 | if not ssh("userdel #{args.join(' ')} #{name} 2>&1", host:node, user: 'root')[:status].success? 47 | CLI.error "Failed to delete user #{CLI.blue name} on host #{CLI.red node}!" 48 | end 49 | CLI.notice "Delete user #{CLI.blue name} on node #{CLI.green node}." 50 | end 51 | else 52 | CLI.error 'Under construction!' 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /framework/os/deepin.rb: -------------------------------------------------------------------------------- 1 | class Deepin < OS 2 | type :deepin 3 | 4 | version do 5 | # VERSION="15.11" 6 | # DISTRIB_RELEASE=15.11 7 | `cat /etc/os-release`.match(/(VERSION|RELEASE)="?(\d+[\.\d+]*)/)[2] 8 | end 9 | 10 | command :add_user do |name, options = {}| 11 | if options[:all_nodes] 12 | uid = [] 13 | Settings.nodes.each do |node| 14 | # First check if user exists. 15 | next if ssh("id #{name} 2>&1", host: node, user: 'root')[:status].success? 16 | # Then we can add user in each node. 17 | args = [] 18 | if options[:system_user] 19 | args << '--system' 20 | args << '--no-create-home' 21 | end 22 | if not ssh("useradd #{args.join(' ')} #{name} 2>&1", host: node, user: 'root')[:status].success? 23 | # Try to delete already added user. 24 | delete_user name, options 25 | CLI.error "Failed to add user #{CLI.blue name} on node #{CLI.red node}!" 26 | end 27 | # Record uid for later check. 28 | res = ssh("id #{name} 2>&1", host: node, user: 'root')[:output] 29 | uid << res.match(/uid=(\d+)/)[1] 30 | CLI.notice "Add user #{CLI.blue name} on node #{CLI.green node} with uid #{uid.last}." 31 | end 32 | # Check if uid is the same across nodes. 33 | if uid.uniq.size > 1 34 | CLI.error "Add user #{CLI.blue name} successfully, but uids are not all the same!" 35 | end 36 | else 37 | CLI.error 'Under construction!' 38 | end 39 | end 40 | 41 | command :delete_user do |name, options = {}| 42 | if options[:all_nodes] 43 | Settings.nodes.each do |node| 44 | # First check if user exists. 45 | next unless ssh("id #{name} 2>&1", host: node, user: 'root')[:status].success? 46 | args = %W[--selinux-user] 47 | if not ssh("userdel #{args.join(' ')} #{name} 2>&1", host:node, user: 'root')[:status].success? 48 | CLI.error "Failed to delete user #{CLI.blue name} on host #{CLI.red node}!" 49 | end 50 | CLI.notice "Delete user #{CLI.blue name} on node #{CLI.green node}." 51 | end 52 | else 53 | CLI.error 'Under construction!' 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /framework/os/redhat.rb: -------------------------------------------------------------------------------- 1 | class RedHatOS < OS 2 | type :redhat 3 | 4 | version do 5 | # Red Hat Enterprise Linux Server release 7.4 (Maipo) 6 | `cat /etc/redhat-release`.match(/Red Hat.*release ([\d\.]+)/)[1] 7 | end 8 | 9 | command :add_user do |name, options = {}| 10 | if options[:all_nodes] 11 | uid = [] 12 | Settings.nodes.each do |node| 13 | # First check if user exists. 14 | next if ssh("id #{name} 2>&1", host: node, user: 'root')[:status].success? 15 | # Then we can add user in each node. 16 | args = [] 17 | if options[:system_user] 18 | args << '--system' 19 | args << '--no-create-home' 20 | end 21 | if not ssh("useradd #{args.join(' ')} #{name} 2>&1", host: node, user: 'root')[:status].success? 22 | # Try to delete already added user. 23 | delete_user name, options 24 | CLI.error "Failed to add user #{CLI.blue name} on node #{CLI.red node}!" 25 | end 26 | # Record uid for later check. 27 | res = ssh("id #{name} 2>&1", host: node, user: 'root')[:output] 28 | uid << res.match(/uid=(\d+)/)[1] 29 | CLI.notice "Add user #{CLI.blue name} on node #{CLI.green node} with uid #{uid.last}." 30 | end 31 | # Check if uid is the same across nodes. 32 | if uid.uniq.size > 1 33 | CLI.error "Add user #{CLI.blue name} successfully, but uids are not all the same!" 34 | end 35 | else 36 | CLI.error 'Under construction!' 37 | end 38 | end 39 | 40 | command :delete_user do |name, options = {}| 41 | if options[:all_nodes] 42 | Settings.nodes.each do |node| 43 | # First check if user exists. 44 | next unless ssh("id #{name} 2>&1", host: node, user: 'root')[:status].success? 45 | args = %W[--selinux-user] 46 | if not ssh("userdel #{args.join(' ')} #{name} 2>&1", host:node, user: 'root')[:status].success? 47 | CLI.error "Failed to delete user #{CLI.blue name} on host #{CLI.red node}!" 48 | end 49 | CLI.notice "Delete user #{CLI.blue name} on node #{CLI.green node}." 50 | end 51 | else 52 | CLI.error 'Under construction!' 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /framework/os/ubuntu.rb: -------------------------------------------------------------------------------- 1 | class Ubuntu < OS 2 | type :ubuntu 3 | 4 | version do 5 | # VERSION="18.04 (Bionic Beaver)" 6 | # DISTRIB_RELEASE=18.04 7 | `cat /etc/lsb-release`.match(/(VERSION|RELEASE)="?(\d+[\.\d+]*)/)[2] 8 | end 9 | 10 | command :add_user do |name, options = {}| 11 | if options[:all_nodes] 12 | uid = [] 13 | Settings.nodes.each do |node| 14 | # First check if user exists. 15 | next if ssh("id #{name} 2>&1", host: node, user: 'root')[:status].success? 16 | # Then we can add user in each node. 17 | args = [] 18 | if options[:system_user] 19 | args << '--system' 20 | args << '--no-create-home' 21 | end 22 | if not ssh("useradd #{args.join(' ')} #{name} 2>&1", host: node, user: 'root')[:status].success? 23 | # Try to delete already added user. 24 | delete_user name, options 25 | CLI.error "Failed to add user #{CLI.blue name} on node #{CLI.red node}!" 26 | end 27 | # Record uid for later check. 28 | res = ssh("id #{name} 2>&1", host: node, user: 'root')[:output] 29 | uid << res.match(/uid=(\d+)/)[1] 30 | CLI.notice "Add user #{CLI.blue name} on node #{CLI.green node} with uid #{uid.last}." 31 | end 32 | # Check if uid is the same across nodes. 33 | if uid.uniq.size > 1 34 | CLI.error "Add user #{CLI.blue name} successfully, but uids are not all the same!" 35 | end 36 | else 37 | CLI.error 'Under construction!' 38 | end 39 | end 40 | 41 | command :delete_user do |name, options = {}| 42 | if options[:all_nodes] 43 | Settings.nodes.each do |node| 44 | # First check if user exists. 45 | next unless ssh("id #{name} 2>&1", host: node, user: 'root')[:status].success? 46 | args = %W[--selinux-user] 47 | if not ssh("userdel #{args.join(' ')} #{name} 2>&1", host:node, user: 'root')[:status].success? 48 | CLI.error "Failed to delete user #{CLI.blue name} on host #{CLI.red node}!" 49 | end 50 | CLI.notice "Delete user #{CLI.blue name} on node #{CLI.green node}." 51 | end 52 | else 53 | CLI.error 'Under construction!' 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /framework/commands/command_parser.rb: -------------------------------------------------------------------------------- 1 | class CommandParser 2 | include Utils 3 | 4 | def initialize 5 | @parser = OptionParser.new 6 | @@args = {} 7 | @parser.banner = <<-EOS 8 | _______ _______ _______ ______ __ __ _______ __ _ 9 | | || || _ || _ | | |_| || _ || | | | 10 | | _____||_ _|| |_| || | || | || |_| || |_| | 11 | | |_____ | | | || |_||_ | || || | 12 | |_____ | | | | || __ || || || _ | 13 | _____| | | | | _ || | | || ||_|| || _ || | | | 14 | |_______| |___| |__| |__||___| |_||_| |_||__| |__||_| |__| 15 | 16 | STARMAN: Another package manager for Linux/Mac programmer. 17 | Copyright (C) 2015-2021 - All Rights Reserved. 18 | Sponsored by Longrun Weather Inc.. 19 | EOS 20 | @parser.separator '' 21 | @parser.on '-rPATH', '--rc-root PATH', 'Set runtime configuration root directory.' do |path| 22 | @@args[:rc_root] = path 23 | end 24 | @parser.on '-d', '--debug', 'Print debug information.' do 25 | @@args[:debug] = true 26 | end 27 | @parser.on '-v', '--verbose', 'Print more information including build output.' do 28 | @@args[:verbose] = true 29 | end 30 | @parser.on_tail '-h', '--help', 'Print this help message.' do 31 | print @parser.help 32 | exit 33 | end 34 | end 35 | 36 | def self.command= val 37 | @@command = val 38 | end 39 | 40 | def self.command 41 | @@command ||= nil 42 | end 43 | 44 | def parse_packages options = {} 45 | # We really needs rc_root! 46 | ARGV.each_with_index do |arg, i| 47 | if arg == '-r' or arg == '--rc-root' 48 | @@args[:rc_root] = ARGV[i+1] 49 | break 50 | end 51 | end 52 | Settings.init silent: true 53 | History.init 54 | CompilerSet.init 55 | # NOTE: Package names should be prior to options. 56 | finish = false 57 | package_names = [] 58 | ARGV.each do |arg| 59 | finish = true if arg[0] == '-' 60 | package_names << arg unless finish 61 | end 62 | PackageLoader.loads package_names, options 63 | end 64 | 65 | def self.args 66 | @@args ||= {} 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /framework/commands/pack.rb: -------------------------------------------------------------------------------- 1 | class PackCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman pack 9 | EOS 10 | # Parse package names and load them. 11 | parse_packages relax: true 12 | # Add possible package option and parse. 13 | PackageLoader.loaded_packages.each_value do |package| 14 | package.options.each do |name, option| 15 | @parser.on "--#{name.to_s.gsub('_', '-')}", option[:desc] do 16 | option[:value] = true 17 | end 18 | end 19 | end 20 | @parser.parse! 21 | Settings.init 22 | end 23 | 24 | def run 25 | PackageLoader.loaded_packages.each do |name, package| 26 | unless package.has_label? :group 27 | package.resources.each_value do |resource| 28 | PackageDownloader.download resource 29 | end 30 | PackageDownloader.download package 31 | end 32 | end 33 | tar_file_path = "/tmp/starman-packages-#{DateTime.now.strftime('%Y%m%d%H%M%S')}.tar" 34 | tar_file = Gem::Package::TarWriter.new(File.open(tar_file_path, 'wb')) 35 | PackageLoader.loaded_packages.each do |name, package| 36 | unless package.has_label? :group 37 | if package.file_name 38 | CLI.blue_arrow package.file_path 39 | tar_file.add_file package.file_name, File.stat(package.file_path).mode do |io| 40 | io.write File.open(package.file_path, 'rb').read 41 | end 42 | end 43 | package.patches.each do |patch| 44 | next if patch.class == String 45 | CLI.blue_arrow patch.file_path 46 | tar_file.add_file patch.file_name, File.stat(patch.file_path).mode do |io| 47 | io.write File.open(patch.file_path, 'rb').read 48 | end 49 | end 50 | package.resources.each_value do |resource| 51 | CLI.blue_arrow resource.file_path 52 | tar_file.add_file resource.file_name, File.stat(resource.file_path).mode do |io| 53 | io.write File.open(resource.file_path, 'rb').read 54 | end 55 | end 56 | end 57 | end 58 | tar_file.close 59 | CLI.notice "Create #{CLI.blue tar_file_path}." 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /framework/commands/setup.rb: -------------------------------------------------------------------------------- 1 | class SetupCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman setup [options] 9 | EOS 10 | # Define options. 11 | @parser.on '--rc-root DIR', 'Set runtime configure root directory.' do |rc_root| 12 | @@args[:rc_root] = rc_root 13 | end 14 | @parser.on '--install-root DIR', 'Set install root directory.' do |install_root| 15 | @@args[:install_root] = install_root 16 | end 17 | @parser.on '--cache-root DIR', 'Set cache root directory.' do |cache_root| 18 | @@args[:cache_root] = cache_root 19 | end 20 | @@args[:no_common] = false 21 | @parser.on '--no-common', 'Do not install common packages into a separate common directory.' do 22 | @@args[:no_common] = true 23 | end 24 | @parser.on '-cVALUE', '--compiler-set VALUE', 'Set compiler set tag or name.' do |compiler_set| 25 | @@args[:compiler_set] = compiler_set 26 | end 27 | @@args[:cc] = (OS.mac? and not which('gcc')) ? 'clang' : 'gcc' 28 | @parser.on '--cc VALUE', 'Set C compiler command.' do |cc| 29 | @@args[:cc] = cc 30 | end 31 | @@args[:cxx] = (OS.mac? and not which('g++')) ? 'clang++' : 'g++' 32 | @parser.on '--cxx VALUE', 'Set C++ compiler command.' do |cxx| 33 | @@args[:cxx] = cxx 34 | end 35 | @@args[:fc] = 'gfortran' if not OS.mac? or (which('gcc') and which('gfortran')) 36 | @parser.on '--fc VALUE', 'Set Fortran compiler command.' do |fc| 37 | @@args[:fc] = fc 38 | end 39 | @parser.on '-f', '--force', 'Setup anyway' do 40 | @@args[:force] = true 41 | end 42 | @parser.parse! 43 | @@args[:rc_root] = "#{ENV['HOME']}/.starman" unless @@args[:rc_root] 44 | @@args[:cache_root] = "/tmp/starman" unless @@args[:cache_root] 45 | CLI.error "Option #{CLI.red '--install-root'} is needed!" unless @@args[:install_root] 46 | end 47 | 48 | def run 49 | runtime_file = "#{ENV['STARMAN_ROOT']}/.runtime" 50 | if File.exist? runtime_file and not @@args[:force] 51 | CLI.error 'STARMAN has been set already!' 52 | end 53 | mkdir @@args[:rc_root] 54 | mkdir @@args[:cache_root] 55 | Runtime.write @@args 56 | Settings.write @@args 57 | History.init 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /framework.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH << "#{ENV['STARMAN_ROOT']}/framework" 2 | 3 | require 'digest' 4 | require 'forwardable' 5 | require 'fileutils' 6 | require 'net/http' 7 | require 'net/ftp' 8 | require 'optparse' 9 | require 'pathname' 10 | require 'uri' 11 | require 'yaml' 12 | begin 13 | require 'rubygems/package' 14 | rescue LoadError 15 | end 16 | 17 | require 'utils/add_env' 18 | require 'utils/append_env' 19 | require 'utils/cli' 20 | require 'utils/cd' 21 | require 'utils/cp' 22 | require 'utils/work_in' 23 | require 'utils/rm' 24 | require 'utils/mkdir' 25 | require 'utils/ln' 26 | require 'utils/sed' 27 | require 'utils/decompress' 28 | require 'utils/write_file' 29 | require 'utils/append_file' 30 | require 'utils/inreplace' 31 | require 'utils/run' 32 | require 'utils/std_cmake_args' 33 | require 'utils/set_compile_env' 34 | require 'utils/set_compile_flags' 35 | require 'utils/version' 36 | require 'utils/system_command' 37 | require 'utils/which' 38 | require 'utils/curl' 39 | require 'utils/mv' 40 | require 'utils/pwd' 41 | require 'utils/ssh' 42 | require 'utils/patch' 43 | require 'utils/mpi' 44 | require 'utils/load_package' 45 | 46 | require 'os/os_spec' 47 | require 'os/os_dsl' 48 | require 'os/os' 49 | require 'os/mac' 50 | require 'os/centos' 51 | require 'os/fedora' 52 | require 'os/deepin' 53 | require 'os/redhat' 54 | require 'os/ubuntu' 55 | require 'os/unknown_os' 56 | 57 | require 'compiler/compiler_spec' 58 | require 'compiler/compiler_dsl' 59 | require 'compiler/compiler' 60 | require 'compiler/gcc' 61 | require 'compiler/clang' 62 | require 'compiler/pgi' 63 | require 'compiler/intel' 64 | require 'compiler/compiler_set' 65 | 66 | require 'runtime' 67 | require 'settings' 68 | 69 | require 'db/history' 70 | 71 | require 'package/package_spec' 72 | require 'package/package_dsl' 73 | require 'package/package' 74 | require 'package/package_loader' 75 | require 'package/package_downloader' 76 | require 'package/package_linker' 77 | require 'package/package_special_labels' 78 | 79 | require 'commands/command_parser' 80 | require 'commands/setup' 81 | require 'commands/list' 82 | require 'commands/install' 83 | require 'commands/uninstall' 84 | require 'commands/load' 85 | require 'commands/config' 86 | require 'commands/edit' 87 | require 'commands/link' 88 | require 'commands/unlink' 89 | require 'commands/pack' 90 | require 'commands/update' 91 | require 'commands/fix' 92 | -------------------------------------------------------------------------------- /packages/intel-oneapi.rb: -------------------------------------------------------------------------------- 1 | class IntelOneapi < Package 2 | version '2023.1.0.46401' 3 | 4 | label :compiler 5 | 6 | resource :base do 7 | url 'https://registrationcenter-download.intel.com/akdlm/IRC_NAS/7deeaac4-f605-4bcf-a81b-ea7531577c61/l_BaseKit_p_2023.1.0.46401_offline.sh' 8 | sha256 '74a457082c529467ecf7fe62dfa83dd36b9b190857993708de60cbe5f017c332' 9 | end 10 | 11 | resource :hpc do 12 | url 'https://registrationcenter-download.intel.com/akdlm/IRC_NAS/1ff1b38a-8218-4c53-9956-f0b264de35a4/l_HPCKit_p_2023.1.0.46346_offline.sh' 13 | sha256 '8822453afef9b6fb163e1d1096797f7bb65200b1ba300b5a8c044b4a0550de71' 14 | end 15 | 16 | def install 17 | install_resource :base, '.', plain_file: true 18 | args = %W[ 19 | -a --install-dir #{prefix}/intel/oneapi 20 | --silent --eula accept 21 | --components 22 | ] 23 | components = %W[ 24 | intel.oneapi.lin.dpcpp-ct 25 | intel.oneapi.lin.dpcpp-cpp-compiler 26 | intel.oneapi.lin.dpl 27 | intel.oneapi.lin.mkl.devel 28 | ] 29 | args << components.join(':') 30 | run 'sh base/l_BaseKit_p_2023.1.0.46401_offline.sh', *args 31 | 32 | install_resource :hpc, '.', plain_file: true 33 | args = %W[ 34 | -a --install-dir #{prefix}/intel/oneapi 35 | --silent --eula accept 36 | --components 37 | ] 38 | components = %W[ 39 | intel.oneapi.lin.dpcpp-cpp-compiler-pro 40 | intel.oneapi.lin.ifort-compiler 41 | intel.oneapi.lin.mpi.devel 42 | ] 43 | args << components.join(':') 44 | run 'sh hpc/l_HPCKit_p_2023.1.0.46346_offline.sh', *args 45 | end 46 | 47 | def post_install 48 | # Update conf file to add this new compiler set. 49 | Settings.settings['compiler_sets']["intel_#{version}"] = { 50 | 'c' => "#{prefix}/intel/oneapi/compiler/latest/linux/bin/icx", 51 | 'mpi_c' => "#{prefix}/intel/oneapi/mpi/latest/bin/mpiicc", 52 | 'cxx' => "#{prefix}/intel/oneapi/compiler/latest/linux/bin/icpx", 53 | 'mpi_cxx' => "#{prefix}/intel/oneapi/mpi/latest/bin/mpiicpc", 54 | 'fortran' => "#{prefix}/intel/oneapi/compiler/latest/linux/bin/ifx", 55 | 'mpi_fortran' => "#{prefix}/intel/oneapi/mpi/latest/bin/mpiifort" 56 | } 57 | Settings.write 58 | CLI.caveat <<-EOS.chomp 59 | Please add the following line into your ~/.bashrc or other shell config file: 60 | source #{prefix}/intel/oneapi/setvars.sh 61 | And relogin or source the shell config file before using Intel OneAPI compiler! 62 | EOS 63 | end 64 | 65 | end 66 | 67 | -------------------------------------------------------------------------------- /framework/package/package_linker.rb: -------------------------------------------------------------------------------- 1 | class PackageLinker 2 | extend Utils 3 | 4 | def self.link package 5 | regex = /#{package.prefix}\/?(.*)/ 6 | if package.links.empty? 7 | Dir.glob("#{package.prefix}/**/*").each do |file_path| 8 | next if File.directory? file_path 9 | basename = File.basename file_path 10 | subdir = File.dirname(file_path).match(regex)[1] 11 | dir = "#{package.link_root}/#{subdir}" 12 | # Fix 'libtool: warning: library XXX was moved.' problem. 13 | inreplace file_path, /^libdir='.*'$/, "libdir='#{dir}'" if basename =~ /.*\.la$/ 14 | mkdir dir unless Dir.exist? dir 15 | FileUtils.ln_sf file_path, "#{dir}/#{basename}" 16 | end 17 | else 18 | # When package maintainer specifies links explicitly, we only link them. 19 | package.links.each do |src, dst| 20 | Pathname.new(package.prefix).ascend do |v| 21 | if File.basename(v) == 'Packages' 22 | dst = "#{File.dirname v}/#{dst}" 23 | break 24 | end 25 | end 26 | mkdir dst unless Dir.exist? dst 27 | Dir.glob(src).each do |file_path| 28 | next if File.directory? file_path 29 | basename = File.basename file_path 30 | FileUtils.ln_sf file_path, "#{dst}/#{basename}" 31 | end 32 | end 33 | end 34 | end 35 | 36 | def self.unlink package 37 | regex = /#{package.prefix}\/?(.*)/ 38 | if package.links.empty? 39 | Dir.glob("#{package.prefix}/**/*").each do |file_path| 40 | next if File.directory? file_path 41 | basename = File.basename file_path 42 | subdir = File.dirname(file_path).match(regex)[1] 43 | dir = "#{package.link_root}/#{subdir}" 44 | FileUtils.rm_f "#{dir}/#{basename}" 45 | # Remove empty directory. 46 | FileUtils.rmdir dir if Dir.glob("#{dir}/*").size == 0 rescue nil 47 | end 48 | else 49 | package.links.each do |src, dst| 50 | Pathname.new(package.prefix).ascend do |v| 51 | if File.basename(v) == 'Packages' 52 | dst = "#{File.dirname v}/#{dst}" 53 | break 54 | end 55 | end 56 | Dir.glob(src).each do |file_path| 57 | next if File.directory? file_path 58 | basename = File.basename file_path 59 | FileUtils.rm_f "#{dst}/#{basename}" 60 | end 61 | # Remove empty directory. 62 | FileUtils.rmdir dst if Dir.glob("#{dst}/*").size == 0 63 | end 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /framework/commands/config.rb: -------------------------------------------------------------------------------- 1 | class ConfigCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman config [options] 9 | EOS 10 | @parser.on '-c', '--compiler-set NAME', 'Set the default compiler set by its name set in conf file.' do |compiler_set| 11 | @@args[:compiler_set] = compiler_set 12 | end 13 | @parser.on '--cc NAME', 'Add new C compiler.' do |cc| 14 | @@args[:cc] = cc 15 | end 16 | @parser.on '--cxx NAME', 'Add new C++ compiler.' do |cxx| 17 | @@args[:cxx] = cxx 18 | end 19 | @parser.on '--fc NAME', 'Add new Fortran compiler.' do |fc| 20 | @@args[:fc] = fc 21 | end 22 | @parser.on '--mpicc NAME', 'Add new MPI C compiler wrapper.' do |mpicc| 23 | @@args[:mpicc] = mpicc 24 | end 25 | @parser.on '--mpicxx NAME', 'Add new MPI C++ compiler wrapper.' do |mpicxx| 26 | @@args[:mpicxx] = mpicxx 27 | end 28 | @parser.on '--mpifc NAME', 'Add new MPI Fortran compiler wrapper.' do |mpifc| 29 | @@args[:mpifc] = mpifc 30 | end 31 | @parser.parse! 32 | Settings.init only_load: true 33 | end 34 | 35 | def run 36 | cmd = system_command?('vim') ? 'vim' : 'vi' 37 | direct_edit = false 38 | if @@args[:compiler_set] and (@@args[:cc] or @@args[:cxx] or @@args[:fc] or @@args[:mpicc] or @@args[:mpicxx] or @@args[:mpifc]) 39 | Settings.settings['defaults']['compiler_set'] = @@args[:compiler_set] 40 | Settings.settings['compiler_sets'][@@args[:compiler_set]] ||= {} 41 | Settings.settings['compiler_sets'][@@args[:compiler_set]]['c'] = @@args[:cc] if @@args[:cc] 42 | Settings.settings['compiler_sets'][@@args[:compiler_set]]['cxx'] = @@args[:cxx] if @@args[:cxx] 43 | Settings.settings['compiler_sets'][@@args[:compiler_set]]['fortran'] = @@args[:fc] if @@args[:fc] 44 | Settings.settings['compiler_sets'][@@args[:compiler_set]]['mpi_c'] = @@args[:mpicc] if @@args[:mpicc] 45 | Settings.settings['compiler_sets'][@@args[:compiler_set]]['mpi_cxx'] = @@args[:mpicxx] if @@args[:mpicxx] 46 | Settings.settings['compiler_sets'][@@args[:compiler_set]]['mpi_fortran'] = @@args[:mpifc] if @@args[:mpifc] 47 | Settings.write force: true, just_write: true 48 | direct_edit = true 49 | elsif @@args[:compiler_set] 50 | inreplace Settings.conf_file, /compiler_set:.*$/, "compiler_set: #{@@args[:compiler_set]}" 51 | direct_edit = true 52 | end 53 | system "#{cmd} -c 'set filetype=yaml' #{Settings.conf_file}" unless direct_edit 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /setup/install_sqlite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export STARMAN_ROOT=$(cd $(dirname $BASH_SOURCE) && cd .. && pwd) 4 | 5 | # Check some commands presence. 6 | for cmd in wget gcc make; do 7 | if ! (which $cmd > /dev/null); then 8 | echo "[Error]: No $cmd is installed by system! Please install one by apt-get or yum according to your OS." 9 | exit 1 10 | fi 11 | done 12 | 13 | # Check Ruby availability. 14 | SQLITE_URL=https://sqlite.org/2019/sqlite-autoconf-3300100.tar.gz 15 | SQLITE_SHA=8383f29d53fa1d4383e4c8eb3e087f2ed940a9e0 16 | SQLITE_PACKAGE=$(basename $SQLITE_URL) 17 | SQLITE_PACKAGE_DIR=$(basename $SQLITE_PACKAGE .tar.gz) 18 | 19 | if which shasum 2>&1 1> /dev/null 2>&1; then 20 | SHASUM=shasum 21 | elif which sha1sum 2>&1 1> /dev/null 2>&1; then 22 | SHASUM=sha1sum 23 | else 24 | SHASUM=none 25 | fi 26 | 27 | function install_sqlite 28 | { 29 | if [[ -f "$STARMAN_ROOT/sqlite/bin/sqlite3" ]]; then 30 | export PATH=$STARMAN_ROOT/sqlite/bin:$PATH 31 | return 32 | fi 33 | if [[ ! -d "$STARMAN_ROOT/sqlite" ]]; then 34 | mkdir "$STARMAN_ROOT/sqlite" 35 | fi 36 | cd $STARMAN_ROOT/sqlite 37 | if [[ ! -f $SQLITE_PACKAGE ]]; then 38 | wget $SQLITE_URL -O $SQLITE_PACKAGE 39 | fi 40 | if [[ "$SHASUM" == 'none' || "$($SHASUM $SQLITE_PACKAGE | cut -d ' ' -f 1)" != "$SQLITE_SHA" ]]; then 41 | echo '[Error]: SQLITE is not downloaded successfully!' 42 | exit 1 43 | fi 44 | rm -rf $SQLITE_PACKAGE_DIR 45 | tar -xzf $SQLITE_PACKAGE 46 | cd $SQLITE_PACKAGE_DIR 47 | echo "[Notice]: Building SQLITE, please wait for a moment!" 48 | export LD_LIBRARY_PATH= 49 | # In some environment, openssl cannot been compiled with successfully, so disable the openssl ext. 50 | CC=gcc CFLAGS=-fPIC ./configure --prefix=$STARMAN_ROOT/sqlite 1> $STARMAN_ROOT/sqlite/out 2>&1 51 | make install 1>> $STARMAN_ROOT/sqlite/out 2>&1 52 | if [[ $? == 0 ]]; then 53 | cd $STARMAN_ROOT/sqlite 54 | rm -rf $SQLITE_PACKAGE_DIR 55 | export PATH=$STARMAN_ROOT/sqlite/bin:$PATH 56 | else 57 | echo "[Error]: Failed to build SQLITE! please see $STARMAN_ROOT/sqlite/out!" 58 | exit 1 59 | fi 60 | } 61 | 62 | if ! which sqlite3 2>&1 1> /dev/null 2>&1; then 63 | echo '[Warning]: System does not provide a SQLITE! STARMAN will install one for you!' 64 | install_sqlite 65 | fi 66 | 67 | cd "$OLD_DIR" 68 | 69 | # Check .bashrc in HOME. 70 | if [[ "$SHELL" =~ "bash" ]]; then 71 | if [[ -d "$STARMAN_ROOT/sqlite/bin" ]]; then 72 | LINE="export PATH=$STARMAN_ROOT/sqlite/bin:\$PATH" 73 | if ! grep "$LINE" ~/.bashrc 1>/dev/null; then 74 | echo $LINE >> ~/.bashrc 75 | echo "[Notice]: Append \"$LINE\" into ~/.bashrc. Reopen or relogin to the terminal please." 76 | fi 77 | fi 78 | else 79 | echo "[Error]: Shell $SHELL is not supported currently!" 80 | exit 1 81 | fi 82 | -------------------------------------------------------------------------------- /framework/utils/cli.rb: -------------------------------------------------------------------------------- 1 | class CLI 2 | @@color_map = { 3 | :red => 31, 4 | :green => 32, 5 | :yellow => 33, 6 | :blue => 34, 7 | :purple => 35, 8 | :cyan => 36, 9 | :gray => 37, 10 | :white => 39, 11 | } 12 | 13 | def self.reset 14 | escape 0 15 | end 16 | 17 | def self.width 18 | `tput -T xterm-256color cols`.strip.to_i rescue 80 19 | end 20 | 21 | def self.truncate str 22 | str.to_s[0, width - 4] 23 | end 24 | 25 | def self.bold str 26 | "#{escape(1)}#{str}#{escape(0)}" 27 | end 28 | 29 | def self.color n 30 | escape "0;#{n}" 31 | end 32 | 33 | def self.underline n 34 | escape "4;#{n}" 35 | end 36 | 37 | def self.escape n 38 | "\033[#{n}m" if $stdout.tty? 39 | end 40 | 41 | @@color_map.each do |color_name, color_code| 42 | self.class_eval(<<-EOT) 43 | def self.#{color_name} str = nil 44 | if str 45 | "\#{#{color_name}}\#{str}\#{reset}" 46 | else 47 | color #{color_code} 48 | end 49 | end 50 | EOT 51 | end 52 | 53 | def self.blue_arrow message, options = [] 54 | options = [options] if not options.class == Array 55 | print "#{blue '==>'} " 56 | if options.include? :truncate 57 | print "#{truncate message}\n" 58 | else 59 | print "#{message}\n" 60 | end 61 | end 62 | 63 | def self.print_call_stack 64 | Kernel.caller.each do |stack_line| 65 | print "#{red '==>'} #{stack_line}\n" 66 | end 67 | end 68 | 69 | def self.notice message 70 | print "[#{green 'Notice'}]: #{message}\n" 71 | end 72 | 73 | def self.warning message 74 | print "[#{yellow 'Warning'}]: #{message}\n" 75 | print_call_stack if CommandParser.args[:debug] 76 | end 77 | 78 | def self.error message, options = {} 79 | if options[:raise_exception] 80 | raise message 81 | else 82 | print "[#{red 'Error'}]: #{message}\n" 83 | print_call_stack if CommandLine.option(:debug) rescue exit 84 | exit 1 85 | end 86 | end 87 | 88 | def self.repeat x, times, color, suffix = nil 89 | for i in 1..times 90 | if color 91 | print "#{eval "#{color} x"}" 92 | else 93 | print x 94 | end 95 | end 96 | print suffix 97 | end 98 | 99 | def self.caveat message 100 | times = [80, width].min 101 | repeat '#', times/2-4, 'red', "#{red ' CAVEAT '}" 102 | repeat '#', times-(times/2-4)-8, 'red', "\n" 103 | message.each_line do |line| 104 | print line 105 | end 106 | print "\n" 107 | repeat '#', times, 'red', "\n" 108 | end 109 | 110 | def self.pause options = {} 111 | print options[:message] 112 | if options.has_key? :seconds 113 | sleep options[:seconds] 114 | else 115 | STDIN.gets 116 | end 117 | p 118 | end 119 | end 120 | -------------------------------------------------------------------------------- /setup/install_ruby.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export STARMAN_ROOT=$(cd $(dirname $BASH_SOURCE) && cd .. && pwd) 4 | 5 | # Check some commands presence. 6 | for cmd in wget gcc make; do 7 | if ! (which $cmd > /dev/null); then 8 | echo "[Error]: No $cmd is installed by system! Please install one by apt-get or yum according to your OS." 9 | exit 1 10 | fi 11 | done 12 | 13 | # Check Ruby availability. 14 | RUBY_URL=https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.gz 15 | RUBY_SHA=2347ed6ca5490a104ebd5684d2b9b5eefa6cd33c 16 | RUBY_PACKAGE=$(basename $RUBY_URL) 17 | RUBY_PACKAGE_DIR=$(basename $RUBY_PACKAGE .tar.gz) 18 | 19 | if which shasum 2>&1 1> /dev/null 2>&1; then 20 | SHASUM=shasum 21 | elif which sha1sum 2>&1 1> /dev/null 2>&1; then 22 | SHASUM=sha1sum 23 | else 24 | SHASUM=none 25 | fi 26 | 27 | function install_ruby 28 | { 29 | if [[ -f "$STARMAN_ROOT/ruby/bin/ruby" ]]; then 30 | export PATH=$STARMAN_ROOT/ruby/bin:$PATH 31 | return 32 | fi 33 | if [[ ! -d "$STARMAN_ROOT/ruby" ]]; then 34 | mkdir "$STARMAN_ROOT/ruby" 35 | fi 36 | cd $STARMAN_ROOT/ruby 37 | if [[ ! -f $RUBY_PACKAGE ]]; then 38 | wget $RUBY_URL -O $RUBY_PACKAGE 39 | fi 40 | if [[ "$SHASUM" == 'none' || "$($SHASUM $RUBY_PACKAGE | cut -d ' ' -f 1)" != "$RUBY_SHA" ]]; then 41 | echo '[Error]: Ruby is not downloaded successfully!' 42 | exit 1 43 | fi 44 | rm -rf $RUBY_PACKAGE_DIR 45 | tar -xzf $RUBY_PACKAGE 46 | cd $RUBY_PACKAGE_DIR 47 | echo "[Notice]: Building Ruby, please wait for a moment!" 48 | export LD_LIBRARY_PATH= 49 | # In some environment, openssl cannot been compiled with successfully, so disable the openssl ext. 50 | CC=gcc CFLAGS=-fPIC ./configure --prefix=$STARMAN_ROOT/ruby --with-out-ext=openssl,zlib --disable-install-rdoc 1> $STARMAN_ROOT/ruby/out 2>&1 51 | make install 1>> $STARMAN_ROOT/ruby/out 2>&1 52 | if [[ $? == 0 ]]; then 53 | cd $STARMAN_ROOT/ruby 54 | rm -rf $RUBY_PACKAGE_DIR 55 | export PATH=$STARMAN_ROOT/ruby/bin:$PATH 56 | else 57 | echo "[Error]: Failed to build Ruby! please see $STARMAN_ROOT/ruby/out!" 58 | exit 1 59 | fi 60 | } 61 | 62 | if ! which ruby 2>&1 1> /dev/null 2>&1; then 63 | echo '[Warning]: System does not provide a Ruby! STARMAN will install one for you!' 64 | install_ruby 65 | fi 66 | 67 | RUBY_VERSION=$(ruby -v | cut -d ' ' -f 2) 68 | if [[ $RUBY_VERSION =~ $(echo '^1\.8') || $RUBY_VERSION =~ $(echo '^1\.9') ]]; then 69 | echo "[Warning]: Ruby version is too old, STARMAN will install a newer one for you!" 70 | install_ruby 71 | fi 72 | 73 | cd "$OLD_DIR" 74 | 75 | # Check .bashrc in HOME. 76 | if [[ "$SHELL" =~ "bash" ]]; then 77 | if [[ -d "$STARMAN_ROOT/ruby/bin" ]]; then 78 | LINE="export PATH=$STARMAN_ROOT/ruby/bin:\$PATH" 79 | if ! grep "$LINE" ~/.bashrc 1>/dev/null; then 80 | echo $LINE >> ~/.bashrc 81 | echo "[Notice]: Append \"$LINE\" into ~/.bashrc. Reopen or relogin to the terminal please." 82 | fi 83 | fi 84 | else 85 | echo "[Error]: Shell $SHELL is not supported currently!" 86 | exit 1 87 | fi 88 | -------------------------------------------------------------------------------- /framework/package/package_spec.rb: -------------------------------------------------------------------------------- 1 | # PackageSpec store specifications of a package. 2 | 3 | class PackageSpec 4 | def initialize 5 | @url = nil 6 | @mirror = nil 7 | @sha256 = nil 8 | @version = nil 9 | @file_name = nil 10 | @group = nil 11 | @labels = {} 12 | @dependencies = {} 13 | @options = {} 14 | @patches = [] 15 | @conflicts = [] 16 | @resources = {} 17 | @links = {} 18 | end 19 | 20 | def url val = nil 21 | return @url unless val 22 | @url = val 23 | self.file_name = File.basename(URI.parse(val).path) 24 | end 25 | def url= val 26 | @url = val 27 | self.file_name = File.basename(URI.parse(val).path) 28 | end 29 | 30 | [:mirror, :sha256, :version, :group].each do |attr| 31 | define_method(attr) do |val = nil| 32 | return self.instance_variable_get :"@#{attr}" unless val 33 | self.instance_variable_set :"@#{attr}", val 34 | end 35 | end 36 | attr_writer :mirror, :sha256, :version, :group 37 | 38 | def version= val 39 | begin 40 | @version = Version.new val, raise_exception: true 41 | rescue 42 | @version = val 43 | end 44 | end 45 | 46 | def file_name val = nil 47 | return @file_name unless val 48 | @file_name = val 49 | # Assume a reasonable file name pattern to extract version information. 50 | match = /.*-(\d+\.\d+(\.\d+(\.\d+)?)?)/.match(val) 51 | self.version = match[1] if match 52 | end 53 | def file_name= val 54 | @file_name = val 55 | # Assume a reasonable file name pattern to extract version information. 56 | match = /.*-(\d+\.\d+(\.\d+(\.\d+)?)?)/.match(val) 57 | self.version = match[1] if match 58 | end 59 | def file_path 60 | Settings.cache_root + '/' + file_name 61 | end 62 | 63 | attr_reader :labels 64 | def label val, options = {} 65 | @labels[val] = options 66 | end 67 | def has_label? val 68 | @labels.has_key? val 69 | end 70 | 71 | attr_accessor :dependencies 72 | def depends_on val, options = {} 73 | @dependencies[val.to_sym] = options 74 | end 75 | 76 | attr_accessor :options 77 | def option val, options = {} 78 | @options[val] ||= options 79 | end 80 | 81 | attr_reader :resources 82 | def resource name, spec = nil 83 | @resources[name.to_sym] = spec if spec 84 | @resources[name.to_sym] 85 | end 86 | 87 | attr_reader :patches 88 | def patch options=nil, &block 89 | if options.class == String 90 | @patches << options 91 | else 92 | spec = PackageSpec.new 93 | spec.instance_exec &block 94 | return if @patches.any? { |patch| patch.sha256 == spec.sha256 } 95 | spec.options = options if options.class == Hash 96 | @patches << spec 97 | end 98 | end 99 | 100 | attr_reader :conflicts 101 | def conflicts_with *vals 102 | vals.each do |val| 103 | @conflicts << val.to_sym unless @conflicts.include? val.to_sym 104 | end 105 | end 106 | 107 | attr_reader :links 108 | def link src, dst 109 | @links[src] = dst 110 | end 111 | 112 | attr_accessor :system_prefix 113 | attr_accessor :system_inc 114 | attr_accessor :system_lib 115 | end 116 | -------------------------------------------------------------------------------- /framework/package/package_dsl.rb: -------------------------------------------------------------------------------- 1 | module PackageDSL 2 | def self.included base 3 | base.extend self 4 | end 5 | 6 | def spec 7 | package_class = self.name.split('::').last 8 | return self.class_variable_get "@@#{package_class}_spec" if self.class_variable_defined? "@@#{package_class}_spec" 9 | self.class_variable_set "@@#{package_class}_spec", PackageSpec.new 10 | end 11 | 12 | [:url, :mirror, :sha256, :version, :file_name].each do |keyword| 13 | self.send :define_method, keyword do |val = nil| 14 | if val 15 | spec.send "#{keyword}=", val 16 | else 17 | spec.send keyword 18 | end 19 | end 20 | end 21 | 22 | [:label, :depends_on].each do |keyword| 23 | self.send :define_method, keyword do |val, options = {}| 24 | spec.send keyword, val, options 25 | end 26 | end 27 | 28 | def conflicts_with *val 29 | spec.conflicts_with *val 30 | end 31 | 32 | def grouped_by val 33 | spec.group = val.to_sym 34 | end 35 | 36 | def option name, desc, options = {} 37 | name = name.gsub('-', '_').to_sym 38 | options[:desc] = desc 39 | options[:type] = :boolean if not options[:type] 40 | spec.option name, options 41 | # Create a helper for querying option. 42 | case options[:type] 43 | when :boolean 44 | define_method(:"#{name}?") do 45 | @spec.options[name][:value] 46 | end 47 | self.class.send :define_method, :"#{name}?" do 48 | self.class_variable_get("@@#{self.name.split('::').last}_spec").options[name][:value] 49 | end 50 | define_method(:"#{name}=") do |val| 51 | @spec.options[name][:value] = val 52 | end 53 | else 54 | define_method(:"#{name}") do 55 | @spec.options[name][:value] || @spec.options[name][:default] 56 | end 57 | self.class.send :define_method, :"#{name}" do 58 | self.class_variable_get("@@#{self.name.split('::').last}_spec").options[name][:value] || 59 | self.class_variable_get("@@#{self.name.split('::').last}_spec").options[name][:default] 60 | end 61 | end 62 | end 63 | 64 | def resource name, &block 65 | return spec.resources[name.to_sym] if not block_given? 66 | res = PackageSpec.new 67 | res.instance_eval &block 68 | spec.resource name, res 69 | end 70 | 71 | def patch options=nil, &block 72 | if options == :DATA 73 | data = '' 74 | start = false 75 | File.open("#{ENV['STARMAN_ROOT']}/packages/#{Package.package_name self}.rb", 'r').each do |line| 76 | if line =~ /__END__/ 77 | start = true 78 | next 79 | end 80 | data << line if start 81 | end 82 | spec.patch data 83 | elsif options.class == Hash 84 | spec.patch options, &block 85 | else 86 | spec.patch &block 87 | end 88 | end 89 | 90 | def skip_test? 91 | CommandParser.args[:skip_test] 92 | end 93 | 94 | def multiple_jobs? 95 | CommandParser.args.has_key? :make_jobs 96 | end 97 | 98 | def jobs_number 99 | CommandParser.args[:make_jobs] || '1' 100 | end 101 | 102 | def link src, dst 103 | spec.link src, dst 104 | end 105 | end 106 | -------------------------------------------------------------------------------- /framework/commands/load.rb: -------------------------------------------------------------------------------- 1 | class LoadCommand < CommandParser 2 | include Utils 3 | 4 | def initialize 5 | super 6 | @parser.banner += <<-EOS 7 | 8 | >>> starman load [@] ... 9 | EOS 10 | @parser.on '-cNAME', '--compiler-set NAME', 'Set the active compiler set by its name set in conf file.' do |compiler_set| 11 | @@args[:compiler_set] = compiler_set 12 | end 13 | @parser.on '-w', '--without-deps', 'Do not load dependencies.' do 14 | @@args[:without_deps] = true 15 | end 16 | @parser.on '-a', '--all', 'Load all packages for current compiler set.' do 17 | @@args[:all] = true 18 | end 19 | @parser.on '-p', '--print', 'Print modified environment variables.' do 20 | @@args[:print] = true 21 | @@args[:verbose] = false 22 | end 23 | @parser.parse! 24 | parse_packages empty_is_ok: true 25 | end 26 | 27 | def run 28 | if @@args[:all] 29 | append_path Package.link_bin if Dir.exist? Package.link_bin 30 | append_ld_library_path Package.link_lib if Dir.exist? Package.link_lib 31 | append_ld_library_path Package.link_lib64 if Dir.exist? Package.link_lib64 32 | append_pkg_config_path Package.link_lib + '/pkgconfig' if Dir.exist? Package.link_lib + '/pkgconfig' 33 | append_pkg_config_path Package.link_lib64 + '/pkgconfig' if Dir.exist? Package.link_lib64 + '/pkgconfig' 34 | append_manpath Package.link_man if Dir.exist? Package.link_man 35 | append_path Package.common_bin if Package.common_bin 36 | append_ld_library_path Package.common_lib if Dir.exist? Package.common_lib 37 | append_ld_library_path Package.common_lib64 if Dir.exist? Package.common_lib64 38 | append_pkg_config_path Package.common_lib + '/pkgconfig' if Dir.exist? Package.common_lib + '/pkgconfig' 39 | append_pkg_config_path Package.common_lib64 + '/pkgconfig' if Dir.exist? Package.common_lib64 + '/pkgconfig' 40 | append_manpath Package.common_man if Dir.exist? Package.common_man 41 | else 42 | PackageLoader.loaded_packages.each do |name, package| 43 | next if (not PackageLoader.from_cmd_line? package and CommandParser.args[:without_deps]) or package.skipped? 44 | if package.has_label? :group 45 | CLI.notice "Load package group #{CLI.green package.name}@#{CLI.blue package.version} ..." if CommandParser.args[:verbose] 46 | elsif not History.installed?(package) 47 | CLI.warning "Package #{CLI.red package.name}@#{CLI.blue package.version} has not been installed." 48 | else 49 | CLI.notice "Load package #{CLI.green package.name}@#{CLI.blue package.version} ..." if CommandParser.args[:verbose] 50 | load_package package 51 | end 52 | end 53 | end 54 | if @@args[:print] 55 | if @@args[:all] 56 | print "export STARMAN_INSTALL_ROOT=#{Package.link_root}\n" 57 | else 58 | PackageLoader.loaded_packages.each do |name, package| 59 | next unless PackageLoader.from_cmd_line? package 60 | env_name = name.to_s.gsub('-', '_').upcase 61 | print "export #{env_name}_ROOT=#{package.prefix}\n" 62 | print "export #{env_name}_DIR=#{package.prefix}\n" 63 | print "export #{env_name}_PATH=#{package.prefix}\n" 64 | end 65 | end 66 | added_env.each do |key, val| 67 | print "export #{key}=#{val}\n" 68 | end 69 | appended_env.each do |key, val| 70 | print "export #{key}=#{val}\n" 71 | end 72 | end 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /packages/gcc.rb: -------------------------------------------------------------------------------- 1 | class Gcc < Package 2 | url 'http://mirrors.aliyun.com/gnu/gcc/gcc-12.3.0/gcc-12.3.0.tar.xz' 3 | sha256 '949a5d4f99e786421a93b532b22ffab5578de7321369975b91aec97adfda8c3b' 4 | 5 | label :compiler 6 | 7 | resource :mpfr do 8 | url 'http://mirrors.aliyun.com/gnu/mpfr/mpfr-4.2.0.tar.xz' 9 | sha256 '06a378df13501248c1b2db5aa977a2c8126ae849a9d9b7be2546fb4a9c26d993' 10 | end 11 | 12 | resource :gmp do 13 | url 'http://mirrors.aliyun.com/gnu/gmp/gmp-6.3.0.tar.xz' 14 | sha256 'a3c2b80201b89e68616f4ad30bc66aee4927c3ce50e33929ca819d5c43538898' 15 | end 16 | 17 | resource :mpc do 18 | url 'http://mirrors.aliyun.com/gnu/mpc/mpc-1.3.1.tar.gz' 19 | sha256 'ab642492f5cf882b74aa0cb730cd410a81edcdbec895183ce930e706c1c759b8' 20 | end 21 | 22 | resource :isl do 23 | url 'https://libisl.sourceforge.io/isl-0.26.tar.xz' 24 | sha256 'a0b5cb06d24f9fa9e77b55fabbe9a3c94a336190345c2555f9915bb38e976504' 25 | end 26 | 27 | option 'disable-lto', 'Disable Link Time Optimisation support.' 28 | 29 | def export_env 30 | append_ld_library_path "#{lib}/gcc/lib64" 31 | end 32 | 33 | def build_name 34 | if OS.mac? 35 | 'x86_64-apple-darwin' 36 | elsif OS.linux? 37 | 'x86_64-pc-linux-gnu' 38 | else 39 | 'unknown' 40 | end 41 | end 42 | 43 | def install 44 | ENV['LIBRARY_PATH'] = '' 45 | if CompilerSet.c.version <= '4.8.5' 46 | CLI.warning 'Using old GCC (<= 4.8.5), so STARMAN made some tricks!' 47 | inreplace 'gcc/Makefile.in', 'mv tmp-specs $(SPECS)', '#mv tmp-specs $(SPECS)' 48 | self.disable_lto = true 49 | end 50 | if OS.redhat? 51 | CLI.warning 'STARMAN is trying hard to fix GCC build for Red Hat Enterprise Linux!' 52 | Dir.glob('libgfortran/generated/*.F90').concat(['libgfortran/libgfortran.h', 'libgfortran/ieee/ieee_exceptions.F90', 'libgfortran/ieee/ieee_arithmetic.F90']).each do |file| 53 | inreplace file, '"config.h"', "\"#{pwd}/../gcc-build/#{build_name}/libgfortran/config.h\"" 54 | end 55 | end 56 | if CompilerSet.c.vendor == :gcc 57 | ENV['CC'] += " -I#{`gcc --print-file-name=include`.chomp}" 58 | ENV['CXX'] += " -I#{`gcc --print-file-name=include`.chomp}" 59 | end 60 | args = %W[ 61 | --prefix=#{prefix} 62 | --build=#{build_name} 63 | --enable-languages=c,c++,fortran 64 | --disable-multilib 65 | --enable-libstdcxx-time=yes 66 | --enable-stage1-checking 67 | --enable-checking=release 68 | --with-build-config=bootstrap-debug 69 | --disable-werror 70 | --disable-nls 71 | ] 72 | args << '--enable-lto' unless disable_lto? 73 | install_resource :mpfr, '.' 74 | mv 'mpfr-4.2.0', 'mpfr' 75 | install_resource :gmp, '.' 76 | mv 'gmp-6.2.1', 'gmp' 77 | install_resource :mpc, '.' 78 | mv 'mpc-1.3.1', 'mpc' 79 | install_resource :isl, '.' 80 | mv 'isl-0.25', 'isl' 81 | mkdir '../gcc-build' do 82 | run "../gcc-#{version}/configure", *args 83 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '', 'bootstrap' 84 | #run 'ulimit -s 32768 && make -k check' unless skip_test? 85 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '', 'install' 86 | end 87 | end 88 | 89 | def post_install 90 | # Update conf file to add this new compiler set. 91 | Settings.settings['compiler_sets']["gcc_#{version}"] = { 92 | 'c' => "#{bin}/gcc", 93 | 'cxx' => "#{bin}/g++", 94 | 'fortran' => "#{bin}/gfortran" 95 | } 96 | Settings.write 97 | end 98 | end 99 | -------------------------------------------------------------------------------- /framework/db/history.rb: -------------------------------------------------------------------------------- 1 | class History 2 | extend Utils 3 | 4 | def self.db_path 5 | "#{Runtime.rc_root}/history.db" 6 | end 7 | 8 | def self.db_cmd 9 | 'sqlite3' 10 | end 11 | 12 | def self.init 13 | if not system_command? 'sqlite3' 14 | CLI.error 'There is no sqlite3!' 15 | end 16 | # Create history database if not exists. 17 | if not File.file? db_path 18 | CLI.notice "Initialize history database at #{CLI.blue db_path}." 19 | FileUtils.mkdir_p File.dirname(db_path) 20 | old_ld_library_path = ENV[OS.ld_library_path] 21 | ENV[OS.ld_library_path] = '' 22 | system "cat #{ENV['STARMAN_ROOT']}/framework/db/tables.sql | #{db_cmd} #{db_path}" 23 | ENV[OS.ld_library_path] = old_ld_library_path 24 | end 25 | end 26 | 27 | def self.save_install package 28 | old_ld_library_path = ENV[OS.ld_library_path] 29 | ENV[OS.ld_library_path] = '' 30 | system "echo 'insert into install (name, version, prefix, compiler_set, options, time) " + 31 | "values (\"#{package.name}\", \"#{package.version}\", \"#{package.prefix}\", \"#{Settings.compiler_set}\", " + 32 | "\"#{package.options.to_s.gsub('"', '""')}\", \"#{Time.now}\");' | #{db_cmd} #{db_path}" 33 | ENV[OS.ld_library_path] = old_ld_library_path 34 | end 35 | 36 | def self.remove_install package 37 | old_ld_library_path = ENV[OS.ld_library_path] 38 | ENV[OS.ld_library_path] = '' 39 | system "echo 'delete from install where prefix = \"#{package.prefix}\";' | #{db_cmd} #{db_path}" 40 | ENV[OS.ld_library_path] = old_ld_library_path 41 | CLI.error "Failed to update history database!" if not $?.success? 42 | end 43 | 44 | def self.installed_packages 45 | old_ld_library_path = ENV[OS.ld_library_path] 46 | ENV[OS.ld_library_path] = '' 47 | res = `echo 'select name from install where compiler_set = "#{Settings.compiler_set}";' | #{db_cmd} #{db_path}`.split("\n") 48 | ENV[OS.ld_library_path] = old_ld_library_path 49 | return [] if res.empty? 50 | res.map! { |record| record.split('|') } 51 | package_names = [] 52 | res.each do |columns| 53 | package_names << columns[0] 54 | end 55 | PackageLoader.loads package_names 56 | end 57 | 58 | def self.installed? package 59 | old_ld_library_path = ENV[OS.ld_library_path] 60 | ENV[OS.ld_library_path] = '' 61 | if package.has_label? :group 62 | res = `echo 'select * from install where like(\"#{File.dirname(package.prefix)}%\", prefix);' | #{db_cmd} #{db_path}`.split("\n") 63 | else 64 | res = `echo 'select * from install where name = \"#{package.name}\";' | #{db_cmd} #{db_path}`.split("\n") 65 | end 66 | ENV[OS.ld_library_path] = old_ld_library_path 67 | return false if res.empty? 68 | res.map! { |record| record.split('|') } 69 | res.sort_by! { |columns| columns[2] } 70 | res.each do |columns| 71 | next unless package.has_label?(:common) or package.has_label?(:compiler) or columns[3] =~ /#{Settings.compiler_set}/ 72 | # If old version package has been installed, we should tell user that 73 | # he/she must use force option to override with newer version. 74 | if package.version != columns[2] or package.prefix != columns[3] 75 | if CommandParser.args[:force] 76 | res = :different_version_installed_but_unlink_it 77 | else 78 | res = [:different_version_installed, columns[2]] 79 | end 80 | else 81 | # Add method if necessary. 82 | columns.each do |column| 83 | if column[0] == '{' 84 | eval(column).each do |key, value| 85 | package.options[key] = value 86 | end 87 | end 88 | end 89 | # If name and version match, just return. 90 | return true 91 | end 92 | end 93 | res 94 | end 95 | end 96 | -------------------------------------------------------------------------------- /packages/python3@3.6.rb: -------------------------------------------------------------------------------- 1 | class Python3 < Package 2 | url 'https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz' 3 | sha256 '81fd1401a9d66533b0a3e9e3f4ea1c7c6702d57d5b90d659f971e6f1b745f77d' 4 | 5 | label :common 6 | 7 | depends_on :readline 8 | depends_on :openssl 9 | depends_on :libffi 10 | depends_on :zlib 11 | 12 | option 'without-dtrace', 'Disable DTrace support.' 13 | 14 | resource :setuptools do 15 | url 'https://files.pythonhosted.org/packages/ef/1d/201c13e353956a1c840f5d0fbf0461bd45bbd678ea4843ebf25924e8984c/setuptools-40.2.0.zip' 16 | sha256 '47881d54ede4da9c15273bac65f9340f8929d4f0213193fa7894be384f2dcfa6' 17 | end 18 | 19 | resource :pip do 20 | url 'https://files.pythonhosted.org/packages/69/81/52b68d0a4de760a2f1979b0931ba7889202f302072cc7a0d614211bc7579/pip-18.0.tar.gz' 21 | sha256 'a0e11645ee37c90b40c46d607070c4fd583e2cd46231b1c06e389c5e814eed76' 22 | end 23 | 24 | resource :wheel do 25 | url 'https://files.pythonhosted.org/packages/2a/fb/aefe5d5dbc3f4fe1e815bcdb05cbaab19744d201bbc9b59cfa06ec7fc789/wheel-0.31.1.tar.gz' 26 | sha256 '0a2e54558a0628f2145d2fc822137e322412115173e8a2ddbe1c9024338ae83c' 27 | end 28 | 29 | def site_packages 30 | "#{link_lib}/python3.6/site-packages" 31 | end 32 | 33 | def export_env 34 | add_env 'PYTHONPATH', site_packages 35 | end 36 | 37 | def install 38 | # CLI.error 'Use Clang compilers to build Python3!' if OS.mac? and CompilerSet.c.gcc? 39 | ENV['PYTHONHOME'] = nil 40 | ENV['PYTHONPATH'] = nil 41 | args = %W[ 42 | --prefix=#{prefix} 43 | --enable-ipv6 44 | --without-ensurepip 45 | --enable-optimizations 46 | CPPFLAGS="-I#{Openssl.inc}" 47 | LDFLAGS="-L#{Openssl.lib}" 48 | ] 49 | args << without_dtrace? ? '--without-dtrace' : '--with-dtrace' 50 | if not Readline.skipped? 51 | inreplace 'setup.py', 52 | "do_readline = self.compiler.find_library_file(lib_dirs, 'readline')", 53 | "do_readline = '#{Readline.link_lib}/libhistory.#{OS.soname}'" 54 | end 55 | if not Libffi.skipped? 56 | ENV['CPPFLAGS'] = "-I#{Libffi.common_inc}" 57 | ENV['LDFLAGS'] = "-L#{Libffi.common_lib} -L#{Libffi.common_lib64} -lffi" 58 | end 59 | run './configure', *args 60 | # Fix missing zlib module error. 61 | inreplace 'Modules/Setup', { 62 | '#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz' => "zlib zlibmodule.c -I#{Zlib.link_inc} -L#{Zlib.link_lib} -lz" 63 | } 64 | run 'make', skip_test? ? 'build_all' : '' 65 | run 'make', skip_test? ? 'altinstall' : 'install' 66 | run "ln -s #{bin}/python3.6 #{bin}/python3" if not File.exist? "#{bin}/python3" 67 | # Install pip related tools. 68 | install_resource :setuptools, "#{libexec}/setuptools" 69 | install_resource :pip, "#{libexec}/pip", strip_leading_dirs: 1 70 | install_resource :wheel, "#{libexec}/wheel", strip_leading_dirs: 1 71 | mkdir site_packages 72 | ENV['PYTHONPATH'] = site_packages 73 | # Remove possible previous installed resouces. 74 | rm "#{site_packages}/setuptools*" 75 | rm "#{site_packages}/distribute*" 76 | rm "#{site_packages}/pip[-_.][0-9]*" 77 | rm "#{site_packages}/pip" 78 | setup_args = %W[ 79 | -s setup.py 80 | --no-user-cfg 81 | install 82 | --force 83 | --verbose 84 | --single-version-externally-managed 85 | --record=installed.txt 86 | --install-scripts=#{bin} 87 | --install-lib=#{site_packages} 88 | ] 89 | append_ld_library_path lib 90 | work_in "#{libexec}/setuptools" do 91 | run "#{bin}/python3", 'bootstrap.py' 92 | run "#{bin}/python3", *setup_args 93 | end 94 | work_in "#{libexec}/pip" do 95 | run "#{bin}/python3", *setup_args 96 | end 97 | work_in "#{libexec}/wheel" do 98 | run "#{bin}/python3", *setup_args 99 | end 100 | rm "#{libexec}/setuptools*" 101 | rm "#{libexec}/pip" 102 | rm "#{libexec}/wheel" 103 | end 104 | end 105 | -------------------------------------------------------------------------------- /framework/package/package_loader.rb: -------------------------------------------------------------------------------- 1 | module PackageLoader 2 | def self.loaded_packages 3 | @@loaded_packages 4 | end 5 | 6 | def self.loads package_names, options = {} 7 | if package_names.empty? and options[:empty_is_ok] != true 8 | package_names = Dir.glob("#{ENV['STARMAN_ROOT']}/packages/*").map { |x| File.basename(x, '.rb') } 9 | end 10 | @@direct_packages ||= package_names.map &:to_sym 11 | if options[:force] 12 | @@loaded_packages = {} 13 | else 14 | @@loaded_packages ||= {} 15 | end 16 | @@relax = options[:relax] 17 | package_names.each do |package_name| 18 | # package_name may be in @ form. 19 | name, version = package_name.to_s.split '@' 20 | name = name.to_sym 21 | scan name, version: version 22 | end 23 | @@loaded_packages 24 | end 25 | 26 | def self.scan name, options = {} 27 | return if @@loaded_packages.has_key? name 28 | file_path = package_file_path(name, options[:version]) 29 | # Clean dependencies if set previously. 30 | class_name = name.to_s.split(/[-_]/).map(&:capitalize).join 31 | if PackageLoader.const_defined? class_name and const_get(class_name).method_defined? :spec 32 | const_get(class_name).spec.dependencies = {} 33 | end 34 | if File.exist? file_path 35 | eval open(file_path, 'r').read 36 | package = eval("#{name.to_s.split(/[-_]/).map(&:capitalize).join}").new 37 | if not options[:nodeps] and not package.skipped? 38 | package.dependencies.keys.each do |depend_name| 39 | depend_package = scan depend_name, package.dependencies[depend_name] 40 | if depend_package and depend_package.name != depend_name 41 | package.dependencies[depend_package.name] = {} 42 | package.dependencies.delete depend_name 43 | elsif not depend_package 44 | package.dependencies.delete depend_name 45 | end 46 | end 47 | end 48 | # Reset version if not the same. 49 | if options[:version] != nil and options[:version] != package.version.to_s 50 | package.version = options[:version] 51 | end 52 | scan package.group, nodeps: true if package.group 53 | @@loaded_packages[name] = package 54 | else 55 | return if PackageSpecialLabels.check name 56 | possible_packages = [] 57 | search_packages_for_label(name).each do |path| 58 | eval open(path, 'r').read 59 | name = File.basename(path, '.rb') 60 | possible_packages << eval("#{name.to_s.split('@').first.split('-').collect(&:capitalize).join}").new 61 | if History.installed?(possible_packages.last) == true 62 | return scan(possible_packages.last.name) 63 | end 64 | end 65 | if possible_packages.size > 1 and @@relax != true 66 | CLI.error "You should install one of #{possible_packages.map(&:name).join(', ')} first!" 67 | elsif possible_packages.size == 0 68 | CLI.error "Unknown input #{CLI.red name}!" 69 | else 70 | name, version = name.split '@' 71 | scan name, version: version 72 | @@loaded_packages[name].version = options[:version] if options[:version] 73 | end 74 | end 75 | end 76 | 77 | def self.package_file_path name, version 78 | path = "#{ENV['STARMAN_ROOT']}/packages/#{name.to_s.gsub('_', '-')}#{version ? '@' + version : ''}.rb" 79 | if not File.file? path 80 | path = "#{ENV['STARMAN_ROOT']}/packages/#{name.to_s.gsub('_', '-')}.rb" 81 | end 82 | return path 83 | end 84 | 85 | def self.from_cmd_line? package 86 | @@direct_packages.include? package.name or @@direct_packages.include? :"#{package.name}@#{package.version}" or 87 | @@direct_packages.any? do |package_name| 88 | name, version = package_name.to_s.split '@' 89 | name = name.to_sym 90 | loaded_package = @@loaded_packages[name] 91 | next if not loaded_package 92 | loaded_package.dependencies.has_key? package.name and loaded_package.has_label? :group 93 | end 94 | end 95 | 96 | def self.search_packages_for_label label 97 | matches = [] 98 | Dir.glob("#{ENV['STARMAN_ROOT']}/packages/*.rb").each do |path| 99 | matches << path if open(path, 'r').read =~ /label :#{label}/ 100 | end 101 | matches 102 | end 103 | end 104 | -------------------------------------------------------------------------------- /packages/esmf.rb: -------------------------------------------------------------------------------- 1 | class Esmf < Package 2 | url 'https://github.com/esmf-org/esmf/archive/refs/tags/v8.6.0.tar.gz' 3 | sha256 'ed057eaddb158a3cce2afc0712b49353b7038b45b29aee86180f381457c0ebe7' 4 | version '8.6.0' 5 | file_name 'esmf-8.6.0.tar.gz' 6 | 7 | option 'use-mkl', 'Use MKL for LAPACK dependency.' 8 | option 'use-pnetcdf', 'Use Parallel-NetCDF dependency.' 9 | option 'use-pio', 'Use PIO dependency.' 10 | option 'mpi-type', 'Set MPI type.', type: :string, choices: ['mpich', 'mpich2', 'mpich3', 'lam', 'openmpi', 'intelmpi'] 11 | option 'with-esmpy', 'Install ESMPy interface.' 12 | 13 | if use_mkl? 14 | CLI.notice 'Use MKL for LAPACK.' 15 | else 16 | depends_on :lapack 17 | end 18 | depends_on :mpi 19 | depends_on :netcdf 20 | depends_on :pnetcdf if use_pnetcdf? 21 | depends_on :pio if use_pio? 22 | 23 | def export_env 24 | append_env 'PYTHONPATH', "#{lib}/python3.6/site-packages" if Dir.exist? "#{lib}/python3.6/site-packages" 25 | end 26 | 27 | def install 28 | ENV['ESMF_DIR'] = pwd 29 | ENV['ESMF_BOPT'] = 'O' 30 | ENV['ESMF_OPTLEVEL'] = '2' 31 | if CompilerSet.c.vendor == :gcc and CompilerSet.fortran.vendor == :gcc 32 | CLI.error "ESMF needs gfortran with version >= 4.3!" if CompilerSet.fortran.version <= '4.3' 33 | ENV['ESMF_COMPILER'] = 'gfortran' 34 | elsif CompilerSet.c.vendor == :gcc and CompilerSet.fortran.vendor == :intel 35 | ENV['ESMF_COMPILER'] = 'intelgcc' 36 | elsif CompilerSet.c.vendor == :intel and CompilerSet.fortran.vendor == :intel 37 | ENV['ESMF_COMPILER'] = 'intel' 38 | else 39 | CLI.error "Unsupported compiler set!" 40 | end 41 | ENV['ESMF_INSTALL_PREFIX'] = prefix 42 | ENV['ESMF_INSTALL_BINDIR'] = bin 43 | ENV['ESMF_INSTALL_HEADERDIR'] = inc 44 | ENV['ESMF_INSTALL_LIBDIR'] = lib 45 | ENV['ESMF_INSTALL_MODDIR'] = inc 46 | if use_mkl? 47 | ENV['ESMF_LAPACK'] = 'mkl' 48 | else 49 | ENV['ESMF_LAPACK'] = 'system' 50 | ENV['ESMF_LAPACK_LIBPATH'] = Dir.exist?(Lapack.link_lib64) ? Lapack.link_lib64 : Lapack.link_lib 51 | ENV['ESMF_LAPACK_LIBS'] = '-llapack -lblas' 52 | end 53 | ENV['ESMF_NETCDF'] = 'nc-config' 54 | ENV['ESMF_PNETCDF'] = 'pnetcdf-config' if use_pnetcdf? 55 | if use_pio? 56 | ENV['ESMF_PIO'] = Pio.prefix 57 | ENV['ESMF_PIO_INCLUDE'] = Pio.inc 58 | else 59 | ENV['ESMF_PIO'] = 'OFF' 60 | end 61 | if mpi_type 62 | ENV['ESMF_COMM'] = mpi_type.to_s 63 | elsif ENV['MPICXX'] =~ /mpiicpx$/ or ENV['MPICXX'] =~ /mpiicpc$/ or ENV['MPIFC'] =~ /mpiifort$/ 64 | ENV['ESMF_COMM'] = 'intelmpi' 65 | else 66 | CLI.error "You should set #{CLI.blue '--mpi-type'} option!" 67 | end 68 | inreplace 'build_config/Linux.gfortran.default/ESMC_Conf.h', { 69 | 'typedef size_t ESMCI_FortranStrLenArg;' => "#include \ntypedef size_t ESMCI_FortranStrLenArg;" 70 | } 71 | ENV['ESMF_CCOMPILER'] = ENV['MPICC'] 72 | ENV['ESMF_CLINKER'] = ENV['MPICC'] 73 | ENV['ESMF_CXXCOMPILER'] = ENV['MPICXX'] 74 | ENV['ESMF_CXXLINKER'] = ENV['MPICXX'] 75 | ENV['ESMF_F90COMPILER'] = ENV['MPIFC'] 76 | ENV['ESMF_F90LINKER'] = ENV['MPIFC'] 77 | if OS.mac? and CompilerSet.c.vendor == :gcc 78 | ['src/Infrastructure/IO/PIO/configure', 79 | 'src/Infrastructure/IO/PIO/ParallelIO/tests/cperf/CMakeLists.txt', 80 | 'src/Infrastructure/IO/PIO/ParallelIO/examples/c/CMakeLists.txt', 81 | 'src/Infrastructure/IO/PIO/ParallelIO/src/clib/CMakeLists.txt', 82 | 'src/Infrastructure/IO/PIO/ParallelIO/tests/cunit/CMakeLists.txt', 83 | 'src/Infrastructure/IO/PIO/ParallelIO/.github/workflows/autotools.yml'].each do |file| 84 | inreplace file, '-std=c99' => '-std=gnu11' 85 | end 86 | ENV['ESMF_CSTD'] = 'gnu11' 87 | inreplace 'build/common.mk', 'ESMF_CSTDFLAG = -std=c$(ESMF_CSTD)' => 'ESMF_CSTDFLAG = -std=$(ESMF_CSTD)' 88 | end 89 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 90 | run 'make', 'unit_tests' if not skip_test? 91 | run 'make', 'install' 92 | 93 | if with_esmpy? 94 | work_in 'src/addon/ESMPy' do 95 | ENV['ESMFMKFILE'] = "#{lib}/esmf.mk" 96 | run 'python3', 'setup.py', 'build', "--ESMFMKFILE=#{lib}/esmf.mk" 97 | run 'python3', 'setup.py', 'install', "--prefix=#{prefix}" 98 | end 99 | end 100 | end 101 | end 102 | -------------------------------------------------------------------------------- /packages/python3.rb: -------------------------------------------------------------------------------- 1 | class Python3 < Package 2 | url 'https://www.python.org/ftp/python/3.9.9/Python-3.9.9.tar.xz' 3 | sha256 '06828c04a573c073a4e51c4292a27c1be4ae26621c3edc7cf9318418ce3b6d27' 4 | 5 | label :skip_if_exist, binary_file: 'python3.9' 6 | 7 | label :common 8 | 9 | depends_on :bzip2 10 | depends_on :zlib 11 | depends_on :xz 12 | depends_on :readline 13 | depends_on :openssl 14 | depends_on :libffi 15 | 16 | option 'without-dtrace', 'Disable DTrace support.' 17 | 18 | resource :setuptools do 19 | url 'https://files.pythonhosted.org/packages/cd/9a/6fff2cee92de1d34c0e8d48bb2ccedb0899eebb2cfe7955584b53bdaded7/setuptools-59.0.1.tar.gz' 20 | sha256 '899d27ec8104a68d4ba813b1afd66708a1a10e9391e79be92c8c60f9c77d05e5' 21 | end 22 | 23 | resource :pip do 24 | url 'https://files.pythonhosted.org/packages/da/f6/c83229dcc3635cdeb51874184241a9508ada15d8baa337a41093fab58011/pip-21.3.1.tar.gz' 25 | sha256 'fd11ba3d0fdb4c07fbc5ecbba0b1b719809420f25038f8ee3cd913d3faa3033a' 26 | end 27 | 28 | resource :wheel do 29 | url 'https://files.pythonhosted.org/packages/4e/be/8139f127b4db2f79c8b117c80af56a3078cc4824b5b94250c7f81a70e03b/wheel-0.37.0.tar.gz' 30 | sha256 'e2ef7239991699e3355d54f8e968a21bb940a1dbf34a4d226741e64462516fad' 31 | end 32 | 33 | def site_packages 34 | "#{link_lib}/python3.9/site-packages" 35 | end 36 | 37 | def export_env 38 | add_env 'PYTHONPATH', site_packages 39 | end 40 | 41 | def install 42 | CLI.error 'Use Clang compilers to build Python3!' if OS.mac? and CompilerSet.c.gcc? 43 | ENV['PYTHONHOME'] = nil 44 | ENV['PYTHONPATH'] = nil 45 | args = %W[ 46 | --prefix=#{prefix} 47 | --enable-ipv6 48 | --without-ensurepip 49 | ] 50 | unless CompilerSet.c.gcc? and CompilerSet.c.version <= '4.8.5' 51 | # Avoid error 'Could not import runpy module' 52 | args << '--enable-optimizations' 53 | end 54 | args << without_dtrace? ? '--without-dtrace' : '--with-dtrace' 55 | args << "--with-openssl=#{Openssl.prefix}" if not Openssl.skipped? 56 | inreplace 'setup.py', 57 | " zlib_inc = find_file('zlib.h', [], self.inc_dirs)", 58 | " self.inc_dirs.append('#{Zlib.inc}')\n self.lib_dirs.append('#{Zlib.lib}')\n zlib_inc = find_file('zlib.h', [], self.inc_dirs)" 59 | ENV['CPPFLAGS'] = "-I#{Zlib.inc} -I#{Bzip2.link_inc} -I#{Xz.link_inc}" 60 | ENV['LDFLAGS'] = "-L#{Zlib.lib} -L#{Bzip2.link_lib} -L#{Xz.link_lib} -Wl,-rpath,#{Openssl.lib} -Wl,-rpath,#{Zlib.lib}" 61 | if not Readline.skipped? 62 | inreplace 'setup.py', 63 | "do_readline = self.compiler.find_library_file(lib_dirs, 'readline')", 64 | "do_readline = '#{Readline.link_lib}/libhistory.#{OS.soname}'" 65 | end 66 | if not Libffi.skipped? 67 | ENV['CPPFLAGS'] += " -I#{Libffi.link_inc}" 68 | ENV['LDFLAGS'] += " -L#{Libffi.link_lib} -L#{Libffi.link_lib64}" 69 | # See: https://unix.stackexchange.com/questions/631725/how-do-i-build-pkgconf-and-libffi-and-subsequently-python3-9-with-ctypes-support 70 | inreplace 'setup.py', 71 | ' def detect_decimal(self):', 72 | " ext.libraries.append('ffi')\n\n def detect_decimal(self):" 73 | end 74 | run './configure', *args 75 | run 'make', multiple_jobs? ? "-j#{jobs_number}" : '' 76 | run 'make', 'install' 77 | # Install pip related tools. 78 | install_resource :setuptools, "#{libexec}/setuptools" 79 | install_resource :pip, "#{libexec}/pip", strip_leading_dirs: 1 80 | install_resource :wheel, "#{libexec}/wheel", strip_leading_dirs: 1 81 | mkdir site_packages 82 | ENV['PYTHONPATH'] = site_packages 83 | # Remove possible previous installed resouces. 84 | rm "#{site_packages}/setuptools*" 85 | rm "#{site_packages}/distribute*" 86 | rm "#{site_packages}/pip[-_.][0-9]*" 87 | rm "#{site_packages}/pip" 88 | setup_args = %W[ 89 | -s setup.py 90 | --no-user-cfg 91 | install 92 | --force 93 | --verbose 94 | --single-version-externally-managed 95 | --record=installed.txt 96 | --install-scripts=#{bin} 97 | --install-lib=#{site_packages} 98 | ] 99 | append_ld_library_path lib 100 | work_in "#{libexec}/setuptools" do 101 | run "#{bin}/python3", 'bootstrap.py' 102 | run "#{bin}/python3", *setup_args 103 | end 104 | work_in "#{libexec}/pip" do 105 | run "#{bin}/python3", *setup_args 106 | end 107 | work_in "#{libexec}/wheel" do 108 | run "#{bin}/python3", *setup_args 109 | end 110 | rm "#{libexec}/setuptools" 111 | rm "#{libexec}/pip" 112 | rm "#{libexec}/wheel" 113 | end 114 | end 115 | -------------------------------------------------------------------------------- /packages/vim.rb: -------------------------------------------------------------------------------- 1 | class Vim < Package 2 | url 'https://github.com/vim/vim/archive/v8.2.0348.tar.gz' 3 | sha256 '63a178c80f1dfffd85071eaeec52b7614955237c4920aa726bef694a13ec440e' 4 | version '8.2.0348' 5 | file_name 'vim-8.2.0348.tar.gz' 6 | 7 | label :common 8 | 9 | option 'with-python', 'Build Python3 support.' 10 | 11 | depends_on :lua 12 | depends_on :python3 if with_python? 13 | depends_on :ncurses 14 | 15 | resource :neocomplete do 16 | # This plugin is not compatible with above Vim 8.2.1066! 17 | url 'https://github.com/Shougo/neocomplete.vim/archive/4be617947f3fcf2d725fab20b0e12f8b46c9e2f3.zip' 18 | sha256 '41ec5f593981d7455f482ea9adb68dbd31d3a93ef09f4a5be2135b9ad3398cc4' 19 | file_name 'neocomplete.4be617.zip' 20 | end 21 | 22 | resource :neosnippet_snippets do 23 | url 'https://github.com/Shougo/neosnippet-snippets/archive/e5946e9ec4c68965dbabfaaf2584b1c057738afd.zip' 24 | sha256 '9a8c4ba5228dbcd19ba73d1d179b730fd8fbe24751651eb08431720d5b90625d' 25 | file_name 'neosnippet_snippets.e5946e.zip' 26 | end 27 | 28 | resource :neosnippet do 29 | url 'https://github.com/Shougo/neosnippet.vim/archive/f7755084699db69ce9ff51c87baf8e639b7e543a.zip' 30 | sha256 'dfd39a8bfa40b18e8d90a084c77621db4dbd267e8fdf792ae27c1ac8934393e0' 31 | file_name 'neosnippet.f77550.zip' 32 | end 33 | 34 | resource :nerdtree do 35 | url 'https://github.com/scrooloose/nerdtree/archive/d6032c876c6d6932ab7f07e262a16c9a85a31d5b.zip' 36 | sha256 'b2c56084bd9636a9d720fefcc099fea7c6854f8f01b5402acc1c875e9eabe37f' 37 | file_name 'nerdtree.d6032c.zip' 38 | end 39 | 40 | resource :vim_ncl do 41 | url 'https://github.com/dongli/vim-ncl/archive/f4019ebe70df9f1bd2b9a491ea244a7d565f558a.zip' 42 | sha256 '042cf88d46ca99e436e43aa6778229cacd5ba86567127ae8e27d5baeccb6d441' 43 | file_name 'vim_ncl.f4019e.zip' 44 | end 45 | 46 | resource :numbertoggle do 47 | url 'https://github.com/jeffkreeftmeijer/vim-numbertoggle/archive/2.1.1.zip' 48 | sha256 '29212786f53743a55ac8f54f681e4287110e67da953f9cf615ba7eb4570b54ed' 49 | file_name 'numbertoggle.cfaecb9.zip' 50 | end 51 | 52 | def install 53 | args = %W[ 54 | --prefix=#{prefix} 55 | --enable-multibyte 56 | --enable-gui=no 57 | --enable-cscope 58 | --enable-luainterp=yes 59 | --with-lua-prefix='#{Lua.prefix}' 60 | --without-x 61 | --with-features=huge 62 | ] 63 | if not OS.mac? and not CompilerSet.c.clang? 64 | args << "--with-tlib=ncurses CPPFLAGS='-I#{Ncurses.inc}' LDFLAGS='-L#{Ncurses.lib}'" 65 | end 66 | if CompilerSet.c.clang? 67 | inreplace 'src/auto/configure', { 68 | '#ifdef HAVE_STDINT_H' => "#include \n#ifdef HAVE_STDINT_H" 69 | } 70 | end 71 | if with_python? 72 | args << '--enable-python3interp=yes' 73 | args << "--with-python3-command='#{Python3.bin}/python3'" 74 | end 75 | run './configure', *args 76 | run 'make' 77 | run 'make', 'install', "prefix=#{prefix}", 'STRIP=true' 78 | ln "#{bin}/vim", "#{bin}/vi" 79 | # Install handy plugins. 80 | mkdir "#{share}/vim/vim82/pack/dist/start" do 81 | install_resource :neocomplete, '.' 82 | install_resource :neosnippet_snippets, '.' 83 | install_resource :neosnippet, '.' 84 | install_resource :nerdtree, '.' 85 | install_resource :vim_ncl, '.' 86 | install_resource :numbertoggle, '.' 87 | end 88 | # Create a vimrc for users. 89 | write_file "#{share}/vim/vimrc", <<-EOS 90 | " Setup neocomplete and neosnippet. 91 | let g:neocomplete#enable_at_startup = 1 92 | let g:neocomplete#enable_smart_case = 1 93 | " Left and right arrows are used to close popup menu. 94 | imap neocomplete#close_popup()."\" 95 | imap neocomplete#close_popup()."\" 96 | " When popup menu is open, close it or just print . 97 | imap pumvisible() ? neocomplete#close_popup() : "\" 98 | " When popup menu is open, iterate the candidate options or expand expandables. 99 | imap pumvisible() ? "\" : neosnippet#expandable_or_jumpable() ? "\(neosnippet_expand_or_jump)" : "\" 100 | let g:neosnippet#enable_snipmate_compatibility = 1 101 | let g:neosnippet#snippets_directory='~/.vim/snippets' 102 | " Setup nerdtree. 103 | autocmd BufEnter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif 104 | map :NERDTreeToggle 105 | set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936 106 | set termencoding=utf-8 107 | set encoding=utf-8 108 | " Silly VIM does not delete characters by DELETE key default. 109 | set backspace=indent,eol,start 110 | EOS 111 | CLI.caveat "Please add the following line into your ~/.vimrc.\nsource #{share}/vim/vimrc" 112 | end 113 | end 114 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | This is the third time I rewrote this package manager, and hope this will be 5 | the final version. This time I try to simplify the design to make STARMAN 6 | robust and focus on HPC usage. I set down the following goals: 7 | 8 | * [X] User can use `load` command to change shell environment for specific packages 9 | like `modules`. 10 | * [X] Use database to manage information. 11 | * [ ] Support package update which is lacked in previous version. 12 | 13 | Prerequisites 14 | ============= 15 | 16 | STARMAN is implemented by using Ruby programming language which is good at 17 | writing DSL (Domain Specific Language), so the system should have Ruby 18 | installed. 19 | 20 | - Ruby >= 2.0 21 | - SQLite 22 | 23 | Installation 24 | ============ 25 | 26 | Put STARMAN in any location, and add the following `source` statement in your `.bashrc`: 27 | 28 | ``` 29 | source /setup/bashrc 30 | ``` 31 | 32 | Relogin. Then run setup command to kickoff: 33 | 34 | ``` 35 | starman setup --install-root \ 36 | --rc-root \ 37 | --cache-root 38 | ``` 39 | 40 | Where `rc_root` (default is `$USER/.starman`) stores `config` and `history.db` 41 | which should be accessible by anyone who needs to use STARMAN, and `cache_root` 42 | (default is `/tmp/starman`) is used to store package source codes. *You can put 43 | predownloaded packages into `cache_root` to avoid download.* 44 | 45 | Usage 46 | ===== 47 | 48 | When first use, you need to edit the configuration by running: 49 | 50 | ``` 51 | starman config 52 | ``` 53 | 54 | An example is: 55 | ``` 56 | --- 57 | install_root: /nfs/software 58 | cache_root: /tmp/starman 59 | defaults: 60 | compiler_set: ifort_2013.2.146 61 | compiler_sets: 62 | ifort_2013.2.146: 63 | c: /nfs/software/intel/composer_xe_2013.2.146/bin/intel64/icc 64 | cxx: /nfs/software/intel/composer_xe_2013.2.146/bin/intel64/icpc 65 | fortran: /nfs/software/intel/composer_xe_2013.2.146/bin/intel64/ifort 66 | ``` 67 | 68 | You are advised to give each compiler set a good name, and NEVER change them 69 | since they will be casted into packages' prefix. 70 | 71 | You can list the help message of each command by: 72 | 73 | ``` 74 | $ starman -h/--help 75 | ``` 76 | 77 | ``` 78 | _______ _______ _______ ______ __ __ _______ __ _ 79 | | || || _ || _ | | |_| || _ || | | | 80 | | _____||_ _|| |_| || | || | || |_| || |_| | 81 | | |_____ | | | || |_||_ | || || | 82 | |_____ | | | | || __ || || || _ | 83 | _____| | | | | _ || | | || ||_|| || _ || | | | 84 | |_______| |___| |__| |__||___| |_||_| |_||__| |__||_| |__| 85 | 86 | STARMAN: Another package manager for Linux/Mac programmer. 87 | Copyright (C) 2015-2018 - All Rights Reserved. 88 | 89 | >>> starman install ... [options] 90 | 91 | -r, --rc-root PATH Set runtime configuration root directory. 92 | -d, --debug Print debug information. 93 | -v, --verbose Print more information including build output. 94 | -c, --compiler-set NAME Set the active compiler set by its name set in conf file. 95 | -k, --skip-test Skip possible build test (e.g., make test). 96 | -j, --make-jobs NUMBER Set the number of making jobs (currently only works for hdf5 and netcdf). 97 | -h, --help Print this help message. 98 | ``` 99 | 100 | Install package 101 | --------------- 102 | 103 | ``` 104 | $ starman install netcdf 105 | ``` 106 | 107 | or 108 | 109 | ``` 110 | $ starman install hdf5 -j 4 # Currently only works for hdf5 and netcdf. 111 | ``` 112 | 113 | to use more threads to build hdf5. 114 | 115 | Load package 116 | ------------ 117 | 118 | In your `.bashrc` after STARMAN source statement, add the load commands: 119 | 120 | ``` 121 | starman load netcdf 122 | ``` 123 | 124 | This command will load the environment settings (e.g., `PATH`, 125 | `LD_LIBRARY_PATH`) into current shell (currently only BASH). You can use 126 | `NETCDF_ROOT` environment variable in any place you need to refer to the 127 | location of netcdf. 128 | 129 | Uninstall package 130 | ----------------- 131 | 132 | ``` 133 | $ starman uninstall netcdf 134 | ``` 135 | 136 | or 137 | 138 | ``` 139 | $ starman rm netcdf 140 | ``` 141 | 142 | Contribution 143 | ============ 144 | 145 | If you are familiar with package installation and system admin, you can 146 | contribute new packages by writing a package `DSL` file in Ruby language as 147 | [netcdf-c.rb](https://github.com/dongli/starman/blob/master/packages/netcdf-c.rb). 148 | -------------------------------------------------------------------------------- /framework/settings.rb: -------------------------------------------------------------------------------- 1 | class Settings 2 | extend Utils 3 | 4 | @@settings = {} 5 | 6 | def self.settings 7 | @@settings 8 | end 9 | 10 | def self.install_root 11 | @@settings['install_root'] 12 | end 13 | 14 | def self.cache_root 15 | @@settings['cache_root'] 16 | end 17 | 18 | def self.link_root package = nil 19 | if package and package != Package 20 | if package.has_label? :not_link 21 | package.prefix 22 | elsif package.has_label? :alone 23 | File.dirname(package.prefix) + '/link' 24 | elsif package.has_label? :common and not @@settings['no_common'] 25 | common_root 26 | elsif package.has_label? :compiler 27 | File.dirname(File.dirname(File.dirname(package.prefix))) 28 | else 29 | "#{Settings.install_root}/#{Settings.compiler_set}" 30 | end 31 | else 32 | "#{Settings.install_root}/#{Settings.compiler_set}" 33 | end 34 | end 35 | 36 | def self.common_root 37 | "#{install_root}/common" 38 | end 39 | 40 | def self.conf_file 41 | "#{Runtime.rc_root}/conf.yml" 42 | end 43 | 44 | def self.compiler_set 45 | CommandParser.args[:compiler_set] || @@settings['defaults']['compiler_set'] 46 | end 47 | 48 | def self.compilers 49 | @@settings['compiler_sets'][compiler_set] 50 | end 51 | 52 | def self.c_compiler 53 | compilers['c'] || compilers[:c] rescue CLI.error 'Invalid C compiler!' 54 | end 55 | 56 | def self.cxx_compiler 57 | compilers['cxx'] || compilers[:cxx] rescue nil 58 | end 59 | 60 | def self.fortran_compiler 61 | compilers['fortran'] || compilers[:fortran] rescue nil 62 | end 63 | 64 | def self.mpi_c_compiler 65 | compilers['mpi_c'] || compilers[:mpi_c] rescue nil 66 | end 67 | 68 | def self.mpi_cxx_compiler 69 | compilers['mpi_cxx'] || compilers[:mpi_cxx] rescue nil 70 | end 71 | 72 | def self.mpi_fortran_compiler 73 | compilers['mpi_fortran'] || compilers[:mpi_fortran] 74 | end 75 | 76 | def self.nodes 77 | [@@settings['nodes']['master_node'], @@settings['nodes']['slave_nodes']].flatten.uniq 78 | end 79 | 80 | def self.master_node 81 | @@settings['nodes']['master_node'] 82 | end 83 | 84 | def self.slave_nodes 85 | @@settings['nodes']['slave_nodes'] 86 | end 87 | 88 | def self.init options = {} 89 | if File.file? conf_file 90 | @@settings = YAML.load(open(conf_file).read) 91 | @@settings['no_common'] ||= false 92 | return if options[:only_load] 93 | if (not install_root or install_root == '') and not options[:ignore_errors] 94 | CLI.error "#{CLI.red 'install_root'} is not set in #{CLI.blue conf_file}!" 95 | end 96 | if (not compiler_set or compiler_set == '') and not options[:ignore_errors] 97 | CLI.error "#{CLI.red 'compiler_set'} is not set in #{CLI.blue conf_file}!" 98 | end 99 | set_compile_env 100 | if CommandParser.args[:verbose] and not options[:silent] 101 | CLI.notice "Use #{CLI.blue compiler_set} compilers." 102 | ['CC', 'CXX', 'FC', 'MPICC', 'MPICXX', 'MPIFC', 'MPIF90', 'MPIF77'].each do |env| 103 | CLI.notice "#{env} = #{CLI.blue ENV[env]}" if ENV[env] 104 | end 105 | end 106 | end 107 | end 108 | 109 | def self.write options = nil 110 | if options 111 | if File.file? conf_file and not options[:force] 112 | CLI.error "#{CLI.red conf_file} exists! Overwrite it by using --force option!" 113 | end 114 | if not options[:just_write] 115 | @@settings['install_root'] = options[:install_root] if options[:install_root] 116 | @@settings['cache_root'] = options[:cache_root] if options[:cache_root] 117 | @@settings['no_common'] = options[:no_common] || false 118 | if system_command? CommandParser.args[:cc] and system_command? CommandParser.args[:cxx] 119 | if CommandParser.args[:compiler_set] 120 | tag = CommandParser.args[:compiler_set] 121 | else 122 | if CommandParser.args[:cc] =~ /gcc/ 123 | res = `#{CommandParser.args[:cc]} -v 2>&1`.match(/^gcc\s+.+\s+(\d+\.\d+\.\d+)/)[1] rescue nil 124 | elsif CommandParser.args[:cc] =~ /clang/ 125 | res = `#{CommandParser.args[:cc]} -v 2>&1`.match(/version\s(\d+\.\d+\.\d+)/)[1] rescue nil 126 | elsif CommandParser.args[:cc] =~ /icc/ 127 | res = `#{CommandParser.args[:cc]} -v 2>&1`.match(/^icc\s*(\(ICC\)|version)*\s*(\d+\.\d+(\.\d+)?)/)[2] rescue nil 128 | elsif CommandParser.args[:cc] =~ /nvcc/ 129 | res = `#{CommandParser.args[:cc]} --version 2>&1`.match(/V(\d+\.\d+(\.\d+)?)/)[1] rescue nil 130 | end 131 | if res 132 | version = res 133 | else 134 | CLI.error "Failed to check version of #{`which #{CommandParser.args[:cc]}`.chomp}!".chomp 135 | end 136 | tag = "#{File.basename(CommandParser.args[:cc]).gsub(/-.*$/, '')}_#{version}" 137 | end 138 | @@settings['defaults'] = { 'compiler_set' => tag } 139 | @@settings['compiler_sets'] = { tag => {} } 140 | @@settings['compiler_sets'][tag]['c'] = which(CommandParser.args[:cc]) 141 | @@settings['compiler_sets'][tag]['cxx'] = which(CommandParser.args[:cxx]) 142 | @@settings['compiler_sets'][tag]['fortran'] = which(CommandParser.args[:fc]) if system_command? CommandParser.args[:fc] 143 | else 144 | CLI.warning "There are no GCC compilers. Install ones or use your preferred ones, and run again with #{CLI.red '-f'} option!" 145 | end 146 | end 147 | end 148 | begin 149 | write_file conf_file, @@settings.to_yaml 150 | rescue Errno::EACCES => e 151 | CLI.error "Failed to create runtime configuration directory at #{CLI.red Runtime.rc_root}!\n#{e}" 152 | end 153 | if not File.file? conf_file 154 | CLI.notice "Create runtime configuration directory #{CLI.blue Runtime.rc_root}." 155 | CLI.notice "Please edit #{CLI.blue conf_file} to suit your environment and come back." 156 | end 157 | end 158 | end 159 | --------------------------------------------------------------------------------