Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:

strategy:
fail-fast: false
matrix: ${{ fromJSON(github.event_name == 'push' && github.ref == 'refs/heads/main' && '{"platform":["x64","Win32"],"configuration":["Debug","Release"]}' || '{"platform":["x64"],"configuration":["Debug","Release"]}') }}
matrix: ${{ fromJSON(github.event_name == 'push' && github.ref == 'refs/heads/main' && '{"platform":["x64","Win32"],"configuration":["Debug","Release"]}' || github.event_name == 'pull_request' && '{"include":[{"platform":"x64","configuration":"Debug"},{"platform":"x64","configuration":"Release"},{"platform":"Win32","configuration":"Debug"}]}' || '{"platform":["x64"],"configuration":["Debug","Release"]}') }}

env:
VCPKG_BINARY_SOURCES: 'clear;files,${{ github.workspace }}\vcpkg-binary-cache,readwrite'
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,10 @@ CMakeUserPresets.json
# C++ language server compilation database
.mscppls/

# Local tools and PowerShell editor state
.tools/
PowerShellEditorServices.json

# used by Pi.dev
/APPEND_SYSTEM.md

Expand Down
10 changes: 3 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,9 @@ cmake --build --preset x64-debug
ctest --preset x64-debug
```

Until CMake registers the ActiveX tests, also build the legacy solution and run
its ActiveX suite:

```powershell
msbuild MapWinGIS6.slnx -restore -p:Configuration=Debug -p:Platform=x64 -m
bin\Debug\x64\MapWinGIS.ActiveX.Tests.exe
```
When `MWG_BUILD_ACTIVEX` is enabled, CMake also registers the ActiveX native
tests with CTest. The registered-control activation check is labeled
`interactive` and is excluded from the standard CTest preset.

Every task must leave the tree in this state: CMake `Debug | x64` builds with
no new Level 4 warnings and all non-interactive tests pass. The legacy
Expand Down
7 changes: 3 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,10 @@ if(MWG_BUILD_ACTIVEX)
endif()

if(MWG_BUILD_TESTS)
enable_testing()
add_subdirectory(tests/MapWinGIS.Core.Tests)
if(MWG_BUILD_ACTIVEX)
enable_testing()
add_subdirectory(tests/MapWinGIS.Core.Tests)
else()
message(STATUS "Skipping the native GoogleTest suite: it requires MWG_BUILD_ACTIVEX=ON.")
add_subdirectory(tests/MapWinGIS.ActiveX.Tests)
endif()
endif()

Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ CTest runs the CMake-built test cases:
ctest --preset x64-debug
```

CTest discovers both native suites when ActiveX is enabled. Core tests remain
available when configuring with `-DMWG_BUILD_ACTIVEX=OFF`.

For the legacy MSBuild build, run its test executables from the repository root:

```powershell
Expand Down Expand Up @@ -115,7 +118,8 @@ See the CMake section in the build guide for target names and additional command
CI Release artifacts use the `full-drivers` feature. Their tests require
HDF5, NetCDF, KML, SpatiaLite, and PostgreSQL support.
Pull requests build and test Debug and full-driver Release for x64 using both
CMake and MSBuild. Each CI build has a 180-minute timeout.
CMake and MSBuild, and also run CMake Win32 Debug. Pushes to `main` include the
full Win32 Debug and Release matrix. Each CI build has a 180-minute timeout.

After vector geometry edits, call `VectorDataset::Flush()` before closing to
persist exact Shapefile and GeoPackage bounds. The flush batches stored-extent
Expand Down
2 changes: 1 addition & 1 deletion build/props/MapWinGIS.Cpp.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<ConformanceMode>true</ConformanceMode>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">true</TreatWarningAsError>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ExceptionHandling>Sync</ExceptionHandling>
Expand Down
6 changes: 6 additions & 0 deletions build/scripts/Compare-CompileCommands.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ $explainedCompileDifferencesByTarget = @{
'^/I<builddir>/.*/midl$' = 'MIDL output directory (D3)'
'^/I<vcpkg_installed>/[^/]+/include$' = 'MSBuild vcpkg auto-include; the OCX has no direct vcpkg dependency in CMake'
}
'MapWinGIS.ActiveX.Tests' = [ordered]@{
'^/I<intdir>$' = 'MIDL output moved from the intermediate directory to <build>/.../midl (D3)'
'^/I<repo>/obj/MapWinGIS\.ActiveX/[^/]+/[^/]+$' = 'MSBuild ActiveX intermediate directory containing MIDL headers; CMake uses its MIDL target output'
'^/I<builddir>/.*/midl$' = 'MIDL output directory (D3)'
'^/I<vcpkg_installed>/[^/]+/include$' = 'MSBuild vcpkg auto-include; CMake exposes dependency includes through imported targets'
}
}

# MSBuild project names that differ from the CMake target names.
Expand Down
4 changes: 1 addition & 3 deletions cmake/MwgCompilerOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,13 @@ function(mwg_apply_common_options target)

set(c_cxx "$<COMPILE_LANGUAGE:C,CXX>")
set(debug "$<AND:${c_cxx},$<CONFIG:Debug>>")
set(debug_x64 "$<AND:$<CONFIG:Debug>,$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>>")
set(release "$<AND:${c_cxx},$<CONFIG:Release>>")

target_compile_options(${target} PRIVATE
# WarningLevel, DisableSpecificWarnings. 4251 is safe: one toolset and
# one CRT for every binary of the product.
"$<${c_cxx}:/W4;/wd4251;/external:W4>"
"$<$<AND:${c_cxx},${debug_x64}>:/WX>"
"$<$<AND:${c_cxx},$<NOT:${debug_x64}>>:/WX->"
"$<${c_cxx}:/WX>"
# AdditionalOptions
"$<${c_cxx}:/utf-8;/Zc:__cplusplus;/Zc:preprocessor;/Zc:throwingNew;/bigobj>"
# ConformanceMode, SDLCheck, ExceptionHandling and MSBuild defaults
Expand Down
25 changes: 16 additions & 9 deletions docs/BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ ctest --preset x64-debug
```

