# RPerl Install Notes
# Last Updated September 3, 2015

#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# NOTE: STEP 1 IS ONLY FOR SINGLE-USER INSTALL, NOT SYSTEM-WIDE INSTALL
# IMPORTANT WARNING: ONLY USE ONE OF STEP 1A, 1B, OR 1C - NOT ALL THREE
# IMPORTANT WARNING: ONLY USE ONE OF STEP 2A OR 2B - NOT BOTH
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

################################################################################
# STEP 0.
# PRE-INSTALL, GCC & MAKEMAKER MUST BE UP-TO-DATE & INSTALLED SYSTEM-WIDE
################################################################################

$ g++ --version
	# must be v4.7 or higher
$ apt-get install g++
	# OR
$ wget http://people.centos.org/tru/devtools-1.1/devtools-1.1.repo -P /etc/yum.repos.d
$ sh -c 'echo "enabled=1" >> /etc/yum.repos.d/devtools-1.1.repo'
$ yum install devtoolset-1.1
$ export CC=/opt/centos/devtoolset-1.1/root/usr/bin/gcc  
$ export CPP=/opt/centos/devtoolset-1.1/root/usr/bin/cpp
$ export CXX=/opt/centos/devtoolset-1.1/root/usr/bin/c++
	# OR
$ wget http://www.netgull.com/gcc/releases/gcc-5.2.0/gcc-5.2.0.tar.bz2  # or other mirror
$ tar -xjvf gcc-5.2.0.tar.bz2
$ cd gcc-5.2.0
$ ./configure
$ make

$ mv ~/perl5 ~/perl5.old  # disable any previous local::lib or Perlbrew
$ perl -v  # NOTE! the version of Perl determines whether you take step 1A or 1B
$ perl -MExtUtils::MakeMaker\ 999  # v7.04 or greater required by Inline::C
$ cpan ExtUtils::MakeMaker  # cpan system-wide, not cpanm single-user

# Optional C++ formatter, Artistic Style
$ sudo apt-get install astyle
# OR
# visit http://astyle.sourceforge.net/

################################################################################
# STEP 1A.  ONLY FOR NORMAL OPERATING SYSTEMS, NOT DEBIAN WITH BROKEN PERL v5.14
# INSTALL LOCAL::LIB & CPANMINUS, DO NOT MIX WITH 1B (PERLBREW)
################################################################################

$ curl -L cpanmin.us | perl - -l $HOME/perl5 App::cpanminus local::lib
$ echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >> ~/.bashrc
$ source ~/.bashrc;  set | grep perl5
# Ensure the following 4 environmental variables are updated to include ~/perl5: 
# PERL_MM_OPT, PERL_MB_OPT, PERL5LIB, PATH

################################################################################
# STEP 1B.  ONLY FOR DEBIAN WITH BROKEN PERL v5.14 AND ANYBODY WITH PERL <=v5.8
# INSTALL PERLBREW & CPANMINUS, DO NOT MIX WITH 1A (LOCAL::LIB)
################################################################################

$ wget http://www.cpan.org/src/5.0/perl-5.20.2.tar.bz2; tar -xjvf perl-5.20.2.tar.bz2; cd perl-5.20.2; ./Configure -des; make; make test; make install  # IS THIS CORRECT???
# OR
$ curl https://raw.githubusercontent.com/tokuhirom/Perl-Build/master/perl-build | perl - 5.20.2 /install/path/perl-5.20.2/
# OR
$ sudo apt-get install perlbrew
# OR
$ curl -L http://install.perlbrew.pl | bash

$ echo 'source ~/perl5/perlbrew/etc/bashrc' >> ~/.bashrc
$ source ~/.bashrc; set | grep PERL
    # Ensure the following 3 environmental variables are updated to include ~/perl5: 
    # PERLBREW_MANPATH, PERLBREW_PATH, PERLBREW_ROOT
$ perlbrew init
$ perlbrew mirror  # Arlington, TX  http://mirror.uta.edu/CPAN/

$ perlbrew install perl-5.20.2
$ perlbrew use perl-5.20.2  # TEMPORARY, THIS SESSION ONLY
$ perlbrew switch perl-5.20.2  # PERMANENT, FUTURE SESSIONS
$ perlbrew off
$ perlbrew install-cpanm
$ perl -MExtUtils::MakeMaker\ 999  # v7.04 or greater required by Inline::C
$ cpanm ExtUtils::MakeMaker  # cpanm single-user, due to perlbrew overriding cpan system-wide

################################################################################
# STEP 1C.  ONLY FOR WINDOWS
# INSTALL STRAWBERRY PERL
################################################################################

# RPerl on Windows requires Strawberry Perl v5.20 or higher.
# http://strawberryperl.com/

# RPerl system developers may use the Mingw64 GCC v4.8 compiler.
# The Mingw64 GCC v4.6 and older compilers are not compatible.

################################################################################
# STEP 2A.  FOR NORMAL RPERL USERS
# INSTALL RPERL & DEPENDENCIES, CPAN RELEASE VERSION, DO NOT MIX WITH 2B
################################################################################

$ cpanm -v RPerl
# OR
$ cpan RPerl  # if cpanm is not installed

################################################################################
# STEP 2B.  ONLY FOR RPERL DEVELOPERS
# INSTALL RPERL & DEPENDENCIES, GITHUB DEVELOPMENT VERSION, DO NOT MIX WITH 2A
################################################################################

