1
2# generate vcxproj file
3
4from os.path import normpath, join, split, relpath
5from enum import IntEnum
6
7class Project_Type(IntEnum):
8  APP = 0
9  LIB = 1
10  DLL = 2
11
12app_ext = ('.exe', '.lib', '.dll')
13app_str = ('Application', 'StaticLibrary', 'DynamicLibrary')
14
15def vcx_proj_cfg(plat, outf):
16
17  f1 = r'''  <ItemGroup Label="ProjectConfigurations">
18'''
19  f2 = r'''    <ProjectConfiguration Include="{1:s}|{0:s}">
20      <Configuration>{1:s}</Configuration>
21      <Platform>{0:s}</Platform>
22    </ProjectConfiguration>
23'''
24  f3 = r'''  </ItemGroup>
25'''
26  outf.write(f1)
27  for pl in plat:
28    for conf in ('Release', 'Debug'):
29      outf.write(f2.format(pl, conf))
30  outf.write(f3)
31
32def vcx_globals(name, guid, outf):
33
34  f1 = r'''  <PropertyGroup Label="Globals">
35    <RootNamespace>{0:s}</RootNamespace>
36    <Keyword>Win32Proj</Keyword>
37    <ProjectGuid>{1:s}</ProjectGuid>
38  </PropertyGroup>
39'''
40  outf.write(f1.format(name, guid))
41
42def vcx_default_cpp_props(outf):
43
44  f1 = r'''  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
45'''
46  outf.write(f1)
47
48def vcx_library_type(plat, proj_type, vs_info, outf):
49
50  f1 = r'''  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='{1:s}|{0:s}'" Label="Configuration">
51    <ConfigurationType>{2:s}</ConfigurationType>
52    <UseDebugLibraries>{3:s}</UseDebugLibraries>
53    <PlatformToolset>v{4:s}</PlatformToolset>
54  </PropertyGroup>
55'''
56  for pl in plat:
57    for conf, bool in (('Release', 'false'), ('Debug', 'true')):
58      outf.write(f1.format(pl, conf, app_str[proj_type], bool, vs_info['platform_toolset']))
59
60def vcx_cpp_props(outf):
61
62  f1 = r'''  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
63'''
64  outf.write(f1)
65
66def vcx_extensions(outf):
67
68  f1 = r'''  <ImportGroup Label="ExtensionSettings">
69    <Import Project="..\..\build.vc\vsyasm.props" />
70  </ImportGroup>
71'''
72  outf.write(f1)
73
74def vcx_user_props(plat, proj_type, outf):
75
76  f1 = r'''  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='{1:s}|{0:s}'" Label="PropertySheets">
77    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
78    <Import Project="..\..\build.vc\mpir_{2:s}_{3:s}.props" />
79  </ImportGroup>
80'''
81  for pl in plat:
82    for conf in ('Release', 'Debug'):
83      outf.write(f1.format(pl, conf, conf.lower(), app_ext[proj_type][1:]))
84
85def vcx_target_name_and_dirs(name, plat, proj_type, outf):
86
87  f1 = r'''  <PropertyGroup>
88    <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
89'''
90  f2 = r'''    <TargetName Condition="'$(Configuration)|$(Platform)'=='{1:s}|{0:s}'">{2:s}</TargetName>
91'''
92  f3 = r'''  </PropertyGroup>
93'''
94  outf.write(f1)
95  for pl in plat:
96    for conf in ('Release', 'Debug'):
97      outf.write(f2.format(pl, conf, name))
98  outf.write(f3)
99
100def yasm_options(plat, proj_type, outf):
101
102  f1 = r'''    <YASM>
103      <Defines>{0:s}</Defines>
104      <IncludePaths>..\..\mpn\x86{1:s}w\</IncludePaths>
105      <Debug>true</Debug>
106      <ObjectFile>$(IntDir)mpn\</ObjectFile>
107    </YASM>
108'''
109
110  outf.write(f1.format('DLL' if proj_type == Project_Type.DLL else '', '' if plat == 'Win32' else '_64'))
111
112def compiler_options(plat, proj_type, is_debug, outf):
113
114  f1 = r'''    <ClCompile>
115      <AdditionalIncludeDirectories>..\..\</AdditionalIncludeDirectories>
116      <PreprocessorDefinitions>{0:s}%(PreprocessorDefinitions)</PreprocessorDefinitions>
117    </ClCompile>
118'''
119
120  if proj_type == Project_Type.APP:
121    s1 = 'DEBUG;WIN32;_CONSOLE;'
122  if proj_type == Project_Type.DLL:
123    s1 = 'DEBUG;WIN32;HAVE_CONFIG_H;MSC_BUILD_DLL;'
124  elif proj_type == Project_Type.LIB:
125    s1 = 'DEBUG;WIN32;_LIB;HAVE_CONFIG_H;'
126  else:
127    pass
128  if plat == 'x64':
129    s1 = s1 + '_WIN64;'
130  s1 = ('_' if is_debug else 'N') + s1
131  outf.write(f1.format(s1))
132
133def linker_options(outf):
134
135  f1 = r'''    <Link>
136    </Link>
137'''
138  outf.write(f1)
139
140def vcx_pre_build(name, plat, msvc_ver, outf):
141
142  f1 = r'''    <PreBuildEvent>
143      <Command>cd ..\..\build.vc
144prebuild {0:s} {1:s} {2:s}
145      </Command>
146    </PreBuildEvent>
147'''
148  outf.write(f1.format(name, plat, msvc_ver))
149
150def vcx_post_build(is_cpp, msvc_ver, outf):
151
152  f1 = r'''
153    <PostBuildEvent>
154      <Command>cd ..\..\build.vc
155postbuild "$(TargetPath)" {0:s}
156      </Command>
157    </PostBuildEvent>
158'''
159
160  outf.write(f1.format(msvc_ver))
161
162def vcx_tool_options(config, plat, proj_type, is_cpp, af_list, add_prebuild, msvc_ver, outf):
163
164  f1 = r'''  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='{1:s}|{0:s}'">
165'''
166  f2 = r'''  </ItemDefinitionGroup>
167'''
168  for pl in plat:
169    for is_debug in (False, True):
170      outf.write(f1.format(pl, 'Debug' if is_debug else 'Release'))
171      if add_prebuild and not is_cpp:
172        vcx_pre_build(config, pl, msvc_ver, outf)
173      if af_list:
174        yasm_options(pl, proj_type, outf)
175      compiler_options(pl, proj_type, is_debug, outf)
176      if proj_type != Project_Type.LIB:
177        linker_options(outf)
178      vcx_post_build(is_cpp, msvc_ver, outf)
179      outf.write(f2)
180
181def vcx_external_props(outf):
182
183  f1 = r'''  <ImportGroup>
184    <Import Condition="exists('$(MPIR_Props_External)')" Project="$(MPIR_Props_External)" />
185  </ImportGroup>
186'''
187  outf.write(f1)
188
189def vcx_hdr_items(hdr_list, relp, outf):
190
191  f1 = r'''  <ItemGroup>
192'''
193  f2 = r'''    <ClInclude Include="{}{}" />
194'''
195  f3 = r'''  </ItemGroup>
196'''
197  outf.write(f1)
198  for i in hdr_list:
199    outf.write(f2.format(relp, i))
200  outf.write(f3)
201
202def vcx_c_items(cf_list, plat, relp, outf):
203
204  f1 = r'''  <ItemGroup>
205'''
206  f2 = r'''    <ClCompile Include="{0:s}{1[0]:s}{1[1]:s}" />
207'''
208  f3 = r'''    <ClCompile Include="{0:s}{1[2]:s}\{1[0]:s}{1[1]:s}" />
209'''
210  f6 = r'''  </ItemGroup>
211'''
212  outf.write(f1)
213  for nxd in cf_list:
214    if nxd[2] == '':
215      outf.write(f2.format(relp, nxd))
216    else:
217      outf.write(f3.format(relp, nxd))
218
219  outf.write(f6)
220
221def vcx_a_items(af_list, relp, outf):
222
223  f1 = r'''  <ItemGroup>
224'''
225  f2 = r'''    <YASM Include="{0:s}{1[2]:s}\{1[0]:s}{1[1]:s}" />
226'''
227  f3 = r'''  </ItemGroup>
228'''
229  outf.write(f1)
230  for nxd in af_list:
231    outf.write(f2.format(relp, nxd))
232  outf.write(f3)
233
234def gen_vcxproj(path, root_dir, proj_name, guid, config, plat, proj_type,
235                is_cpp, hf_list, cf_list, af_list, add_prebuild, vs_info):
236
237  f1 = r'''<?xml version="1.0" encoding="utf-8"?>
238<Project DefaultTargets="Build" ToolsVersion="{}" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
239'''
240  f2 = r'''  <PropertyGroup Label="UserMacros" />
241'''
242  f3 = r'''  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
243'''
244  f4 = r'''  <ImportGroup Label="ExtensionTargets">
245    <Import Project="..\..\build.vc\vsyasm.targets" />
246    </ImportGroup>
247'''
248
249  f5 = r'''<ItemGroup>
250    <None Include="..\..\gmp-h.in" />
251    </ItemGroup>
252</Project>
253'''
254
255  relp = split(relpath(root_dir, path))[0] + '\\'
256  with open(path, 'w') as outf:
257    outf.write(f1.format(vs_info['vcx_tool']))
258    vcx_proj_cfg(plat, outf)
259    vcx_globals(proj_name, guid, outf)
260    vcx_default_cpp_props(outf)
261    vcx_library_type(plat, proj_type, vs_info, outf)
262    vcx_cpp_props(outf)
263    if af_list:
264      vcx_extensions(outf)
265    vcx_user_props(plat, proj_type, outf)
266    outf.write(f2)
267    vcx_target_name_and_dirs(proj_name, plat, proj_type, outf)
268    vcx_tool_options(config, plat, proj_type, is_cpp, af_list, add_prebuild, vs_info['msvc'], outf)
269    vcx_external_props(outf)
270    if hf_list:
271      vcx_hdr_items(hf_list, relp, outf)
272    vcx_c_items(cf_list, plat, relp, outf)
273    vcx_a_items(af_list, relp, outf)
274    outf.write(f3)
275    if af_list:
276      outf.write(f4)
277    outf.write(f5)
278
279