On Jan 19, 2009, at 10:49 AM, Austin Roberts wrote:
Because of some issues I've been having (discussed in another
thread), I've made a few changes to the rdiff-backup source, and I'm
trying to build it for windows.
I have installed the Visual C++ 2008 redistributable, and the Python
for Windows Extensions, but I get an error:
building 'rdiff_backup.C' extension
error: None
Is there anything else I need to have installed?
Yup.
You need a C compiler, Visual C++ Express Edition 2008 (free):
http://www.microsoft.com/express/vc/
If you got Python for Windows Extensions installed, then I assume you
have already installed Python for Windows, but if not: http://www.python.org/download/releases/2.6.1/
To make a single executable, you will need py2exe: http://www.py2exe.org
Finally, you either need to build librsync for Windows, or (much
easier) you should use the Windows build script written by Josh Nisly.
To use the script, open a Visual Studio 2008 Command Prompt, then do
something like:
python C:\path-to-script\build_rdiff_backup.py (you need the complete
path) .... currently, the build script can clobber your changes if
you're not paying attention, so you'll need to edit it by hand if
you're doing development. I suppose that's part of why I haven't put
it under CVS control yet, but that's a lame excuse. :-/
If you use the build script, then it will automatically patch librsync
to support files > 4gb, however, to do the patching, you will need the
patch utility: http://gnuwin32.sourceforge.net/packages/patch.htm
(Optional) If you want to develop against CVS, then you need CVS for
Windows, so the build script can automatically download the CVS HEAD: http://www.cvsnt.org
After installing patch, you will need to manually add the location to
your PATH. The best way to do that is by using the Environment
Variables control, which can be found by right-clicking My Computer ->
Properties -> Advanced.
thanks for building from source!
Andrew
import glob
import os
import shutil
import sys
import tarfile
import urllib
RDIFF_BACKUP_VERSION = '1.2.5'
RDIFF_BACKUP_NAME = 'rdiff-backup-'+RDIFF_BACKUP_VERSION
RDIFF_BACKUP_URL = 'http://download.savannah.gnu.org/releases-noredirect/rdiff-backup/'+RDIFF_BACKUP_NAME+'.tar.gz'
LIBRSYNC_URL = 'http://superb-east.dl.sourceforge.net/sourceforge/librsync/librsync-0.9.7.tar.gz'
LIBRSYNC_VCPROJ_TEXT = r"""<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="librsync"
ProjectGUID="{B7D1448D-017B-4035-86A1-12B5B736101F}"
RootNamespace="librsync"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="popt; .\"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_STRERROR"
MinimalRebuild="true"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/rsync.lib"
IgnoreAllDefaultLibraries="true"
IgnoreDefaultLibraryNames=""
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\base64.c"
>
</File>
<File
RelativePath=".\buf.c"
>
</File>
<File
RelativePath=".\checksum.c"
>
</File>
<File
RelativePath=".\command.c"
>
</File>
<File
RelativePath=".\delta.c"
>
</File>
<File
RelativePath=".\emit.c"
>
</File>
<File
RelativePath=".\fileutil.c"
>
</File>
<File
RelativePath=".\popt\findme.c"
>
</File>
<File
RelativePath=".\hex.c"
>
</File>
<File
RelativePath=".\isprefix.c"
>
</File>
<File
RelativePath=".\job.c"
>
</File>
<File
RelativePath=".\mdfour.c"
>
</File>
<File
RelativePath=".\mksum.c"
>
</File>
<File
RelativePath=".\msg.c"
>
</File>
<File
RelativePath=".\netint.c"
>
</File>
<File
RelativePath=".\patch.c"
>
</File>
<File
RelativePath=".\popt\popt.c"
>
</File>
<File
RelativePath=".\popt\poptconfig.c"
>
</File>
<File
RelativePath=".\popt\popthelp.c"
>
</File>
<File
RelativePath=".\popt\poptparse.c"
>
</File>
<File
RelativePath=".\prototab.c"
>
</File>
<File
RelativePath=".\rdiff.c"
>
</File>
<File
RelativePath=".\readsums.c"
>
</File>
<File
RelativePath=".\rollsum.c"
>
</File>
<File
RelativePath=".\scoop.c"
>
</File>
<File
RelativePath=".\search.c"
>
</File>
<File
RelativePath=".\snprintf.c"
>
</File>
<File
RelativePath=".\stats.c"
>
</File>
<File
RelativePath=".\stream.c"
>
</File>
<File
RelativePath=".\sumset.c"
>
</File>
<File
RelativePath=".\trace.c"
>
</File>
<File
RelativePath=".\tube.c"
>
</File>
<File
RelativePath=".\util.c"
>
</File>
<File
RelativePath=".\version.c"
>
</File>
<File
RelativePath=".\whole.c"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
"""
LIBRSYNC_SLN_TEXT = r"""Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librsync", "librsync.vcproj", "{B7D1448D-017B-4035-86A1-12B5B736101F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B7D1448D-017B-4035-86A1-12B5B736101F}.Debug|Win32.ActiveCfg = Debug|Win32
{B7D1448D-017B-4035-86A1-12B5B736101F}.Debug|Win32.Build.0 = Debug|Win32
{B7D1448D-017B-4035-86A1-12B5B736101F}.Release|Win32.ActiveCfg = Release|Win32
{B7D1448D-017B-4035-86A1-12B5B736101F}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
"""
LIBRSYNC_PATCH_TEXT="""diff -w -Nur librsync-0.9.7/buf.c librsync-0.9.7dev/buf.c
--- librsync-0.9.7/buf.c 2004-02-07 18:17:57.000000000 -0500
+++ librsync-0.9.7-win/buf.c 2008-11-20 12:28:23.000000000 -0500
@@ -59,6 +59,11 @@
#define fseek fseeko
#endif
+#ifdef NEED_FSEEKI64
+int __cdecl _fseeki64(FILE *, __int64, int);
+#define fseek _fseeki64
+#endif
+
/**
* File IO buffer sizes.
*/
diff -urN librsync-0.9.7/mdfour.h librsync-0.9.7dev/mdfour.h
--- librsync-0.9.7/mdfour.h 2004-02-07 18:17:57.000000000 -0500
+++ librsync-0.9.7dev/mdfour.h 2006-03-06 03:21:46.000000000 -0500
@@ -24,7 +24,7 @@
#include "types.h"
struct rs_mdfour {
- int A, B, C, D;
+ unsigned int A, B, C, D;
#if HAVE_UINT64
uint64_t totalN;
#else
diff -urN librsync-0.9.7/patch.c librsync-0.9.7dev/patch.c
--- librsync-0.9.7/patch.c 2004-09-17 17:35:50.000000000 -0400
+++ librsync-0.9.7dev/patch.c 2006-03-06 03:21:06.000000000 -0500
@@ -214,12 +214,12 @@
void *buf, *ptr;
rs_buffers_t *buffs = job->stream;
- len = job->basis_len;
-
/* copy only as much as will fit in the output buffer, so that we
* don't have to block or store the input. */
- if (len > buffs->avail_out)
+ if (job->basis_len > buffs->avail_out)
len = buffs->avail_out;
+ else
+ len = job->basis_len;
if (!len)
return RS_BLOCKED;
"""
CONFIG_H_TEXT = """
#define SIZEOF_UNSIGNED_INT 4
#define PACKAGE "librsync"
#define VERSION "0.9.7"
#define RS_CANONICAL_HOST "librsync.sourceforge.net"
#define inline
#define NEED_FSEEKI64
"""
class BuildError(Exception):
pass
def copy(src_pattern, dest_dir):
if '*' in src_pattern:
files = glob.glob(src_pattern)
else:
files = [src_pattern]
for file in files:
shutil.copyfile(file, os.path.join(dest_dir, os.path.basename(file)))
def unzip(src_file, target_dir):
print 'Extracting %s...' % src_file
extension = src_file.rpartition('.')[2]
tar = tarfile.open(src_file, 'r:'+extension)
for tarinfo in tar:
dest_path = os.path.join(target_dir, tarinfo.name.replace('/', os.sep))
if tarinfo.isreg():
tar.extract(tarinfo, target_dir)
elif tarinfo.isdir():
if not os.path.isdir(dest_path):
os.mkdir(dest_path)
elif tarinfo.issym():
pass # We don't care about symlinks
else:
raise ValueError, 'Unhandled .tar.gz file:'+str(tarinfo)
tar.close()
def verify_env(require_cvs):
for path in os.environ['PATH'].split(';'):
if os.path.exists(os.path.join(path, 'MSBuild.exe')):
break
else:
raise BuildError, '''This script must be run from \
the Visual Studio 2008 Commandline.'''
if require_cvs:
for path in os.environ['PATH'].split(';'):
if os.path.exists(os.path.join(path, 'cvs.exe')):
break
else:
raise BuildError, '''Cvs.exe (CVSNT) must be in the path.'''
def download_file(url, target_dir):
filename = os.path.basename(url)
target_name = os.path.join(target_dir, filename)
if not os.path.exists(target_name):
print 'Downloading %s...' % url
urllib.urlretrieve(url, target_name)
unzip(target_name, target_dir)
def write_text(filepath, text):
file = open(filepath, 'w')
file.write(text)
file.close()
def build_librsync(root_dir):
# Download package if necessary
download_file(LIBRSYNC_URL, root_dir)
# Add in support files
librsync_dir = os.path.join(root_dir, 'librsync-0.9.7')
write_text(os.path.join(librsync_dir, 'librsync.sln'), LIBRSYNC_SLN_TEXT)
write_text(os.path.join(librsync_dir, 'librsync.vcproj'), LIBRSYNC_VCPROJ_TEXT)
write_text(os.path.join(librsync_dir, 'config.h'), CONFIG_H_TEXT)
# Patch for 4GB support
large_file_patch = os.path.join(librsync_dir, 'lfs_support.patch')
write_text(large_file_patch, LIBRSYNC_PATCH_TEXT)
os.chdir(root_dir)
if os.system('patch.exe -p0 < %s' % large_file_patch):
raise BuildError, 'Unable to patch librsync.'
# Build
sln_path = os.path.join(librsync_dir, 'librsync.sln')
if os.system('MSBuild.exe %s /t:Build /p:Configuration=Release' % sln_path):
raise BuildError, 'Unable to build librsync.'
# Copy built library to where rdiff-backup's setup.py expects it
output_dir = os.path.join(librsync_dir, 'lib')
if not os.path.isdir(output_dir):
os.mkdir(output_dir)
lib_path = os.path.join(librsync_dir, 'Release', 'rsync.lib')
copy(lib_path, output_dir)
# Copy include files to where rdiff-backup expects them
include_dir = os.path.join(librsync_dir, 'include')
if not os.path.isdir(include_dir):
os.mkdir(include_dir)
for file in ('librsync.h', 'librsync-config.h'):
copy(os.path.join(librsync_dir, file), include_dir)
def build_rdiff_backup(use_cvs, rebuild, root_dir, output_dir):
rdiff_dir = os.path.join(root_dir, 'rdiff-backup')
librsync_dir = os.path.join(root_dir, 'librsync-0.9.7')
# Check out rdiff-backup
if rebuild:
if os.path.exists(rdiff_dir):
shutil.rmtree(rdiff_dir)
if use_cvs:
if not os.path.isdir(rdiff_dir):
os.chdir(root_dir)
if os.system('cvs -z3 -d:pserver:[email protected]:/sources/rdiff-backup co .'):
raise BuildError, 'Unable to check out rdiff-backup!'
# Patch rdiff-backup
os.chdir(rdiff_dir)
patch_exe = 'patch.exe'
for patch in (os.path.join(root_dir, '..', 'rdiff-backup-windows-drive.patch'), ):
print 'patching:', patch
if os.system('%s -N -p0 < %s' % (patch_exe, patch)):
raise BuildError, 'Unable to patch rdiff-backup!'
# Make an rdiff-backup dist package
os.chdir(rdiff_dir)
if os.system('python dist\\makedist ' + RDIFF_BACKUP_VERSION):
raise BuildError, 'Unable to make rdiff-backup dist package.'
# There is now a built version in the rdiff-backup dir.
# Extract it, build it, and copy the exe to output_dir.
rdiff_output_name = 'rdiff-backup-'+RDIFF_BACKUP_VERSION
target_dir = os.path.join(rdiff_dir, rdiff_output_name)
if os.path.exists(target_dir):
shutil.rmtree(target_dir)
rdiff_tar = target_dir + '.tar.gz'
unzip(rdiff_tar, rdiff_dir)
else:
if not os.path.exists(rdiff_dir):
os.mkdir(rdiff_dir)
download_file(RDIFF_BACKUP_URL, rdiff_dir)
rdiff_output_name = RDIFF_BACKUP_NAME
rdiff_output_dir = os.path.join(rdiff_dir, rdiff_output_name)
os.chdir(rdiff_output_dir)
# Build rdiff-backup
if os.system('setup.py build --librsync-dir=%s --lflags=%s' % \
(librsync_dir, '"/NODEFAULTLIB:libcmt.lib msvcrt.lib"')):
raise BuildError, 'Unable to build rdiff-backup.'
if os.system('setup.py py2exe --single-file > py2exe-out.txt'):
raise BuildError, 'Unable to rdiff-backup via py2exe.'
copy(os.path.join(rdiff_output_dir, 'dist', 'rdiff-backup.exe'), output_dir)
if __name__ == '__main__':
root_dir = os.path.dirname(__file__)
target_dir = os.path.join(root_dir, 'temp')
output_dir = os.path.join(root_dir, 'output')
rebuild = '--rebuild' in sys.argv[1:]
use_cvs = '--cvs' in sys.argv[1:]
for dir in (target_dir, output_dir):
if not os.path.isdir(dir):
os.makedirs(dir)
verify_env(use_cvs)
build_librsync(target_dir)
build_rdiff_backup(use_cvs, rebuild, target_dir, output_dir)
_______________________________________________
rdiff-backup-users mailing list at [email protected]
http://lists.nongnu.org/mailman/listinfo/rdiff-backup-users
Wiki URL: http://rdiff-backup.solutionsfirst.com.au/index.php/RdiffBackupWiki