# Complete 'SET UP SSH KEYS' section of Git Notes before `git clone` below.
# https://github.com/wbraswell/lampuniversity.org/blob/master/docs/git_notes.txt
$ git clone https://github.com/wbraswell/rperl.git  # public git
# OR
$ git clone git@github.com:wbraswell/rperl.git  # secured git
# OR
$ wget https://github.com/wbraswell/rperl/archive/master.zip;  unzip master.zip

$ cd rperl*
$ perl Makefile.PL
$ cpanm --installdeps .  # note the dot at the end of this command
$ make; make test; make install
# OR
$ make; make test TEST_VERBOSE=1; make install

################################################################################
# STEP 3.
# RUN RPERL COMPILER
################################################################################

# Optional environmental variables
$ export RPERL_VERBOSE=1   # additional user output, off by default
$ export RPERL_DEBUG=1     # additional system output, off by default
$ export RPERL_WARNINGS=0  # additional user & system warnings, on by default

# Run RPerl test commands from within RPerl installation directory
$ cd ~/perl5/lib/perl5  # for step 1A local::lib installs
# OR
$ cd OTHER_RPERL_INSTALL_DIRECTORY

# Display command usage
$ rperl -?

# Compile & run RPerl test commands
$ export RPERL_DEBUG=1

# [[[ Test command sequence #1: OO INHERITANCE TEST ]]]

$ rm -Rf _Inline RPerl/Algorithm.pmc RPerl/Algorithm.h RPerl/Algorithm.cpp RPerl/Algorithm/Sort.pmc RPerl/Algorithm/Sort.h RPerl/Algorithm/Sort.cpp RPerl/Algorithm/Sort/Bubble.pmc RPerl/Algorithm/Sort/Bubble.h RPerl/Algorithm/Sort/Bubble.cpp
$ perl -e 'use RPerl::Algorithm::Sort::Bubble; my $o = RPerl::Algorithm::Sort::Bubble->new(); $o->inherited__Bubble("logan");  $o->inherited__Sort("wolvie");  $o->inherited__Algorithm("claws");'
    # should be PERLOPS_PERLTYPES, PERLOPS_PERLTYPES, PERLOPS_PERLTYPES
    
$ rperl -V RPerl/Algorithm.pm
$ perl -e 'use RPerl::Algorithm::Sort::Bubble; my $o = RPerl::Algorithm::Sort::Bubble->new(); $o->inherited__Bubble("logan");  $o->inherited__Sort("wolvie");  $o->inherited__Algorithm("claws");'
    # should be PERLOPS_PERLTYPES, PERLOPS_PERLTYPES, CPPOPS_CPPTYPES

$ rperl -V RPerl/Algorithm/Sort.pm
$ perl -e 'use RPerl::Algorithm::Sort::Bubble; my $o = RPerl::Algorithm::Sort::Bubble->new(); $o->inherited__Bubble("logan");  $o->inherited__Sort("wolvie");  $o->inherited__Algorithm("claws");'
    # should be PERLOPS_PERLTYPES, CPPOPS_CPPTYPES, CPPOPS_CPPTYPES

$ rperl -V RPerl/Algorithm/Sort/Bubble.pm
$ perl -e 'use RPerl::Algorithm::Sort::Bubble; my $o = RPerl::Algorithm::Sort::Bubble->new(); $o->inherited__Bubble("logan");  $o->inherited__Sort("wolvie");  $o->inherited__Algorithm("claws");'
    # should be CPPOPS_CPPTYPES, CPPOPS_CPPTYPES, CPPOPS_CPPTYPES

# [[[ Test command sequence #2: BUBBLESORT TIMING TEST ]]]

$ rm -Rf _Inline RPerl/Algorithm.pmc RPerl/Algorithm.h RPerl/Algorithm.cpp RPerl/Algorithm/Sort.pmc RPerl/Algorithm/Sort.h RPerl/Algorithm/Sort.cpp RPerl/Algorithm/Sort/Bubble.pmc RPerl/Algorithm/Sort/Bubble.h RPerl/Algorithm/Sort/Bubble.cpp
$ perl -e 'use RPerl::Algorithm::Sort::Bubble; my $a = [reverse 0 .. 5000]; use Time::HiRes qw(time); my $start = time; my $s = integer_bubblesort($a); my $elapsed = time - $start; print Dumper($s); print "elapsed: " . $elapsed . "\n";'
    # SLOW...  :-(  approx 15 seconds for 5000 elements, 60 for 10000

$ rperl -V lib/RPerl/Algorithm/Sort/Bubble.pm
$ perl -e 'use RPerl::Algorithm::Sort::Bubble; my $a = [reverse 0 .. 5000]; use Time::HiRes qw(time); my $start = time; my $s = integer_bubblesort($a); my $elapsed = time - $start; print Dumper($s); print "elapsed: " . $elapsed . "\n";'
	# same exact command as above...
    # FAST!!!  :-D  approx 0.045 seconds for 5000 elements, 0.18 for 10000

# [[[ Test command sequence #3: N-BODY TIMING TEST ]]]

$ export PATH=script:$PATH
$ export PERL5LIB=lib:$PATH
$ wget https://github.com/wbraswell/physicsperl/archive/master.zip
$ unzip master.zip
$ cd physicsperl-master
$ ./script/unlink_astro.sh

$ ./script/nbody.perl-3.pl
    # SLOW...  :-(  thousands of seconds for 50M steps w/out graphics
	
$ rperl lib/PhysicsPerl/Astro/System.pm
$ ./script/nbody.perl-3.pl
    # FAST!!!  :-D  approx 13 seconds for 50M steps w/out graphics!
