gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > libnds Install Script for Linux

#169934 - RyanFox - Sun Aug 16, 2009 8:04 am

The latest version of this script can be found at here.

Hey guys,
I'm not sure if anyone's already done this (a quick search revealed nothing), but I wrote myself an install script for libnds, devkitARM, etc.

When it's run, it will check Sourceforge for the latest files, download them, install into the proper directory structure (under the current directory) and then add lines to ~/.bashrc to set up the environment variables.

I've only tested this on my own computer, so I make no guarantees for it.

Edit: Apparently, I didn't test well enough, as I just found a bug. Now it should work. :)

Code:
#!/usr/bin/perl
use strict;
use warnings;
use LWP::Simple;
use List::Util qw(maxstr);
use Date::Manip;

my $arch = `uname -m`; chomp($arch);
my $os = "linux";

my $pages_base = "http://sourceforge.net/projects/devkitpro/files";
my $download_base = "http://downloads.sourceforge.net/project/devkitpro";

my @pages =
(
 "devkitARM",
 "libnds",
 "default%20arm7",
 "maxmod",
 "dswifi",
 "libfat",
 "filesystem",
 "examples_%20nds",
);

print "Downloading the latest Nintendo DS development tool chain files...\n\n";

foreach my $page (@pages)
{
    my %options;
    my $page_data;

    # If we don't get the page, try again twice more.
    for(my $i = 0; $i < 3; ++$i)
    {
        $page_data = get("$pages_base/$page");
        if ($page_data)
        {
            last;
        }
    }
    if (!$page_data)
    {
        print "Failed 3 attempts to access $pages_base/$page.\n";
    }

    my @content = split(/\n/,$page_data);
   
    foreach(@content)
    {
        if (/title="\/(.*($arch)?.*($os)?.*tar.*):\s* released on (.*)"/ && !/src/ && !/gba/ && !/ogc/)
        {
            my $key = ParseDate($4);
            my $val = $1;

            # Replace spaces to work properly in the URL.
            $val =~ s/ /%20/g;

            $options{$key} = $val;
        }
    }

    `wget -c -nc $download_base/$options{maxstr(keys %options)}`;
}

my $current_dir = `pwd`; chomp($current_dir);

print "Extracting downloaded archives...\n";

print `tar -xvjf devkitARM*.tar.bz2`;

mkdir "libnds";
chdir "libnds";

my @files = ("libnds", "libfat", "dswifi", "maxmod", "default_arm7", "libfilesystem");
foreach(@files)
{
    print `tar -xvjf ../$_*.tar.bz2`;
}

chdir "..";
mkdir "examples";
chdir "examples";
mkdir "ds";
chdir "ds";
print `tar -xvjf ../../nds-examples*.tar.bz2`;

`echo "export DEVKITPRO=$current_dir" >> ~/.bashrc`;
`echo "export DEVKITARM=\\\$DEVKITPRO/devkitARM" >> ~/.bashrc`;


Last edited by RyanFox on Thu Sep 10, 2009 4:01 am; edited 1 time in total

#169939 - gauauu - Sun Aug 16, 2009 10:21 pm

Thanks for posting that. I always forget to grab default_arm7 and get annoyed when I try to set it all up under linux.

#169961 - zazery - Wed Aug 19, 2009 1:20 am

I've been manually downloading and building everything from source. Next time I need to install or update I will certainly try this script. Thanks for sharing.

#170019 - wintermute - Sat Aug 22, 2009 12:54 pm

Interesting.

I have been trying to put together a universal installer that works on linux/OSX/win but it's going pretty slowly. Your script looks like it might be helpful in the meantime.

You might want to try parsing http://devkitpro.sourceforge.net/devkitProUpdate.ini instead of scraping the SF pages - we did that with the original installer to obtain a list of mirrors but SF kept reworking the pages and breaking the code.

The toolchain archives are uploaded as devkitARM-<version>-<OS>.tar.bz2

devkitARM_r26-i686-linux.tar.bz2
devkitARM_r26-osx.tar.bz2
devkitARM_r26-x86_64-linux.tar.bz2

you should be able to detect host OS, parse the devkitARM version from the ini file & then build an appropriate filename. OSX has perl installed by default but not wget, you can use curl there though. The windows installer also deletes the devkitARM folder on updates to avoid cruft from the old toolchains building up in there.

If you're willing then I'd be happy to upload an updated script as an official interim method of installing on linux/OSX.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#170051 - RyanFox - Mon Aug 24, 2009 9:53 pm

Thanks for the suggestions. I hadn't considered treating the architecture as part of the OS. That would make it easier to add in the OSX part. I also wasn't sure of how to detect if the user was running OSX. uname says "Linux" on Linux, but apparently for some OSX users, it says "Darwin"? That seemed like something that might change between versions, and I couldn't find anything definitive, so I just left it out.

Also, that INI file you linked to would be very useful. I was having a hard time trying to figure out how to treat the version numbers until I saw that there was a part in the HTML that included the date. I agree that scraping the HTML isn't the best way of doing it, but it was the only way I could find.

The use of wget and tar could be replaced with libraries written entirely in Perl (I was sort of being lazy by using system calls when I wrote the script), and then all of the dependencies could be packaged together (using pp) with a Perl interpreter so that it looks like a single executable. That way, the same code could be used across each platform. You would still need to make the individual packages on the respective platforms though.