The first configure installs GDAL and its dependencies and can take a while;
later builds reuse the vcpkg binary cache. See [Building with CMake](#building-with-cmake)
for other presets, Visual Studio, and CLion.
later builds reuse the vcpkg binary cache. CTest runs the Core suite and, when
`MWG_BUILD_ACTIVEX` is enabled, the ActiveX suite. See
[Building with CMake](#building-with-cmake) for other presets, Visual Studio,
and CLion.

## Legacy MSBuild build

Expand All @@ -47,9 +49,10 @@ do not overwrite one another. If `msbuild` is not on `PATH`, see

### ActiveX activation

The solution builds `MapWinGIS.ocx` beside `MapWinGIS.Core.dll`. To verify
COM activation without machine-wide registration, run the activation check
from a PowerShell process that matches the target architecture:
The solution and CMake build `MapWinGIS.ocx` beside `MapWinGIS.Core.dll` when
ActiveX is enabled. To verify COM activation without machine-wide registration,
run the activation check from a PowerShell process that matches the target
architecture:

```powershell
pwsh -File tests\MapWinGIS.ActiveX.Tests\Verify-ActiveXActivation.ps1 -Configuration Debug -Platform x64
Expand Down Expand Up @@ -272,9 +275,11 @@ hardcode a Visual Studio installation path in repository files.

### Building with CMake

The CMake build covers `MapWinGIS.Core.dll`, `MapWinGIS.ocx`, and the Core
GoogleTest suite. It does not yet build the ActiveX-specific test executable;
run the legacy ActiveX tests until CMake registers that suite. Set
The CMake build covers `MapWinGIS.Core.dll`, `MapWinGIS.ocx`, and both native
GoogleTest suites. Core tests remain available when `MWG_BUILD_ACTIVEX=OFF`;
the ActiveX suite and OCX require ActiveX to be enabled. CTest labels the
registration-based ActiveX activation check `interactive`, so the standard
test preset excludes it. Set
`MWG_BUILD_SAMPLES=ON` to add the `translate` sample and, when .NET and
PowerShell 7 are installed, targets to build and launch the C# ActiveX test
host. The OCX needs the **C++ ATL for latest v145 build tools** component for
Expand Down Expand Up @@ -316,6 +321,7 @@ Then build individual targets:
```powershell
cmake --build --preset x64-debug --target MapWinGIS.Core
cmake --build --preset x64-debug --target MapWinGIS.ActiveX
cmake --build --preset x64-debug --target MapWinGIS.ActiveX.Tests
cmake --build --preset x64-debug --target MapWinGIS.Samples.Translate
cmake --build --preset x64-debug --target build_activex_host
cmake --build --preset x64-debug --target run_activex_host
Expand Down Expand Up @@ -503,4 +509,5 @@ The CMake `run_activex_host` targets pass the runtime directory automatically.
When launching the C# host script directly, pass that directory with
`-BinDirectory`, for example `-BinDirectory out\b\x64d\bin`. This directory
override does not enable native ActiveX hosting verification: that check
requires the legacy `MapWinGIS.ActiveX.Tests.exe` and its hosting test.
requires `MapWinGIS.ActiveX.Tests.exe` and its hosting test. CMake builds this
executable when `MWG_BUILD_ACTIVEX` is enabled.
46 changes: 27 additions & 19 deletions docs/CMAKE-MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ collected with [`build/scripts/Compare-CompileCommands.ps1`](#parity-measurement

## Targets

| MSBuild project | Output | Type | Planned CMake target |
| MSBuild project | Output | Type | CMake target |
|---|---|---|---|
| `src/MapWinGIS.Core/MapWinGIS.Core.vcxproj` | `MapWinGIS.Core.dll` (+ `.lib`, `.pdb`) | DLL, subsystem `WINDOWS` | `MapWinGIS.Core` |
| `src/MapWinGIS.ActiveX/MapWinGIS.ActiveX.vcxproj` | `MapWinGIS.ocx` (+ `.lib`, `.pdb`, `MapWinGIS.ActiveX.tlb`) | DLL, subsystem `WINDOWS`, `UseOfAtl=Static` | `MapWinGIS.ActiveX.Interface` (MIDL) + `MapWinGIS.ActiveX` |
| `tests/MapWinGIS.Core.Tests/MapWinGIS.Core.Tests.vcxproj` | `MapWinGIS.Core.Tests.exe` | Console | `MapWinGIS.Core.Tests` |
| `tests/MapWinGIS.ActiveX.Tests/MapWinGIS.ActiveX.Tests.vcxproj` | `MapWinGIS.ActiveX.Tests.exe` | Console | `MapWinGIS.ActiveX.Tests` |
| `samples/Cpp/Translate.vcxproj` (project name `TranslateSample`) | `translate.exe` | Console | `MapWinGIS.Samples.Translate` (`OUTPUT_NAME translate`) |
| `samples/CSharp/ActiveXTestHost/ActiveXTestHost.csproj` | `ActiveXTestHost.exe` | .NET 10 WinForms | custom targets around `dotnet build` |

Expand Down Expand Up @@ -57,24 +58,30 @@ and `src` (private).
`DllUnregisterServer`, `DllInstall`).
- No `.manifest` file; the linker embeds its default manifest.

**MapWinGIS.Core.Tests** — `MWG_ENABLE_RENDERER_TEST_HOOKS`; include
directories `src/MapWinGIS.Core/include`, `src/MapWinGIS.ActiveX` and the
ActiveX MIDL output directory `obj/MapWinGIS.ActiveX/<Config>/<Platform>`.
**MapWinGIS.Core.Tests** — include directory `src/MapWinGIS.Core/include`.

- Headers: `TestData.h`.
- Sources: `GdalAlgorithmRunnerTests.cpp`, `GdalEnvironmentTests.cpp`,
`GdalModernCapabilitiesTests.cpp`, `GdalRuntimeTests.cpp`,
`GdalTypedOptionsTests.cpp`, `GdalUtilsTests.cpp`, `Main.cpp` (defines
`main`), `MapRenderSceneTests.cpp`, `MapTests.cpp`, `MapViewTests.cpp`,
`PolygonTriangulationTests.cpp`, `TestData.cpp`, `VectorDatasetTests.cpp`,
`VectorLayerTests.cpp`, `VectorRenderSceneTests.cpp`, and `ViewportTests.cpp`.
- Project reference: Core.

**MapWinGIS.ActiveX.Tests** — `MWG_ENABLE_RENDERER_TEST_HOOKS`; include
directories `src/MapWinGIS.Core/include`, `src/MapWinGIS.ActiveX`,
`tests/MapWinGIS.Core.Tests` and the ActiveX MIDL output directory.

- Sources: `ActiveXActivationTests.cpp`, `ComConversionTests.cpp`,
`GdalAlgorithmRunnerTests.cpp`, `GdalEnvironmentTests.cpp`,
`GdalModernCapabilitiesTests.cpp`, `GdalOperationDispatcherTests.cpp`,
`GdalRuntimeTests.cpp`, `GdalTypedOptionsTests.cpp`, `GdalUtilsTests.cpp`,
`Main.cpp` (defines `main`), `RenderingBaselineTests.cpp`, `TestData.cpp`,
`VectorDatasetTests.cpp`, `VectorLayerRendererTests.cpp`,
`VectorLayerTests.cpp`, `VectorRenderSceneTests.cpp`.
- ActiveX sources compiled again with the test hook definition:
`GdiVectorLayerRenderer.cpp`, `OpenGlVectorLayerRenderer.cpp`,
`GdalOperationDispatcher.cpp`, `ComConversion.cpp`,
`VectorLayerRenderer.cpp`, `ViewTransform.cpp`.
- Project references: Core (linked) and ActiveX (build order only,
`LinkLibraryDependencies=false`), so the OCX is beside the test executable.
`FrameBufferTests.cpp`, `GdalOperationDispatcherTests.cpp`,
`Main.cpp` and `TestData.cpp` from Core.Tests, `RenderingBaselineTests.cpp`,
`VectorLayerRendererTests.cpp`, `FrameBuffer.cpp`, and the ActiveX shared
implementation sources.
- Links Core, GDAL, GoogleTest and the COM, GDI, OpenGL and process-status
libraries used by the tests. The OCX is a build-order dependency, not a
linked library, so activation tests load the built control from the runtime
directory.

**Translate sample** — `samples/Cpp/translate.cpp` (`wmain`); include
directory `src/MapWinGIS.Core/include`. It uses only the Core public API.
Expand All @@ -86,7 +93,7 @@ and MSBuild defaults):

| Option | Source |
|---|---|
| `/W4 /WX (Debug x64), /WX- (other configurations) /wd4251 /external:W4` | `WarningLevel`, `TreatWarningAsError` for Debug x64, `DisableSpecificWarnings`; `/external:W4` is the MSBuild default for external headers |
| `/W4 /WX /wd4251 /external:W4` | `WarningLevel`, `TreatWarningAsError` for every configuration and platform, `DisableSpecificWarnings`; `/external:W4` is the MSBuild default for external headers |
| `/utf-8 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /bigobj` | `AdditionalOptions` |
| `/permissive- /sdl /EHsc /GS /Gd /Gm- /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline` | `ConformanceMode`, `SDLCheck`, `ExceptionHandling`, MSBuild defaults |
| `/std:c++20` (`/TP`), `/std:c17` (`/TC`, `_i.c` only) | `LanguageStandard`, `LanguageStandard_C` |
Expand All @@ -104,7 +111,7 @@ Per configuration:
| Release | `/O2 /Oi /Gy /guard:cf /MD /D NDEBUG` |

Per target: `MWG_CORE_BUILD` (Core), `_ATL_APARTMENT_THREADED` (ActiveX),
`MWG_ENABLE_RENDERER_TEST_HOOKS` (tests).
`MWG_ENABLE_RENDERER_TEST_HOOKS` (ActiveX.Tests).

Not defined by any project: `WIN32`, `_WINDOWS`, `_USRDLL`, `_CONSOLE`. The
CMake defaults `/DWIN32 /D_WINDOWS` are therefore removed, so the two builds
Expand Down Expand Up @@ -135,7 +142,8 @@ hides what each target uses. From the sources and `dumpbin /dependents`:
|---|---|
| Core | `GDAL::GDAL`, `GEOS::geos_c` (`GdalEnvironment.cpp` includes `geos_c.h` and calls `GEOSversion()`). PROJ is reached only through GDAL/OGR (`OSRSetPROJSearchPaths`). Windows: `kernel32` only. |
| ActiveX | Core, `ole32`, `oleaut32`, `uuid`, `user32`, `gdi32`, `advapi32` (registration), `opengl32` (through `#pragma comment(lib, ...)` in `OpenGlVectorLayerRenderer.cpp`), static ATL. No direct GDAL use. |
| Tests | Core, `GDAL::GDAL` (`gdal_priv.h`, `gdalalgorithm.h`, `vrtdataset.h`, `cpl_error.h`), `GTest::gtest` (not `gtest_main`: `Main.cpp` defines `main`), ATL headers (`atlbase.h`, `atlhost.h`), `ole32`, `oleaut32`, `uuid`, `user32`, `gdi32`, `opengl32`. |
| Core.Tests | Core, `GDAL::GDAL`, `GTest::gtest` (not `gtest_main`: `Main.cpp` defines `main`). |
| ActiveX.Tests | Core, `GDAL::GDAL`, `GTest::gtest`, ATL headers (`atlbase.h`, `atlhost.h`), `ole32`, `oleaut32`, `uuid`, `user32`, `gdi32`, `opengl32`, `psapi`. |
| Sample | Core only. |

`dumpbin` of the MSBuild tests shows `gmock.dll` instead of `gtest.dll`: the
Expand Down
37 changes: 20 additions & 17 deletions docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
on for CMake).
- Core test project: `tests/MapWinGIS.Core.Tests`, built with the solution or
CMake.
- ActiveX test project: `tests/MapWinGIS.ActiveX.Tests`, built with the solution.
- CMake currently registers the Core suite, not the ActiveX-specific tests.
- ActiveX implementation units shared by the OCX and its tests are built as
`MapWinGIS.ActiveX.Impl.lib`.
- ActiveX test project: `tests/MapWinGIS.ActiveX.Tests`, built with the solution
or CMake when `MWG_BUILD_ACTIVEX` is enabled.
- CMake registers the Core tests independently of ActiveX. It adds the
ActiveX-specific suite only when ActiveX is enabled.
- ActiveX implementation sources used by tests are compiled into the test
executable with `MWG_ENABLE_RENDERER_TEST_HOOKS`; MSBuild builds those units
in `MapWinGIS.ActiveX.Impl.lib`.
- Shared fixtures and helpers live in `TestData.h/.cpp` (`TempDirectory`,
`MakeSampleShapefile`, `MakeProvincesDataset`, `MakeRectanglesDataset`, and
layer constants). Extend these instead of writing per-file fixture code.
Expand All @@ -31,21 +34,22 @@ up automatically).

