|
66 | 66 | <_NativeLibExt Condition="$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))">.dylib</_NativeLibExt> |
67 | 67 | <_NativeLibExt Condition="'$(_NativeLibExt)' == ''">.so</_NativeLibExt> |
68 | 68 |
|
| 69 | + <!-- Source-side paths (in native/*/build or target/) --> |
69 | 70 | <_CdtLibFile>$(_CdtBuildDir)/$(_NativeLibPrefix)cdt_wrapper$(_NativeLibExt)</_CdtLibFile> |
70 | 71 | <_CgalLibFile>$(_CgalBuildDir)/$(_NativeLibPrefix)cgal_wrapper$(_NativeLibExt)</_CgalLibFile> |
71 | 72 | <_SpadeLibFile>$(_SpadeReleaseDir)/$(_NativeLibPrefix)spade_wrapper$(_NativeLibExt)</_SpadeLibFile> |
72 | 73 | </PropertyGroup> |
73 | 74 |
|
74 | 75 | <!-- ── artem-ogre/CDT C++ wrapper ──────────────────────────────────────── --> |
75 | 76 |
|
76 | | - <!-- Friendly error when cmake is not on PATH (shared by all C++ wrappers) --> |
| 77 | + <!-- Friendly error when cmake is not on PATH (shared by both C++ wrappers). |
| 78 | + BeforeTargets means this is also skipped when its owning targets are |
| 79 | + skipped via Condition (i.e. when the output libs already exist). --> |
77 | 80 | <Target Name="CheckCmake" BeforeTargets="BuildCdtNative;BuildCgalNative"> |
78 | 81 | <Exec Command="cmake --version" |
79 | 82 | IgnoreExitCode="true" |
|
86 | 89 | Text="cmake was not found on PATH. It is required to build the C++ wrappers. Install CMake from https://cmake.org/download/ and ensure it is on your PATH." /> |
87 | 90 | </Target> |
88 | 91 |
|
89 | | - <Target Name="BuildCdtNative" BeforeTargets="Build" DependsOnTargets="CheckCmake"> |
| 92 | + <!-- |
| 93 | + IMPORTANT: $(OutputPath) is empty at PropertyGroup evaluation time in SDK-style |
| 94 | + projects, so the output lib paths must be inlined directly in Condition attributes |
| 95 | + (which are evaluated at target-execution time when $(OutputPath) is fully resolved). |
| 96 | +
|
| 97 | + Condition="!Exists('$(OutputPath)...')" means: |
| 98 | + • First build (or after `dotnet clean`): output lib is missing → run cmake/cargo. |
| 99 | + The BeforeTargets check targets (CheckCmake/CheckCargo) also run. |
| 100 | + • Every subsequent `dotnet build`: output lib already in output dir → entire |
| 101 | + target AND its BeforeTargets prerequisites are skipped — no cmake or cargo invoked. |
| 102 | + The cmake/cargo build dirs (native/*/build, native/*/target) are NOT cleaned by |
| 103 | + `dotnet clean`, so a rebuild after clean is fast (only re-links if needed). |
| 104 | + --> |
| 105 | + <Target Name="BuildCdtNative" BeforeTargets="Build" |
| 106 | + Condition="!Exists('$(OutputPath)$(_NativeLibPrefix)cdt_wrapper$(_NativeLibExt)')"> |
90 | 107 | <MakeDir Directories="$(_CdtBuildDir)" /> |
91 | 108 | <Exec Command="cmake -S "$(_CdtNativeDir)" -B "$(_CdtBuildDir)" -DCMAKE_BUILD_TYPE=Release" /> |
92 | 109 | <Exec Command="cmake --build "$(_CdtBuildDir)" --config Release" /> |
93 | 110 | <MakeDir Directories="$(OutputPath)" /> |
94 | | - <Copy SourceFiles="$(_CdtLibFile)" |
95 | | - DestinationFolder="$(OutputPath)" |
96 | | - SkipUnchangedFiles="true" /> |
| 111 | + <Copy SourceFiles="$(_CdtLibFile)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="true" /> |
97 | 112 | </Target> |
98 | 113 |
|
99 | 114 | <!-- ── CGAL C++ wrapper ─────────────────────────────────────────────────── --> |
100 | 115 |
|
101 | | - <Target Name="BuildCgalNative" BeforeTargets="Build" DependsOnTargets="CheckCmake"> |
| 116 | + <Target Name="BuildCgalNative" BeforeTargets="Build" |
| 117 | + Condition="!Exists('$(OutputPath)$(_NativeLibPrefix)cgal_wrapper$(_NativeLibExt)')"> |
102 | 118 | <MakeDir Directories="$(_CgalBuildDir)" /> |
103 | 119 | <Exec Command="cmake -S "$(_CgalNativeDir)" -B "$(_CgalBuildDir)" -DCMAKE_BUILD_TYPE=Release" /> |
104 | 120 | <Exec Command="cmake --build "$(_CgalBuildDir)" --config Release" /> |
105 | 121 | <MakeDir Directories="$(OutputPath)" /> |
106 | | - <Copy SourceFiles="$(_CgalLibFile)" |
107 | | - DestinationFolder="$(OutputPath)" |
108 | | - SkipUnchangedFiles="true" /> |
| 122 | + <Copy SourceFiles="$(_CgalLibFile)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="true" /> |
109 | 123 | </Target> |
110 | 124 |
|
111 | 125 | <!-- ── Spade Rust wrapper ───────────────────────────────────────────────── --> |
|
123 | 137 | Text="cargo was not found on PATH. It is required to build the Spade Rust wrapper. Install Rust from https://rustup.rs/ and ensure cargo is on your PATH." /> |
124 | 138 | </Target> |
125 | 139 |
|
126 | | - <Target Name="BuildSpadeNative" BeforeTargets="Build" DependsOnTargets="CheckCargo"> |
| 140 | + <Target Name="BuildSpadeNative" BeforeTargets="Build" |
| 141 | + Condition="!Exists('$(OutputPath)$(_NativeLibPrefix)spade_wrapper$(_NativeLibExt)')"> |
127 | 142 | <Exec Command="cargo build --release --manifest-path "$(_SpadeNativeDir)/Cargo.toml"" /> |
128 | 143 | <MakeDir Directories="$(OutputPath)" /> |
129 | | - <Copy SourceFiles="$(_SpadeLibFile)" |
130 | | - DestinationFolder="$(OutputPath)" |
131 | | - SkipUnchangedFiles="true" /> |
| 144 | + <Copy SourceFiles="$(_SpadeLibFile)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="true" /> |
| 145 | + </Target> |
| 146 | + |
| 147 | + <!-- ── Clean hook ───────────────────────────────────────────────────────── --> |
| 148 | + |
| 149 | + <!-- Remove the native libs from the output dir when `dotnet clean` runs, |
| 150 | + so the next build will re-copy (and re-compile if needed) them. --> |
| 151 | + <Target Name="CleanNativeWrappers" AfterTargets="Clean"> |
| 152 | + <Delete Files="$(OutputPath)$(_NativeLibPrefix)cdt_wrapper$(_NativeLibExt); |
| 153 | + $(OutputPath)$(_NativeLibPrefix)cgal_wrapper$(_NativeLibExt); |
| 154 | + $(OutputPath)$(_NativeLibPrefix)spade_wrapper$(_NativeLibExt)" /> |
132 | 155 | </Target> |
133 | 156 |
|
134 | 157 | </Project> |
0 commit comments