Add experimental Python VC++ build file creator

This commit is contained in:
gladman 2011-09-12 09:17:35 +00:00
parent 65b1ec121a
commit 65b06c968a
2 changed files with 858 additions and 33 deletions

807
build.vc10/mpir_config.py Normal file
View File

@ -0,0 +1,807 @@
'''
Set up Visual Sudio 2010 to build a specified MPIR configuration
Copyright (C) 2011, Brian Gladman
32-bit:
x86w: x86, i386, i486, i586, pentium, pentiummmx, k6, k62, k63, k7, athlon, viac3, viac32, x86_64
p6: pentiumpro, i686
mmx: pentium2
sse2: pentium4, prescott, core, netburst, netburstlahf
p3mmx: pentium3, k8, k10, k102, k103, bulldozer, bobcat, core2, penryn, nehalem, westmere, sandybridge, atom, nano
64-bit:
x86_64: x86_64w
netburst: netburst, netburstlahf
k8only: k8, nano
k10: k10
k102: k102, k103, bulldozer
bobcat: bobcat
core2: core2
penryn: penryn
nehalem: nehalem
westmere: westmere
sandybridge: sandybridge
atom atom
'''
from __future__ import print_function
from operator import itemgetter
from os import listdir, walk, unlink, makedirs
from os.path import split, splitext, isdir, relpath, join, exists
from copy import deepcopy
from sys import exit
from filecmp import cmp
from shutil import copy
from re import search
is_DLL = False
is_debug = False
lib_type = 'dll' if is_DLL else 'lib'
# The path to the mpir root directory
mpir_dir = 'C:/Users/Brian Gladman/Documents/Visual Studio 2010/Projects/mpir/'
vc10_dir = mpir_dir + 'build.vc10/'
out_dir = vc10_dir + 'dll/' if is_DLL else 'lib/'
# paths that might incsrc_listude source filesv(*.c, *.h, *.asm)
c_directories = ( '', 'build.vc10', 'mpf', 'mpq', 'mpz', 'printf', 'scanf' )
# files that are to be excluded from the build
exclude_file_list = ('config.guess', 'cfg', 'getopt', 'getrusage', 'gettimeofday', 'cpuid',
'obsolete', 'win_timing', 'gmp-mparam', 'tal-debug', 'tal-notreent',
'new_fft', 'new_fft_with_flint', 'compat', 'udiv_w_sdiv' )
# copy from file ipath to file opath but avoid copying if
# opath exists and is the same as ipath (this is to avoid
# triggering an unecessary rebuild).
def write_f(ipath, opath):
if exists(ipath) and not isdir(ipath):
if exists(opath):
if isdir(opath) or cmp(ipath, opath):
return
copy(ipath, opath)
# append a file (ipath) to an existing file (opath)
def append_f(ipath, opath):
try:
with open(opath, 'ab') as out_file:
try:
with open(ipath, 'rb') as in_file:
buf = in_file.read(8192)
while buf:
out_file.write(buf)
buf = in_file.read(8192)
except IOError:
print('error reading {0:s} for input'.format(f))
return
except IOError:
print('error opening {0:s} for output'.format(opath))
# copy files in a list from in_dir to out_dir
def copy_files(file_list, in_dir, out_dir):
makedirs(out_dir, exist_ok=True)
for f in file_list:
copy(join(in_dir, f), out_dir)
# Recursively search a given directory tree to find header,
# C and assembler code files that either replace or augment
# the generic C source files in the input list 'cf_list'.
# As the directory tree is searched, files in each directory
# become the source code files for the current directory and
# the default source code files for its child directories.
#
# Lists of default header, C and assembler source code files
# are maintained as the tree is traversed and if a file in
# the current directory matches the name of a file in the
# default file list (name matches ignore file extensions),
# the name in the list is removed and is replaced by the new
# file found. On return each directory in the tree had an
# entry in the returned dictionary that contains:
#
# 1. The list of header files
#
# 2. The list of C source code files for the directory
#
# 3. The list of assembler code files that replace C files
#
# 4. The list of assembler files that are not C replacements
#
def find_asm(path, cf_list):
d = dict()
for root, dirs, files in walk(path):
if '.svn' in dirs: # ignore SVN directories
dirs.remove('.svn')
relp = relpath(root, path) # path from asm root
relr = relpath(root, mpir_dir) # path from MPIR root
if relp == '.': # set C files as default
relp = h = t = ''
d[''] = [ [], deepcopy(cf_list), [], [] ]
else:
h, t = split(relp) # h = parent, t = this directory
hh, h = split(h)
# copy defaults from this directories parent
d[t] = [ deepcopy(d[h][0]), deepcopy(d[h][1]),
deepcopy(d[h][2]), deepcopy(d[h][3]) ]
for f in files: # for the files in this directory
n, x = splitext(f)
if x == '.h': # if it is a header file, remove
for cf in reversed(d[t][0]): # any matching default
if cf[0] == n:
d[t][0].remove(cf)
d[t][0] += [(n, x, relr)] # and add the local header file
if x == '.c': # if it is a C file, remove
for cf in reversed(d[t][1]): # any matching default
if cf[0] == n:
d[t][1].remove(cf)
d[t][1] += [(n, x, relr)] # and add the local C file
if x == '.asm': # if it is an assembler file
match = False
for cf in reversed(d[t][1]): # remove any matching C file
if cf[0] == n:
d[t][1].remove(cf)
match = True
break
for cf in reversed(d[t][2]): # and remove any matching
if cf[0] == n: # assembler file
d[t][2].remove(cf)
match = True
break
if match: # if a match was found, put the
d[t][2] += [(n, x, relr)] # file in the replacement list
else: # otherwise look for it in the
for cf in reversed(d[t][3]): # additional files list
if cf[0] == n:
d[t][3].remove(cf)
break
d[t][3] += [(n, x, relr)]
for k in d: # additional assembler list
for i in range(4):
d[k][i].sort(key=itemgetter(0)) # sort the four file lists
return d
# create 4 lists of c, h, cc (or cpp) and asm (or as) in a directory
def find_src(dir_list):
# list number from file extension
di = { '.h': 0, '.c': 1, '.cc': 2, '.cpp': 2, '.asm': 3, '.as': 3 }
list = [ [], [], [], [] ]
for d in dir_list:
for f in listdir(join(mpir_dir, d)):
if f == '.svn':
continue # ignore SVN directories
if not isdir(f):
n, x = splitext(f) # split into name + extension
if x in di and not n in exclude_file_list:
list[di[x]] += [(n, x, d)] # if of the right type and is
for x in list: # not in the exclude list
x.sort(key=itemgetter(2, 0, 1)) # add it to appropriaate list
return list
# generate VIsual Studio 2010 IDE Filter
def filter_folders(cf_list, af_list, outf):
f1 = r''' <ItemGroup>
<Filter Include="Header Files" />
<Filter Include="Source Files" />
'''
f2 = r''' <Filter Include="Source Files\{0:s}" />
'''
f3 = r''' </ItemGroup>
'''
c_dirs = set(i[2] for i in cf_list)
a_dirs = set(i[2] for i in af_list)
if a_dirs:
c_dirs |= set(('mpn\yasm',))
outf.write(f1)
for d in sorted(c_dirs):
if d:
t = d if d != 'mpn\generic' else 'mpn'
outf.write(f2.format(t))
outf.write(f3)
filter_hdr_item = ' <ClInclude Include="..\..\{}">\n <Filter>Header Files</Filter>\n </ClInclude>\n'
def filter_headers(hdr_list, outf):
f1 = r''' <ItemGroup>
'''
f2 = r''' <ClInclude Include="..\..\{}">
<Filter>Header Files</Filter>
</ClInclude>
'''
f3 = r''' </ItemGroup>
'''
outf.write(f1)
for h in hdr_list:
outf.write(f2.format(h))
outf.write(f3)
def filter_csrc(cf_list, outf):
f1 = r''' <ItemGroup>
'''
f2 = r''' <ClCompile Include="..\..\{1:s}\{0:s}">
<Filter>Source Files\{2:s}</Filter>
</ClCompile>
'''
f3 = r''' </ItemGroup>
'''
outf.write(f1)
for i in cf_list:
t = 'mpn' if i[2].endswith('generic') else i[2]
outf.write(f2.format(i[0] + i[1], i[2], t))
outf.write(f3)
def filter_asrc(af_list, outf):
f1 = r''' <ItemGroup>
'''
f2 = r''' <YASM Include="..\..\{1:s}\{0:s}">
<Filter>Source Files\mpn\yasm</Filter>
</YASM>
'''
f3 = r''' </ItemGroup>
'''
outf.write(f1)
for i in af_list:
outf.write(f2.format(i[0] + i[1], i[2], i[2]))
outf.write(f3)
def gen_filter(name, hf_list, cf_list, af_list):
f1 = r'''<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
'''
f2 = r'''</Project>
'''
fn = join(vc10_dir, name)
makedirs(split(fn)[0], exist_ok=True)
with open(fn, 'w') as outf:
outf.write(f1)
filter_folders(cf_list, af_list, outf)
filter_headers(hf_list, outf)
filter_csrc(cf_list, outf)
filter_asrc(af_list, outf)
outf.write(f2)
# generate vcxproj file
def vcx_proj_cfg(plat, outf):
f1 = r''' <ItemGroup Label="ProjectConfigurations">
'''
f2 = r''' <ProjectConfiguration Include="{1:s}|{0:s}">
<Configuration>{1:s}</Configuration>
<Platform>{0:s}</Platform>
</ProjectConfiguration>
'''
f3 = r''' </ItemGroup>
'''
outf.write(f1)
for conf in ('Release', 'Debug'):
outf.write(f2.format(plat, conf))
outf.write(f3)
def vcx_globals(name, outf):
f1 = r''' <PropertyGroup Label="Globals">
<RootNamespace>{0:s}</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
'''
outf.write(f1.format(name))
def vcx_default_cpp_props(outf):
f1 = r''' <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
'''
outf.write(f1)
def vcx_library_type(plat, is_dll, outf):
f1 = r''' <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='{1:s}|{0:s}'" Label="Configuration">
<ConfigurationType>{2:s}Library</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
'''
for conf in ('Release', 'Debug'):
outf.write(f1.format(plat, conf, 'Dynamic' if is_dll else 'Static' ))
def vcx_cpp_props(outf):
f1 = r''' <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
'''
outf.write(f1)
def vcx_extensions(outf):
f1 = r''' <ImportGroup Label="ExtensionSettings">
<Import Project="..\vsyasm.props" />
</ImportGroup>
'''
outf.write(f1)
def vcx_user_props(plat, outf):
f1 = r''' <ImportGroup Condition="'$(Configuration)|$(Platform)'=='{1:s}|{0:s}'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
'''
for conf in ('Release', 'Debug'):
outf.write(f1.format(plat, conf))
def vcx_target_name_and_dirs(name, plat, is_dll, outf):
f1 = r''' <PropertyGroup>
<_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
'''
f2 = r''' <TargetName Condition="'$(Configuration)|$(Platform)'=='{1:s}|{0:s}'">{2:s}</TargetName>
<IntDir Condition="'$(Configuration)|$(Platform)'=='{1:s}|{0:s}'">$(Platform)\$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='{1:s}|{0:s}'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
'''
f3 = r''' </PropertyGroup>
'''
outf.write(f1)
for conf in ('Release', 'Debug'):
outf.write(f2.format(plat, conf, name))
outf.write(f3)
def yasm_options(is_dll, outf):
f1 = r''' <YASM>
<Defines>{0:s}</Defines>
<IncludePaths>..\..\mpn\x86_64w\</IncludePaths>
<Debug>true</Debug>
<ObjectFileName>$(IntDir)mpn\</ObjectFileName>
<ObjectFile>$(IntDir)mpn\</ObjectFile>
</YASM>
'''
outf.write(f1.format('DLL' if is_dll else ''))
def compiler_options(is_dll, is_debug, outf):
f1 = r''' <ClCompile>
<Optimization>{0:s}</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>{1:s}%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded{2:s}</RuntimeLibrary>
<ProgramDataBaseFileName>$(TargetDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
'''
if is_dll:
s1 = 'DEBUG;HAVE_CONFIG_H;__GMP_LIBGMP_DLL;__GMP_WITHIN_GMP;__GMP_WITHIN_GMPXX;'
s2 = 'DLL'
else:
s1 = 'DEBUG;_LIB;HAVE_CONFIG_H;'
s2 = ''
if is_debug:
opt, defines, crt = 'Disabled', '_' + s1, 'Debug' + s2
else:
opt, defines, crt = 'Full', 'N' + s1, s2
outf.write(f1.format(opt, defines, crt))
def linker_options(outf):
f1 = r''' <Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LargeAddressAware>true</LargeAddressAware>
</Link>
'''
outf.write(f1)
def vcx_post_build(outf):
f1 = ''' <PostBuildEvent>
<Command>cd ..\
postbuild "$(TargetPath)"</Command>
</PostBuildEvent>
'''
outf.write(f1)
def vcx_tool_options(plat, is_dll, outf):
f1 = r''' <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='{1:s}|{0:s}'">
'''
f2 = r''' </ItemDefinitionGroup>
'''
for is_debug in (False, True):
outf.write(f1.format(plat, 'Debug' if is_debug else 'Release'))
yasm_options(is_dll, outf)
compiler_options(is_dll, is_debug, outf)
if is_dll:
linker_options(outf)
vcx_post_build(outf)
outf.write(f2)
def vcx_hdr_items(hdr_list, outf):
f1 = r''' <ItemGroup>
'''
f2 = r''' <ClInclude Include="..\..\{0:s}" />
'''
f3 = r''' </ItemGroup>
'''
outf.write(f1)
for i in hdr_list:
outf.write(f2.format(i))
outf.write(f3)
def vcx_c_items(cf_list, plat, outf):
f1 = r''' <ItemGroup>
'''
f2 = r''' <ClCompile Include="..\..\{0[0]:s}{0[1]:s}" />
'''
f3 = r''' <ClCompile Include="..\..\{0[2]:s}\{0[0]:s}{0[1]:s}">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|{1:s}'">$(IntDir){2:s}\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|{1:s}'">$(IntDir){2:s}\</ObjectFileName>
</ClCompile>
'''
f4 = r''' </ItemGroup>
'''
outf.write(f1)
for nxd in cf_list:
if nxd[2] == '':
outf.write(f2.format(nxd))
else:
outf.write(f3.format(nxd, plat, 'mpn' if nxd[2].endswith('generic') else nxd[2]))
outf.write(f4)
def vcx_a_items(af_list, outf):
f1 = r''' <ItemGroup>
'''
f2 = r''' <YASM Include="..\..\{0[2]:s}\{0[0]:s}{0[1]:s}" />
'''
f3 = r''' </ItemGroup>
'''
outf.write(f1)
for nxd in af_list:
outf.write(f2.format(nxd))
outf.write(f3)
def gen_vcxproj(proj_name, file_name, plat, is_dll, hf_list, cf_list, af_list):
f1 = r'''<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
'''
f2 = r''' <PropertyGroup Label="UserMacros" />
'''
f3 = r''' <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
'''
f4 = r''' <ImportGroup Label="ExtensionTargets">
<Import Project="..\vsyasm.targets" />
</ImportGroup>
'''
f5 = '''</Project>
'''
with open(join(vc10_dir, file_name), 'w') as outf:
outf.write(f1)
vcx_proj_cfg(plat, outf)
vcx_globals(proj_name, outf)
vcx_default_cpp_props(outf)
vcx_library_type(plat, is_dll, outf)
vcx_cpp_props(outf)
vcx_extensions(outf)
vcx_user_props(plat, outf)
outf.write(f2)
vcx_target_name_and_dirs(proj_name, plat, is_dll, outf)
vcx_tool_options(plat, is_dll, outf)
vcx_hdr_items(hf_list, outf)
vcx_c_items(cf_list, plat, outf)
vcx_a_items(af_list, outf)
outf.write(f3)
outf.write(f4)
outf.write(f5)
t = find_src(c_directories)
c_hdr_list = t[0]
c_src_list = t[1]
if t[2] or t[3]:
print('found C++ and/or assembler file(s) in a C directory')
for f in c_hdr_list:
print(f)
print()
for f in c_src_list:
print(f)
print()
t = find_src(['cxx'])
cc_hdr_list = t[0]
cc_src_list = t[2]
if t[1] or t[3]:
print('found C+ and/or assembler file(s) in a C++ directory')
for f in cc_hdr_list:
print(f)
print()
for f in cc_src_list:
print(f)
print()
t = find_src([r'mpn\generic'])
gc_hdr_list = t[0]
gc_src_list = t[1]
if t[1] or t[3]:
print('found C++ and/or assembler file(s) in a C directory')
for f in gc_hdr_list:
print(f)
print()
for f in gc_src_list:
print(f)
print()
mpn_32 = find_asm(mpir_dir + 'mpn/x86w', gc_src_list)
mpn_32['gc-win32'] = [ gc_hdr_list, gc_src_list, [], [] ]
del mpn_32['']
mpn_64 = find_asm(mpir_dir + 'mpn/x86_64w', gc_src_list)
mpn_64['gc-x64'] = [ gc_hdr_list, gc_src_list, [], [] ]
del mpn_64['']
err = False
config = ''
mode = ''
while True:
cnt = 0
for v in sorted(mpn_32):
cnt += 1
print('{0:2d}. {1:12s} (win32)'.format(cnt, v))
for v in sorted(mpn_64):
cnt += 1
print('{0:2d}. {1:12s} (x64)'.format(cnt, v))
if err:
s = input('please enter a number <= {0:d} (0 to exit)? '.format(cnt))
err = False
else:
s = input('Number of configuation to build (0 to exit)? ')
try:
n = int(s)
if n < 1:
n = 0
break
if n <= len(mpn_32):
config = sorted(mpn_32)[n - 1]
mode = 'win32'
mpn_f = mpn_32[config]
break
elif n <= len(mpn_32) + len(mpn_64):
config = sorted(mpn_64)[n - len(mpn_32) - 1]
mode = 'x64'
mpn_f = mpn_64[config]
break
except:
pass
err = True
if n == 0:
exit()
if mode == 'x64':
for l in mpn_f[1:]:
for t in l:
if t[0].startswith('preinv_'):
if (mode == 'x64' and t[0] == 'preinv_divrem_1' or
mode == 'win32' and t[0] == 'preinv_mod_1'):
l.remove(t)
print(config, mode)
# generate mpir.h and gmp.h from gmp_h.in
gmp_h_32 = '''
#define __GMP_BITS_PER_MP_LIMB 32
#define GMP_LIMB_BITS 32
#if defined _LONG_LONG_LIMB
# undef _LONG_LONG_LIMB 1
#endif
#if defined _WIN64
# undef _WIN64
#endif
#define GMP_NAIL_BITS 0
#define SIZEOF_MP_LIMB_T (GMP_LIMB_BITS >> 3)
'''
gmp_h_64 = '''
#define __GMP_BITS_PER_MP_LIMB 64
#define GMP_LIMB_BITS 64
#if !defined _LONG_LONG_LIMB
# define _LONG_LONG_LIMB 1
#endif
#if !defined _WIN64
#define _WIN64
#endif
#define GMP_NAIL_BITS 0
#define SIZEOF_MP_LIMB_T (GMP_LIMB_BITS >> 3)
'''
try:
lines = open(join(mpir_dir, 'gmp-h.in'), 'r').readlines()
except IOError:
print('error attempting to read from gmp_h.in')
exit()
try:
tfile = join(mpir_dir, 'tmp.h')
with open(tfile, 'w') as outf:
first = True
for line in lines:
if search('@\w+@', line):
if first:
first = False
outf.writelines(gmp_h_32 if mode == 'win32' else gmp_h_64)
else:
outf.writelines([line])
# write result to mpir.h but only overwrite the existing
# version if this version is different (don't trigger an
# unnecessary rebuild)
write_f(tfile, join(mpir_dir, 'mpir.h'))
write_f(tfile, join(mpir_dir, 'gmp.h'))
unlink(tfile)
except IOError:
print('error attempting to create mpir.h from gmp-h.in')
exit()
# generate config.h
try:
tfile = join(mpir_dir, 'tmp.h')
with open(tfile, 'w') as outf:
for i in mpn_f[3]:
outf.writelines(['#define HAVE_NATIVE_{0:s} 1\n'.format(i[0])])
append_f(join(vc10_dir, 'cfg.h'), tfile)
write_f(tfile, join(mpir_dir, 'config.h'))
unlink(tfile)
except IOError:
print('error attempting to write to {0:s}'.format(tfile))
exit()
# generate longlong.h and copy gmp-mparam.h
try:
li_file = None
for i in mpn_f[0]:
if i[0] == 'longlong_inc':
li_file = join(mpir_dir, join(i[2], r'longlong_inc.h'))
if i[0] == 'gmp-mparam':
write_f(join(mpir_dir, join(i[2], 'gmp-mparam.h')), join(mpir_dir, 'gmp-mparam.h'))
if not li_file or not exists(li_file):
print('error attempting to read {0:s}'.format(li_file))
exit()
tfile = join(mpir_dir, 'tmp.h')
write_f(join(mpir_dir, 'longlong_pre.h'), tfile)
append_f(li_file, tfile)
append_f(join(mpir_dir, 'longlong_post.h'), tfile)
write_f(tfile, join(mpir_dir, 'longlong.h'))
unlink(tfile)
except IOError:
print('error attempting to generate longlong.h')
exit()
# generate vcxproj filter
hf_list = ('config.h', 'gmp-impl.h', 'longlong.h', 'mpir.h', 'gmp-mparam.h')
af_list = sorted(mpn_f[2] + mpn_f[3])
# set up DLL build
is_DLL = True
proj_name = 'mpir'
vcx_name = 'dll_mpir_' + config + '\\dll_mpir_' + config + '.2.vcxproj'
gen_filter(vcx_name + '.filters', hf_list, c_src_list + cc_src_list + mpn_f[1], af_list)
gen_vcxproj(proj_name, vcx_name, mode, is_DLL, hf_list, c_src_list + cc_src_list + mpn_f[1], af_list)
# set up LIB build
is_DLL = False
proj_name = 'mpir'
vcx_name = 'lib_mpir_' + config + '\\lib_mpir_' + config + '.2.vcxproj'
gen_filter(vcx_name + '.filters', hf_list, c_src_list + mpn_f[1], af_list)
gen_vcxproj(proj_name, vcx_name, mode, is_DLL, hf_list, c_src_list + mpn_f[1], af_list)
exit()
for x in sorted(mpn_f[0] + mpn_f[1]):
print(x)
print()
for x in sorted(mpn_f[2] + mpn_f[3]):
print(x)
print()
exit()
# mpn_files = dict()
# mpn_files.update(mpn_32)
# mpn_files.update(mpn_64)
for x in mpn_f[config]:
print(x)
if False:
print('1:')
for y in mpn_files[x][0]:
print(y)
print('2:')
for y in mpn_files[x][1]:
print(y)
print('3:')
for y in mpn_files[x][2]:
print(y)
print('4:')
for y in mpn_files[x][3]:
print(y)
print()
for y in sorted(x[2] + x[3]):
print(y)
print()
print()
exit()
mpn_dirs = ('mpn/generic', 'mpn/x86_64w', 'mpn/x86w' )
# compile a list of files in directories in 'dl' under root 'r' with extension 'p'
def findf(r, dl, p):
l = []
for d in dl:
for root, dirs, files in os.walk(r + d):
relp = os.path.relpath(root, r) # path relative to mpir root directory
if '.svn' in dirs:
dirs.remove('.svn') # ignore SVN directories
if d == '' or root.endswith('build.vc10'):
for d in reversed(dirs): # don't scan build.vc10 subdirectories
dirs.remove(d)
for f in files:
if f.endswith(p):
l += [(tuple(relp.split('\\')), f)]
return sorted(l)
hdr_list = findf(dpath, c_dirs, '.h')
for x in hdr_list:
print(x)
print()
src_list = findf(dpath, c_dirs, '.c')
for x in src_list:
print(x)
print()
cpp_list = findf(dpath, ['cpp'], '.cc')
for x in cpp_list:
print(x)
print()
gnc_list = findf(dpath + 'mpn/', ['generic'], '.c')
for x in gnc_list:
print(x)
print()
w32_list = findf(dpath + 'mpn/', ['x86w'], '.asm')
for x in w32_list:
print(x)
print()
x64_list = findf(dpath + 'mpn/', ['x86_64w'], '.asm')
for x in x64_list:
print(x)
print()
nd = dict([])
for d, f in gnc_list:
n, x = os.path.splitext(f)
nd[n] = nd.get(n, []) + [(d, 'c')]
for d, f in x64_list:
n, x = os.path.splitext(f)
nd[n] = nd.get(n, []) + [(d, 'asm')]
for d, f in w32_list:
n, x = os.path.splitext(f)
nd[n] = nd.get(n, []) + [(d, 'asm')]
for x in nd:
print(x, nd[x])

