# Install MinGw, MSYS, GNU Radio, and all it prerequisites (except python) # on a Windows system. # # Python must be installed first in order to run this script. This version # is based on the Python 2.6.5 Windows installer at # http://www.python.org/download/ # import os import sys import shutil import urllib import subprocess # # Install options # install_python_packages = True # wants admin privileges, but can do without install_git = False # requires administrator privileges install_mingw_and_msys = True install_gr_prerequisites = False install_gnuradio_tarball = False install_gnuradio_git = False option_usrp = True option_portaudio = True option_sdl_video = False # doesn't build # # Important locations # # Default is to install on drive containing Python executable # If you override the default, you will need to check the install paths # used by automated installers install_drive = os.path.splitdrive(sys.executable)[0] # install_drive = "D:" # override default here # MinGW and MSYS locations mingw_dir = install_drive+"/MinGW" msys_dir = install_drive+"/msys/1.0" # GNU Radio install directory gr_inst_dir = msys_dir+"/home/"+os.environ['USERNAME'] local_src = msys_dir+"/src" local_bin = msys_dir+"/local/bin" local_dir = os.path.dirname( local_bin ) sh_env = os.environ sh_env['PATH'] = local_bin+";"+mingw_dir+"/bin;"+msys_dir+"/bin;"+os.environ['PATH'] sh_env['MSYSTEM'] = "MINGW32" sh_env['PKG_CONFIG_PATH'] = local_dir+"/lib/pkgconfig" pyv = sys.version_info py_vers = "python%d.%d"%pyv[0:2] numpy_vers = "1.4.1" numpy_URL = "http://downloads.sourceforge.net/numpy/numpy-"+numpy_vers+"-win32-superpack-"+py_vers+".exe" # Python version py_vers = "py%d%d"%pyv[0:2] wxpython_vers = "2.8-win32-ansi-2.8.10.1" wxpython_URL = "http://downloads.sourceforge.net/wxpython/wxPython"+wxpython_vers+"-"+py_vers+".exe" wxpython_file = sys.exec_prefix+"/Lib/site-packages/wxversion.py" sdcc_vers = "2.9.0" sdcc_file = install_drive+"/Program Files/SDCC" sdcc_URL = "http://downloads.sourceforge.net/sdcc/sdcc-"+sdcc_vers+"-setup.exe" mingw_dl = "http://downloads.sourceforge.net/mingw/" mingw_URL = mingw_dl+"MinGW-5.1.6.exe" msys_URL = mingw_dl+"MSYS-1.0.11.exe" msys_vers = 'msys-1.0.11' mingw_install_bin = ( 'autoconf2.5-2.64-1', 'autoconf-7-1', 'automake1.11-1.11-1', 'automake-4-1', 'libtool-2.2.7a-1', ) mingw_install_dll = ( ) msys_install_bin = ( 'perl-5.6.1_2-1', 'm4-1.4.13-1', 'guile-1.8.7-1', 'patch-2.5.9-1', ) msys_install_dll = ( ('libcrypt-1.1_1-2',0), ('libguile-1.8.7-1',17), ('libgmp-4.3.1-1',3), ('libltdl-2.2.7a-1',7), ('libregex-1.20090805-1',1), ) msys_install_rtm = ( 'libguile-1.8.7-1', ) xemacs_exe = install_drive+"/Program Files/XEmacs/XEmacs-21.4.22/i586-pc-win32/xemacs.exe" unzip_prog = "unz600xn" unzip_file = unzip_prog+".exe" unzip_URL = "ftp://ftp.info-zip.org/pub/infozip/win32/"+unzip_file unzip_exe = "unzip.exe" glib_file = "glib_2.24.0-2_win32.zip" glib_URL = "http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.24/"+glib_file gnome_URL_deps = "http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/" pkgconfig_file = "pkg-config_0.23-3_win32.zip" pkgconfig_URL = gnome_URL_deps+pkgconfig_file swig_version = "swigwin-1.3.40" swig_file = swig_version+".zip" swig_URL = "http://prdownloads.sourceforge.net/swig/"+swig_file fftw_version = "fftw-3.2.2" fftw_dir = local_src+"/"+fftw_version fftw_file = fftw_version+".tar.gz" fftw_URL = "http://www.fftw.org/"+fftw_file cppunit_version = "cppunit-1.12.0" # 1.12.1 fails make check (05/02/08) cppunit_dir = local_src+"/"+cppunit_version cppunit_file = cppunit_version+".tar.gz" cppunit_URL="http://downloads.sourceforge.net/cppunit/"+cppunit_file boost_numbers = (1,43,0) boost_version = "boost_%d_%d_%d"%boost_numbers boost_dir = local_src+"/"+boost_version boost_file = boost_version + ".tar.bz2" boost_URL = "http://downloads.sourceforge.net/project/boost/boost/%d.%d.%d/"%boost_numbers + boost_file gsl_version = "gsl-1.14" gsl_dir = local_src+"/"+gsl_version gsl_file = gsl_version + ".tar.gz" gsl_URL = "ftp://ftp.gnu.org/gnu/gsl/" + gsl_file portaudio_version = "pa_snapshot" # v19_20071207 doesn't install portaudio_ext = ".tar.gz" portaudio_dir = "portaudio" portaudio_dl = "http://www.portaudio.com/archives/" sdl_version = "SDL-1.2.14" sdl_file = "SDL-devel-1.2.14-mingw32.tar.gz" sdl_dl = "http://www.libsdl.org/release/" libusb_numbers = "0.1.12.2" libusb_version = "libusb-win32-device-bin-"+libusb_numbers libusb_ext = ".tar.gz" libusb_dl = "http://downloads.sourceforge.net/project/libusb-win32/libusb-win32-releases/"+libusb_numbers+"/" gr_tarball_version = "gnuradio-3.2.2" gr_tarball_ext = ".tar.gz" gr_tarball_dl = "ftp://ftp.gnu.org/gnu/gnuradio/" git_dir = install_drive+'/Program Files/Git' git_file = 'Git-1.7.0.2-preview20100309.exe' git_URL = 'http://msysgit.googlecode.com/files/'+git_file # Location of git executable git_exe = git_dir+'/bin/git.exe' gr_git_dl = 'git://gnuradio.org/gnuradio' gr_git_version = 'gnuradio-git' # # Code starts here # def my_excepthook( *args ): sys.__excepthook__( *args ) raw_input( "Press any key to continue..." ) sys.excepthook = my_excepthook def my_exit( status ): # Allow user to view shell output before exiting raw_input( "Press any key to exit..." ) sys.exit(status) def w_to_m( path ): # Convert Windows path to MSYS path p = path i = p.find(':') while i >= 0: p = p[0:i-1]+'/'+p[i-1].lower()+p[i+1:] i = p.find(':') p = p.replace( ';', ':' ).replace( '\\', '/' ) return p def makedirs( dir ): # Make directory (including parents) if not os.access( dir, os.F_OK ): os.makedirs( dir ) print "created directory",dir def remove_file( f ): # Remove file, even if it isn't there if os.access( f, os.F_OK ): os.remove( f ) def rmdir( d ): # Remove directory tree, even if it isn't there if os.access( d, os.F_OK): shutil.rmtree( d ) def query_file( file ): print if os.access( file, os.F_OK ): ans = raw_input( file+" already exists: [s]kip, [r]einstall, or [q]uit? " ) c = ans[0].lower() if c == 'q': my_exit(0) return c return None def check_file( file ): print if( os.stat(file).st_size == 0 ): ans = raw_input( file+' is empty: [c]ontinue or [q]uit?' ) c = ans[0].lower() if c == 'q': my_exit(0) return c return None def sh_cmd( cmd, env=sh_env ): # run cmd with "sh -c"; cmd should not contain "'" s = subprocess.call( msys_dir+"/bin/sh -c '"+cmd+"'", env=env ) return s def sh_script( file, env=sh_env ): # execute sh script s = subprocess.call( msys_dir+"/bin/sh "+file, env=env ) return s def msys_cmd( cmd, env=sh_env ): # run an MSYS executable s = subprocess.call( msys_dir+"/bin/"+cmd, env=env ) return s def local_cmd( cmd, env=sh_env ): # run a locally-installed executable (i.e., from /local/bin) s = subprocess.call( local_bin+"/"+cmd, env=env ) return s def exe_install( url, test=None, reinstall=None, instructions=None, file=None ): # Download to temporary location and execute if test: c = query_file( test ) if c == 's': return elif c and reinstall: print "To reinstall",reinstall,"you must remove or rename",test my_exit(1) print "downloading",url,"..." if file: d = os.path.dirname( file ) makedirs( d ) os.chdir( d ) print "chdir to", d print "retrieving to", file t = urllib.urlretrieve( url, file ) else: t = urllib.urlretrieve( url ) if instructions: print instructions subprocess.call( t[0] ) urllib.urlcleanup() def tar_install( url, test=None, dir=local_src, options="-xf", install=True ): # Download to temporary location and execute if test: c = query_file( test ) if c == 's': return 0 if os.path.isdir( test ): rmdir( test ) else: remove_file( test ) makedirs( dir ) os.chdir( dir ) f = dir+"/"+os.path.basename(url) remove_file( f ) print "downloading",url,"..." t = urllib.urlretrieve( url, f ) if check_file(t[0]): return 0 f = w_to_m( f ) if install: print "upacking",f,"..." sh_cmd( "tar "+options+" "+f, env=sh_env ) urllib.urlcleanup() return 1 # install done def zip_install( url, test=None, dir=local_dir, inst_dir=None ): makedirs( dir ) os.chdir( dir ) if test: c = query_file( test ) if c == 's': return 0 f = os.path.basename(url) remove_file( f ) print "downloading",url,"..." t = urllib.urlretrieve( url, f ) print "unpacking",f,"..." if inst_dir: local_cmd( "unzip "+f+" -d "+inst_dir ) else: local_cmd( "unzip "+f ) urllib.urlcleanup() return 1 def git_install( url, repo, reinstall=None ): dir = os.path.dirname(repo) makedirs( dir ) os.chdir( dir ) if repo: c = query_file(repo) if c == 's': return 0 elif c and reinstall: print "To reinstall",reinstall,"you must remove or rename",repo my_exit(1) print "retrieving",url,"to",repo,"..." subprocess.call( git_exe + ' clone ' + url + ' ' + repo ) return 1 def link_install( p_w, name_m, dir=local_bin, default_arg=None ): # Add "link" to Windows program in MSYS search path if not os.access( p_w, os.F_OK ): print p_w+" not found; link not installed." return p_m = local_bin+"/"+name_m c = query_file( p_m ) if c == 's': return makedirs( local_bin ) f = open( p_m, "w+" ) f.writelines( [ "#! /bin/sh\n" ] ) if( default_arg ): f.writelines( [ "if test $# -ne 0; then\n", " exec '"+p_w+"' "+'"$@"\n', "else\n", " exec '"+p_w+"' "+default_arg+"\n" ] ) f.writelines( [ "fi\n" ] ) else: f.writelines( [ "exec '"+p_w+"' "+'"$@"\n' ] ) f.close() print p_m,"linked to",p_w def make_install( dir, cfg_opt="", env=sh_env, check=True ): os.chdir( dir ) s = sh_script( "configure "+cfg_opt, env=env ) if s: return s s = msys_cmd( "make", env=env ) if s: return s if check: s = msys_cmd( "make check", env=env ) if s: return s s = msys_cmd( "make install", env=env ) return s def gr_make_install(): if False: # example of handling a patch; not needed at present c = query_file( "makefiles-3.1.2.patch" ) if c != 's': print "downloading makefiles-3.1.2.patch ..." urllib.urlretrieve( "http://www.gnuradio.org/trac/attachment/wiki/MingwInstallMain/makefiles-3.1.2.patch?format=raw", "makefiles-3.1.2.patch" ) urllib.urlcleanup() msys_cmd( "patch -p0 -i makefiles-3.1.2.patch" ) print "running ./bootstrap ..." sh_script( "bootstrap" ) remove_file( "config.status" ) sh_env[ "CXX" ] = "g++ -mthreads" sh_env[ "CPPFLAGS" ] = "-DWINVER=0x0501 -I/usr/local/include" sh_env[ "LDFLAGS" ] = "-L/usr/local/lib -lws2_32" make_install( ".", cfg_opt="--prefix="+local_dir ) def mingw_install( name, type="bin" ): full_name = name + '-mingw32-' + type + '.tar.lzma' u = mingw_dl + full_name f = mingw_dir + '/' + full_name tar_install( u, test=f, dir=mingw_dir, options="--lzma -xvf" ) return def msys_install( name, type="bin" ): full_name = name + '-' + msys_vers + '-' + type + '.tar.lzma' u = mingw_dl + full_name f = msys_dir + '/' + full_name tar_install( u, test=f, dir=msys_dir, options="--lzma -xvf" ) return #=======================# # Execution begins here # #=======================# if install_python_packages: # Install NumPy inst = "Use wizard to install NumPy." t = sys.exec_prefix+"/Removenumpy.exe" exe_install( numpy_URL, test=t, instructions=inst ) # Install wxPython (requires Admin privs?) inst = "Use wizard to install wxPython." exe_install( wxpython_URL, test=wxpython_file, instructions=inst ) if option_usrp: # Install SDCC (requires Admin privs for default install) inst = "Use wizard to install SDCC; the only option you need is the include files." exe_install( sdcc_URL, test=sdcc_file, instructions=inst ) if install_mingw_and_msys: # Install MinGW inst = "Use wizard to install MinGW. Select Candidate and g++ compiler." exe_install( mingw_URL, test=mingw_dir, reinstall="MinGW", instructions=inst ) # Install MSYS inst = "Use wizard to install MSYS using default settings;" inst = inst+"\n do post-installation." exe_install( msys_URL, test=msys_dir, reinstall="MSYS", instructions=inst ) makedirs( local_bin ) # MinGW modules with common naming convention and install procedure for n in mingw_install_bin: mingw_install(n) for n in mingw_install_dll: mingw_install( n[0], type='dll-%d'%n[1] ) # MSYS modules with common naming convention and install procedure for n in msys_install_bin: msys_install(n) for n in msys_install_dll: msys_install( n[0], type='dll-%d'%n[1] ) for n in msys_install_rtm: msys_install( n, type='rtm' ) # Create link for xemacs link_install( xemacs_exe, "xemacs" ) # Create link for python python_exe = sys.executable.replace('pythonw.exe','python.exe') link_install( python_exe, "python", default_arg="-i" ) if install_gr_prerequisites: # Install unzip d = local_src+"/"+unzip_prog+"/" f = d+unzip_file exe_install( unzip_URL, test=f, file=f ) shutil.copy( d+unzip_exe, local_bin ) # Install pkg-config and dependencies zip_install( pkgconfig_URL, test=pkgconfig_file ) zip_install( glib_URL, test=glib_file ) # Install SWIG zip_install( swig_URL, test=swig_file ) link_install( local_dir+"/"+swig_version+"/swig.exe", "swig" ) # Install FFTW if tar_install( fftw_URL, test=fftw_dir, dir=local_src, options="-zxf" ): s = make_install( fftw_dir, cfg_opt="--with-our-malloc16 --enable-shared --disable-static --enable-threads --with-combined-threads --enable-float --enable-sse" ) # Install CppUnit if tar_install( cppunit_URL, test=cppunit_dir, dir=local_src, options="-zxf" ): s = make_install( cppunit_dir, cfg_opt="--disable-static" ) # Install boost libraries if tar_install( boost_URL, test=boost_dir, dir=local_src, options="-jxf" ): os.chdir(boost_dir) sh_script( "bootstrap.sh --with-toolset=mingw" ) sh_script( "bootstrap.sh --with-libraries=thread,date_time,program_options --with-bjam=tools/jam/src/bin.ntx86/bjam" ) subprocess.call( "bjam --prefix="+local_dir+" link=shared install", env=sh_env ) msys_cmd( "mv "+local_dir+"/lib/*.dll "+local_bin ) # Install GSL if tar_install( gsl_URL, test=gsl_dir, dir=local_src, options="-zxf" ): s = make_install( gsl_dir, cfg_opt="--disable-static" ) if option_portaudio: # Install PortAudio u = portaudio_dl + portaudio_version + portaudio_ext d = local_src+'/'+portaudio_dir if tar_install( u, test=d, dir=local_src, options="-zxf" ): # patch portaudio-2.0.pc.in to avoid unnecessary linking of -luuid os.chdir(d) fn = 'portaudio-2.0.pc.in' f = open( fn, 'rb' ) t = f.read() f.close() t = t.replace('@LIBS','@DLL_LIBS') f = open( fn, 'wb' ) f.write(t) f.close() s = make_install( d, cfg_opt="--disable-static", check=False ) if option_sdl_video: # Install SDL u = sdl_dl + sdl_file d = local_src+'/'+sdl_version if tar_install( u, test=d, options="-zxf" ): os.chdir( d ) #subprocess.call( msys_dir+"/bin/make cross CROSS_PATH="+local_dir, env=sh_env ) msys_cmd( "make cross CROSS_PATH="+local_dir, env=sh_env ) if option_usrp: # Install libusb-win32 u = libusb_dl + libusb_version + libusb_ext d = local_src+'/'+libusb_version if tar_install( u, test=d, options="-zxf" ): os.chdir( d ) sh_cmd( "cp include/* "+local_dir+"/include" ) sh_cmd( "cp lib/gcc/* "+local_dir+"/lib" ) sh_cmd( "cp bin/* "+local_dir+"/bin" ) if install_gnuradio_tarball: u = gr_tarball_dl + gr_tarball_version + gr_tarball_ext d = gr_inst_dir+'/'+gr_tarball_version tar_install( u, test=d, dir=gr_inst_dir, options="-zxf" ) if os.access( d, os.F_OK): os.chdir( d ) gr_make_install() if install_git: inst = "Use wizard to install git to "+git_dir exe_install( git_URL, test=git_dir, reinstall="Git" ) if install_gnuradio_git: u = gr_git_dl d = gr_inst_dir+'/'+gr_git_version git_install( u, d, reinstall='GNU Radio' ) if os.access( d, os.F_OK): os.chdir( d ) c = query_file( "configure" ) if c != 's': print "running ./bootstrap ..." sh_script( "bootstrap" ) gr_make_install() # Allow user to view shell before it goes away raw_input( "Press any key to continue..." )