### CMake and CTest

The CMake target registers the Core GoogleTest sources and fixtures; the
ActiveX-specific tests remain MSBuild-only:
CTest discovers individual cases from both native suites. Core tests remain
available when `MWG_BUILD_ACTIVEX` is disabled:

```powershell
cmake --preset x64-debug
cmake --build --preset x64-debug
ctest --preset x64-debug
```

`gtest_discover_tests()` registers individual cases for CTest. Each test runs
from the build's runtime directory, which contains the OCX, dependent DLLs,
and GDAL/PROJ data. GoogleTest writes per-test XML files under `test-results`
in the build directory. The `x64-debug` test preset already shows output on
failure and excludes tests labelled `interactive`, which change per-user COM
registration or require a desktop. CTest can also write a single JUnit report:
`gtest_discover_tests()` registers individual cases for CTest. Tests run from
the build's runtime directory, which contains their dependent DLLs and
GDAL/PROJ data. When ActiveX is enabled, this directory also contains the OCX.
GoogleTest writes per-test XML files under `test-results` in the build
directory. The `x64-debug` test preset shows output on failure and excludes
tests labelled `interactive`, including the registration-based activation
check. CTest can also write a single JUnit report:

```powershell
ctest --test-dir out\b\x64d --output-on-failure -LE interactive `
Expand Down Expand Up @@ -93,11 +97,10 @@ pwsh -File tests\MapWinGIS.ActiveX.Tests\Verify-ActiveXActivation.ps1 -Configura
```

The native script requires `MapWinGIS.ActiveX.Tests.exe` and its
`ActiveXHosting.ResizesRepaintsAndRecreatesControl` test, which CMake does not
currently build. Use the MSBuild output for this verification until CMake
registers the ActiveX test suite. CMake's `Verify-ActiveXActivation` CTest
entry currently uses `MapWinGIS.Core.Tests.exe`, which does not contain that
hosting test and is not a substitute for this check.
`ActiveXHosting.ResizesRepaintsAndRecreatesControl` test. Both CMake and
MSBuild build this executable when ActiveX is enabled. CMake's
`Verify-ActiveXActivation` CTest entry runs the script against the
ActiveX-specific executable and is labeled `interactive`.

## Build configuration tests

Expand Down
4 changes: 1 addition & 3 deletions src/MapWinGIS.ActiveX/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ set_source_files_properties(MapWinGIS.ActiveX.rc PROPERTIES
target_link_libraries(MapWinGIS.ActiveX PRIVATE
MapWinGIS::Core
MapWinGIS.ActiveX.Interface.Generated
# Explicit Windows libraries (audit). ATL is static: atlbase.h links
# atls.lib through #pragma comment, and OpenGlVectorLayerRenderer.cpp links
# opengl32.lib the same way.
# Explicit Windows dependencies of the COM, registration, and rendering code.
ole32 oleaut32 uuid user32 gdi32 advapi32 kernel32
)

Expand Down
Loading