View File

@ -7,7 +7,7 @@ A Note On Licensing
Files in this distribution that have been created by me for use in
building MPIR with Microsoft Visual Studio 2010 are provided under
the LGPL v2.1+ license terms.
the terms of the LGPL v2.1+ license.
The MPIR library uses numerous files which are LGPL v3+ and so the
overall license of the library distribution is LGPL v3+. Some of
@ -18,8 +18,8 @@ Using the Assembler Based Build Projects
If you wish to use the assembler files you will need VSYASM, a
version of YASM x86/x64 assembler tailored specifically for use with
Microsoft Visual Studio 2010. You will need a
recent revision of YASM from:
Microsoft Visual Studio 2010. You will need a recent revision of
YASM from:
http://www.tortall.net/projects/yasm/
@ -111,11 +111,11 @@ of their build project in the IDE and exclude all the files in this
subdirectory from the build process.
All the DLLs and static libraries are multi-threaded and are linked to
the multi-threaded Microsoft run-time libraries (DLLs are linked to DLL
the multi-threaded Microsoft run-time libraries (DLLs are linked to DLL
run time libraries and static libraries are linked to run time static
libraries).
Within the 'dll' and 'lib' sub-directories used for output the structure
Within the 'dll' and 'lib' sub-directories used for output, the layout
is:
DLL or LIB
@ -126,11 +126,11 @@ is:
Release
Debug
in order to enable the appropriate library for the desired target
platform to be easily located. The individual project sub-
directories also contain the libraries once they have been built (the
'dll' and 'lib' directories are just used to hold the latest built
versions for linking the tests that are described later).
so that the appropriate library for the desired target platform can be
easily located. The individual project sub-directories also contain the
libraries once they have been built (as indicaated earlier, the 'dll'
and 'lib' directories are used to hold the latest built versions for
linking the tests).
C++ Interface
=============
@ -144,23 +144,42 @@ DLL) that has been built. To build the MPIR C+ library wrapper use:
The DLL projects include the C++ functions so an additional library
is not needed when they are used.
Python Build File Generator
===========================
Only a limited number of build configurations are supported in the
VC++ IDE build. If another build is needed, other configurations
can be created using the program mpir_build.py (Python 2.6 or later
needs to be installed).
When this program is run, it outputs a list of all available MPIR
configurations and allows the user to select one of them. It then
creates VC++ IDE build projects for both a static library and DLL
build for this configuaration.
These can then be added to a VC++ solution using the facilities of
the IDE in the normal way. The project and fillter files are named
with the extensions *.2.vcxproj and *.2.vcxproj.filters to avoid
interfering with the conflict project files already provided for
VC++.
The Tests
=========
There is a separate solution for the MPIR tests: mpir-tests.sln. In
Visual Studio 2010 this is in build.vc10 folder.
The tests are configured to always test the last version of MPIR that is
built. But this is controlled by the file lastbuild.txt in the mpir-tests
directory whose contents are typically:
The tests are configured to always test the last version of MPIR that
has been built. This is automatic but it can be changed by editing
the file lastbuild.txt in the mpir-tests directory whose content
controls the tests by setting the 'library type', the 'platform',
the 'configuration' and the 'MPIR binary directory' relative to the
mpir-tests' directory. Its content is typically:
dll Win32 Release "..\dll\Win32\Release"
giving the 'library type', the 'platform', the 'configuration' and the
'MPIR binary directory' relative to the mpir-tests' directory.
This file can be edited to test a different version of MPIR but it is also
necessary to copy either:
If this file can be edited to test a different version of MPIR, it
is also necessary to copy either:
mpir\build.vc10\mpir-tests\lib-test-config.props
@ -172,8 +191,7 @@ into:
mpir\build.vc10\mpir-tests\test-config.props
depending on whether a static or DLL build of MPIR is to be tested
respectively.
depending on whether a static or DLL build of MPIR is to be tested.
The tests also use the C++ library functions so for testing MPIR static
libraries both the desired version of MPIR and the C++ library must be
@ -183,17 +201,17 @@ MPIR DLLs as they contain the C++ routines.
Test Automation
===============
After they have been built the tests cn be run using the Python script
After they have been built the tests can be run using the Python script
run-tests.py in the build.vc10\mpir-tests directory. To see the test
output the python script should be run in a command window from within
these sub-directories:
cmd>run-tests.py
cmd>run-tests.py
and the output can be directed to a file:
cmd>run-tests.py >out.txt
cmd>run-tests.py >out.txt
When an MPIR library is built the file 'last_build.txt' is written to
the buid.vc10 subdirectory giving details of the build configuration.
These details are then used to run the MPIR tests and this means that
@ -282,8 +300,8 @@ In Windows the different C runtime libraries each have their own stream
input/output tables, which means that FILE* pointers cannot be passed from
one to another. In consequence, if an application that is built with one
library attempts to pass FILE parameters to a DLL that is built with
another, the FILE parameters will not be recognised and the program will
fail.
another library, the FILE parameters will not be recognised and the
program will fail.
It is hence important to build a MPIR application using the same run time
library as that used to build any DLL that is used - in this case the
@ -305,7 +323,7 @@ that provides a _stdcall interface to the normal _cdecl MPIR DLLs.
Prebuild
--------
It is not necessary to read this unless you wnat to change the buiild
It is not necessary to read this unless you want to change the build
process. The first step in an MPIR build is managed by the batch file
prebuilld.bat which has the following steps:
@ -363,10 +381,10 @@ file postbuild.bat which has the following steps:
for a DLL, mpir.lib and mpir.pdb for a static library) are then
copied into the output directory.
6. In the sub-directory mpir-tests, either dll-test-config.props (for
a DLL) or lib-test-config.props (for a static library) is copied
into test-config.props to set up the tests for the version of MPIR
being built.
6. In the sub-directory mpir-tests, either dll-test-config.props (for
a DLL) or lib-test-config.props (for a static library) is copied
into test-config.props to set up the tests for the version of MPIR
being built.
ACKNOWLEDGEMENTS
================
@ -381,4 +399,4 @@ My thanks to:
4. Jeff Gilchrist for his help in testing, debugging and
improving the readme giving the VC++ build instructions
Brian Gladman, August 2010
Brian Gladman, September 2011