• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""
2Provides .props file.
3"""
4
5import os
6
7from .constants import *
8
9__all__ = ["get_props_layout"]
10
11PYTHON_PROPS_NAME = "python.props"
12
13PROPS_DATA = {
14    "PYTHON_TAG": VER_DOT,
15    "PYTHON_VERSION": os.getenv("PYTHON_NUSPEC_VERSION"),
16    "PYTHON_PLATFORM": os.getenv("PYTHON_PROPS_PLATFORM"),
17    "PYTHON_TARGET": "",
18}
19
20if not PROPS_DATA["PYTHON_VERSION"]:
21    PROPS_DATA["PYTHON_VERSION"] = "{}.{}{}{}".format(
22        VER_DOT, VER_MICRO, "-" if VER_SUFFIX else "", VER_SUFFIX
23    )
24
25PROPS_DATA["PYTHON_TARGET"] = "_GetPythonRuntimeFilesDependsOn{}{}_{}".format(
26    VER_MAJOR, VER_MINOR, PROPS_DATA["PYTHON_PLATFORM"]
27)
28
29PROPS_TEMPLATE = r"""<?xml version="1.0" encoding="utf-8"?>
30<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
31  <PropertyGroup Condition="$(Platform) == '{PYTHON_PLATFORM}'">
32    <PythonHome Condition="$(Configuration) == 'Debug'">$([msbuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), "python_d.exe")</PythonHome>
33    <PythonHome Condition="$(PythonHome) == ''">$([msbuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), "python.exe")</PythonHome>
34    <PythonInclude>$(PythonHome)\include</PythonInclude>
35    <PythonLibs>$(PythonHome)\libs</PythonLibs>
36    <PythonTag>{PYTHON_TAG}</PythonTag>
37    <PythonVersion>{PYTHON_VERSION}</PythonVersion>
38
39    <IncludePythonExe Condition="$(IncludePythonExe) == ''">true</IncludePythonExe>
40    <IncludeDistutils Condition="$(IncludeDistutils) == ''">false</IncludeDistutils>
41    <IncludeLib2To3 Condition="$(IncludeLib2To3) == ''">false</IncludeLib2To3>
42    <IncludeVEnv Condition="$(IncludeVEnv) == ''">false</IncludeVEnv>
43
44    <GetPythonRuntimeFilesDependsOn>{PYTHON_TARGET};$(GetPythonRuntimeFilesDependsOn)</GetPythonRuntimeFilesDependsOn>
45  </PropertyGroup>
46
47  <ItemDefinitionGroup Condition="$(Platform) == '{PYTHON_PLATFORM}'">
48    <ClCompile>
49      <AdditionalIncludeDirectories>$(PythonInclude);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
50      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
51    </ClCompile>
52    <Link>
53      <AdditionalLibraryDirectories>$(PythonLibs);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
54    </Link>
55  </ItemDefinitionGroup>
56
57  <Target Name="GetPythonRuntimeFiles" Returns="@(PythonRuntime)" DependsOnTargets="$(GetPythonRuntimeFilesDependsOn)" />
58
59  <Target Name="{PYTHON_TARGET}" Returns="@(PythonRuntime)">
60    <ItemGroup>
61      <_PythonRuntimeExe Include="$(PythonHome)\python*.dll" />
62      <_PythonRuntimeExe Include="$(PythonHome)\python*.exe" Condition="$(IncludePythonExe) == 'true'" />
63      <_PythonRuntimeExe>
64        <Link>%(Filename)%(Extension)</Link>
65      </_PythonRuntimeExe>
66      <_PythonRuntimeDlls Include="$(PythonHome)\DLLs\*.pyd" />
67      <_PythonRuntimeDlls Include="$(PythonHome)\DLLs\*.dll" />
68      <_PythonRuntimeDlls>
69        <Link>DLLs\%(Filename)%(Extension)</Link>
70      </_PythonRuntimeDlls>
71      <_PythonRuntimeLib Include="$(PythonHome)\Lib\**\*" Exclude="$(PythonHome)\Lib\**\*.pyc;$(PythonHome)\Lib\site-packages\**\*" />
72      <_PythonRuntimeLib Remove="$(PythonHome)\Lib\distutils\**\*" Condition="$(IncludeDistutils) != 'true'" />
73      <_PythonRuntimeLib Remove="$(PythonHome)\Lib\lib2to3\**\*" Condition="$(IncludeLib2To3) != 'true'" />
74      <_PythonRuntimeLib Remove="$(PythonHome)\Lib\ensurepip\**\*" Condition="$(IncludeVEnv) != 'true'" />
75      <_PythonRuntimeLib Remove="$(PythonHome)\Lib\venv\**\*" Condition="$(IncludeVEnv) != 'true'" />
76      <_PythonRuntimeLib>
77        <Link>Lib\%(RecursiveDir)%(Filename)%(Extension)</Link>
78      </_PythonRuntimeLib>
79      <PythonRuntime Include="@(_PythonRuntimeExe);@(_PythonRuntimeDlls);@(_PythonRuntimeLib)" />
80    </ItemGroup>
81
82    <Message Importance="low" Text="Collected Python runtime from $(PythonHome):%0D%0A@(PythonRuntime->'  %(Link)','%0D%0A')" />
83  </Target>
84</Project>
85"""
86
87
88def get_props_layout(ns):
89    if ns.include_all or ns.include_props:
90        # TODO: Filter contents of props file according to included/excluded items
91        d = dict(PROPS_DATA)
92        if not d.get("PYTHON_PLATFORM"):
93            d["PYTHON_PLATFORM"] = {
94                "win32": "Win32",
95                "amd64": "X64",
96                "arm32": "ARM",
97                "arm64": "ARM64",
98            }[ns.arch]
99        props = PROPS_TEMPLATE.format_map(d)
100        yield "python.props", ("python.props", props.encode("utf-8"))
101