I chose to leave the downloaded archives so that if you run the script again, it will a) not re-download the files if they haven't changed; and b) continue downloading the files if they were interrupted. There are other ways of doing these, but again, I was lazy. :P

By all means, feel free to use this script on the main website. I'm happy to contribute.

#170056 - RyanFox - Tue Aug 25, 2009 4:49 am

New version!

This will now check the devkitProUpdate.ini file for file information, rather than scraping the Sourceforge pages, and removes the dependencies on wget and tar (and bash).

It should also be friendly with OSX and Windows, but I can't test them at the moment.

There is a way to programatically add environment variables in Windows, but it involves adding to the registry, so I haven't had a chance to play with that. All of the necessary information is in comments there though, if anyone wants to fill in that gap.

I'm also going to see about getting some packages for those who don't want to get the script's dependencies themselves.

In the meantime, if you need to install a dependency, you should be able to do it by running these commands on the command line:
Code:
cpan Config::INI::Reader
cpan Archive::Tar


Code:
#!/usr/bin/perl
use strict;
use warnings;
use Cwd;
use LWP::Simple;
use Config::INI::Reader;
use Archive::Tar;

# Used to figure out which files to get, based on the user's OS
my $original_extension = '.exe';
my $new_extension = '.tar.bz2';
my $os = lc($^O);
if ($os eq 'linux')
{
    my $arch = `uname -m`; chomp($arch);
    $os = $arch.'-'.$os;
}
elsif ($os eq 'darwin')
{
    $os = 'osx';
}
elsif ($os eq 'mswin32' || $os eq 'cygwin')
{
    $os = 'win32';
    $new_extension = '.exe';
}
else
{
    die "There are no libnds binaries available for your operating system.\n";
}

# Parse the INI file into a hash
my $ini = get('http://devkitpro.sourceforge.net/devkitProUpdate.ini') or die "Unable to access the devkitPro website.\n";
$ini =~ s/win32/$os/g;
$ini =~ s/$original_extension/$new_extension/g;
my %ini_hash = %{Config::INI::Reader->read_string($ini)};

# Files to download for NDS development
# Note: The script currently depends on devkitARM and ndsexamples being first and second in this array.
my @files =
    (
     'devkitARM',
     'ndsexamples',
     'libnds',
     'libndsfat',
     'maxmodds',
     'dswifi',
     'defaultarm7',
     'filesystem',
    );

# Base URL for all files
my $download_base = $ini_hash{devkitProUpdate}{URL};

# Download each file
foreach(@files)
{
    print "Downloading $_ v$ini_hash{$_}{Version}...\n";
    my $file = $ini_hash{$_}{File};
    my $url = "$download_base/$file";
    mirror($url,$file) or die $!;
}

my $f;

# Extract devkitARM into its own directory
$f = $ini_hash{shift(@files)}{File};
print "Extracting $f...\n";
Archive::Tar->extract_archive("$f",1);

# Extract the examples into their own directory
mkdir 'examples';
chdir 'examples';
mkdir 'ds';
chdir 'ds';
$f = $ini_hash{shift(@files)}{File};
print "Extracting $f...\n";
Archive::Tar->extract_archive("../../$f",1);
chdir '../..';

# Extract all of the libraries under the 'libnds' directory
# devkitARM and ndsexamples have been removed from this array by the shift() function.
mkdir 'libnds';
chdir 'libnds';
foreach(@files)
{
    $f = $ini_hash{$_}{File};
    print "Extracting $f...\n";
    Archive::Tar->extract_archive("../$f",1);
}
chdir '..';

# Either set up the user's environment variables, or tell him to do so.
my $current_dir = getcwd;
if ($os eq 'win32' && 0) # The && 0 part will cause this to fail, until I figure out the registry stuff.
{
# Add DEVKITPRO and DEVKITARM environment variables to the registry, using the module found here:
# http://search.cpan.org/perldoc?Win32::TieRegistry
# The values go in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
# From http://msdn.microsoft.com/en-us/library/ms682653%28VS.85%29.aspx
# (Ew, MSDN. I feel dirty!)
}
elsif ($ENV{SHELL} =~ /bash/)
{
    my $home = $ENV{HOME};
   
    print "\nAdding environment variables to $home/.bashrc:\n";
    print "  export DEVKITPRO=$current_dir\n";
    print "  export DEVKITARM=\$DEVKITPRO/devkitARM\n";

    open my $bashrc, ">>$home/.bashrc" or die $!;
    print $bashrc "export DEVKITPRO=$current_dir\n";
    print $bashrc "export DEVKITARM=\$DEVKITPRO/devkitARM\n";
    close $bashrc;
}
else
{
    print "\nPlease set up the following environment variables for your shell:\n";
    print "  DEVKITPRO=$current_dir\n";
    print "  DEVKITARM=\$DEVKITPRO/devkitARM\n";
}

#170215 - shadowghost21 - Tue Sep 08, 2009 10:12 pm

I most appreciate this script! From what I can see from the compiled and correctly installed chain, I see that missed one small thing, compiling the arm7 binary. Oops. This thing works like a charm, again thank for all the work!

#170230 - RyanFox - Thu Sep 10, 2009 3:59 am

FYI, I've made a page for the script here: http://www.eng.uwaterloo.ca/~rcfox/dokuwiki/doku.php?id=devkitarm_libnds_installer_for_linux_osx

It will always have my latest version of the script, since it's linking to the file in SVN.