From 8b14bb69be608fa60d17b1433e42b677d575e3f6 Mon Sep 17 00:00:00 2001 From: "B. Scott Michel" Date: Wed, 17 May 2023 17:18:42 -0700 Subject: [PATCH] CMake build infrastructure II (#53) * CMake build infrastructure The squashed commit that builds and packages releases for the SIMH simulator suite with CMake, version 3.14 or newer. See README-CMake.md for documentation. --- .github/workflows/build.yml | 20 +- .github/workflows/cmake-builds.yml | 227 +++ .github/workflows/release.yml | 40 + .gitignore | 10 + .travis/deps.sh | 50 +- 3B2/CMakeLists.txt | 70 + ALTAIR/CMakeLists.txt | 27 + AltairZ80/CMakeLists.txt | 81 + B5500/CMakeLists.txt | 34 + BESM6/CMakeLists.txt | 131 ++ CDC1700/CMakeLists.txt | 38 + CMakeLists.txt | 531 ++++++ GRI/CMakeLists.txt | 26 + H316/CMakeLists.txt | 37 + HP2100/CMakeLists.txt | 59 + HP3000/CMakeLists.txt | 40 + I1401/CMakeLists.txt | 30 + I1620/CMakeLists.txt | 31 + I650/CMakeLists.txt | 43 + I7000/CMakeLists.txt | 151 ++ I7094/CMakeLists.txt | 36 + Ibm1130/CMakeLists.txt | 41 + Intel-Systems/Intel-MDS/CMakeLists.txt | 47 + Intel-Systems/scelbi/CMakeLists.txt | 26 + Interdata/CMakeLists.txt | 63 + LGP/CMakeLists.txt | 26 + ND100/CMakeLists.txt | 28 + NOVA/CMakeLists.txt | 58 + PDP1/CMakeLists.txt | 37 + PDP10/CMakeLists.txt | 231 +++ PDP11/CMakeLists.txt | 104 ++ PDP18B/CMakeLists.txt | 83 + PDP8/CMakeLists.txt | 41 + PDQ-3/CMakeLists.txt | 29 + README-CMake.md | 1533 +++++++++++++++++ README.md | 6 + S3/CMakeLists.txt | 29 + SAGE/CMakeLists.txt | 41 + SDS/CMakeLists.txt | 35 + SEL32/CMakeLists.txt | 43 + SSEM/CMakeLists.txt | 25 + TX-0/CMakeLists.txt | 30 + VAX/CMakeLists.txt | 738 ++++++++ alpha/CMakeLists.txt | 34 + appveyor.yml | 168 +- cmake/.gitignore | 6 + cmake/CMake-Maintainers.md | 582 +++++++ cmake/FindEDITLINE.cmake | 142 ++ cmake/FindPCAP.cmake | 76 + cmake/FindPCRE.cmake | 102 ++ cmake/FindPCRE2.cmake | 97 ++ cmake/FindPTW.cmake | 75 + cmake/FindVDE.cmake | 64 + cmake/GitHub-release.md | 41 + cmake/add_simulator.cmake | 426 +++++ cmake/build_dep_matrix.cmake | 85 + cmake/cmake-builder.ps1 | 570 ++++++ cmake/cmake-builder.sh | 394 +++++ cmake/cpack-setup.cmake | 139 ++ cmake/dep-link.cmake | 346 ++++ cmake/dep-locate.cmake | 361 ++++ cmake/diff-master.ps1 | 14 + cmake/file-link-copy.cmake | 50 + cmake/fpintrin.cmake | 79 + cmake/generate.py | 192 +++ cmake/git-commit-id.cmake | 90 + .../CPackSimhCustom.cmake.in | 3 + .../installer-customizations/NSIS.template.in | 1018 +++++++++++ .../NSIS/FileLinks.nsh | 198 +++ cmake/os-features.cmake | 207 +++ cmake/patches/SDL_ttf/fix-pkgconfig.patch | 22 + ...id-inclusions-when-HAVE_-is-set-to-0.patch | 53 + .../zlib/0002-skip-building-examples.patch | 17 + ...0003-build-static-or-shared-not-both.patch | 53 + .../zlib/0004-android-and-mingw-fixes.patch | 31 + cmake/platform-quirks.cmake | 260 +++ cmake/pthreads-dep.cmake | 75 + cmake/simgen/basic_simulator.py | 327 ++++ cmake/simgen/cmake_container.py | 411 +++++ cmake/simgen/packaging.py | 247 +++ cmake/simgen/parse_makefile.py | 184 ++ cmake/simgen/sim_collection.py | 158 ++ cmake/simgen/simulators.py | 75 + cmake/simgen/text_file.py | 291 ++++ cmake/simgen/utils.py | 9 + cmake/simgen/vax_simulators.py | 51 + cmake/simh-packaging.cmake | 103 ++ cmake/simh-simulators.cmake | 123 ++ cmake/v141_xp_install.ps1 | 84 + cmake/vcpkg-setup.cmake | 86 + imlac/CMakeLists.txt | 33 + sigma/CMakeLists.txt | 38 + sim_inttypes.h | 27 + sim_printf_fmts.h | 92 + slirp/CMakeLists.txt | 56 + swtp6800/swtp6800/CMakeLists.txt | 54 + tt2500/CMakeLists.txt | 33 + vcpkg.json | 14 + 98 files changed, 13549 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/cmake-builds.yml create mode 100644 .github/workflows/release.yml create mode 100644 3B2/CMakeLists.txt create mode 100644 ALTAIR/CMakeLists.txt create mode 100644 AltairZ80/CMakeLists.txt create mode 100644 B5500/CMakeLists.txt create mode 100644 BESM6/CMakeLists.txt create mode 100644 CDC1700/CMakeLists.txt create mode 100644 CMakeLists.txt create mode 100644 GRI/CMakeLists.txt create mode 100644 H316/CMakeLists.txt create mode 100644 HP2100/CMakeLists.txt create mode 100644 HP3000/CMakeLists.txt create mode 100644 I1401/CMakeLists.txt create mode 100644 I1620/CMakeLists.txt create mode 100644 I650/CMakeLists.txt create mode 100644 I7000/CMakeLists.txt create mode 100644 I7094/CMakeLists.txt create mode 100644 Ibm1130/CMakeLists.txt create mode 100644 Intel-Systems/Intel-MDS/CMakeLists.txt create mode 100644 Intel-Systems/scelbi/CMakeLists.txt create mode 100644 Interdata/CMakeLists.txt create mode 100644 LGP/CMakeLists.txt create mode 100644 ND100/CMakeLists.txt create mode 100644 NOVA/CMakeLists.txt create mode 100644 PDP1/CMakeLists.txt create mode 100644 PDP10/CMakeLists.txt create mode 100644 PDP11/CMakeLists.txt create mode 100644 PDP18B/CMakeLists.txt create mode 100644 PDP8/CMakeLists.txt create mode 100644 PDQ-3/CMakeLists.txt create mode 100644 README-CMake.md create mode 100644 S3/CMakeLists.txt create mode 100644 SAGE/CMakeLists.txt create mode 100644 SDS/CMakeLists.txt create mode 100644 SEL32/CMakeLists.txt create mode 100644 SSEM/CMakeLists.txt create mode 100644 TX-0/CMakeLists.txt create mode 100644 VAX/CMakeLists.txt create mode 100644 alpha/CMakeLists.txt create mode 100644 cmake/.gitignore create mode 100644 cmake/CMake-Maintainers.md create mode 100644 cmake/FindEDITLINE.cmake create mode 100644 cmake/FindPCAP.cmake create mode 100644 cmake/FindPCRE.cmake create mode 100644 cmake/FindPCRE2.cmake create mode 100644 cmake/FindPTW.cmake create mode 100644 cmake/FindVDE.cmake create mode 100644 cmake/GitHub-release.md create mode 100644 cmake/add_simulator.cmake create mode 100644 cmake/build_dep_matrix.cmake create mode 100644 cmake/cmake-builder.ps1 create mode 100755 cmake/cmake-builder.sh create mode 100644 cmake/cpack-setup.cmake create mode 100644 cmake/dep-link.cmake create mode 100644 cmake/dep-locate.cmake create mode 100644 cmake/diff-master.ps1 create mode 100644 cmake/file-link-copy.cmake create mode 100644 cmake/fpintrin.cmake create mode 100644 cmake/generate.py create mode 100644 cmake/git-commit-id.cmake create mode 100644 cmake/installer-customizations/CPackSimhCustom.cmake.in create mode 100644 cmake/installer-customizations/NSIS.template.in create mode 100644 cmake/installer-customizations/NSIS/FileLinks.nsh create mode 100644 cmake/os-features.cmake create mode 100644 cmake/patches/SDL_ttf/fix-pkgconfig.patch create mode 100644 cmake/patches/zlib/0001-Prevent-invalid-inclusions-when-HAVE_-is-set-to-0.patch create mode 100644 cmake/patches/zlib/0002-skip-building-examples.patch create mode 100644 cmake/patches/zlib/0003-build-static-or-shared-not-both.patch create mode 100644 cmake/patches/zlib/0004-android-and-mingw-fixes.patch create mode 100644 cmake/platform-quirks.cmake create mode 100644 cmake/pthreads-dep.cmake create mode 100644 cmake/simgen/basic_simulator.py create mode 100644 cmake/simgen/cmake_container.py create mode 100644 cmake/simgen/packaging.py create mode 100644 cmake/simgen/parse_makefile.py create mode 100644 cmake/simgen/sim_collection.py create mode 100644 cmake/simgen/simulators.py create mode 100644 cmake/simgen/text_file.py create mode 100644 cmake/simgen/utils.py create mode 100644 cmake/simgen/vax_simulators.py create mode 100644 cmake/simh-packaging.cmake create mode 100644 cmake/simh-simulators.cmake create mode 100644 cmake/v141_xp_install.ps1 create mode 100644 cmake/vcpkg-setup.cmake create mode 100644 imlac/CMakeLists.txt create mode 100644 sigma/CMakeLists.txt create mode 100644 sim_inttypes.h create mode 100644 sim_printf_fmts.h create mode 100644 slirp/CMakeLists.txt create mode 100644 swtp6800/swtp6800/CMakeLists.txt create mode 100644 tt2500/CMakeLists.txt create mode 100644 vcpkg.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9311800d..ee989580 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,16 +1,28 @@ name: Build -on: [pull_request, push] +on: + pull_request: + push: + branches: + - '*' + tags: + - '!v*' defaults: run: shell: bash jobs: - build: + cmake-builds: + uses: ./.github/workflows/cmake-builds.yml + + makefile: runs-on: ${{ matrix.os }} strategy: matrix: + ## macos-10.15: Runner seems to be officially disabled, results in canceled + ## builds. Leaving this "as-is". + ## os: [macos-12, ubuntu-20.04] simulators: # These are supposed to match ALL in makefile. @@ -22,14 +34,14 @@ jobs: - besm6 imlac tt2500 microvax3900 microvax1 rtvax1000 vaxstation3100m76 vaxstation4000m60 - scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 sigma uc15 i650 sel32 intel-mds ibm1130 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies if: ${{runner.os == 'macOS'}} run: sh -ex .travis/deps.sh osx - name: Install dependencies if: ${{runner.os == 'Linux'}} run: sh -ex .travis/deps.sh linux - - name: Build + - name: makefile build env: SIM: ${{matrix.simulators}} run: make LTO=1 OPTIMIZE=-O3 $SIM diff --git a/.github/workflows/cmake-builds.yml b/.github/workflows/cmake-builds.yml new file mode 100644 index 00000000..42b3941f --- /dev/null +++ b/.github/workflows/cmake-builds.yml @@ -0,0 +1,227 @@ +name: CMake build workflows + +on: + workflow_call: + +jobs: + cmake-unix: + name: Ubuntu + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-22.04] + steps: + - uses: actions/checkout@v3 + - name: Install dependencies + run: | + sh -ex .travis/deps.sh linux + sudo apt install -ym ninja-build + - name: cmake-builder.sh + run: | + cmake/cmake-builder.sh --config Release --flavor ninja --lto --notest --parallel --verbose --cpack_suffix x86_64-${{matrix.os}} + - name: SIMH simulator suite test + run: | + cmake/cmake-builder.sh --config Release --flavor ninja --testonly + ## Install isn't strictly necessary, but it's a good way to see what dependencies + ## (IMPORTED_RUNTIME_ARTIFACTS) get installed. + - name: Install + run: | + cmake/cmake-builder.sh --config Release --flavor ninja --installonly + - name: SIMH packaging + run: | + cd cmake/build-ninja + cpack -G DEB -C Release + - name: Upload DEB + uses: actions/upload-artifact@v3 + with: + name: simh-4.0.0-x86_64-${{matrix.os}}.deb + path: cmake/build-ninja/simh-4.0.0-x86_64-${{matrix.os}}.deb + + + cmake-macOS: + name: macOS + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-12, macos-11] + steps: + - uses: actions/checkout@v3 + - name: Install dependencies + run: | + sh -ex .travis/deps.sh osx + - name: cmake-builder.sh + run: | + cmake/cmake-builder.sh --config Release --flavor xcode --lto --notest --cpack_suffix x86_64.${{matrix.os}} + - name: SIMH simulator suite test + run: | + cmake/cmake-builder.sh --config Release --flavor xcode --testonly + ## Install isn't strictly necessary, but it's a good way to see what dependencies + ## (IMPORTED_RUNTIME_ARTIFACTS) get installed. + - name: Install + run: | + cmake/cmake-builder.sh --config Release --flavor xcode --installonly + - name: SIMH packaging + run: | + cd cmake/build-xcode + cpack -G "ZIP;TGZ" -C Release + cpack -G DragNDrop -C Release + - name: Upload ZIP + uses: actions/upload-artifact@v3 + with: + name: simh-4.0.0-x86_64.${{matrix.os}}.zip + path: cmake/build-xcode/simh-4.0.0-x86_64.${{matrix.os}}.zip + - name: Upload DMG + uses: actions/upload-artifact@v3 + with: + name: simh-4.0.0-x86_64.${{matrix.os}}.dmg + path: cmake/build-xcode/simh-4.0.0-x86_64.${{matrix.os}}.dmg + + + ## This looks like it's doing the right thing on the Github CI/CD pipeline because + ## the output contains references to x86_64 and arm64 targets for Mac OS 12. + ## + ## However, need to figure out how to concurrently install BOTH arm64 and intel + ## Homebrews AND how to tell SDL2 which set of header files it should use for + ## platform-specific assembly (/usr/local vs. /opt/local.) + ## + # cmake-macOS-universal: + # name: macOS universal + # runs-on: ${{ matrix.os }} + # strategy: + # matrix: + # os: [macos-12] + # steps: + # - uses: actions/checkout@v3 + # - name: Install dependencies + # run: | + # sh -ex .travis/deps.sh osx + # - name: cmake-builder.sh + # run: | + # cmake/cmake-builder.sh --config Release --flavor xcode-universal --lto --notest + # - name: SIMH simulator suite test + # run: | + # cmake/cmake-builder.sh --config Release --flavor xcode-universal --testonly + + + cmake-vs2022xp: + name: VS 2022 XP-compatible LEGACY + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + ##+ + ## NOTE: This will have to change when Github updates the windows-latest + ## image AND when Microsoft bumps the Visual Studio year. + ## + ## Things that need updating: + ## - Product ID (maybe: MS seems to be very consistent with the component + ## name, hasn't changed since VS 2019.) + ## - Channel ID + ##- + - name: Install v141_xp (XP toolkit) + shell: pwsh + run: | + $ErrorActionPreference="Stop" + $WarningPreference="Continue" + $packageParams = @( "--productId", "Microsoft.VisualStudio.Product.Enterprise", + "--channelId", "VisualStudio.17.Release", + "--add", "Microsoft.VisualStudio.Component.VC.v141.x86.x64", + "--add", "Microsoft.VisualStudio.Component.WinXP", + "--no-includeRecommended", + "--includeOptional", + "--quiet", + "--locale en-US" ) -join " " + choco install visualstudio2022-workload-nativedesktop --package-parameters $packageParams + + - name: vs2022-xp build + shell: pwsh + run: | + $ErrorActionPreference="Stop" + $WarningPreference="Continue" + $env:ChocolateyInstall = Convert-Path "$((Get-Command choco).Path)\..\.." + Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" + Update-SessionEnvironment + # Fix PATH so that "C:\Strawberry" (Strawberry Perl) doesn't mess with the build + # CMake WILL find incompatible libraries within Strawberry. + $fixPATH = (${env:PATH}.Split(';') | ` + Where-Object { $_ -notlike "*\Strawberry\*" -and $_ -notlike "*/Strawberry/*" }) -join ';' + $env:Path = $fixPATH + ## Don't use LTO for XP. XP compatibility comes from VS2017 -- MS is + ## at VS2022. There are likely legacy bugs that have been fixed. + ./cmake/cmake-builder.ps1 -flavor vs2022-xp -config Release -clean -verbose -notest -cpack_suffix win32-xp + - name: SIMH simulator suite test + shell: pwsh + run: | + ./cmake/cmake-builder.ps1 -flavor vs2022-xp -config Release -testOnly + ## Install isn't strictly necessary, but it's a good way to see what dependencies + ## (IMPORTED_RUNTIME_ARTIFACTS) get installed. + - name: Install + shell: pwsh + run: | + cmake/cmake-builder.ps1 -config Release -flavor vs2022-xp -installOnly + - name: SIMH packaging + shell: pwsh + run: | + cd cmake\build-vs2022-xp + cpack -G "ZIP;WIX" -C Release + - name: Upload ZIP + uses: actions/upload-artifact@v3 + with: + name: simh-4.0.0-win32-vs2022xp.zip + path: cmake/build-vs2022-xp/simh-4.0.0-win32-xp.zip + - name: Upload MSI + uses: actions/upload-artifact@v3 + with: + name: simh-4.0.0-win32-vs2022xp.zip + path: cmake/build-vs2022-xp/simh-4.0.0-win32-xp.msi + + cmake-vs2022: + name: VS 2022 Win10 native VCPKG + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + - name: vs2022 build + shell: pwsh + run: | + $ErrorActionPreference="Stop" + $WarningPreference="Continue" + # Fix PATH so that "C:\Strawberry" (Strawberry Perl) doesn't mess with the build + # CMake WILL find incompatible libraries within Strawberry. + $fixPATH = (${env:PATH}.Split(';') | ` + Where-Object { $_ -notlike "*\Strawberry\*" -and $_ -notlike "*/Strawberry/*" }) -join ';' + $env:PATH = $fixPATH + # Make this a vcpkg build: + $env:VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT + Push-Location $env:VCPKG_ROOT + git pull + Pop-Location + ./cmake/cmake-builder.ps1 -flavor vs2022 -config Release -clean -lto -verbose -notest -cpack_suffix win32-native + - name: SIMH simulator suite test + shell: pwsh + run: | + ./cmake/cmake-builder.ps1 -flavor vs2022 -config Release -testOnly + ## Install isn't strictly necessary, but it's a good way to see what dependencies + ## (IMPORTED_RUNTIME_ARTIFACTS) get installed. + - name: Install + shell: pwsh + run: | + cmake/cmake-builder.ps1 -config Release -flavor vs2022 -installOnly + - name: SIMH packaging + shell: pwsh + run: | + cd cmake\build-vs2022 + cpack -G "NSIS;WIX;ZIP" -C Release + - name: Upload ZIP + uses: actions/upload-artifact@v3 + with: + name: simh-4.0.0-win32-vs2022.zip + path: cmake/build-vs2022/simh-4.0.0-win32-native.zip + - name: Upload EXE installer + uses: actions/upload-artifact@v3 + with: + name: simh-4.0.0-win32-vs2022.exe + path: cmake/build-vs2022/simh-4.0.0-win32-native.exe + - name: Upload MSI installer + uses: actions/upload-artifact@v3 + with: + name: simh-4.0.0-win32-vs2022.msi + path: cmake/build-vs2022/simh-4.0.0-win32-native.msi diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..93650852 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release packaging + +on: + push: + tags: + - 'v*' + - 'simh-*' + + +jobs: + build: + uses: ./.github/workflows/cmake-builds.yml + + release: + runs-on: ubuntu-22.04 + needs: [build] + steps: + - uses: actions/checkout@v3 + - name: Make staging directory + run: | + rm -rf work/open-simh/open-simh/staging/ + mkdir -p work/open-simh/open-simh/staging/ + - name: Download packages + uses: actions/download-artifact@v3 + with: + path: ~/work/open-simh/open-simh/staging/ + - name: Show it! + run: | + ls -lR ~/work/open-simh/open-simh/staging/ + echo "----" + pwd + echo "----" + ls -CF + - name: Craft release + uses: softprops/action-gh-release@v1 + with: + body_path: cmake/GitHub-release.md + files: | + staging/*/simh-* + diff --git a/.gitignore b/.gitignore index 33d825e3..95af0ca9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .git-commit-id +.git-commit-id.h #ignore thumbnails created by windows Thumbs.db #ignore Desktop Services Store created by OSX @@ -38,6 +39,10 @@ _ReSharper*/ *# BIN/ ipch/ +# Visual Studio, Visual Code directories: +.vscode/ +.vs/ +build/ # We only care about specific files in the Visual Studio Projects # folder. Things which are there on the fly to support debugging # or other things we don't want git to manage. @@ -49,3 +54,8 @@ Visual Studio Projects/~AutoRecover.* !Visual Studio Projects/0ReadMe_Projects.txt **/*.code-workspace **/.vscode/ +# Visual Studio artifacts in CMake mode +out/ +CMakeSettings.json +## Staging area for cmake install (default install prefix) +SIMH-install diff --git a/.travis/deps.sh b/.travis/deps.sh index d799adb6..fb18ddf7 100755 --- a/.travis/deps.sh +++ b/.travis/deps.sh @@ -2,17 +2,55 @@ install_osx() { brew update - brew install sdl2 - brew install sdl2_ttf + brew install pkg-config + brew install pcre libpng libedit + brew install sdl2 freetype2 sdl2_ttf brew install vde + brew install cmake gnu-getopt coreutils } install_linux() { sudo apt-get update -yqqm + sudo apt-get install -ym pkg-config + sudo apt-get install -ym libpcre3-dev libpng-dev libedit-dev sudo apt-get install -ym libegl1-mesa-dev libgles2-mesa-dev - sudo apt-get install -ym libsdl2-dev libpcap-dev libvdeplug-dev - sudo apt-get install -ym libsdl2-ttf-dev - sudo apt-get install -ym libedit-dev + sudo apt-get install -ym libsdl2-dev libfreetype6-dev libsdl2-ttf-dev + sudo apt-get install -ym libpcap-dev libvdeplug-dev + sudo apt-get install -ym cmake cmake-data } -install_"$1" +install_mingw64() { + pacman -S --needed mingw-w64-x86_64-ninja \ + mingw-w64-x86_64-cmake \ + mingw-w64-x86_64-extra-cmake-modules \ + mingw-w64-x86_64-gcc \ + mingw-w64-x86_64-make \ + mingw-w64-x86_64-pcre \ + mingw-w64-x86_64-freetype \ + mingw-w64-x86_64-SDL2 \ + mingw-w64-x86_64-SDL2_ttf \ + mingw-w64-x86_64-libpcap +} + +install_ucrt64() { + pacman -S --needed mingw-w64-ucrt-x86_64-ninja \ + mingw-w64-ucrt-x86_64-cmake \ + mingw-w64-ucrt-x86_64-extra-cmake-modules \ + mingw-w64-ucrt-x86_64-gcc \ + mingw-w64-ucrt-x86_64-make \ + mingw-w64-ucrt-x86_64-pcre \ + mingw-w64-ucrt-x86_64-freetype \ + mingw-w64-ucrt-x86_64-SDL2 \ + mingw-w64-ucrt-x86_64-SDL2_ttf \ + mingw-w64-ucrt-x86_64-libpcap +} + +case "$1" in + osx|linux|mingw64|ucrt64) + install_"$1" + ;; + *) + echo "$0: Need an operating system name: osx, linux, mingw64 or ucrt64" + exit 1 + ;; +esac diff --git a/3B2/CMakeLists.txt b/3B2/CMakeLists.txt new file mode 100644 index 00000000..8319b70a --- /dev/null +++ b/3B2/CMakeLists.txt @@ -0,0 +1,70 @@ +## 3B2 simulators +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(3b2 + SOURCES + 3b2_cpu.c + 3b2_sys.c + 3b2_rev2_sys.c + 3b2_rev2_mmu.c + 3b2_mau.c + 3b2_rev2_csr.c + 3b2_timer.c + 3b2_stddev.c + 3b2_mem.c + 3b2_iu.c + 3b2_if.c + 3b2_id.c + 3b2_dmac.c + 3b2_io.c + 3b2_ports.c + 3b2_ctc.c + 3b2_ni.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + REV2 + FEATURE_FULL64 + LABEL 3B2 + PKG_FAMILY att3b2_family + TEST 3b2) + +add_simulator(3b2-700 + SOURCES + 3b2_cpu.c + 3b2_sys.c + 3b2_rev3_sys.c + 3b2_rev3_mmu.c + 3b2_mau.c + 3b2_rev3_csr.c + 3b2_timer.c + 3b2_stddev.c + 3b2_mem.c + 3b2_iu.c + 3b2_if.c + 3b2_dmac.c + 3b2_io.c + 3b2_ports.c + 3b2_scsi.c + 3b2_ni.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + REV3 + FEATURE_FULL64 + LABEL 3B2 + PKG_FAMILY att3b2_family + TEST 3b2-700) diff --git a/ALTAIR/CMakeLists.txt b/ALTAIR/CMakeLists.txt new file mode 100644 index 00000000..32e1c085 --- /dev/null +++ b/ALTAIR/CMakeLists.txt @@ -0,0 +1,27 @@ +## ALTAIR simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(altair + SOURCES + altair_sio.c + altair_cpu.c + altair_dsk.c + altair_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL ALTAIR + PKG_FAMILY default_family + TEST altair) diff --git a/AltairZ80/CMakeLists.txt b/AltairZ80/CMakeLists.txt new file mode 100644 index 00000000..242085e8 --- /dev/null +++ b/AltairZ80/CMakeLists.txt @@ -0,0 +1,81 @@ +## AltairZ80 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(altairz80 + SOURCES + altairz80_cpu.c + altairz80_cpu_nommu.c + sol20.c + s100_vdm1.c + mmd.c + s100_dj2d.c + s100_djhdc.c + altairz80_dsk.c + disasm.c + altairz80_sio.c + altairz80_sys.c + altairz80_hdsk.c + altairz80_net.c + s100_hayes.c + s100_2sio.c + s100_pmmi.c + flashwriter2.c + i86_decode.c + i86_ops.c + i86_prim_ops.c + i8272.c + insnsd.c + altairz80_mhdsk.c + ibc.c + ibc_mcc_hdc.c + ibc_smd_hdc.c + mfdc.c + n8vem.c + vfdhd.c + s100_disk1a.c + s100_disk2.c + s100_disk3.c + s100_fif.c + s100_mdriveh.c + s100_icom.c + s100_jadedd.c + s100_mdsa.c + s100_mdsad.c + s100_selchan.c + s100_ss1.c + s100_64fdc.c + s100_scp300f.c + s100_tarbell.c + s100_tdd.c + wd179x.c + s100_hdc1001.c + s100_if3.c + s100_adcs6.c + m68k/m68kcpu.c + m68k/m68kdasm.c + m68k/m68kasm.c + m68k/m68kopac.c + m68k/m68kopdm.c + m68k/softfloat/softfloat.c + m68k/m68kopnz.c + m68k/m68kops.c + m68ksim.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + FEATURE_VIDEO + LABEL AltairZ80 + PKG_FAMILY altairz80_family + TEST altairz80) diff --git a/B5500/CMakeLists.txt b/B5500/CMakeLists.txt new file mode 100644 index 00000000..d391cf78 --- /dev/null +++ b/B5500/CMakeLists.txt @@ -0,0 +1,34 @@ +## B5500 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(b5500 + SOURCES + b5500_cpu.c + b5500_io.c + b5500_sys.c + b5500_dk.c + b5500_mt.c + b5500_urec.c + b5500_dr.c + b5500_dtc.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + B5500 + FEATURE_INT64 + LABEL B5500 + PKG_FAMILY b5500_family + TEST b5500) diff --git a/BESM6/CMakeLists.txt b/BESM6/CMakeLists.txt new file mode 100644 index 00000000..89440e68 --- /dev/null +++ b/BESM6/CMakeLists.txt @@ -0,0 +1,131 @@ +## BESM6 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +set(besm6_font) +set(cand_fonts + "DejaVuSans.ttf" + "LucidaSansRegular.ttf" + "FreeSans.ttf" + "AppleGothic.ttf" + "tahoma.ttf") +set(cand_fontdirs + "/usr/share/fonts" + "/usr/lib/jvm" + "/Library/Fonts" + "/System/Library/Fonts" + "/System/Library/Frameworks/JavaVM.framework/Versions" + "$ENV{WINDIR}/Fonts") + +foreach (fdir ${cand_fontdirs}) + foreach (font ${cand_fonts}) + if (EXISTS ${fdir}/${font}) + get_filename_component(fontfile ${fdir}/${font} ABSOLUTE) + list(APPEND besm6_font ${fontfile}) + endif () + + file(GLOB besm6_font_cand_1 LIST_DIRECTORIES FALSE "${fdir}/*/${font}") + file(GLOB besm6_font_cand_2 LIST_DIRECTORIES FALSE "${fdir}/*/*/${font}") + file(GLOB besm6_font_cand_3 LIST_DIRECTORIES FALSE "${fdir}/*/*/*/${font}") + list(APPEND besm6_font ${besm6_font_cand_1} ${besm6_font_cand_2} ${besm6_font_cand_3}) + endforeach() +endforeach() + +if (besm6_font) + set(besm6_found_fonts "BESM6: Fonts found") + foreach(bfont ${besm6_font}) + string(APPEND besm6_found_fonts " + .. ${bfont}") + endforeach () + message(STATUS ${besm6_found_fonts}) + unset(besm6_found_fonts) + list(GET besm6_font 0 besm6_font) + message(STATUS "BESM6: Using ${besm6_font}") +else () + set(besm6_no_fonts "BESM6: No applicable Cyrillic fonts found.") + string(APPEND besm6_no_fonts " + Font names tried:") + foreach (font ${cand_fonts}) + string(APPEND besm6_no_fonts " + .. ${font}") + endforeach () + string(APPEND besm6_no_fonts " + + Looked in:") + foreach (fdir ${cand_fontdirs}) + string(APPEND besm6_no_fonts " + .. ${fdir}") + endforeach() + string(APPEND besm6_no_fonts " + +BESM6: Not building with panel display.") + message(STATUS ${besm6_no_fonts}) + unset(besm6_no_fonts) +endif () + +if (NOT (besm6_font AND WITH_VIDEO)) + add_simulator(besm6 + SOURCES + besm6_cpu.c + besm6_sys.c + besm6_mmu.c + besm6_arith.c + besm6_disk.c + besm6_drum.c + besm6_tty.c + besm6_panel.c + besm6_printer.c + besm6_pl.c + besm6_mg.c + besm6_punch.c + besm6_punchcard.c + besm6_vu.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + FEATURE_INT64 + LABEL BESM6 + PKG_FAMILY default_family + TEST besm6) +else () + add_simulator(besm6 + SOURCES + besm6_cpu.c + besm6_sys.c + besm6_mmu.c + besm6_arith.c + besm6_disk.c + besm6_drum.c + besm6_tty.c + besm6_panel.c + besm6_printer.c + besm6_pl.c + besm6_mg.c + besm6_punch.c + besm6_punchcard.c + besm6_vu.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + FONTFILE=${besm6_font} + FEATURE_INT64 + FEATURE_VIDEO + FEATURE_DISPLAY + BESM6_SDL_HACK + LABEL BESM6 + PKG_FAMILY default_family + TEST besm6) +endif() +unset(cand_fonts) +unset(cand_fontdirs) diff --git a/CDC1700/CMakeLists.txt b/CDC1700/CMakeLists.txt new file mode 100644 index 00000000..391477ee --- /dev/null +++ b/CDC1700/CMakeLists.txt @@ -0,0 +1,38 @@ +## CDC1700 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(cdc1700 + SOURCES + cdc1700_cpu.c + cdc1700_dis.c + cdc1700_io.c + cdc1700_sys.c + cdc1700_dev1.c + cdc1700_mt.c + cdc1700_dc.c + cdc1700_iofw.c + cdc1700_lp.c + cdc1700_dp.c + cdc1700_cd.c + cdc1700_sym.c + cdc1700_rtc.c + cdc1700_drm.c + cdc1700_msos5.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL CDC1700 + PKG_FAMILY cdc1700_family + TEST cdc1700) diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..12000fe9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,531 @@ +## Note: pthreads4w requires 3.14 or better. +cmake_minimum_required(VERSION 3.14) + +if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) + message(FATAL_ERROR + "" + "!!! DO NOT BUILD CMake artifacts in the SIMH source directory !!!\n" + "" + "Create a subdirectory and build in that subdirectory, e.g.:" + "\n" + " $ mkdir cmake-build\n" + " $ cd cmake-build\n" + " $ cmake -G \"your generator here\" ..\n" + "" + "Preventing in-tree source build.") +endif () + +if (CMAKE_VERSION VERSION_LESS "3.21" AND NOT DEFINED SIMH_INSTALLER_WARNING) + message(WARNING "!!! DO NOT CREATE INSTALLERS WITH THIS VERSION OF CMAKE (${CMAKE_VERSION}) !!!" + "\n" + "Do not create a release or installers with this version of CMake. It does not have " + "the required install(RUNTIME_DEPENDENCY_SET) or install(IMPORTED_RUNTIME_ARTIFACTS) " + "functionality to collect runtime executable dependencies as part of the installation" + " packages, such as Mac OS bundles or Windows DLLs." + "\n" + "Minimum version for creating installers with CPack is 3.21." + ) + set(SIMH_INSTALLER_WARNING TRUE CACHE BOOL "Installer/CPack warning issued when CMAKE_VERSION < 3.21" FORCE) +endif () + +# Places to look for CMake modules/includes +set(SIMH_INCLUDE_PATH_LIST + ${CMAKE_SOURCE_DIR}/cmake + ${CMAKE_SOURCE_DIR}/cmake/installer-customizations) +list(APPEND CMAKE_MODULE_PATH ${SIMH_INCLUDE_PATH_LIST}) +message(STATUS "CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}") + +## vcpkg sanity checking: Cannot use vcpkg and XP toolkit together. If this is +## a XP build, disable vcpkg: +set(USING_VCPKG FALSE) +if (DEFINED ENV{VCPKG_ROOT}) + if (CMAKE_GENERATOR_TOOLSET MATCHES "v[0-9][0-9][0-9]_xp") + message(FATAL_ERROR + "Configuration conflict: Cannot build XP binaries with vcpkg. Either " + "unset VCPKG_ROOT in your environment or remove the '-T' toolkit option." + "\n" + "Also remove CMakeCache.txt and recursively remove the CMakeFiles " + "subdirectory in your build folder before reconfiguring.") + endif () + + set(USING_VCPKG TRUE) + + ## Defer loading the CMAKE_TOOLCHAIN_FILE: + set(SIMH_CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake") + if(DEFINED CMAKE_TOOLCHAIN_FILE) + ## Use the user's provided toolchain file, but load it later. + message(STATUS "Deferring CMAKE_TOOLCHAIN_FILE load.") + set(SIMH_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}") + unset(CMAKE_TOOLCHAIN_FILE) + unset(CMAKE_TOOLCHAIN_FILE CACHE) + endif() + + file(TO_CMAKE_PATH "${SIMH_CMAKE_TOOLCHAIN_FILE}" SIMH_CMAKE_TOOLCHAIN_FILE) + message(STATUS "SIMH_CMAKE_TOOLCHAIN_FILE is ${SIMH_CMAKE_TOOLCHAIN_FILE}") +endif () + +## Respect MSVC_RUNTIME_LIBRARY's setting. the policy has to be set before +## project(), otherwise it'd have been put into platform-quirks. +## +## Note: See cmake\build_dep_matrix.cmake to see how this is propagated down +## into the dependency libraries. +if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.15) + cmake_policy(SET CMP0091 NEW) +endif() + +## SIMH Version variables: +set(SIMH_VERSION_MAJOR 4) +set(SIMH_VERSION_MINOR 0) +set(SIMH_VERSION_PATCH 0) +set(SIMH_VERSION "${SIMH_VERSION_MAJOR}.${SIMH_VERSION_MINOR}.${SIMH_VERSION_PATCH}") + +project(simh VERSION "${SIMH_VERSION}" LANGUAGES C CXX) + +include(vcpkg-setup) +include(GNUInstallDirs) + +## Provide a default CMAKE_BUILD_TYPE if CMAKE_CONFIGURATION_TYPES is empty or not defined. +if (NOT CMAKE_CONFIGURATION_TYPES) + if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") + message(STATUS "CMAKE_BUILD_TYPE defaulted to ${CMAKE_BUILD_TYPE}") + else (NOT CMAKE_BUILD_TYPE) + message(STATUS "CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}") + endif (NOT CMAKE_BUILD_TYPE) +endif () + +# SIMH_SYSTEM_ID: Roughly analogous to the autoconf system triple. Used (almost exclusively) +# as part of the depedencies' top-level directory name. +set(SIMH_SYSTEM_ID ${CMAKE_SYSTEM_NAME}) +string(REPLACE "." ";" version_list ${CMAKE_SYSTEM_VERSION}) +list(GET version_list 0 version_major) +string(APPEND SIMH_SYSTEM_ID "-" ${version_major}) + +if (CMAKE_C_LIBRARY_ARCHITECTURE) + string(APPEND SIMH_SYSTEM_ID -${CMAKE_C_LIBRARY_ARCHITECTURE}) +endif (CMAKE_C_LIBRARY_ARCHITECTURE) +string(APPEND SIMH_SYSTEM_ID -${CMAKE_C_COMPILER_ID}) +string(REPLACE "." ";" version_list ${CMAKE_C_COMPILER_VERSION}) +list(GET version_list 0 version_major) +list(GET version_list 1 version_minor) +if (NOT version_minor) + set(version_minor 0) +endif () +string(APPEND SIMH_SYSTEM_ID "-${version_major}.${version_minor}") +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + string(APPEND SIMH_SYSTEM_ID "-64") +else () + string(APPEND SIMH_SYSTEM_ID "-32") +endif () +if (CMAKE_GENERATOR MATCHES "Visual Studio .*" AND CMAKE_GENERATOR_TOOLSET MATCHES "v[0-9][0-9][0-9]_xp") + string(APPEND SIMH_SYSTEM_ID "-XP") +endif () + +# SIMH_DEP_TOPDIR: This is the top-level directory where dependencies live. It's cached so that +# scripts (e.g., cmake-builder.ps1) can update PATH to find shared objects and DLLs. +# +# Only add to search paths if NO_DEP_BUILD is False +set(SIMH_DEP_TOPDIR + ${CMAKE_SOURCE_DIR}/cmake/dependencies/${SIMH_SYSTEM_ID} + CACHE PATH "Top-level directory for SIMH library dependencies") + +# SIMH_DEP_PATCHES: This is where various external package patches live. Also cached just in case +# it's needed by a script. +set(SIMH_DEP_PATCHES ${CMAKE_SOURCE_DIR}/cmake/patches + CACHE PATH "Top-level directory for external dependency patches") + +##-- Options --## +set(NO_DEP_BUILD_OPTVAL FALSE) +if (NOT DEFINED NO_DEP_BUILD) + ## For Windows, always build dependencies + if (WIN32 AND NOT DEFINED ENV{MSYSTEM} AND NOT USING_VCPKG) + message(STATUS "Setting NO_DEP_BUILD to FALSE, will BUILD missing dependencies") + set(NO_DEP_BUILD_OPTVAL FALSE) + else () + message(STATUS "Setting NO_DEP_BUILD to TRUE, will NOT BUILD missing dependencies") + set(NO_DEP_BUILD_OPTVAL TRUE) + endif () +else () + set(NO_DEP_BUILD_OPTVAL ${NO_DEP_BUILD}) + if (NO_DEP_BUILD_OPTVAL) + message(STATUS "Missing dependencies WILL NOT BE BUILT.") + else () + message(STATUS "Missing dependencies WILL BE BUILT.") + endif () +endif () + +set(MAC_UNIVERSAL_OPTVAL FALSE) +if (NOT DEFINED MAC_UNIVERSAL) + if (APPLE) + message("macOS universal binaries WILL NOT BE BUILT") + endif () +else () + set(MAC_UNIVERSAL_OPTVAL ${MAC_UNIVERSAL}) + if (MAC_UNIVERSAL_OPTVAL) + message(STATUS "macOS unversal binaries WILL BE BUILT.") + else () + message(STATUS "macOS unversal binaries NOT WILL BE BUILT.") + endif () +endif () + +option(NO_DEP_BUILD + "Enable (=1)/disable (=0) Dependency library builds (def: enabled)" + ${NO_DEP_BUILD_OPTVAL}) +option(BUILD_SHARED_DEPS + "Enable (=1)/disable (=0) building dependencies as shared libraries/DLLs (def: disabled)" + FALSE) +option(WITH_ASYNC + "Enable (=1)/disable (=0) Asynchronous I/O and threading." + TRUE) +option(WITH_REGEX + "Enable (=1)/disable (=0) PCRE/PCRE2 regular expression support (def: enabled)" + TRUE) +option(PREFER_PCRE + "Prefer (=1)/ignore (=0) Prefer PCRE over PCRE2 (def: ignore)" + TRUE) +option(WITH_NETWORK + "Enable (=1)/disable (=0) simulator networking support. (def: enabled)" + TRUE) +option(WITH_PCAP + "Enable (=1)/disable (=0) libpcap (packet capture) support. (def: enabled)" + TRUE) +option(WITH_SLIRP + "Enable (=1)/disable (=0) SLIRP network support. (def: enabled)" + TRUE) +option(WITH_VDE + "Enable (=1)/disable (=0) VDE2/VDE4 network support. (def: enabled)" + TRUE) +option(WITH_TAP + "Enable (=1)/disable (=0) TAP/TUN device network support. (def: enabled)" + TRUE) +option(WITH_VIDEO + "Enable (=1)/disable (=0) simulator display and graphics support (def: enabled)" + TRUE) +option(PANDA_LIGHTS + "Enable (=1)/disable (=0) KA-10/KI-11 simulator's Panda display. (def: disabled)" + FALSE) +option(DONT_USE_ROMS + "Enable (=1)/disable (=0) building support ROMs. (def: disabled)" + FALSE) +option(ENABLE_CPPCHECK + "Enable (=1)/disable (=0) 'cppcheck' static code analysis. (def: disabled.)" + FALSE) +option(WINAPI_DEPRECATION + "Show (=1)/mute (=0) Various WinAPI deprecation warning (def: mute.)" + FALSE) +option(WARNINGS_FATAL + "Compile-time warnings are errors (e.g., \"-Werror\" on GCC)" + FALSE) +option(RELEASE_LTO + "Use Link Time Optimization (LTO) in Release builds." + FALSE) +option(DEBUG_WALL + "Turn on maximal compiler warnings in Debug builds (e.g., \"-Wall\" or \"/W4\")" + FALSE) +option(SIMH_PACKAGE_SUFFIX + "The packaging suffix for CPack artifacts, e.g. simh-SIMH_VERSION-SIMH_PACKAGE_SUFFIX." + "") +option(MAC_UNIVERSAL + "macOS universal binary flag: TRUE -> build universal binaries, FALSE -> don't." + ${MAC_UNIVERSAL_OPTVAL}) + +# Places where CMake should look for dependent package configuration fragments and artifacts: +set(SIMH_PREFIX_PATH_LIST) +if (NOT (USING_VCPKG OR NO_DEP_BUILD)) + list(APPEND CMAKE_INCLUDE_PATH ${SIMH_DEP_TOPDIR}) + list(APPEND SIMH_PREFIX_PATH_LIST ${SIMH_DEP_TOPDIR}) + list(APPEND CMAKE_PREFIX_PATH ${SIMH_PREFIX_PATH_LIST}) +endif () + +## libpcap, if not found, will put its headers in $CMAKE_BINARY_DIR/include. +## Make sure we can find them. +list(APPEND CMAKE_INCLUDE_PATH "${CMAKE_BINARY_DIR}/include") + +## Additional command line arguments for dependencies. Need this because Powershell will report +## an error if anything is sent to stderr and $ErrorDefaultAction is set to "Stop". +set(DEP_CMAKE_ARGS "-Wno-dev" "--no-warn-unused-cli") + +## build-stage directory hierarchy for dependency installs: +if (NOT (USING_VCPKG OR NO_DEP_BUILD) AND NOT EXISTS ${SIMH_DEP_TOPDIR}) + message(STATUS "Creating dependency library directory hierarchy") + execute_process( + COMMAND ${CMAKE_COMMAND} -E make_directory ${SIMH_DEP_TOPDIR} ${SIMH_DEP_TOPDIR}/include ${SIMH_DEP_TOPDIR}/lib + ${SIMH_DEP_TOPDIR}/bin + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) +endif () + +## Default install location is ${CMAKE_SOURCE_DIR}/SIMH-install if not otherwise set +if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/SIMH-install" CACHE PATH "${CMAKE_SOURCE_DIR}/SIMH-install default install prefix" FORCE) +endif() + +## The default runtime output directory is the BIN subdirectory in the source tree's top +set(SIMH_LEGACY_INSTALL "${CMAKE_SOURCE_DIR}/BIN") +if (WIN32) + string(APPEND SIMH_LEGACY_INSTALL "/Win32") +endif() +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SIMH_LEGACY_INSTALL}) + +## Source directory is always on the global include path. +include_directories(${CMAKE_SOURCE_DIR}) + +if (NOT USING_VCPKG AND NOT NO_DEP_BUILD) + # Make sure we can include and link from the dependency directory + list(APPEND CMAKE_LIBRARY_PATH ${SIMH_DEP_TOPDIR}/lib) + link_directories(${SIMH_DEP_TOPDIR}/lib) + list(APPEND CMAKE_INCLUDE_PATH ${SIMH_DEP_TOPDIR}/include) + include_directories(${SIMH_DEP_TOPDIR}/include) +endif () + +## CMake policy tweaks + +if (CMAKE_VERSION GREATER_EQUAL 3.24) + ## Until I figure out a way to add DOWNLOAD_EXTRACT_TIMESTAMP to the call to + ## ExternalProject_Add cleanly.. + cmake_policy(SET CMP0135 NEW) +endif() + +## "Standard" includes +include(CheckCSourceCompiles) +include(CheckIncludeFile) +include(CheckSymbolExists) +include(CheckTypeSize) +include(CheckCCompilerFlag) +include(FindPackageHandleStandardArgs) + +## Deal with platform quirkiness +include(platform-quirks) + +# Find packages, arrange for dependency download/compile/install: +# +# SIMH_BUILD_DEPS is the list of the dependecies' names, for pretty-printing. +# SIMH_DEP_TARGETS is the list of dependency targets' names that we'll actually build. + +set(SIMH_BUILD_DEPS) +set(SIMH_DEP_TARGETS) + +set(THREADING_PKG_STATUS "unknown") +set(ZLIB_PKG_STATUS "unknown") +set(PCRE_PKG_STATUS "unknown") +set(VIDEO_PKG_STATUS) +set(NETWORK_PKG_STATUS) + +# if (USING_VCPKG) +# ## Sanity checking output: Ensure that vcpkg picked up the correct triplet +# message(STATUS "VCPKG sanity check:\n" +# " .. VCPKG target triplet is ${VCPKG_TARGET_TRIPLET}\n" +# " .. VCPKG_CRT_LINKAGE is ${VCPKG_CRT_LINKAGE}" +# ## " .. CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}\n" +# ## " .. CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} +# ) +# endif () + +# SIMH local packages: +include(build_dep_matrix) +include(os-features) +include(dep-locate) +include(dep-link) + +if (VIDEO_PKG_STATUS) + string(REPLACE ";" ", " VIDEO_PKG_STATUS "${VIDEO_PKG_STATUS}") +else (VIDEO_PKG_STATUS) + set(VIDEO_PKG_STATUS "unknown") +endif (VIDEO_PKG_STATUS) + +if (NETWORK_PKG_STATUS) + string(REPLACE ";" ", " NETWORK_PKG_STATUS "${NETWORK_PKG_STATUS}") +else (NETWORK_PKG_STATUS) + set(NETWORK_PKG_STATUS "unknown") +endif (NETWORK_PKG_STATUS) + +set(CPPCHECK_STATUS "disabled.") + +if (ENABLE_CPPCHECK) + find_program(cppcheck_cmd NAMES cppcheck) + if (cppcheck_cmd) + list(APPEND cppcheck_cmd + "--language=c" + "--enable=warning,style,performance,portability,information,missingInclude" + "--suppress=missingIncludeSystem" + "--inline-suppr" + "--std=c99" + "--force") + set(CPPCHECK_STATUS "found and enabled.") + if (WIN32) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + list(APPEND cppcheck_cmd + "--platform=win64") + set(CPPCHECK_STATUS "found, Win64 platform.") + else () + list(APPEND cppcheck_cmd + "--platform=win32A") + set(CPPCHECK_STATUS "found, Win32 ASCII platform.") + endif () + endif () + else (cppcheck_cmd) + set(CPPCHECK_STATUS "'cppcheck' not installed.") + endif () +endif () + +set(_feature_text "Libraries and features:\n") +string(APPEND _feature_text "\n * Build with video/graphics support. ${BUILD_WITH_VIDEO}") +string(APPEND _feature_text "\n * Build with networking support .... ${BUILD_WITH_NETWORK}") +string(APPEND _feature_text "\n * Build internal ROMS .............. ") +if (DONT_SET_ROMS) + string(APPEND _feature_text "No") +else () + string(APPEND _feature_text "Yes") +endif () +string(APPEND _feature_text "\n * Thread support ................... ${THREADING_PKG_STATUS}") +string(APPEND _feature_text "\n * zlib ............................. ${ZLIB_PKG_STATUS}") +string(APPEND _feature_text "\n * Perl-Compatible RegExps........... ${PCRE_PKG_STATUS}") +string(APPEND _feature_text "\n * PNG, Freetype, SDL2, SDL2_ttf .... ${VIDEO_PKG_STATUS}") +string(APPEND _feature_text "\n * Network support .................. ${NETWORK_PKG_STATUS}") + +get_target_property(OS_FEATURE_DEFS os_features INTERFACE_COMPILE_DEFINITIONS) +list(LENGTH OS_FEATURE_DEFS len_os_features) +string(APPEND _feature_text "\n * OS Feature definitions") +if (OS_FEATURE_DEFS) + string(APPEND _feature_text ":") + foreach (feature ${OS_FEATURE_DEFS}) + string(APPEND _feature_text "\n .. ${feature}") + endforeach() +else () + string(APPEND _feature_text " ........... None defined.") +endif () + +get_target_property(OS_FEATURE_LIBS os_features INTERFACE_LINK_LIBRARIES) +list(LENGTH OS_FEATURE_LIBS len_os_features) +string(APPEND _feature_text "\n * OS Feature libraries") +if (OS_FEATURE_LIBS) + string(APPEND _feature_text ":") + foreach (feature ${OS_FEATURE_LIBS}) + string(APPEND _feature_text "\n .. ${feature}") + endforeach () +else () + string(APPEND _feature_text " ............. None required.") +endif () + +string(APPEND _feature_text "\n * 'cppcheck' ....................... ${CPPCHECK_STATUS}") +string(APPEND _feature_text "\n") + +message(STATUS ${_feature_text}) +unset(_feature_text) + +unset(ROM_STATUS) + +if (NO_DEP_BUILD AND SIMH_BUILD_DEPS) + ## Don't build dependencies. Just wail about them. + message("") + message("Missing SIMH dependencies:") + foreach (dep ${SIMH_BUILD_DEPS}) + message(STATUS " ${dep}") + endforeach() + message("") + message("Please install the above dependencies via your platform package management or") + message("software installation system and reconfigure.") + message("") + message("Also see the .travis/deps.h file for Brew and apt packages installed during") + message("github.com workflow actions.") + message(FATAL_ERROR "Missing dependencies, cannot continue.") + + ## TODO: Assume that these dependencies are optional? +endif () + +if (NOT DEFINED DO_DEPENDENCY_BUILD OR SIMH_BUILD_DEPS) + if (DEFINED DO_DEPENDENCY_BUILD AND NOT DO_DEPENDENCY_BUILD AND SIMH_BUILD_DEPS) + message(FATAL_ERROR "Dependency libraries did not build successfully!!??") + endif() + + if (SIMH_BUILD_DEPS) + message(STATUS "Building dependency libraries as a superbuild") + set(DO_DEPENDENCY_BUILD ON CACHE BOOL "Superbuild flag" FORCE) + else () + set(DO_DEPENDENCY_BUILD OFF CACHE BOOL "Superbuild flag" FORCE) + endif () +else () + set(DO_DEPENDENCY_BUILD ${DO_DEPENDENCY_BUILD} CACHE BOOL "Superbuild flag" FORCE) +endif () + +if (NOT DO_DEPENDENCY_BUILD) + include (add_simulator) + if (WITH_SLIRP) + add_subdirectory(slirp) + endif (WITH_SLIRP) + +## Don't delete yet ## set(Python_ADDITIONAL_VERSIONS 3) +## Don't delete yet ## include(FindPythonInterp) +## Don't delete yet ## if (PYTHONINTERP_FOUND AND PYTHON_VERSION_MAJOR GREATER_EQUAL 3) +## Don't delete yet ## add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/cmake/simh-simulators.cmake +## Don't delete yet ## COMMAND ${PYTHON_EXECUTABLE} "-m" generate "--srcdir" "${CMAKE_SOURCE_DIR}" +## Don't delete yet ## MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/makefile +## Don't delete yet ## COMMENT "Updating cmake/simh-simulators.cmake" +## Don't delete yet ## WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/cmake +## Don't delete yet ## COMMAND_EXPAND_LISTS) +## Don't delete yet ## message(STATUS "Added makefile update rule.") +## Don't delete yet ## endif (PYTHONINTERP_FOUND AND PYTHON_VERSION_MAJOR GREATER_EQUAL 3) +## Don't delete yet ## +## Don't delete yet ## if (${CMAKE_SOURCE_DIR}/makefile IS_NEWER_THAN ${CMAKE_SOURCE_DIR}/cmake/simh-simulators.cmake) +## Don't delete yet ## if (NOT PYTHONINTERP_FOUND OR PYTHON_VERSION_MAJOR LESS 3) +## Don't delete yet ## if (NOT PYTHONINTERP_FOUND) +## Don't delete yet ## message("!! Python not found") +## Don't delete yet ## elseif (PYTHON_VERSION_MAJOR LESS 3) +## Don't delete yet ## message("!! Python is not python3") +## Don't delete yet ## endif (NOT PYTHONINTERP_FOUND) +## Don't delete yet ## +## Don't delete yet ## message("!!") +## Don't delete yet ## message("!! Cannot update cmake/simh-simulators.cmake, using older version.") +## Don't delete yet ## message("!! Proceed with caution: This build might not succeed.") +## Don't delete yet ## message("!!") +## Don't delete yet ## message(STATUS "Keeping existing cmake/simh-simulators.cmake") +## Don't delete yet ## else (NOT PYTHONINTERP_FOUND OR PYTHON_VERSION_MAJOR LESS 3) +## Don't delete yet ## message(STATUS "Updating cmake/simh-simulators.cmake") +## Don't delete yet ## execute_process(COMMAND ${PYTHON_EXECUTABLE} "-m" generate "--srcdir" "${CMAKE_SOURCE_DIR}" +## Don't delete yet ## WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/cmake) +## Don't delete yet ## endif (NOT PYTHONINTERP_FOUND OR PYTHON_VERSION_MAJOR LESS 3) +## Don't delete yet ## endif () + + message(STATUS "Adding simulators") + include(simh-simulators) + + include(cpack-setup) + include(simh-packaging) +else () + message(STATUS "") + message(STATUS "Building the following dependency libraries:") + message(STATUS "") + foreach(dep ${SIMH_BUILD_DEPS}) + message(STATUS " ${dep}") + endforeach () + message(STATUS "") + + ExternalProject_Add (simh_superbuild + DEPENDS + ${SIMH_DEP_TARGETS} + SOURCE_DIR + ${CMAKE_SOURCE_DIR} + CMAKE_ARGS + -DDO_DEPENDENCY_BUILD:BOOL=OFF + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + INSTALL_COMMAND "" + BINARY_DIR + ${CMAKE_BINARY_DIR} + USES_TERMINAL_CONFIGURE TRUE + USES_TERMINAL_BUILD TRUE + ) + + ## Ensure that the next build rechecks the dependency + ## libraries that were just built and finds them. + unset(Freetype_FOUND CACHE) + unset(PCAP_FOUND CACHE) + unset(PCRE_FOUND CACHE) + unset(PCRE2_FOUND CACHE) + unset(PNG_FOUND CACHE) + unset(PTW_FOUND CACHE) + unset(SDL2_FOUND CACHE) + unset(SDL2_ttf_FOUND CACHE) + unset(ZLIB_FOUND CACHE) +endif () diff --git a/GRI/CMakeLists.txt b/GRI/CMakeLists.txt new file mode 100644 index 00000000..00551eda --- /dev/null +++ b/GRI/CMakeLists.txt @@ -0,0 +1,26 @@ +## GRI simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(gri + SOURCES + gri_cpu.c + gri_stddev.c + gri_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL GRI + PKG_FAMILY grisys_family + TEST gri) diff --git a/H316/CMakeLists.txt b/H316/CMakeLists.txt new file mode 100644 index 00000000..d642cf38 --- /dev/null +++ b/H316/CMakeLists.txt @@ -0,0 +1,37 @@ +## H316 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(h316 + SOURCES + h316_stddev.c + h316_lp.c + h316_cpu.c + h316_sys.c + h316_mt.c + h316_fhd.c + h316_dp.c + h316_rtc.c + h316_imp.c + h316_hi.c + h316_mi.c + h316_udp.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + VM_IMPTIP + LABEL H316 + PKG_FAMILY honeywell_family + TEST h316) diff --git a/HP2100/CMakeLists.txt b/HP2100/CMakeLists.txt new file mode 100644 index 00000000..786af721 --- /dev/null +++ b/HP2100/CMakeLists.txt @@ -0,0 +1,59 @@ +## HP2100 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(hp2100 + SOURCES + hp2100_baci.c + hp2100_cpu.c + hp2100_cpu_fp.c + hp2100_cpu_fpp.c + hp2100_cpu0.c + hp2100_cpu1.c + hp2100_cpu2.c + hp2100_cpu3.c + hp2100_cpu4.c + hp2100_cpu5.c + hp2100_cpu6.c + hp2100_cpu7.c + hp2100_di.c + hp2100_di_da.c + hp2100_disclib.c + hp2100_dma.c + hp2100_dp.c + hp2100_dq.c + hp2100_dr.c + hp2100_ds.c + hp2100_ipl.c + hp2100_lps.c + hp2100_lpt.c + hp2100_mc.c + hp2100_mem.c + hp2100_mpx.c + hp2100_ms.c + hp2100_mt.c + hp2100_mux.c + hp2100_pif.c + hp2100_pt.c + hp2100_sys.c + hp2100_tbg.c + hp2100_tty.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + HAVE_INT64 + LABEL HP2100 + PKG_FAMILY hp_family + TEST hp2100) diff --git a/HP3000/CMakeLists.txt b/HP3000/CMakeLists.txt new file mode 100644 index 00000000..6e0df574 --- /dev/null +++ b/HP3000/CMakeLists.txt @@ -0,0 +1,40 @@ +## HP3000 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(hp3000 + SOURCES + hp_disclib.c + hp_tapelib.c + hp3000_atc.c + hp3000_clk.c + hp3000_cpu.c + hp3000_cpu_base.c + hp3000_cpu_fp.c + hp3000_cpu_cis.c + hp3000_ds.c + hp3000_iop.c + hp3000_lp.c + hp3000_mem.c + hp3000_mpx.c + hp3000_ms.c + hp3000_scmb.c + hp3000_sel.c + hp3000_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL HP3000 + PKG_FAMILY hp_family + TEST hp3000) diff --git a/I1401/CMakeLists.txt b/I1401/CMakeLists.txt new file mode 100644 index 00000000..57543e91 --- /dev/null +++ b/I1401/CMakeLists.txt @@ -0,0 +1,30 @@ +## I1401 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(i1401 + SOURCES + i1401_lp.c + i1401_cpu.c + i1401_iq.c + i1401_cd.c + i1401_mt.c + i1401_dp.c + i1401_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL I1401 + PKG_FAMILY ibm_family + TEST i1401) diff --git a/I1620/CMakeLists.txt b/I1620/CMakeLists.txt new file mode 100644 index 00000000..82af7730 --- /dev/null +++ b/I1620/CMakeLists.txt @@ -0,0 +1,31 @@ +## I1620 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(i1620 + SOURCES + i1620_cd.c + i1620_dp.c + i1620_pt.c + i1620_tty.c + i1620_cpu.c + i1620_lp.c + i1620_fp.c + i1620_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL I1620 + PKG_FAMILY ibm_family + TEST i1620) diff --git a/I650/CMakeLists.txt b/I650/CMakeLists.txt new file mode 100644 index 00000000..3ad49198 --- /dev/null +++ b/I650/CMakeLists.txt @@ -0,0 +1,43 @@ +## I650 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(i650 + SOURCES + i650_cpu.c + i650_cdr.c + i650_cdp.c + i650_dsk.c + i650_mt.c + i650_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + FEATURE_INT64 + LABEL I650 + PKG_FAMILY ibm_family + TEST i650) + +if (WIN32) + if (MSVC) + set(I650_STACK_FLAG "/STACK:8388608") + else () + set(I650_STACK_FLAG "-Wl,--stack,8388608") + endif () + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.13") + target_link_options(i650 PUBLIC "${I650_STACK_FLAG}") + else () + set_property(TARGET i650 LINK_FLAGS " ${I650_STACK_FLAG}") + endif () +endif() \ No newline at end of file diff --git a/I7000/CMakeLists.txt b/I7000/CMakeLists.txt new file mode 100644 index 00000000..a4f781b6 --- /dev/null +++ b/I7000/CMakeLists.txt @@ -0,0 +1,151 @@ +## I7000 simulators +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(i701 + SOURCES + ${I7000D}/i701_cpu.c + ${I7000D}/i701_sys.c + ${I7000D}/i701_chan.c + ${I7000D}/i7090_cdr.c + ${I7000D}/i7090_cdp.c + ${I7000D}/i7090_lpr.c + ${I7000D}/i7000_mt.c + ${I7000D}/i7090_drum.c + ${I7000D}/i7000_chan.c + INCLUDES + ${I7000D} + DEFINES + I701 + FEATURE_INT64 + LABEL I7000 + PKG_FAMILY ibm_family + TEST i701) + +add_simulator(i7010 + SOURCES + ${I7000D}/i7010_cpu.c + ${I7000D}/i7010_sys.c + ${I7000D}/i7010_chan.c + ${I7000D}/i7000_cdp.c + ${I7000D}/i7000_cdr.c + ${I7000D}/i7000_con.c + ${I7000D}/i7000_chan.c + ${I7000D}/i7000_lpr.c + ${I7000D}/i7000_mt.c + ${I7000D}/i7000_chron.c + ${I7000D}/i7000_dsk.c + ${I7000D}/i7000_com.c + ${I7000D}/i7000_ht.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + I7010 + LABEL I7000 + PKG_FAMILY ibm_family + TEST i7010) + +add_simulator(i704 + SOURCES + ${I7000D}/i7090_cpu.c + ${I7000D}/i7090_sys.c + ${I7000D}/i7090_chan.c + ${I7000D}/i7090_cdr.c + ${I7000D}/i7090_cdp.c + ${I7000D}/i7090_lpr.c + ${I7000D}/i7000_mt.c + ${I7000D}/i7090_drum.c + ${I7000D}/i7000_chan.c + INCLUDES + ${I7000D} + DEFINES + I704 + FEATURE_INT64 + LABEL I7000 + PKG_FAMILY ibm_family + TEST i704) + +add_simulator(i7070 + SOURCES + ${I7000D}/i7070_cpu.c + ${I7000D}/i7070_sys.c + ${I7000D}/i7070_chan.c + ${I7000D}/i7000_cdp.c + ${I7000D}/i7000_cdr.c + ${I7000D}/i7000_con.c + ${I7000D}/i7000_chan.c + ${I7000D}/i7000_lpr.c + ${I7000D}/i7000_mt.c + ${I7000D}/i7000_chron.c + ${I7000D}/i7000_dsk.c + ${I7000D}/i7000_com.c + ${I7000D}/i7000_ht.c + INCLUDES + ${I7000D} + DEFINES + I7070 + FEATURE_INT64 + LABEL I7000 + PKG_FAMILY ibm_family + TEST i7070) + +add_simulator(i7080 + SOURCES + ${I7000D}/i7080_cpu.c + ${I7000D}/i7080_sys.c + ${I7000D}/i7080_chan.c + ${I7000D}/i7080_drum.c + ${I7000D}/i7000_cdp.c + ${I7000D}/i7000_cdr.c + ${I7000D}/i7000_con.c + ${I7000D}/i7000_chan.c + ${I7000D}/i7000_lpr.c + ${I7000D}/i7000_mt.c + ${I7000D}/i7000_chron.c + ${I7000D}/i7000_dsk.c + ${I7000D}/i7000_com.c + ${I7000D}/i7000_ht.c + INCLUDES + ${I7000D} + DEFINES + I7080 + LABEL I7000 + PKG_FAMILY ibm_family + TEST i7080) + +add_simulator(i7090 + SOURCES + i7090_cpu.c + i7090_sys.c + i7090_chan.c + i7090_cdr.c + i7090_cdp.c + i7090_lpr.c + i7000_chan.c + i7000_mt.c + i7090_drum.c + i7090_hdrum.c + i7000_chron.c + i7000_dsk.c + i7000_com.c + i7000_ht.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + I7090 + FEATURE_INT64 + LABEL I7000 + PKG_FAMILY ibm_family + TEST i7090) diff --git a/I7094/CMakeLists.txt b/I7094/CMakeLists.txt new file mode 100644 index 00000000..f85475a8 --- /dev/null +++ b/I7094/CMakeLists.txt @@ -0,0 +1,36 @@ +## I7094 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(i7094 + SOURCES + i7094_cpu.c + i7094_cpu1.c + i7094_io.c + i7094_cd.c + i7094_clk.c + i7094_com.c + i7094_drm.c + i7094_dsk.c + i7094_sys.c + i7094_lp.c + i7094_mt.c + i7094_binloader.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + FEATURE_INT64 + LABEL I7094 + PKG_FAMILY ibm_family + TEST i7094) diff --git a/Ibm1130/CMakeLists.txt b/Ibm1130/CMakeLists.txt new file mode 100644 index 00000000..bd0365e3 --- /dev/null +++ b/Ibm1130/CMakeLists.txt @@ -0,0 +1,41 @@ +## Ibm1130 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(ibm1130 + SOURCES + ibm1130_cpu.c + ibm1130_cr.c + ibm1130_disk.c + ibm1130_stddev.c + ibm1130_sys.c + ibm1130_gdu.c + ibm1130_gui.c + ibm1130_prt.c + ibm1130_fmt.c + ibm1130_ptrp.c + ibm1130_plot.c + ibm1130_sca.c + ibm1130_t2741.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL Ibm1130 + PKG_FAMILY ibm_family + TEST ibm1130) + +if (WIN32) + target_compile_definitions(ibm1130 PRIVATE GUI_SUPPORT) + ## missing source in IBM1130? ## target_sources(ibm1130 PRIVATE ibm1130.c) +endif() \ No newline at end of file diff --git a/Intel-Systems/Intel-MDS/CMakeLists.txt b/Intel-Systems/Intel-MDS/CMakeLists.txt new file mode 100644 index 00000000..575cfa8f --- /dev/null +++ b/Intel-Systems/Intel-MDS/CMakeLists.txt @@ -0,0 +1,47 @@ +## Intel-Systems/Intel-MDS simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(intel-mds + SOURCES + ${INTELSYSC}/i8080.c + imds_sys.c + ${INTELSYSC}/i3214.c + ${INTELSYSC}/i8251.c + ${INTELSYSC}/i8253.c + ${INTELSYSC}/i8255.c + ${INTELSYSC}/i8259.c + ${INTELSYSC}/ieprom.c + ${INTELSYSC}/ioc-cont.c + ${INTELSYSC}/ipc-cont.c + ${INTELSYSC}/iram8.c + ${INTELSYSC}/isbc064.c + ${INTELSYSC}/isbc202.c + ${INTELSYSC}/isbc201.c + ${INTELSYSC}/isbc206.c + ${INTELSYSC}/isbc464.c + ${INTELSYSC}/isbc208.c + ${INTELSYSC}/port.c + ${INTELSYSC}/irq.c + ${INTELSYSC}/multibus.c + ${INTELSYSC}/mem.c + ${INTELSYSC}/sys.c + ${INTELSYSC}/zx200a.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + BUILDROMS + LABEL Intel-Systems + PKG_FAMILY intel_family + TEST intel-mds) diff --git a/Intel-Systems/scelbi/CMakeLists.txt b/Intel-Systems/scelbi/CMakeLists.txt new file mode 100644 index 00000000..f710ef6a --- /dev/null +++ b/Intel-Systems/scelbi/CMakeLists.txt @@ -0,0 +1,26 @@ +## Intel-Systems/scelbi simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(scelbi + SOURCES + ${SCELBIC}/i8008.c + scelbi_sys.c + scelbi_io.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL Intel-Systems + PKG_FAMILY intel_family + TEST scelbi) diff --git a/Interdata/CMakeLists.txt b/Interdata/CMakeLists.txt new file mode 100644 index 00000000..2e3648a7 --- /dev/null +++ b/Interdata/CMakeLists.txt @@ -0,0 +1,63 @@ +## Interdata simulators +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(id16 + SOURCES + ${ID16D}/id16_cpu.c + ${ID16D}/id16_sys.c + ${ID16D}/id_dp.c + ${ID16D}/id_fd.c + ${ID16D}/id_fp.c + ${ID16D}/id_idc.c + ${ID16D}/id_io.c + ${ID16D}/id_lp.c + ${ID16D}/id_mt.c + ${ID16D}/id_pas.c + ${ID16D}/id_pt.c + ${ID16D}/id_tt.c + ${ID16D}/id_uvc.c + ${ID16D}/id16_dboot.c + ${ID16D}/id_ttp.c + INCLUDES + ${ID16D} + DEFINES + IFP_IN_MEM + LABEL Interdata + PKG_FAMILY interdata_family + TEST id16) + +add_simulator(id32 + SOURCES + id32_cpu.c + id32_sys.c + id_dp.c + id_fd.c + id_fp.c + id_idc.c + id_io.c + id_lp.c + id_mt.c + id_pas.c + id_pt.c + id_tt.c + id_uvc.c + id32_dboot.c + id_ttp.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL Interdata + PKG_FAMILY interdata_family + TEST id32) diff --git a/LGP/CMakeLists.txt b/LGP/CMakeLists.txt new file mode 100644 index 00000000..b3e89361 --- /dev/null +++ b/LGP/CMakeLists.txt @@ -0,0 +1,26 @@ +## LGP simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(lgp + SOURCES + lgp_cpu.c + lgp_stddev.c + lgp_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL LGP + PKG_FAMILY lgp_family + TEST lgp) diff --git a/ND100/CMakeLists.txt b/ND100/CMakeLists.txt new file mode 100644 index 00000000..a4367e3a --- /dev/null +++ b/ND100/CMakeLists.txt @@ -0,0 +1,28 @@ +## ND100 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(nd100 + SOURCES + nd100_sys.c + nd100_cpu.c + nd100_floppy.c + nd100_stddev.c + nd100_mm.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL ND100 + PKG_FAMILY norsk_family + TEST nd100) diff --git a/NOVA/CMakeLists.txt b/NOVA/CMakeLists.txt new file mode 100644 index 00000000..5d0c0f20 --- /dev/null +++ b/NOVA/CMakeLists.txt @@ -0,0 +1,58 @@ +## NOVA simulators +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(eclipse + SOURCES + eclipse_cpu.c + eclipse_tt.c + nova_sys.c + nova_dkp.c + nova_dsk.c + nova_lp.c + nova_mta.c + nova_plt.c + nova_pt.c + nova_clk.c + nova_tt1.c + nova_qty.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + ECLIPSE + FEATURE_INT64 + LABEL NOVA + PKG_FAMILY dgnova_family + TEST eclipse) + +add_simulator(nova + SOURCES + nova_sys.c + nova_cpu.c + nova_dkp.c + nova_dsk.c + nova_lp.c + nova_mta.c + nova_plt.c + nova_pt.c + nova_clk.c + nova_tt.c + nova_tt1.c + nova_qty.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL NOVA + PKG_FAMILY dgnova_family + TEST nova) diff --git a/PDP1/CMakeLists.txt b/PDP1/CMakeLists.txt new file mode 100644 index 00000000..e43460fd --- /dev/null +++ b/PDP1/CMakeLists.txt @@ -0,0 +1,37 @@ +## PDP1 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(pdp1 + SOURCES + pdp1_lp.c + pdp1_cpu.c + pdp1_stddev.c + pdp1_sys.c + pdp1_dt.c + pdp1_drm.c + pdp1_clk.c + pdp1_dcs.c + pdp1_dpy.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + DISPLAY_TYPE=DIS_TYPE30 + PIX_SCALE=RES_HALF + FEATURE_VIDEO + FEATURE_DISPLAY + LABEL PDP1 + PKG_FAMILY decpdp_family + TEST pdp1) diff --git a/PDP10/CMakeLists.txt b/PDP10/CMakeLists.txt new file mode 100644 index 00000000..714c569a --- /dev/null +++ b/PDP10/CMakeLists.txt @@ -0,0 +1,231 @@ +## PDP10 simulators +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(pdp10 + SOURCES + pdp10_fe.c + ${PDP11D}/pdp11_dz.c + pdp10_cpu.c + pdp10_ksio.c + pdp10_lp20.c + pdp10_mdfp.c + pdp10_pag.c + pdp10_rp.c + pdp10_sys.c + pdp10_tim.c + pdp10_tu.c + pdp10_xtnd.c + ${PDP11D}/pdp11_pt.c + ${PDP11D}/pdp11_ry.c + ${PDP11D}/pdp11_cr.c + ${PDP11D}/pdp11_dup.c + ${PDP11D}/pdp11_dmc.c + ${PDP11D}/pdp11_kmc.c + ${PDP11D}/pdp11_xu.c + ${PDP11D}/pdp11_ch.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_PDP10 + FEATURE_INT64 + LABEL PDP10 + NO_INSTALL + TEST pdp10) + +add_simulator(pdp10-ka + SOURCES + ${KA10D}/kx10_cpu.c + ${KA10D}/kx10_sys.c + ${KA10D}/kx10_df.c + ${KA10D}/kx10_dp.c + ${KA10D}/kx10_mt.c + ${KA10D}/kx10_cty.c + ${KA10D}/kx10_lp.c + ${KA10D}/kx10_pt.c + ${KA10D}/kx10_dc.c + ${KA10D}/kx10_rp.c + ${KA10D}/kx10_rc.c + ${KA10D}/kx10_dt.c + ${KA10D}/kx10_dk.c + ${KA10D}/kx10_cr.c + ${KA10D}/kx10_cp.c + ${KA10D}/kx10_tu.c + ${KA10D}/kx10_rs.c + ${KA10D}/ka10_pd.c + ${KA10D}/kx10_rh.c + ${KA10D}/kx10_imp.c + ${KA10D}/ka10_tk10.c + ${KA10D}/ka10_mty.c + ${KA10D}/ka10_imx.c + ${KA10D}/ka10_ch10.c + ${KA10D}/ka10_stk.c + ${KA10D}/ka10_ten11.c + ${KA10D}/ka10_auxcpu.c + ${KA10D}/ka10_pmp.c + ${KA10D}/ka10_dkb.c + ${KA10D}/pdp6_dct.c + ${KA10D}/pdp6_dtc.c + ${KA10D}/pdp6_mtc.c + ${KA10D}/pdp6_dsk.c + ${KA10D}/pdp6_dcs.c + ${KA10D}/ka10_dpk.c + ${KA10D}/kx10_dpy.c + ${KA10D}/ka10_ai.c + ${KA10D}/ka10_iii.c + ${KA10D}/kx10_disk.c + ${KA10D}/ka10_pclk.c + ${KA10D}/ka10_tv.c + ${DISPLAY340} + ${DISPLAYIII} + INCLUDES + ${KA10D} + DEFINES + KA=1 + FEATURE_INT64 + FEATURE_VIDEO + FEATURE_DISPLAY + LABEL PDP10 + PKG_FAMILY pdp10_family + TEST ka10) + +if (PANDA_LIGHTS) + target_sources(pdp10-ka PUBLIC ${PDP10D}/ka10_lights.c) + target_compile_definitions(pdp10-ka PUBLIC PANDA_LIGHTS) + target_link_libraries(pdp10-ka PUBLIC usb-1.0) +endif (PANDA_LIGHTS) + +add_simulator(pdp10-ki + SOURCES + ${KI10D}/kx10_cpu.c + ${KI10D}/kx10_sys.c + ${KI10D}/kx10_df.c + ${KI10D}/kx10_dp.c + ${KI10D}/kx10_mt.c + ${KI10D}/kx10_cty.c + ${KI10D}/kx10_lp.c + ${KI10D}/kx10_pt.c + ${KI10D}/kx10_dc.c + ${KI10D}/kx10_rh.c + ${KI10D}/kx10_rp.c + ${KI10D}/kx10_rc.c + ${KI10D}/kx10_dt.c + ${KI10D}/kx10_dk.c + ${KI10D}/kx10_cr.c + ${KI10D}/kx10_cp.c + ${KI10D}/kx10_tu.c + ${KI10D}/kx10_rs.c + ${KI10D}/kx10_imp.c + ${KI10D}/kx10_dpy.c + ${KI10D}/kx10_disk.c + ${DISPLAY340} + INCLUDES + ${KI10D} + DEFINES + KI=1 + FEATURE_INT64 + FEATURE_VIDEO + FEATURE_DISPLAY + LABEL PDP10 + PKG_FAMILY pdp10_family + TEST ki10) + +add_simulator(pdp10-kl + SOURCES + ${KL10D}/kx10_cpu.c + ${KL10D}/kx10_sys.c + ${KL10D}/kx10_df.c + ${KA10D}/kx10_dp.c + ${KA10D}/kx10_mt.c + ${KA10D}/kx10_lp.c + ${KA10D}/kx10_pt.c + ${KA10D}/kx10_dc.c + ${KL10D}/kx10_rh.c + ${KA10D}/kx10_dt.c + ${KA10D}/kx10_cr.c + ${KA10D}/kx10_cp.c + ${KL10D}/kx10_rp.c + ${KL10D}/kx10_tu.c + ${KL10D}/kx10_rs.c + ${KL10D}/kx10_imp.c + ${KL10D}/kl10_fe.c + ${KL10D}/ka10_pd.c + ${KL10D}/ka10_ch10.c + ${KL10D}/kl10_nia.c + ${KL10D}/kx10_disk.c + INCLUDES + ${KL10D} + DEFINES + KL=1 + FEATURE_INT64 + LABEL PDP10 + PKG_FAMILY pdp10_family + TEST kl10) + +add_simulator(pdp10-ks + SOURCES + ${KS10D}/kx10_cpu.c + ${KS10D}/kx10_sys.c + ${KS10D}/kx10_disk.c + ${KS10D}/ks10_cty.c + ${KS10D}/ks10_uba.c + ${KS10D}/kx10_rh.c + ${KS10D}/kx10_rp.c + ${KS10D}/kx10_tu.c + ${KS10D}/ks10_dz.c + ${KS10D}/ks10_tcu.c + ${KS10D}/ks10_lp.c + ${KS10D}/ks10_ch11.c + ${KS10D}/ks10_kmc.c + ${KS10D}/ks10_dup.c + ${KS10D}/kx10_imp.c + INCLUDES + ${KS10D} + ${PDP11D} + DEFINES + KS=1 + FEATURE_INT64 + LABEL PDP10 + PKG_FAMILY pdp10_family + TEST ks10) + +add_simulator(pdp6 + SOURCES + ${PDP6D}/kx10_cpu.c + ${PDP6D}/kx10_sys.c + ${PDP6D}/kx10_cty.c + ${PDP6D}/kx10_lp.c + ${PDP6D}/kx10_pt.c + ${PDP6D}/kx10_cr.c + ${PDP6D}/kx10_cp.c + ${PDP6D}/pdp6_dct.c + ${PDP6D}/pdp6_dtc.c + ${PDP6D}/pdp6_mtc.c + ${PDP6D}/pdp6_dsk.c + ${PDP6D}/pdp6_dcs.c + ${PDP6D}/kx10_dpy.c + ${PDP6D}/pdp6_slave.c + ${DISPLAY340} + INCLUDES + ${PDP6D} + DEFINES + PDP6=1 + FEATURE_INT64 + FEATURE_VIDEO + FEATURE_DISPLAY + LABEL PDP10 + PKG_FAMILY decpdp_family + TEST pdp6) diff --git a/PDP11/CMakeLists.txt b/PDP11/CMakeLists.txt new file mode 100644 index 00000000..971843f4 --- /dev/null +++ b/PDP11/CMakeLists.txt @@ -0,0 +1,104 @@ +## PDP11 simulators +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(pdp11 + SOURCES + pdp11_fp.c + pdp11_cpu.c + pdp11_dz.c + pdp11_cis.c + pdp11_lp.c + pdp11_rk.c + pdp11_rl.c + pdp11_rp.c + pdp11_rx.c + pdp11_stddev.c + pdp11_sys.c + pdp11_tc.c + pdp11_tm.c + pdp11_ts.c + pdp11_io.c + pdp11_rq.c + pdp11_tq.c + pdp11_pclk.c + pdp11_ry.c + pdp11_pt.c + pdp11_hk.c + pdp11_xq.c + pdp11_xu.c + pdp11_vh.c + pdp11_rh.c + pdp11_tu.c + pdp11_cpumod.c + pdp11_cr.c + pdp11_rf.c + pdp11_dl.c + pdp11_ta.c + pdp11_rc.c + pdp11_kg.c + pdp11_ke.c + pdp11_dc.c + pdp11_dmc.c + pdp11_kmc.c + pdp11_dup.c + pdp11_rs.c + pdp11_vt.c + pdp11_td.c + pdp11_io_lib.c + pdp11_rom.c + pdp11_ch.c + pdp11_dh.c + pdp11_ng.c + pdp11_daz.c + pdp11_tv.c + pdp11_mb.c + ${DISPLAYNG} + ${DISPLAYVT} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + VM_PDP11 + FEATURE_VIDEO + FEATURE_DISPLAY + BUILDROMS + LABEL PDP11 + PKG_FAMILY pdp11_family + TEST pdp11) + +add_simulator(uc15 + SOURCES + ${UC15D}/pdp11_cis.c + ${UC15D}/pdp11_cpu.c + ${UC15D}/pdp11_cpumod.c + ${UC15D}/pdp11_cr.c + ${UC15D}/pdp11_fp.c + ${UC15D}/pdp11_io.c + ${UC15D}/pdp11_io_lib.c + ${UC15D}/pdp11_lp.c + ${UC15D}/pdp11_rh.c + ${UC15D}/pdp11_rk.c + ${UC15D}/pdp11_stddev.c + ${UC15D}/pdp11_sys.c + ${UC15D}/pdp11_uc15.c + INCLUDES + ${UC15D} + ${PDP18BD} + DEFINES + VM_PDP11 + UC15 + LABEL PDP11 + PKG_FAMILY pdp11_family + TEST uc15) diff --git a/PDP18B/CMakeLists.txt b/PDP18B/CMakeLists.txt new file mode 100644 index 00000000..2bbe6c8b --- /dev/null +++ b/PDP18B/CMakeLists.txt @@ -0,0 +1,83 @@ +## PDP18B simulators +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + + +set(PDP18B + ${PDP18BD}/pdp18b_dt.c + ${PDP18BD}/pdp18b_drm.c + ${PDP18BD}/pdp18b_cpu.c + ${PDP18BD}/pdp18b_lp.c + ${PDP18BD}/pdp18b_mt.c + ${PDP18BD}/pdp18b_rf.c + ${PDP18BD}/pdp18b_rp.c + ${PDP18BD}/pdp18b_stddev.c + ${PDP18BD}/pdp18b_sys.c + ${PDP18BD}/pdp18b_rb.c + ${PDP18BD}/pdp18b_tt1.c + ${PDP18BD}/pdp18b_fpp.c + ${PDP18BD}/pdp18b_g2tty.c + ${PDP18BD}/pdp18b_dr15.c) + + +add_simulator(pdp15 + SOURCES + ${PDP18B} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + PDP15 + LABEL PDP18B + PKG_FAMILY decpdp_family + TEST pdp15) + +add_simulator(pdp4 + SOURCES + ${PDP18B} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + PDP4 + LABEL PDP18B + PKG_FAMILY decpdp_family + TEST pdp4) + +add_simulator(pdp7 + SOURCES + ${PDP18B} + pdp18b_dpy.c + ${DISPLAY340} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + PDP7 + DISPLAY_TYPE=DIS_TYPE30 + PIX_SCALE=RES_HALF + FEATURE_VIDEO + FEATURE_DISPLAY + LABEL PDP18B + PKG_FAMILY decpdp_family + TEST pdp7) + +add_simulator(pdp9 + SOURCES + ${PDP18B} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + PDP9 + LABEL PDP18B + PKG_FAMILY decpdp_family + TEST pdp9) diff --git a/PDP8/CMakeLists.txt b/PDP8/CMakeLists.txt new file mode 100644 index 00000000..780e141a --- /dev/null +++ b/PDP8/CMakeLists.txt @@ -0,0 +1,41 @@ +## PDP8 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(pdp8 + SOURCES + pdp8_cpu.c + pdp8_clk.c + pdp8_df.c + pdp8_dt.c + pdp8_lp.c + pdp8_mt.c + pdp8_pt.c + pdp8_rf.c + pdp8_rk.c + pdp8_rx.c + pdp8_sys.c + pdp8_tt.c + pdp8_ttx.c + pdp8_rl.c + pdp8_tsc.c + pdp8_td.c + pdp8_ct.c + pdp8_fpp.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL PDP8 + PKG_FAMILY decpdp_family + TEST pdp8) diff --git a/PDQ-3/CMakeLists.txt b/PDQ-3/CMakeLists.txt new file mode 100644 index 00000000..50c32b3a --- /dev/null +++ b/PDQ-3/CMakeLists.txt @@ -0,0 +1,29 @@ +## PDQ-3 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(pdq3 + SOURCES + pdq3_cpu.c + pdq3_sys.c + pdq3_stddev.c + pdq3_mem.c + pdq3_debug.c + pdq3_fdc.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL PDQ-3 + PKG_FAMILY experimental + TEST pdq3) diff --git a/README-CMake.md b/README-CMake.md new file mode 100644 index 00000000..0e5a0c0d --- /dev/null +++ b/README-CMake.md @@ -0,0 +1,1533 @@ +# Build `simh` using CMake + + +- [Build `simh` using CMake](#build-simh-using-cmake) + - [Why CMake?](#why-cmake) + - [Before You Begin Building...](#before-you-begin-building) + - [Toolchains and Tools](#toolchains-and-tools) + - [Ninja: "file recompation: Permission denied"](#ninja-file-recompation-permission-denied) + - [Windows XP-compatible/Server 2003 binaries](#windows-xp-compatibleserver-2003-binaries) + - [Feature Libraries](#feature-libraries) + - [Linux, macOS and MinGW-w64](#linux-macos-and-mingw-w64) + - [Windows: "Legacy" superbuild or `vcpkg`](#windows-legacy-superbuild-or-vcpkg) + - [CMake Directory Structure](#cmake-directory-structure) + - [Building the simulators](#building-the-simulators) + - [CMake Builder Scripts](#cmake-builder-scripts) + - [CMake Command Line](#cmake-command-line) + - [Create a build directory](#create-a-build-directory) + - [Linux/Unix/Unix-like/macOS/MinGW-w64 walkthrough](#linuxunixunix-likemacosmingw-w64-walkthrough) + - [Windows PowerShell walkthrough](#windows-powershell-walkthrough) + - [Changing the Compiler](#changing-the-compiler) + - [Configuration Options](#configuration-options) + - [`RELEASE_LTO` static code checks](#release_lto-static-code-checks) + - [`cppcheck` static code checks](#cppcheck-static-code-checks) + - [Visual Studio-Only Development](#visual-studio-only-development) + - [Quirks](#quirks) + - [VS 2022 and 2019 Walkthrough](#vs-2022-and-2019-walkthrough) + - [XP-compatible Build via the VS2019 and VS2022 IDEs](#xp-compatible-build-via-the-vs2019-and-vs2022-ides) + - [`CMake` Generators](#cmake-generators) + - [Simulator Developer Notes](#simulator-developer-notes) + - [How to compile a simulator: `add_simulator`](#how-to-compile-a-simulator-add_simulator) + - [Simulator "core" libraries](#simulator-core-libraries) + - [`add_simulator` Reference](#add_simulator-reference) + - [Adding a new simulator](#adding-a-new-simulator) + - [Regenerating `CMakeLists.txt` from the `makefile`](#regenerating-cmakeliststxt-from-the-makefile) + + +## Why CMake? + +[CMake][cmake] is a cross-platform meta-build system that provides similar +functionality to GNU _autotools_ within a more integrated and platform-agnostic +framework. A sample of the supported build environments include: + + - Unix Makefiles + - [MinGW Makefiles][mingw64] + - [Ninja][ninja] + - macOS XCode + - MS Visual Studio solutions (2015, 2017, 2019, 2022) + - IDE build wrappers ([Sublime Text][sublime] and [CodeBlocks][codeblocks]) + +Making the Windows build process less complex by automatically downloading, +building and installing dependency feature libraries, and consistent cross +platform support were the initial motivations behind a [CMake][cmake]-based +build infrastructure. Since then, that motivation expanded to supporting a wider +variety of platforms and compiler combinations, streamlining the overall compile +process, enhanced IDE integration and SIMH packaging. + +## Before You Begin Building... + +### Toolchains and Tools + +Before you begin building the simulators, you need the following: + +- A C/C++ compiler toolchain. + + - _GNU C Compiler (gcc)_: `gcc` is the default compiler for Linux and + Unix/Unix-like platforms. It can also be used for [Mingw-w64][mingw64]-based + builds on Windows. + + - _Microsoft Visual C/C++_: Visual Studio 2022, 2019, 2017 and 2015 are + supported. The [appveyor CI/CD][appveyor] pipeline builds using these four + Microsoft toolchains in _Release_ and _Debug_ configurations. + + - _VS 2022_: The Community Edition can be downloaded from the + [Microsoft Visual Studio Community][vs_community] page. + + - _VS 2019 Community Edition, VS 2017 and 2015_: + [Microsoft's older Visual Studio Releases page][older_vs_community] + hosts the installers for these previous releases. + + - _CLang/LLVM_: `clang` is the default compiler on MacOS. To use `clang` on + Linux/Unix-like operating systems, [CMake][cmake] needs to be invoked + manually (see [here](#cmake-command-line).) + + Success reports for additional platforms not listed are happily accepted along + with patches to the [CMake][cmake] infrastructure to ensure future support. + +- [CMake][cmake] version 3.14 or newer. + + - Linux: Install `cmake` using your distribution's package manager (e.g. `apt`, + `pacman`, `rpm`, ...) + + apt: `sudo apt install cmake cmake-data` + + pacman: `sudo pacman install cmake` + + - macOS: Install `cmake` using your preferred external package management + system, such as [Homebrew][homebrew] or [MacPorts][macports]. + + Homebrew: `brew install cmake extra-cmake-modules` + + MacPorts: `sudo port install cmake` + + - Windows: + + - _Visual Studio IDE, Developer command or PowerShell console windows_: No + additional software installation needed. Microsoft provides `cmake` that + can be invoked from the command prompt or from within the VS IDE. + Microsoft has bundled various version of `cmake` into Visual Studio since + VS 2015. + + - Otherwise, install `cmake` using your preferred Windows software package + manager, such as [Chocolatey][chocolatey] or [Scoop][scoop]. You can also + [download and install the `cmake` binary distribution][cmake_downloads] + directly. + +- The [Git source control system][gitscm]. + + - Linux: Install `git` using your distribution's package manager (e.g. `apt`, + `pacman`, `rpm`, ...) + + apt: `sudo apt install git` + + pacman: `sudo pacman install git` + + - macOS: Install `git` using your preferred external package management + system, such as [Homebrew][homebrew] or [MacPorts][macports] + + Homebrew: `brew install git` + + MacPorts: `sudo port install git` + + - Windows: + + [Git][gitscm] is needed to apply patches to [dependency feature + libraries](#feature-libraries) when building those libraries. + + - _Visual Studio IDE_: [Git][gitscm] is available via the Visual Studio IDE. + If you do all of your simulator development from within the VS IDE, no + additional software needs to be installed. + + - _Visual Studio Developer command or PowerShell console windows_: Unlike + `cmake`, `git`'s location is not added to `PATH` or `$env:PATH`. Use the + VS IDE for `git`-related tasks (add, commit, branch, push, pull, etc.) + + - Otherwise, install `git` using your preferred Windows software package + manager, such as [Chocolatey][chocolatey] or [Scoop][scoop]. You can also + [download and install the `git` client][gitscm_downloads] directly. + +- GNU Make: + + - Required for Linux and macOS. Consult your appropriate package manager to + install `make` if it is not already installed. + + - MinGW-w64 uses a version of GNU Make named `mingw32-make`. See the MinGW-W64 + notes below under "Feature Libraries." + +- Ninja: + + [Ninja][ninja] is an optional, but useful/faster parallel build alternative to + Unix Makefiles and Visual Studio's `msbuild`. + + +#### Ninja: "file recompation: Permission denied" + +This is a long-standing issue with [Ninja][ninja] on Windows when `ninja` is +recursively invoked. You are very likely to encounter this error message when +you build dependency feature libraries from a [builder script](#cmake-builder-scripts), +[`cmake` on the command line](#cmake-command-line) and +[from inside the Visual Studio IDE](#visual-studio-only-development). + +This error message will halt the build process. It is easy to work around by +restarting the build process. + +#### Windows XP-compatible/Server 2003 binaries + +Microsoft has deprecated XP tool support and it WILL eventually disappear in a +future Visual Studio release. Windows XP itself is well beyond End of Lifetime +support, with extended support having ended on April 8, 2014. + +You should only install this esoterica if you absolutely have a driving need to +do so. The Continuous Integration/Continuous Deployment (CI/CD) pipelines will +produce XP-compatible binaries. If you need XP-compatible binaries, use the +CI/CD artifacts. + +If you absolutely, positively need to build XP-compatible binaries, the steps +for VS 2022 and VS 2019 are essentially the same. If you use the [CMake command line](#cmake-command-line), +you will have to ensure that you add `-A Win32 -T v141_xp` to `cmake`'s configuration arguments +to select a 32-bit target architecture and the `v141_xp` toolkit. + +_VS2022_: Install the `v141_xp` tools + +Start the Visual Studio Installler, whether this is a new VS2022 install or +modifying an existing installation. + +- New install + - In the "Workloads" pane, check "Desktop development with C++" workload's + checkbox, if not already checked. + - Click on the item labeled "Individual components" + - In the "Individual components" pane: + - Enter "XP" in the "Search components (Ctrl-Q)" field. + - Locate the "Compilers, build tools and runtimes" heading + - Select "C++ for Windows XP Support for VS 2017 (v141) tools [Deprecated]" checkbox. + - Continue to customize your VS 2022 installation as needed. + - Click on "Install" in the lower right hand corner + +- Modifying an existing VS2022 installation + - Click on the Visual Studio 2022 `Modify` button. + - In the "Modifying --" window, click on "Individual Components" + - Click on the item labeled "Individual components" + - In the "Individual components" pane: + - Enter "XP" in the "Search components (Ctrl-Q)" field. + - Locate the "Compilers, build tools and runtimes" heading + - Select "C++ for Windows XP Support for VS 2017 (v141) tools [Deprecated]" checkbox. + - Continue to customize your VS 2022 installation as needed. + - Click on the "Modify" button in the lower right corner of the Window. + +VS 2022 can build XP-compatible binaries via the [`cmake-builder` scripts](#cmake-builder-scripts), +the [command line](#cmake-command-line) or [via the IDE](#xp-compatible-build-via-the-vs2019-and-vs2022-ides). + +_VS2019_: Install the `v141_xp` tools. + +Start the Visual Studio Installler, whether this is a new VS2019 install or +modifying an existing installation. + +- New installation: Follow the VS 2022 "New install" instructions. The steps are + the same. + +- Modifying an existing VS 2019 installation: + - Click on the Visual Studio 2019 `Modify` button. + - Follow the remaining VS 2022 modification steps, starting with the "In the + 'Modifying --' window, ..." step. + - Instead of "Continue to customize your VS 2022 installation as needed", continue + to customize your VS 2019 installation as needed. + +VS 2019 can build XP-compatible binaries via the [`cmake-builder` scripts](#cmake-builder-scripts), +the [command line](#cmake-command-line) or [via the IDE](#xp-compatible-build-via-the-vs2019-and-vs2022-ides). + +_VS2017_: There are two requirements that need to be satisfied: + +- `CMake` version 3.14 or higher. The `CMake` distributed with VS 2017 is + version 3.12. + + - You will need to install a newer version of `CMake` (see above + for download links.) + - You will also need to ensure that the directory to the updated `cmake.exe` is on + the front of your `PATH` (`cmd`) or `env:PATH` (`PowerShell`). If you are + unsure what this means, do not proceed further. + +- Ensure that the `v141_xp` toolkit is installed. Installation instructions + can be found [by following this link to the Stackoverflow question's solution.][v141_xp]. + +VS 2017 can build XP-compatible binaries via the [`cmake-builder` scripts](#cmake-builder-scripts) or +the [command line](#cmake-command-line). + +### Feature Libraries + +All SIMH features are enabled by default. `CMake` only disables features +when the underlying support headers and libraries are not detected or the +feature is specifically disabled at `cmake` configuration time. + +Available features are PCAP, TUN/TAP and VDE networking, SDL2 graphics, SDL2 +TrueType font rendering, and simulator window snapshot support. Note that some +of these features are platform specific. For example, TUN/TAP and VDE networking +are not available on Windows platforms, whereas `cmake` tries to detect the +TUN/TAP header file on Linux and macOS, and VDE is an optionally installed +package on Linux and macOS. + +#### Linux, macOS and MinGW-w64 + +[Github Actions][open_simh_actions] and [appveyor][appveyor] CI/CD pipelines +execute the `.travis/deps.sh` script to install these feature libraries on Linux +and macOS. `.travis/deps.sh` can also install the requisite toolchains and +feature libraries for and MinGW-64 Win64 native and Universal C Runtime (UCRT) +binaries. + + - Linux apt-based distributions (e.g., Debian, Ubuntu): + + ```bash + $ sudo sh .travis/deps.sh linux + ``` + + - macOS Homebrew: + + ```bash + $ sudo sh .travis/deps.sh osx + ``` + + - MinGW-w64 Win64 console: + + ```bash + $ echo $MSYSTEM + MINGW64 + $ .travis/deps.sh mingw64 + ``` + + - MinGW-w64 UCRT console: + + ```bash + $ echo $MSYSTEM + UCRT64 + $ .travis/deps.sh ucrt64 + ``` + +#### Windows: "Legacy" superbuild or `vcpkg` + +The SIMH CMake infrastructure has two distinct feature library dependency +strategies: the _"legacy"_ superbuild and `vcpkg`. The principal differences +between the two strategies are: + + 1. _"legacy"_ can produce Windows XP-compatible executables. + + 2. `vcpkg` has robust compiler support for MS Visual Studio compilers. Using + GCC or Clang with vcpkg is a work-in-progress. + + 3. `vcpkg` has a larger open source ecosystem and better long term support + outlook[^1]. + + 4. _"legacy"_ installs the minimal dependency features necessary to avoid + becoming its own "ports" system (which is what `vcpkg` provides.) For + example, _"legacy"_ does not install `bzip2` as a `libpng` subdependency, + which limits the compression methods available to `libpng` when capturing + screenshots. + + 5. `vcpkg` installs more subdependencies, potentially increasing + functionality. Continuing `libpng` as the example, `vcpkg` will install + `bzip2` as a subdependency, which adds compression methods to `libpng` when + capturing simulator screenshots. `vcpkg` also installs the Harfbuzz text + shaper as a Freetype subdependency. + + 6. _"legacy"_ compiles the dependency libraries as part of the overall + compile/build process. + + 7. `vcpkg` compiles and installs dependencies during the CMake configuration + step, which makes the configuration process longer. + +Setup and Usage: + +- _"legacy"_ superbuild + + This is the default dependency feature library build strategy. It will + download, compile and install the minimal feature libraries necessary to + support the SIMH simulators: `zlib`, `libpng`, `pcre` (version 1, not + PCRE2), `freetype`, `SDL2` and `SDL_ttf`. The CMake configuration process + generates a _superbuild_ that installs the dependencies under the + `cmake/dependencies` subdirectory tree. Once the dependency feature + libraries finish building successfully, the _superbuild_ invokes CMake to + reconfigure SIMH to use these newly installed dependencies. + +- [`vcpkg`](https://vcpkg.io) + + Simply set the `VCPKG_ROOT` environment variable to use the `vcpkg` strategy. + `vcpkg` operates in [Manifest mode][vcpkg_manifest]; refer to the `vcpkg.json` + manifest file. + + The default platform triplets for the Visual Studio compilers are + `x86-windows-static` and `x64-windows-static`, depending on the architecture + flag passed to CMake. + + The `x64-mingw-dynamic` triplet is known to work from within a MinGW-w64 + console/terminal window using the GCC compiler. + + If you haven't git-cloned `vcpkg`, `git clone vcpkg` somewhere outside of the + SIMH source tree. For example, you could choose to clone `vcpkg` in the + directory above `open-simh`: + + ```powershell + PS C:\...\open-simh> pwd + C:\...\open-simh + PS C:\...\open-simh> cd .. + PS C:\...> git clone https://github.com/Microsoft/vcpkg.git + PS C:\...> cd vcpkg + PS C:\...\vcpkg> .\vcpkg\bootstrap-vcpkg.bat + PS C:\...\vcpkg> cd ..\open-simh + PS C:\...\open-simh> + ``` + Then set the `VCPKG_ROOT` environment variable to the `vcpkg` installaton directory. + +[^1]: `vcpkg` does not support the `v141_xp` toolkit required to compile Windows +XP binaries. Windows XP is a target platform that SIMH can hopefully deprecate +in the future. For the time being, Windows XP is a target platform that is part +of the CI/CD pipelines and requires the _"legacy"_ superbuild strategy. + + +### CMake Directory Structure + +The directory structure below is a guide to where to find things and where to +look for things, such as simulator executables. + +``` +simh # Top-level SIMH source directory ++-- CMakeLists.txt # Top-level CMake configuration file ++-- BIN # Simulator executables (note 1) +| +-- Debug +| +-- Release +| +-- Win32 +| +-- Debug +| +-- Release ++-- cmake # CMake modules and build subdirectories +| +-- build-vs2022 # Build directory for VS-2022 (note 2) +| +-- build-vs2019 # Build directory for VS-2019 (note 2) +| +-- build-vs2017 # Build directory for VS-2017 (note 2) +| +-- build-vs2017-xp # Build directory for VS-2017 v141_xp toolkit (note 2) +| +-- build-vs2015 # Build directory for VS-2015 (note 2) +| +-- build-unix # Build directory for Unix Makefiles (note 2) +| +-- build-ninja # Build directory for Ninja builder (note 2) +| +-- dependencies # Install subdirectory for Windows dependency libraries +| | +-- Windows-10-MSVC-19.34 +| | | |... # Feature library subdirectory for Windows legacy +| | | |... # dependency superbuilds (note 3) +|... ++-- out # Visual Studio build directories (note 4) +| +-- build +| +-- install ++-- 3b2 +| +-- CMakeLists.txt # 3b2 simulator CMake configuration file ++-- alpha +| +-- CMakeLists.txt # alpha simulator CMake configuration file +|... ++-- VAX +| +-- CMakeLists.txt # VAX simulators family CMake configuration file +``` + +Notes: +1. The `BIN` directory is where CMake directs the underlying build system to + place SIMH simulator executables. The `BIN` directory's structure varies, + depending on the underlying build system. + - Single configuration builders (`make`, `ninja`): Simulators executables + will appear directly underneath the `BIN` directory. + - Multi-configuration builders (`msbuild`, `xcodebuild`): The simulator + executables will appear underneath individual configuration subdirectories + ("Debug" and "Release"). + - The Windows platform has its `Win32` subdirectory. +2. The `cmake-builder.ps1` and `cmake-builder.sh` scripts create the + `cmake/build-*` subdirectories as needed. +3. `Windows-10-MSVC-19.34` is an example feature library subdirectory created as + the installation area for VS 2022-built dependencies on Windows. Linux, + macOS and MinGW-w64 do not build feature libraries because those platforms install + feature libraries via their respective package managers. +4. The `out` subdirectory is the default build subdirectory hierarchy when + directly building the simulator suite using the Visual Studio IDE. + + +## Building the simulators + +The basic workflow for building the `simh` simulator suite is: configure, build, +test and install. There are two principal ways of executing this workflow: via +the `cmake/cmake-builder.sh` or `cmake/cmake-builder.ps1` scripts or manually +invoking `cmake` directly. For Visual Studio users, the simulators can be build +entirely from within the VS IDE. + +### CMake Builder Scripts + +Building the simulator suite via the build scripts is simply a matter of +following the appropriate script below. If you are a build-from-source SIMH +user, this is all you need to do. The [Github Actions][open_simh_actions] and +the [appveyor] CI/CD pipelines execute these scripts. + +- Linux/Unix-lib/macOS/MinGW-w64: + + ```bash + # Clone the open-simh repository, if not already done: + $ git clone https://github.com/open-simh/simh.git + $ cd simh + + # Install feature dependency libraries (use "osx" instead of "linux" + # on macOS with HomeBrew.) + $ sh .travis/deps.sh linux + + # Configure cmake to generate Unix Makefiles, compile the simulators + # using the 'Release' configuration inside the cmake/build-unix build + # directory: + $ cmake/cmake-builder.sh + ``` + +- Windows PowerShell: + + ```powershell + # Clone the open-simh repository, if not already done: + PS C:\...\open-simh> git clone https://github.com/open-simh/simh.git + PS C:\...\open-simh> cd simh + + # VS 2022 default build in Release configuration. + # + # Build directory is cmake\build-vs2022. Will also perform a superbuild + # the first time to build the dependency feature libraries for VS 2022: + PS C:\...\open-simh> cmake\cmake-builder.ps1 + ``` + +When the scripts complete, the simulators will be copied in the top-level SIMH +`BIN` directory. Alternatively, you can navigate to the desired simulator +binary's subdirectory and execute the simulator from inside the `cmake/build-*` +subdirectories. Refer to the [directory structure](#cmake-directory-structure) +notes, above. + +Both builder scripts provide options to change the build tool, configuration and +options. You should add the `--clean` flag to clean the build subdirectory +before rebuilding with a different configuration or when you change options +e.g., switching from a `Release` to a `Debug` build or building without network +or video support. + +- Linux/Unix-lib/macOS/MinGW-w64: + + ```bash + # Rebuild with the Debug configuration. Clean the Release configuration + # out of the build directory before rebuilding: + $ cmake/cmake-builder.sh --config Debug --clean + + # Use Ninja instead of Unix Makefiles in the Release configuration. + # Build directory is cmake/build-ninja: + $ cmake/cmake-builder.sh --flavor ninja + + # List the supported command line flags: + $ cmake/cmake-builder.sh --help + Configure and build simh simulators on Linux and *nix-like platforms. + + Subdirectories: + cmake/build-unix: Makefile-based build simulators + cmake/build-ninja: Ninja build-based simulators + + Options: + -------- + --clean (-x) Remove the build subdirectory + --generate (-g) Generate the build environment, don't compile/build + --regenerate (-r) Regenerate the build environment from scratch. + --parallel (-p) Enable build parallelism (parallel builds) + --nonetwork Build simulators without network support + --novideo Build simulators without video support + --notest Do not execute 'ctest' test cases + --noinstall Do not install SIMH simulators. + --testonly Do not build, execute the 'ctest' test cases + --installonly Do not build, install the SIMH simulators + + --flavor (-f) Specifies the build flavor. Valid flavors are: + unix + ninja + xcode + xcode-universal + msys + msys2 + mingw + ucrt + --config (-c) Specifies the build configuration: 'Release' or 'Debug' + + --target Build a specific simulator (e.g., pdp11, vax, ...) + --lto Enable Link Time Optimization (LTO) in Release builds + --debugWall Enable maximal warnings in Debug builds + --cppcheck Enable cppcheck static code analysis rules + + --cpack_suffix Specify CPack's packaging suffix, e.g., "ubuntu-22.04" + to produce the "simh-4.0.0-ubuntu-22.04.deb" Debian + package. + + --verbose Turn on verbose build output + + --help (-h) Print this help. + ``` + + +- Windows PowerShell: + + ```powershell + # Use VS 2017 toolchain, Debug configuration. Build directory is + # cmake\build-vs2017. Will also perform a superbuild the first time + # to build the dependency feature libraries for VS 2017: + PS C:\...\open-simh> cmake\cmake-builder.ps1 -flavor vs2017 -config Debug + + # List the supported command line flags: + PS C:\...\open-simh> Get-Help -deatailed cmake\cmake-builder.ps1 + + NAME + C:\Users\bsm21317\play\open-simh\cmake\cmake-builder.ps1 + + SYNOPSIS + Configure and build SIMH's dependencies and simulators using the Microsoft Visual + Studio C compiler or MinGW-W64-based gcc compiler. + + + SYNTAX + C:\Users\bsm21317\play\open-simh\cmake\cmake-builder.ps1 [[-flavor] ] [[-config] ] [[-cpack_suffix] ] [[-target] ] + [-clean] [-help] [-nonetwork] [-novideo] [-notest] [-noinstall] [-parallel] [-generate] [-regenerate] [-testonly] [-installOnly] [-windeprecation] + [-package] [-lto] [-debugWall] [-cppcheck] [] + + + DESCRIPTION + This script executes the three (3) phases of building the entire suite of SIMH + simulators using the CMake meta-build tool. The phases are: + + 1. Configure and generate the build environment selected by '-flavor' option. + 2. Build missing runtime dependencies and the simulator suite with the compiler + configuration selected by the '-config' option. The "Release" configuration + generates optimized executables; the "Debug" configuration generates + development executables with debugger information. + 3. Test the simulators + + There is an install phase that can be invoked separately as part of the SIMH + packaging process. + + The test and install phases can be enabled or disabled by the appropriate command line + flag (e.g., '-noInstall', '-noTest', '-testOnly', '-installOnly'.) + + Build environment and artifact locations: + ----------------------------------------- + cmake/build-vs* MSVC build products and artifacts + cmake/build-mingw MinGW-W64 products and artifacts + cmake/build-ninja Ninja builder products and artifacts + + + PARAMETERS + -flavor + The build environment's "flavor" that determines which CMake generator is used + to create all of the build machinery to compile the SIMH simulator suite + and the target compiler. + + Supported flavors: + ------------------ + vs2022 Visual Studio 2022 (default) + vs2022-xp Visual Studio 2022 XP compat + vs2019 Visual Studio 2019 + vs2019-xp Visual Studio 2019 XP compat + vs2017 Visual Studio 2017 + vs2017-xp Visual Studio 2017 XP compat + vs2015 Visual Studio 2015 + mingw-make MinGW GCC/mingw32-make + mingw-ninja MinGW GCC/ninja + + [...truncated for brevity...] + ``` + + +### CMake Command Line + +This section is targeted to simulator developers and build-from-source users who +want or need fine-grained control over the configure/build/test workflow. + +The thumbnail view of this process for both Linux/macOS/MinGW-w64 and Windows +resembles: + +1. Create a subdirectory where `cmake` will do its work (the build subdirectory.) + +2. `cd` into your `cmake` build subdirectory. + +3. Configure: + ```sh + cmake -G "" -DOPTION=VALUE -DOPTION=VALUE ... -S ${simh_source_directory} + ``` + +4. Build: + ```sh + cmake --build . [build options...] + ``` + +5. Test + ```sh + ctest [ctest options] + ``` + +#### Create a build directory + +Create a build directory that isn't the same as the top-level SIMH source directory: + +```sh +# Clone the open-simh repository, if not already done: +$ git clone https://github.com/open-simh/simh.git +$ cd simh + +# Create a subdirectory where you will build the simulators with +# CMake. .gitignore ignores all directories starting with "build-" +# under the cmake subdirectory (but you don't have to follow this +# convention) +$ mkdir cmake/build-mybuild +$ cd cmake/build-mybuild +``` + +The `CMakeLists.txt` driver will not allow you to configure in the SIMH +top-level source directory. This is a __feature__, not a bug. Separating the +build from the source directory makes it a lot easier to clean up after builds +(just recursively remove the build directory). If you try to configure in the +same directory as the source, you __will__ be reminded to create a separate +build directory._ + + +#### Linux/Unix/Unix-like/macOS/MinGW-w64 walkthrough + +The following walkthrough shows how to manually configure, build, test and +install the simulators from a Linux and macOS terminal window, and a MinGW-w64 +shell console. This walkthrough has all features enabled (video, networking); +[configuration options](#configuration-options) are discussed separately. + +```bash +# Should be in the cmake/build-mybuild subdirectory +$ pwd +/.../simh/cmake/build-mybuild + +# Configure: Generate Unix Makefiles, all options enabled in the +# Release build configuration. +$ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -S ../.. + +# Build all simulators +$ cmake --build . + +# Run the tests with a 5 minute timeout per test (most tests only require 2 +# minutes, SEL32 is a notable exception) +$ ctest --build-config Release --output-on-failure --timeout 300 +``` + +Examples of other things you can do from the command line: + +```sh +# To build a specific simulator, such as b5500, specify the +# target: +$ cmake --build . --target b5500 + +# Since cmake generated a Makefile and we're in the same directory as +# the Makefile, invoke make directly. This what the previous command line +# does. +$ make b5500 + +# Need to reconfigure for a Debug configuration (you just built a Release +# configuration above..)? +$ rm -rf CMakeCache.txt CMakeFiles +$ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -S ../.. -B . + +# Then build via cmake or make... +``` + +To build with Ninja as the CMake generator (or [any other available generator](#cmake-generators)), +from the `simh` top-level source directory: + +```bash +$ mkdir cmake/build-ninja +$ cd cmake/build-ninja +$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S ../.. -B . +$ cmake --build . + +# Build a specific simulator +$ cmake --build . --target 3b2 + +# Build the 3b2 simulator using ninja if we're in the same subdirectory +# as build.ninja: +$ ninja 3b2 + +# Run the tests +$ ctest --build-config Release --output-on-failure --timeout 300 +``` + +#### Windows PowerShell walkthrough + +Windows follows the same pattern as the Linux/macOS/MinGW-w64 walkthrough with +minor changes. The most notable change is the `cmake` build system generator's +name. You will need to choose the generator that corresponds to your installed +Visual Studio version. You also have to specify the build configuration at +compile time when using Visual Studio and `msbuild`. + +```powershell +# Create a Visual Studio build directory +PS> mkdir cmake/build-vstudio +PS> cd cmake/build-vstudio + +# Choose one of the following that corresponds to your installed Visual Studio: +PS> cmake -G "Visual Studio 17 2022" -A Win32 -S ../.. +PS> cmake -G "Visual Studio 16 2019" -A Win32 -S ../.. +PS> cmake -G "Visual Studio 15 2017" -A Win32 -S ../.. +PS> cmake -G "Visual Studio 14 2015" -A Win32 -S ../.. +# If you insist on building XP-compatible binaries, use this configuration +# command line -- you must have the v141_xp toolkit installed. +PS> cmake -G "Visual Studio 17 2022" -A Win32 -T v141_xp -S ../.. +PS> cmake -G "Visual Studio 16 2019" -A Win32 -T v141_xp -S ../.. +PS> cmake -G "Visual Studio 15 2017" -A Win32 -T v141_xp -S ../.. + +# Build +PS> cmake --build . --config Release + +# Test +PS> ctest --build-config Release --output-on-failure --timeout 300 +``` + +The `cmake` Visual Studio generators create the solution file, which you +can open from within Visual Studio. In the above example, look for the `.sln` +file underneath the `cmake/build-vstudio` subdirectory. + +If you have [Ninja][ninja] installed, you can the following as your `cmake` +configure command from inside a Visual Studio developer PowerShell console: + +```powershell +# Configure. +# +# Note that Ninja is a single configuration build system, so you have to +# specify CMAKE_BUILD_TYPE at configuration time: +PS> cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -A Win32 -S ../.. + +# Build. +PS> ninja + +# Test step is the same as above. +``` + +#### Changing the Compiler + +The C and C++ compilers can be manually configured via the `CMAKE_C_COMPILER` +and `CMAKE_CXX_COMPILER` options on the command line. The following example uses +the [Ninja][ninja] build system and the `Clang` compilers: + +```sh +## From inside your build directory: +$ cmake -G Ninja CMAKE_C_COMPILER=clang CMAKE_CXX_COMPILER=clang ... +``` + +#### Configuration Options + +You can enable or disable SIMH simulator suite options on the `cmake` +configuration command line by specifying `-DOPTION=VALUE`. The configuration +options generally mirror those in the original `simh` `makefile`. + +_NOTE:_ `CMake` __aggressively__ caches option values. If you change an option, +you should also remove the `CMakeCache.txt` file and recursively remove the +`CMakeFiles` subdirectory within your build directory. See the examples +following the table. + +| Option | Default | Description | +| -------------------- | ------------------ | ----------- | +| `CMAKE_BUILD_TYPE` | | [`CMake`-defined variable][cmake_build_type] that controls the build's configuration, typical values are _"Release"_ and _"Debug"_. This only needs to be set for single configuration tools, such as `make` and `ninja`. It does not have to be set for multi-configuration tools such as `msbuild` | +| `NO_DEP_BUILD` | platform-specific | Build dependency libraries on Windows (def: enabled), disabled on Linux/macOS, MinGW-w64. | +| `BUILD_SHARED_DEPS` | platform-specific | Build dependencies as shared libraries/DLLs on Windows. Does nothing on Linux/macOS. Disabled by default on Windows to ensure that the simulators link against static libraries. | +| `WITH_ASYNC` | enabled | Asynchronous I/O and threading support. | +| `WITH_REGEX` | enabled | PCRE regular expression support. | +| `WITH_NETWORK` | enabled | Simulator networking support. `WITH_PCAP`, `WITH_SLIRP`, `WITH_VDE` and `WITH_TAP` only have meaning if `WITH_NETWORK` is enabled. | +| `WITH_PCAP` | enabled | libpcap (packet capture) support. | +| `WITH_SLIRP` | enabled | SLIRP UDP network support. | +| `WITH_VDE` | enabled | VDE2/VDE4 network support. | +| `WITH_TAP` | enabled | TAP/TUN device network support. | +| `WITH_VIDEO` | enabled | Simulator display and graphics support | +| `PANDA_LIGHTS` | disabled | KA-10/KI-11 simulator's Panda display. | +| `DONT_USE_ROMS` | disabled | Do not build support ROM header files (i.e., embed the simulator's boot ROMs in the simulator executable.) | +| `ENABLE_CPPCHECK` | disabled | `cppcheck` static code analysis support. | +| `WINAPI_DEPRECATION` | disabled | Show (enable) or mute (disable) WinAPI deprecation warnings. | +| `WARNINGS_FATAL` | disabled | Compiler warnings are fatal errors, e.g. set "-Werror" on `gcc`, "/WX" for MSVC | +| `RELEASE_LTO` | disabled | Use Link-Time Optimization in Release builds, where supported. Normally disabled; the CI/CD builds turn this on to catch additional warnings emitted with higher optimization and LTO. | +| `DEBUG_WALL` | disabled | Turn on maximal warnings for Debug builds, e.g., `-Wall` for GCC/Clang and `/W4` for MSVC. | + +The following table summarizes "enabled" and "disabled" option values on the command line: + +| Option | `CMake` value | +| -------- | ------------- | +| enabled | "On", "1" or "True" | +| disabled | "Off", "0" or "False | + +- Linux/macOS/MinGW-w64 example: + + ```bash + # Remove the CMakeCache.txt file and CMakeFiles subdirectory if you are + # reconfiguring: + $ rm -rf CMakeCache.txt CMakeFiles/ + + # Then (re)configure: + $ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DWITH_NETWORK=Off -DENABLE_CPPCHECK=Off -S ../.. + + # Alteratively, "0" and "Off" are equivalent, as are "1" and "On". + $ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DWITH_NETWORK=0 -DENABLE_CPPCHECK=0 -S ../.. + ``` + +- Windows Powershell example (VS 2022, turn off networking and enable WinAPI deprecation warnings) + + ```powershell + # Remove the CMakeCache.txt file and CMakeFiles subdirectory if you are + # reconfiguring: + PS> remove-item -recurse -force CMakeCache.txt CMakeFiles/ + + # Then (re)configure: + PS> cmake -G "Visual Studio 17 2022" -A Win32 -DWITH_NETWORK=Off -DWINAPI_DEPRECATION=True -S ../.. + ``` + + +### `RELEASE_LTO` static code checks + +_GCC_ and _Clang_ _Release_ builds use the `-O2` optimization level unless the +`RELEASE_LTO` configuration option is set to `True` (or `On` or `1`), e.g.: + +```sh +$ cmake -G Ninja -DRELEASE_LTO:Bool=True ... +``` + +Or using the builder scripts: + +```sh +$ cmake-builder.sh --flavor unix --lto ... +``` +```powershell +PS> cake-builder.ps1 -flavor mingw-unix -lto ... +``` + +Setting `RELEASE_LTO` to `True` does two things: + + 1. It changes the optimization level to `-O3` and turns on link-time + optimization (`-flto`). + 2. It will also turn all compiler warnings into errors (`-Werror`). + +The net effect of turning on `-O3`, `-flto` and `-Werror` is additional static +code checking and any LTO-emitted warnings are fatal compilation errors. + +`RELEASE_LTO` is the default optimization for the appveyor and Github Actions + CI/CD builds. Any warnings will cause these CI/CD builds to fail and must be + corrected before the code is accepted in the SIMH main branch. + + +### `cppcheck` static code checks + +[Cppcheck][cppcheck] is a robust, open source static code checking tool that +provides more in-depth code style analysis to complement the `RELEASE_LTO` +approach. If the `ENABLE_CPPCHECK` option is `True` or `On` and the `cppcheck` +executable is detected on your `PATH`, you will be able to use the `cppcheck` +rule to run the checker over ALL of SIMH's source: + +```sh +## Execute from inside your build directory. +## (note: the command is the same for Windows) +$ cmake --build . --target cppcheck +``` + +This will execute ALL of the static code analysis across ALL simulators and ALL +SIMH core libraries. This will result in VOLUMINOUS output. + +Add the simulator or [core library](#simulator-core-libraries) name to +`_cppcheck` to cppcheck an individual simulator or core library, such as +`pdp8_cppcheck` or `simhcore_cppcheck`. + +The `cppcheck` rule is not currently executed by a CI/CD build. It is an +optional build rule intended to improve overall code quality over the long term. + +### Visual Studio-Only Development + +Microsoft packages `cmake` and `git` in several versions of Visual Studio, which +can be accessed from the IDE and build the SIMH simulator suite solely from +within the IDE. The walkthrough provides directions for VS 2022 and VS 2019. + + +#### Quirks + +- Visual Studio uses the `ninja` build tool by default -- not `msbuild`. You can + change this setting via the "CMake Settings" pane. + +- The Visual Studio CMake build places the intermediate build products and + artifacts in an `out\build` subdirectory relative to the `simh` top level + source directory. Refer to the [directory structure](#cmake-directory-structure) + section. + +- Visual Studio installs the simulator executables under the + `out\install\\bin`, where `` is the current + Visual Studio configuration. This differs from where the CMake build would + normally install executables in a top-level source directory named `BIN`. + +- The initial configuration created by Visual Studio is `x64-Debug`. You will + need to add configurations, such as `x64-Release` or `x86-Debug`, to suit + your needs. The walkthrough will show you how to add the `x64-Release` + configuration. + + +#### VS 2022 and 2019 Walkthrough + +1. Start VS 2022 or VS 2019 and choose "Clone a repository". + + - The repository location is [https://github.com/open-simh/simh.git](https://github.com/open-simh/simh.git) + + - Path: The directory here you want the repository to be cloned. This is the + source directory. + +2. When Visual Studio finishes cloning the repository: + + - Choose `Open>CMake...` from the `File` menu. Open the `CMakeLists.txt` file + in the source directory where `git` just checked out SIMH's source code. + + - The _Output_ pane should switch to "CMake" and display CMake's + configuration output. It should look similar to the following: + + ``` + 1> CMake generation started for default configuration: 'x64-Debug'. + 1> Command line: "C:\WINDOWS\system32\cmd.exe" /c [... long command line ...] + 1> Working directory: C:\...\open-simh-github\out\build\x64-Debug + 1> [CMake] -- The C compiler identification is MSVC 19.33.31630.0 + 1> [CMake] -- The CXX compiler identification is MSVC 19.33.31630.0 + 1> [CMake] -- Detecting C compiler ABI info + 1> [CMake] -- Detecting C compiler ABI info - done + 1> [CMake] -- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.33.31629/bin/Hostx64/x64/cl.exe - skipped + 1> [CMake] -- Detecting C compile features + 1> [CMake] -- Detecting C compile features - done + 1> [CMake] -- Detecting CXX compiler ABI info + 1> [CMake] -- Detecting CXX compiler ABI info - done + 1> [CMake] -- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.33.31629/bin/Hostx64/x64/cl.exe - skipped + 1> [CMake] -- Detecting CXX compile features + 1> [CMake] -- Detecting CXX compile features - done + 1> [CMake] -- CMAKE_BUILD_TYPE is Debug + 1> [CMake] -- CMAKE_MODULE_PATH: C:/.../open-simh-github/cmake + 1> [CMake] -- Setting NO_DEP_BUILD to FALSE, will BUILD missing dependencies + 1> [CMake] -- Creating dependency library directory hierarchy + + [... snipped for brevity ...] + + 1> [CMake] -- + 1> [CMake] -- Configuring done + 1> [CMake] -- Generating done + 1> [CMake] -- Build files have been written to: C:/Users/bsm21317/play/open-simh-gitlab/out/build/x64-Debug + 1> Extracted CMake variables. + 1> Extracted source files and headers. + 1> Extracted code model. + 1> Extracted toolchain configurations. + 1> Extracted includes paths. + 1> CMake generation finished. + ``` + +3. Wait for `CMake` configuration to complete (`CMake generation finished` in the log output.) + +4. If you want or need to add additional build configurations to the default + `x64-Debug`, click on the dropdown arrow next to `x64-Debug` on the IDE's + ribbon. Select the `Manage Configurations...` dropdown item. + + - Click the green "`+`" sign on the left side of the `CMakeSettings.json` + ("CMake Settings") window. + + - Select the configuration that you want to add from the list of supported + configurations. For the purposes of this example, choose `x64-Release` to + add the Win64 Release configuration. + + Other suitable configurations include `x86-Debug` and `x86-Release`. + + - Save `CMakeSettings.json` (`File>Save` or `Ctrl-S`) + + - Visual Studio will reconfigure `cmake` using the current VS configuration. + In this example, it will still be set to `x64-Debug`. Wait for + reconfiguration to finish. + + - When reconfiguration finishes, choose `x64-Release` from the configuration + dropdown. Visual Studio will (again) reconfigure, this time using the + `x64-Release` configuration. And wait for reconfiguration to finish (again.) + +5. Select `Build All` from the `Build` menu, or equivalently chord `Ctrl-Shift-B` + on the keyboard, to start the dependecy feature library superbuild. + + - When all dependency feature libraries have been built, the build process + __will__ unexpectedly terminate with a _"file recompation: Permission + denied"_ error (see [this `ninja` note](#ninja-file-recompation-permission-denied).) + + Choose `Delete Cache and Reconfigure` from the `Project` menu. This will + cause CMake to reconfigure the project and detect the dependency feature + libraries. + + When reconfiguration is complete, choose `Build All` from the `Build` menu, + or equivalently chord `Ctrl-Shift-B` on the keyboard and restart building + the simulator suite. + + Choose `Run CTests for simh` from the `Test` menu to run the simulator suite + tests. + +6. To install the simulators, choose `Install simh` from the `Build` menu. Note + that the VS IDE will install the simulators in `out\build\\install\bin`, + and not the `BIN` directory off the top level SIMH source directory. + + +#### XP-compatible Build via the VS2019 and VS2022 IDEs + +- Ensure that you previously installed [the `v141_xp` tools](#windows-xp-compatibleserver-2003-binaries). +- Follow steps 1-3 [above](#vs-2022-and-2019-walkthrough) +- Add the `x86-Debug` configuration, similar to step 4, with the following + modifications: + + - Click the green "`+`" sign on the left side of the `CMakeSettings.json` + ("CMake Settings") window. + + - Select the `x86-Debug` configuration. + + - Add `-T v141_xp` in the "CMake command arguments" text box. + + - Click on the "Show advanced settings" link. + + - Change the "CMake generator" to "Visual Studio 16 2019" for VS 2019 or + "Visual Studio 17 2022" for VS 2022 from the "CMake generator" dropdown. + + - Save `CMakeSettings.json` (`File>Save` or `Ctrl-S`) + + - Scroll the "CMake Settings" window up until the "Save and generate CMake + cache to load variables" link is visible. Click on this link and allow + Visual Studio to reconfigure `CMake`. + +- Repeat the above steps for the `x86-Release` configuration. + +- Build, test and install as in steps 5 and 6 [above](#vs-2022-and-2019-walkthrough) + + +## `CMake` Generators + +The available list of [CMake][cmake] build system generators is always available via: + +```shell +$ cmake --help +[...] + +Generators + +The following generators are available on this platform (* marks default): +* Visual Studio 17 2022 = Generates Visual Studio 2022 project files. + Use -A option to specify architecture. +* Visual Studio 16 2019 = Generates Visual Studio 2019 project files. + Use -A option to specify architecture. +[...] +``` +## Simulator Developer Notes + + +### How to compile a simulator: `add_simulator` + +Each simulator subdirectory contains a `CMakeLists.txt` file (see [the directory +structure](#cmake-directory-structure).) Each of these simulator +`CMakeLists.txt` contain one or more [`add_simulator`](cmake/add_simulator.cmake) +function calls. For example, the AT&T 3b2 simulator invokes `add_simulator` as: + +```cmake +add_simulator(3b2 + SOURCES + 3b2_cpu.c + 3b2_sys.c + 3b2_rev2_sys.c + 3b2_rev2_mmu.c + 3b2_mau.c + 3b2_rev2_csr.c + 3b2_timer.c + 3b2_stddev.c + 3b2_mem.c + 3b2_iu.c + 3b2_if.c + 3b2_id.c + 3b2_dmac.c + 3b2_io.c + 3b2_ports.c + 3b2_ctc.c + 3b2_ni.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + REV2 + FEATURE_FULL64 + LABEL 3B2 + TEST 3b2) +``` + +`add_simulator` is relatively self explanitory: + +- The first argument is the simulator's executable name: `3b2`. This generates + an executable named `3b2` on Unix platforms or `3b2.exe` on Windows. + +- Argument list keywords: `SOURCES`, `INCLUDES`, `DEFINES`, `LABEL` and `TEST`. + + - `SOURCES`: The source files that comprise the simulator. The file names + are relative to the simulator's source directory. In the `3b2`'s case, + this is relative to the `3B2/` subdirectory where `3B2/CMakeLists.txt` is + located. + + [CMake][cmake] sets the variable `CMAKE_CURRENT_SOURCE_DIR` to the same + directory from which `CMakeLists.txt` is being read. + + - `INCLUDES`: Additional include/header file directories needed by the + simulator, i.e., subdirectories that follow the compiler's `-I` flag). + These subdirectories are relative to the top level `simh` directory. + + It's a good idea to add `${CMAKE_CURRENT_SOURCE_DIR}` to the list of + simulator includes if the simulator uses header files in its own + subdirectory. + + - `DEFINES`: Preprocessor defines needed by the simulator, i.e., values that + follow the compiler's `-D` flags. + + - `LABEL`: The simulator's `ctest` test label to which `add_simulator` will + prepend `simh-`. `ctest` labels group simulators in the same subdirectory, + so it's possible to run an entire simulator group's tests: + + ```sh + # Run all of the 3b2 simulator tests (3b2 and 3b2-700): + $ ctest -L simh-3B2 + ``` + + `add_simulator` names individual simulator tests by concatenating `simh-` + and the executable's name, e.g., `simh-3b2` for the 3b2 simulator and + `simh-3b2-700` for the 3b2/700 simulator. To execute the individual 3b2 + simulator's test: + + ```sh + $ ctest -R simh-3b2 + ``` + + - `TEST`: Some simulators have test scripts that follow the naming + convention `[sim]_test.ini` -- the argument to the `TEST` parameter is the + `[sim]` portion of the test script's name. + +- Option keywords: These determine which of [six (6) simulator core libraries](#simulator-core-libraries) is + linked with the simulator. + + - `FEATURE_INT64`: 64-bit integers, 32-bit pointers + - `FEATURE_FULL64`: 64-bit integers, 64-bit pointers + - `FEATURE_VIDEO`: Simulator video support. + - `FEATURE_DISPLAY`: Video display support. + +- `PKG_FAMILY` option: This option adds the simulator to a package "family" or + simulator packaging group, e.g., "DEC PDP simulators". The default package + family is `default_family` if not specified. + +- `BUILDROMS` option keyword: If the simulator has a boot ROM header file that + is maintained or generated by `BuildROMS`, add this keyword to the + `add_simulator` function call. + + +### Simulator "core" libraries + +The `CMake` build infrastructure avoids repeatedly compiling the simulator +"core" source code. Instead, a simulator "links" with one of six (6) static +libraries that represents the combination of required features: 32/64 bit +support and video: + +| Library | Video | Integer size | Address size | `add_simulator` flags | +| :--------------- | :---: | -----------: | -----------: | :-------------------- | +| simhcore.a | N | 32 | 32 | | +| simhi64.a | N | 64 | 32 | `FEATURE_INT64` | +| simhz64.a | N | 64 | 64 | `FEATURE_FULL64` | +| simhcore_video.a | Y | 32 | 32 | `FEATURE_VIDEO` | +| simhi64_video.a | Y | 64 | 32 | `FEATURE_INT64`, `FEATURE_VIDEO` | +| simhz64_video.a | Y | 64 | 64 | `FEATURE_FULL64`, `FEATURE_VIDEO` | + +Internally, these core libraries are [`CMake` interface libraries][cmake_interface_library] -- when they +are added to a simulator's executable via `target_link_libraries`, the simulator +inherits the public compile and linker flags from the interface library. Thus, each +core library provides a consistent set of preprocessor definitions, header file +directories, linker options, compiler flags appropriate to the desired simulator +support features for network, video and regular expressions. + +## `add_simulator` Reference + +```cmake +add_simulator(simulator_name + SOURCES + ## Source files here. Do not include the top-level + ## 'sim*.c' or 'scp.c' -- those are part of the + ## simulator core libraries. + INCLUDES + ## Places where the compiler should look for additional + ## header files. Always a good idea to include + ## CMAKE_CURRENT_SOURCE_DIR since it's the same as the + ## simulator subdirectory + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + ## Additional preprocessor definitions, if needed. If + ## not needed, leave it out. + + ## If neither FEATURE_INT64 or FEATURE_FULL64 is used, the + ## simulator uses 32-bit integers and addresses. + ## + ## If you define both FEATURE_INT64 and FEATURE_FULL64, + ## FEATURE_INT64 wins. + + ## 64-bit integers, 32-bit addresses + FEATURE_INT64 + ## 64-bit integers, 64-bit addresses + FEATURE_FULL64 + + ## Simulator needs video support + FEATURE_VIDEO + + ## Simulator needs display support (-DUSE_DISPLAY). Use + ## in conjunction with FEATURE_VIDEO + FEATURE_DISPLAY + + ## Packaging "family" (group) to which the simulator belongs, + ## for packagers that support grouping (Windows: NSIS .exe, + ## WIX .msi; macOS) + PKG_FAMILY decpdp_family + + ## CTest label for grouping related simulators (3b2, VAXen, + ## PDP-10) + LABEL 3B2 + + ## [sim] prefix for the simulator's "tests/[sim]_diag.ini" script + TEST 3b2) +``` + +`add_simulator` defines a `CMake` executable target, which can be referenced +via the `simulator_name`. This can be useful if you need to add specific linker +flags, such as increasing the default thread stack size. The IBM 650 simulator +has example code that increases the thread stack size on Windows: + +```cmake +add_simulator(i650 + SOURCES + i650_cpu.c + i650_cdr.c + i650_cdp.c + i650_dsk.c + i650_mt.c + i650_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + FEATURE_INT64 + LABEL I650 + TEST i650) + +if (WIN32) + if (MSVC) + set(I650_STACK_FLAG "/STACK:8388608") + else () + set(I650_STACK_FLAG "-Wl,--stack,8388608") + endif () + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.13") + target_link_options(i650 PUBLIC "${I650_STACK_FLAG}") + else () + set_property(TARGET i650 LINK_FLAGS " ${I650_STACK_FLAG}") + endif () +endif() +``` + +### Adding a new simulator + +1. Create a new subdirectory in the top-level SIMH source directory. + + ```sh + $ mkdir MySimulator + $ cd MySimulator + ``` + +2. Add your source to the `MySimulator` directory. + +3. Create the `CMakeLists.txt` file that invokes `add_simulator`. + +4. Include your new simulator in the `cmake/simh-simulators.cmake` file. + + ```cmake + ## ... + add_subdirectory(VAX) + add_subdirectory(alpha) + add_subdirectory(imlac) + add_subdirectory(sigma) + add_subdirectory(tt2500) + + ## add_subdirectory tells CMake to include MySimulator's CMakeLists.txt. + ## + ## This also adds MySimulator to Visual Studio's projects, and possibly informs + ## other IDEs about the subdirectory. + add_subdirectory(MySimulator) + ``` + +5. Reconfigure your build. Refer to the [CMake command line](#cmake-command-line) + section. + +6. Build and develop. + +### Regenerating `CMakeLists.txt` from the `makefile` + +An alternate development path for new simulators is updating the SIMH `makefile` +in the top-level source directory, then regenerating the simulator suite's +`CMakeLists.txt` via the `cmake/generate.py` Python3 script. This works on both +Linux and Windows. + +_Note:_ The `cmake/generate.py` script is not automatically run by `cmake` when +the `makefile` is newer than the top-level `CMakeLists.txt`. If you have done a +`git pull` and you get undefined symbols when a simulator is linked, the +solution is `cmake/generate.py` to update the affected simulator +`CMakeLists.txt` file. + +```sh +## You have to be in the cmake subdirectory to run the generate.py script +$ cd cmake +# [simh_source] is the absolute path to your top-level SIMH source directory +$ python -m generate +generate.py: Expecting to emit 77 simulators. +generate.py: Looking for makefile, starting in [simh-source]/open-simh/cmake +generate.py: Looking for makefile, trying [simh-source]/open-simh +generate.py: Processing [simh-source]/open-simh/makefile +generate.py: all target pdp1 +generate.py: all target pdp4 +generate.py: all target pdp7 +generate.py: all target pdp8 +generate.py: all target pdp9 +generate.py: all target pdp15 +generate.py: all target pdp11 +generate.py: all target pdp10 +generate.py: all target vax +generate.py: all target microvax3900 +generate.py: all target microvax1 +generate.py: all target rtvax1000 +generate.py: all target microvax2 +generate.py: all target vax730 +generate.py: all target vax750 +generate.py: all target vax780 +generate.py: all target vax8200 +generate.py: all target vax8600 +generate.py: all target besm6 +generate.py: all target microvax2000 +generate.py: all target infoserver100 +generate.py: all target infoserver150vxt +generate.py: all target microvax3100 +generate.py: all target microvax3100e +generate.py: all target vaxstation3100m30 +generate.py: all target vaxstation3100m38 +generate.py: all target vaxstation3100m76 +generate.py: all target vaxstation4000m60 +generate.py: all target microvax3100m80 +generate.py: all target vaxstation4000vlc +generate.py: all target infoserver1000 +generate.py: all target nova +generate.py: all target eclipse +generate.py: all target hp2100 +generate.py: all target hp3000 +generate.py: all target i1401 +generate.py: all target i1620 +generate.py: all target s3 +generate.py: all target altair +generate.py: all target altairz80 +generate.py: all target gri +generate.py: all target i7094 +generate.py: all target ibm1130 +generate.py: all target id16 +generate.py: all target id32 +generate.py: all target sds +generate.py: all target lgp +generate.py: all target h316 +generate.py: all target cdc1700 +generate.py: all target swtp6800mp-a +generate.py: all target swtp6800mp-a2 +generate.py: all target tx-0 +generate.py: all target ssem +generate.py: all target b5500 +generate.py: all target intel-mds +generate.py: all target scelbi +generate.py: all target 3b2 +generate.py: all target 3b2-700 +generate.py: all target i701 +generate.py: all target i704 +generate.py: all target i7010 +generate.py: all target i7070 +generate.py: all target i7080 +generate.py: all target i7090 +generate.py: all target sigma +generate.py: all target uc15 +generate.py: all target pdp10-ka + undefined make macro: KA10_DPY + undefined make macro: KA10_LDFLAGS +generate.py: all target pdp10-ki + undefined make macro: KI10_DPY +generate.py: all target pdp10-kl +generate.py: all target pdp10-ks +generate.py: all target pdp6 + undefined make macro: PDP6_DPY + undefined make macro: PDP6_LDFLAGS +generate.py: all target i650 +generate.py: all target imlac +generate.py: all target tt2500 +generate.py: all target sel32 +generate.py: exp target alpha +generate.py: exp target pdq3 +generate.py: exp target sage +==== writing to [simh-source]/open-simh/3B2/CMakeLists.txt +==== writing to [simh-source]/open-simh/ALTAIR/CMakeLists.txt +==== writing to [simh-source]/open-simh/AltairZ80/CMakeLists.txt +==== writing to [simh-source]/open-simh/B5500/CMakeLists.txt +==== writing to [simh-source]/open-simh/BESM6/CMakeLists.txt +==== writing to [simh-source]/open-simh/CDC1700/CMakeLists.txt +==== writing to [simh-source]/open-simh/GRI/CMakeLists.txt +==== writing to [simh-source]/open-simh/H316/CMakeLists.txt +==== writing to [simh-source]/open-simh/HP2100/CMakeLists.txt +==== writing to [simh-source]/open-simh/HP3000/CMakeLists.txt +==== writing to [simh-source]/open-simh/I1401/CMakeLists.txt +==== writing to [simh-source]/open-simh/I1620/CMakeLists.txt +==== writing to [simh-source]/open-simh/I650/CMakeLists.txt +==== writing to [simh-source]/open-simh/I7000/CMakeLists.txt +==== writing to [simh-source]/open-simh/I7094/CMakeLists.txt +==== writing to [simh-source]/open-simh/Ibm1130/CMakeLists.txt +==== writing to [simh-source]/open-simh/Intel-Systems/Intel-MDS/CMakeLists.txt +==== writing to [simh-source]/open-simh/Intel-Systems/scelbi/CMakeLists.txt +==== writing to [simh-source]/open-simh/Interdata/CMakeLists.txt +==== writing to [simh-source]/open-simh/LGP/CMakeLists.txt +==== writing to [simh-source]/open-simh/NOVA/CMakeLists.txt +==== writing to [simh-source]/open-simh/PDP1/CMakeLists.txt +==== writing to [simh-source]/open-simh/PDP10/CMakeLists.txt +==== writing to [simh-source]/open-simh/PDP11/CMakeLists.txt +==== writing to [simh-source]/open-simh/PDP18B/CMakeLists.txt +==== writing to [simh-source]/open-simh/PDP8/CMakeLists.txt +==== writing to [simh-source]/open-simh/PDQ-3/CMakeLists.txt +==== writing to [simh-source]/open-simh/S3/CMakeLists.txt +==== writing to [simh-source]/open-simh/SAGE/CMakeLists.txt +==== writing to [simh-source]/open-simh/SDS/CMakeLists.txt +==== writing to [simh-source]/open-simh/SEL32/CMakeLists.txt +==== writing to [simh-source]/open-simh/SSEM/CMakeLists.txt +==== writing to [simh-source]/open-simh/TX-0/CMakeLists.txt +==== writing to [simh-source]/open-simh/VAX/CMakeLists.txt +==== writing to [simh-source]/open-simh/alpha/CMakeLists.txt +==== writing to [simh-source]/open-simh/imlac/CMakeLists.txt +==== writing to [simh-source]/open-simh/sigma/CMakeLists.txt +==== writing to [simh-source]/open-simh/swtp6800/swtp6800/CMakeLists.txt +==== writing to [simh-source]/open-simh/tt2500/CMakeLists.txt +==== writing [simh-source]/open-simh/cmake/simh-simulators.cmake +==== writing [simh-source]/open-simh/cmake/simh-packaging.cmake +``` + + +[appveyor]: https://www.appveyor.com/ +[bison]: https://www.gnu.org/software/bison/ +[chocolatey]: https://chocolatey.org/ +[cmake_build_type]: https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html +[cmake_downloads]: https://cmake.org/download/ +[cmake_interface_library]: https://cmake.org/cmake/help/latest/command/add_library.html#id4 +[cmake]: https://cmake.org +[codeblocks]: http://www.codeblocks.org +[coreutils]: https://www.gnu.org/software/coreutils/coreutils.html +[cppcheck]: http://cppcheck.sourceforge.net/ +[flex]: https://github.com/westes/flex +[FreeType]: https://www.freetype.org/ +[gitscm_downloads]: https://git-scm.com/downloads +[gitscm]: https://git-scm.com/ +[homebrew]: https://brew.sh/ +[libpcap]: https://www.tcpdump.org/ +[libpng]: http://www.libpng.org/pub/png/libpng.html +[macports]: https://www.macports.org/ +[mingw64]: https://mingw-w64.org/ +[ninja]: https://ninja-build.org/ +[npcap]: https://nmap.org/npcap/ +[older_vs_community]: https://visualstudio.microsoft.com/vs/older-downloads/ +[open_simh_actions]: https://github.com/open-simh/simh/actions +[pcre2]: https://pcre.org +[pthreads4w]: https://github.com/jwinarske/pthreads4w +[scoop]: https://scoop.sh/ +[SDL2_ttf]: https://www.libsdl.org/projects/SDL_ttf/ +[SDL2]: https://www.libsdl.org/ +[sublime]: https://www.sublimetext.com +[util-linux]: https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/ +[v141_xp]: https://stackoverflow.com/questions/49516896/how-to-install-build-tools-for-v141-xp-for-vc-2017 +[vcpkg_manifest]: https://learn.microsoft.com/en-us/vcpkg/users/manifests +[vs_community]: https://visualstudio.microsoft.com/vs/community/ +[winflexbison]: https://github.com/lexxmark/winflexbison +[winsdk_download]: https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/ +[zlib]: https://www.zlib.net diff --git a/README.md b/README.md index 5ed30c36..9625e42b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +Github Actions CI/CD status: + + master branch: ![master](https://github.com/bscottm/open-simh/actions/workflows/build.yml/badge.svg) + + cmake branch: ![cmake](https://github.com/bscottm/open-simh/actions/workflows/build.yml/badge.svg?branch=cmake) + # Open SIMH machine simulator This is the codebase of SIMH, a framework and collection of computer system simulators. diff --git a/S3/CMakeLists.txt b/S3/CMakeLists.txt new file mode 100644 index 00000000..ce659ad1 --- /dev/null +++ b/S3/CMakeLists.txt @@ -0,0 +1,29 @@ +## S3 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(s3 + SOURCES + s3_cd.c + s3_cpu.c + s3_disk.c + s3_lp.c + s3_pkb.c + s3_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL S3 + PKG_FAMILY ibm_family + TEST s3) diff --git a/SAGE/CMakeLists.txt b/SAGE/CMakeLists.txt new file mode 100644 index 00000000..5fd745c2 --- /dev/null +++ b/SAGE/CMakeLists.txt @@ -0,0 +1,41 @@ +## SAGE simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(sage + SOURCES + sage_cpu.c + sage_sys.c + sage_stddev.c + sage_cons.c + sage_fd.c + sage_lp.c + m68k_cpu.c + m68k_mem.c + m68k_scp.c + m68k_parse.tab.c + m68k_sys.c + i8251.c + i8253.c + i8255.c + i8259.c + i8272.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + HAVE_INT64 + LABEL SAGE + PKG_FAMILY experimental + TEST sage) diff --git a/SDS/CMakeLists.txt b/SDS/CMakeLists.txt new file mode 100644 index 00000000..740617ba --- /dev/null +++ b/SDS/CMakeLists.txt @@ -0,0 +1,35 @@ +## SDS simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(sds + SOURCES + sds_cpu.c + sds_drm.c + sds_dsk.c + sds_io.c + sds_lp.c + sds_mt.c + sds_mux.c + sds_rad.c + sds_stddev.c + sds_sys.c + sds_cp.c + sds_cr.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL SDS + PKG_FAMILY sds_family + TEST sds) diff --git a/SEL32/CMakeLists.txt b/SEL32/CMakeLists.txt new file mode 100644 index 00000000..0b5ac5fb --- /dev/null +++ b/SEL32/CMakeLists.txt @@ -0,0 +1,43 @@ +## SEL32 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(sel32 + SOURCES + sel32_cpu.c + sel32_sys.c + sel32_chan.c + sel32_iop.c + sel32_com.c + sel32_con.c + sel32_clk.c + sel32_mt.c + sel32_lpr.c + sel32_scfi.c + sel32_fltpt.c + sel32_disk.c + sel32_hsdp.c + sel32_mfp.c + sel32_scsi.c + sel32_ec.c + sel32_ipu.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + USE_INT32 + SEL32 + LABEL SEL32 + PKG_FAMILY gould_family + TEST sel32) diff --git a/SSEM/CMakeLists.txt b/SSEM/CMakeLists.txt new file mode 100644 index 00000000..6276ba61 --- /dev/null +++ b/SSEM/CMakeLists.txt @@ -0,0 +1,25 @@ +## SSEM simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(ssem + SOURCES + ssem_cpu.c + ssem_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL SSEM + PKG_FAMILY default_family + TEST ssem) diff --git a/TX-0/CMakeLists.txt b/TX-0/CMakeLists.txt new file mode 100644 index 00000000..d7123cd8 --- /dev/null +++ b/TX-0/CMakeLists.txt @@ -0,0 +1,30 @@ +## TX-0 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(tx-0 + SOURCES + tx0_cpu.c + tx0_dpy.c + tx0_stddev.c + tx0_sys.c + tx0_sys_orig.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + FEATURE_VIDEO + FEATURE_DISPLAY + LABEL TX-0 + PKG_FAMILY default_family + TEST tx-0) diff --git a/VAX/CMakeLists.txt b/VAX/CMakeLists.txt new file mode 100644 index 00000000..ab400d42 --- /dev/null +++ b/VAX/CMakeLists.txt @@ -0,0 +1,738 @@ +## VAX simulators +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + + +set(VAX + ${VAXD}/vax_cpu.c + ${VAXD}/vax_cpu1.c + ${VAXD}/vax_fpa.c + ${VAXD}/vax_io.c + ${VAXD}/vax_cis.c + ${VAXD}/vax_octa.c + ${VAXD}/vax_cmode.c + ${VAXD}/vax_mmu.c + ${VAXD}/vax_stddev.c + ${VAXD}/vax_sysdev.c + ${VAXD}/vax_sys.c + ${VAXD}/vax_syscm.c + ${VAXD}/vax_syslist.c + ${VAXD}/vax_vc.c + ${VAXD}/vax_lk.c + ${VAXD}/vax_vs.c + ${VAXD}/vax_2681.c + ${PDP11D}/pdp11_rl.c + ${PDP11D}/pdp11_rq.c + ${PDP11D}/pdp11_ts.c + ${PDP11D}/pdp11_dz.c + ${PDP11D}/pdp11_lp.c + ${PDP11D}/pdp11_tq.c + ${PDP11D}/pdp11_xq.c + ${PDP11D}/pdp11_vh.c + ${PDP11D}/pdp11_cr.c + ${PDP11D}/pdp11_td.c + ${PDP11D}/pdp11_io_lib.c + ${PDP11D}/pdp11_dup.c) + +set(VAX420 + ${VAXD}/vax_cpu.c + ${VAXD}/vax_cpu1.c + ${VAXD}/vax_fpa.c + ${VAXD}/vax_cis.c + ${VAXD}/vax_octa.c + ${VAXD}/vax_cmode.c + ${VAXD}/vax_mmu.c + ${VAXD}/vax_sys.c + ${VAXD}/vax_syscm.c + ${VAXD}/vax_watch.c + ${VAXD}/vax_nar.c + ${VAXD}/vax4xx_stddev.c + ${VAXD}/vax420_sysdev.c + ${VAXD}/vax420_syslist.c + ${VAXD}/vax4xx_dz.c + ${VAXD}/vax4xx_rd.c + ${VAXD}/vax4xx_rz80.c + ${VAXD}/vax_xs.c + ${VAXD}/vax4xx_va.c + ${VAXD}/vax4xx_vc.c + ${VAXD}/vax4xx_ve.c + ${VAXD}/vax_lk.c + ${VAXD}/vax_vs.c + ${VAXD}/vax_gpx.c) + +set(VAX440 + ${VAXD}/vax_cpu.c + ${VAXD}/vax_cpu1.c + ${VAXD}/vax_fpa.c + ${VAXD}/vax_cis.c + ${VAXD}/vax_octa.c + ${VAXD}/vax_cmode.c + ${VAXD}/vax_mmu.c + ${VAXD}/vax_sys.c + ${VAXD}/vax_syscm.c + ${VAXD}/vax_watch.c + ${VAXD}/vax_nar.c + ${VAXD}/vax4xx_stddev.c + ${VAXD}/vax440_sysdev.c + ${VAXD}/vax440_syslist.c + ${VAXD}/vax4xx_dz.c + ${VAXD}/vax_xs.c + ${VAXD}/vax_lk.c + ${VAXD}/vax_vs.c + ${VAXD}/vax4xx_rz94.c) + +set(VAX630 + ${VAXD}/vax_cpu.c + ${VAXD}/vax_cpu1.c + ${VAXD}/vax_fpa.c + ${VAXD}/vax_cis.c + ${VAXD}/vax_octa.c + ${VAXD}/vax_cmode.c + ${VAXD}/vax_mmu.c + ${VAXD}/vax_sys.c + ${VAXD}/vax_syscm.c + ${VAXD}/vax_watch.c + ${VAXD}/vax630_stddev.c + ${VAXD}/vax630_sysdev.c + ${VAXD}/vax630_io.c + ${VAXD}/vax630_syslist.c + ${VAXD}/vax_va.c + ${VAXD}/vax_vc.c + ${VAXD}/vax_lk.c + ${VAXD}/vax_vs.c + ${VAXD}/vax_2681.c + ${VAXD}/vax_gpx.c + ${PDP11D}/pdp11_rl.c + ${PDP11D}/pdp11_rq.c + ${PDP11D}/pdp11_ts.c + ${PDP11D}/pdp11_dz.c + ${PDP11D}/pdp11_lp.c + ${PDP11D}/pdp11_tq.c + ${PDP11D}/pdp11_xq.c + ${PDP11D}/pdp11_vh.c + ${PDP11D}/pdp11_cr.c + ${PDP11D}/pdp11_td.c + ${PDP11D}/pdp11_io_lib.c + ${PDP11D}/pdp11_dup.c) + + +add_simulator(infoserver100 + SOURCES + ${VAX420} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_420 + VAX_411 + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(infoserver1000 + SOURCES + vax_cpu.c + vax_cpu1.c + vax_fpa.c + vax_cis.c + vax_octa.c + vax_cmode.c + vax_mmu.c + vax_sys.c + vax_syscm.c + vax_watch.c + vax_nar.c + vax_xs.c + vax4xx_rz94.c + vax4nn_stddev.c + is1000_sysdev.c + is1000_syslist.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + VM_VAX + IS_1000 + FEATURE_FULL64 + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(infoserver150vxt + SOURCES + ${VAX420} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_420 + VAX_412 + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(microvax1 + SOURCES + vax_cpu.c + vax_cpu1.c + vax_fpa.c + vax_cis.c + vax_octa.c + vax_cmode.c + vax_mmu.c + vax_sys.c + vax_syscm.c + vax610_stddev.c + vax610_sysdev.c + vax610_io.c + vax610_syslist.c + vax610_mem.c + vax_vc.c + vax_lk.c + vax_vs.c + vax_2681.c + ${PDP11D}/pdp11_rl.c + ${PDP11D}/pdp11_rq.c + ${PDP11D}/pdp11_ts.c + ${PDP11D}/pdp11_dz.c + ${PDP11D}/pdp11_lp.c + ${PDP11D}/pdp11_tq.c + ${PDP11D}/pdp11_xq.c + ${PDP11D}/pdp11_vh.c + ${PDP11D}/pdp11_cr.c + ${PDP11D}/pdp11_td.c + ${PDP11D}/pdp11_io_lib.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_610 + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(microvax2 + SOURCES + ${VAX630} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_630 + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(microvax2000 + SOURCES + vax_cpu.c + vax_cpu1.c + vax_fpa.c + vax_cis.c + vax_octa.c + vax_cmode.c + vax_mmu.c + vax_sys.c + vax_syscm.c + vax_watch.c + vax_nar.c + vax4xx_stddev.c + vax410_sysdev.c + vax410_syslist.c + vax4xx_dz.c + vax4xx_rd.c + vax4xx_rz80.c + vax_xs.c + vax4xx_va.c + vax4xx_vc.c + vax_lk.c + vax_vs.c + vax_gpx.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + VM_VAX + VAX_410 + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(microvax3100 + SOURCES + ${VAX420} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_420 + VAX_41A + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(microvax3100e + SOURCES + ${VAX420} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_420 + VAX_41D + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(microvax3100m80 + SOURCES + ${VAX440} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + VM_VAX + VAX_440 + VAX_47 + FEATURE_FULL64 + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(rtvax1000 + SOURCES + ${VAX630} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_620 + FEATURE_FULL64 + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(vax + SOURCES + ${VAX} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +set(vax_binary_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +if (CMAKE_CONFIGURATION_TYPES) + string(APPEND vax_binary_dir "/$") +endif (CMAKE_CONFIGURATION_TYPES) + +add_custom_command(TARGET vax POST_BUILD + COMMAND "${CMAKE_COMMAND}" + -DSRCFILE=vax${CMAKE_EXECUTABLE_SUFFIX} + -DDSTFILE=microvax3900${CMAKE_EXECUTABLE_SUFFIX} + -DWORKING_DIR=${vax_binary_dir} + -P ${CMAKE_SOURCE_DIR}/cmake/file-link-copy.cmake + COMMENT "Symlink vax${CMAKE_EXECUTABLE_SUFFIX} to microvax3900${CMAKE_EXECUTABLE_SUFFIX}" + WORKING_DIRECTORY ${vax_binary_dir}) + +install( + CODE " + execute_process( + COMMAND ${CMAKE_COMMAND} + -DSRCFILE=vax${CMAKE_EXECUTABLE_SUFFIX} + -DDSTFILE=microvax3900${CMAKE_EXECUTABLE_SUFFIX} + -DWORKING_DIR=\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin + -P ${CMAKE_SOURCE_DIR}/cmake/file-link-copy.cmake)" + COMPONENT vax_family) + + +add_simulator(vax730 + SOURCES + vax_cpu.c + vax_cpu1.c + vax_fpa.c + vax_cis.c + vax_octa.c + vax_cmode.c + vax_mmu.c + vax_sys.c + vax_syscm.c + vax730_stddev.c + vax730_sys.c + vax730_mem.c + vax730_uba.c + vax730_rb.c + vax_uw.c + vax730_syslist.c + ${PDP11D}/pdp11_rl.c + ${PDP11D}/pdp11_rq.c + ${PDP11D}/pdp11_ts.c + ${PDP11D}/pdp11_dz.c + ${PDP11D}/pdp11_lp.c + ${PDP11D}/pdp11_tq.c + ${PDP11D}/pdp11_xu.c + ${PDP11D}/pdp11_ry.c + ${PDP11D}/pdp11_cr.c + ${PDP11D}/pdp11_hk.c + ${PDP11D}/pdp11_vh.c + ${PDP11D}/pdp11_dmc.c + ${PDP11D}/pdp11_td.c + ${PDP11D}/pdp11_tc.c + ${PDP11D}/pdp11_rk.c + ${PDP11D}/pdp11_io_lib.c + ${PDP11D}/pdp11_ch.c + ${PDP11D}/pdp11_dup.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_730 + FEATURE_FULL64 + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(vax750 + SOURCES + vax_cpu.c + vax_cpu1.c + vax_fpa.c + vax_cis.c + vax_octa.c + vax_cmode.c + vax_mmu.c + vax_sys.c + vax_syscm.c + vax750_stddev.c + vax750_cmi.c + vax750_mem.c + vax750_uba.c + vax7x0_mba.c + vax_uw.c + vax750_syslist.c + ${PDP11D}/pdp11_rl.c + ${PDP11D}/pdp11_rq.c + ${PDP11D}/pdp11_ts.c + ${PDP11D}/pdp11_dz.c + ${PDP11D}/pdp11_lp.c + ${PDP11D}/pdp11_tq.c + ${PDP11D}/pdp11_xu.c + ${PDP11D}/pdp11_ry.c + ${PDP11D}/pdp11_cr.c + ${PDP11D}/pdp11_hk.c + ${PDP11D}/pdp11_rp.c + ${PDP11D}/pdp11_tu.c + ${PDP11D}/pdp11_vh.c + ${PDP11D}/pdp11_dmc.c + ${PDP11D}/pdp11_dup.c + ${PDP11D}/pdp11_td.c + ${PDP11D}/pdp11_tc.c + ${PDP11D}/pdp11_rk.c + ${PDP11D}/pdp11_io_lib.c + ${PDP11D}/pdp11_ch.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_750 + FEATURE_FULL64 + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(vax780 + SOURCES + vax_cpu.c + vax_cpu1.c + vax_fpa.c + vax_cis.c + vax_octa.c + vax_cmode.c + vax_mmu.c + vax_sys.c + vax_syscm.c + vax780_stddev.c + vax780_sbi.c + vax780_mem.c + vax780_uba.c + vax7x0_mba.c + vax780_fload.c + vax_uw.c + vax780_syslist.c + ${PDP11D}/pdp11_rl.c + ${PDP11D}/pdp11_rq.c + ${PDP11D}/pdp11_ts.c + ${PDP11D}/pdp11_dz.c + ${PDP11D}/pdp11_lp.c + ${PDP11D}/pdp11_tq.c + ${PDP11D}/pdp11_xu.c + ${PDP11D}/pdp11_ry.c + ${PDP11D}/pdp11_cr.c + ${PDP11D}/pdp11_rp.c + ${PDP11D}/pdp11_tu.c + ${PDP11D}/pdp11_hk.c + ${PDP11D}/pdp11_vh.c + ${PDP11D}/pdp11_dmc.c + ${PDP11D}/pdp11_dup.c + ${PDP11D}/pdp11_td.c + ${PDP11D}/pdp11_tc.c + ${PDP11D}/pdp11_rk.c + ${PDP11D}/pdp11_io_lib.c + ${PDP11D}/pdp11_ch.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_780 + FEATURE_FULL64 + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(vax8200 + SOURCES + vax_cpu.c + vax_cpu1.c + vax_fpa.c + vax_cis.c + vax_octa.c + vax_cmode.c + vax_mmu.c + vax_sys.c + vax_syscm.c + vax_watch.c + vax820_stddev.c + vax820_bi.c + vax820_mem.c + vax820_uba.c + vax820_ka.c + vax820_syslist.c + ${PDP11D}/pdp11_rl.c + ${PDP11D}/pdp11_rq.c + ${PDP11D}/pdp11_ts.c + ${PDP11D}/pdp11_dz.c + ${PDP11D}/pdp11_lp.c + ${PDP11D}/pdp11_tq.c + ${PDP11D}/pdp11_xu.c + ${PDP11D}/pdp11_ry.c + ${PDP11D}/pdp11_cr.c + ${PDP11D}/pdp11_hk.c + ${PDP11D}/pdp11_vh.c + ${PDP11D}/pdp11_dmc.c + ${PDP11D}/pdp11_td.c + ${PDP11D}/pdp11_tc.c + ${PDP11D}/pdp11_rk.c + ${PDP11D}/pdp11_io_lib.c + ${PDP11D}/pdp11_ch.c + ${PDP11D}/pdp11_dup.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_820 + FEATURE_FULL64 + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(vax8600 + SOURCES + vax_cpu.c + vax_cpu1.c + vax_fpa.c + vax_cis.c + vax_octa.c + vax_cmode.c + vax_mmu.c + vax_sys.c + vax_syscm.c + vax860_stddev.c + vax860_sbia.c + vax860_abus.c + vax780_uba.c + vax7x0_mba.c + vax860_syslist.c + ${PDP11D}/pdp11_rl.c + ${PDP11D}/pdp11_rq.c + ${PDP11D}/pdp11_ts.c + ${PDP11D}/pdp11_dz.c + ${PDP11D}/pdp11_lp.c + ${PDP11D}/pdp11_tq.c + ${PDP11D}/pdp11_xu.c + ${PDP11D}/pdp11_ry.c + ${PDP11D}/pdp11_cr.c + ${PDP11D}/pdp11_rp.c + ${PDP11D}/pdp11_tu.c + ${PDP11D}/pdp11_hk.c + ${PDP11D}/pdp11_vh.c + ${PDP11D}/pdp11_dmc.c + ${PDP11D}/pdp11_dup.c + ${PDP11D}/pdp11_td.c + ${PDP11D}/pdp11_tc.c + ${PDP11D}/pdp11_rk.c + ${PDP11D}/pdp11_io_lib.c + ${PDP11D}/pdp11_ch.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_860 + FEATURE_FULL64 + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(vaxstation3100m30 + SOURCES + ${VAX420} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_420 + VAX_42A + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(vaxstation3100m38 + SOURCES + ${VAX420} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + ${PDP11D} + DEFINES + VM_VAX + VAX_420 + VAX_42B + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(vaxstation3100m76 + SOURCES + vax_cpu.c + vax_cpu1.c + vax_fpa.c + vax_cis.c + vax_octa.c + vax_cmode.c + vax_mmu.c + vax_sys.c + vax_syscm.c + vax_watch.c + vax_nar.c + vax4xx_stddev.c + vax43_sysdev.c + vax43_syslist.c + vax4xx_dz.c + vax4xx_rz80.c + vax_xs.c + vax4xx_vc.c + vax4xx_ve.c + vax_lk.c + vax_vs.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + VM_VAX + VAX_43 + FEATURE_FULL64 + FEATURE_VIDEO + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(vaxstation4000m60 + SOURCES + ${VAX440} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + VM_VAX + VAX_440 + VAX_46 + FEATURE_FULL64 + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) + +add_simulator(vaxstation4000vlc + SOURCES + ${VAX440} + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + DEFINES + VM_VAX + VAX_440 + VAX_48 + FEATURE_FULL64 + BUILDROMS + LABEL VAX + PKG_FAMILY vax_family + TEST vax-diag) diff --git a/alpha/CMakeLists.txt b/alpha/CMakeLists.txt new file mode 100644 index 00000000..7598baa8 --- /dev/null +++ b/alpha/CMakeLists.txt @@ -0,0 +1,34 @@ +## alpha simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(alpha + SOURCES + alpha_500au_syslist.c + alpha_cpu.c + alpha_ev5_cons.c + alpha_ev5_pal.c + alpha_ev5_tlb.c + alpha_fpi.c + alpha_fpv.c + alpha_io.c + alpha_mmu.c + alpha_sys.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + FEATURE_FULL64 + LABEL alpha + PKG_FAMILY experimental + TEST alpha) diff --git a/appveyor.yml b/appveyor.yml index 8066a766..60e2a909 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,19 +1,161 @@ -platform: - - x86 cache: - - ../windows-build + - cmake\dependencies -> appveyor.yml, **\CMakeLists.txt, cmake\dep-targets.cmake + +## shallow_clone: true +## clone_depth: 50 + +environment: + DIST_DIR: '%APPVEYOR_BUILD_FOLDER%\dist' + CMAKE_DIST_DIR: C:/projects/simh/dist + + matrix: + ##+ + ## The matrix is ordered by relative popularity/priority: + ##- + + - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu + SIMH_BUILD_FLAVOR: ninja + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 + SIMH_BUILD_FLAVOR: vs2022 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + SIMH_BUILD_FLAVOR: vs2019 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + SIMH_BUILD_FLAVOR: vs2017 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 + SIMH_BUILD_FLAVOR: vs2022-xp + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + SIMH_BUILD_FLAVOR: vs2019-xp + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + SIMH_BUILD_FLAVOR: vs2017-xp + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + SIMH_BUILD_FLAVOR: vs2015 + + - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2004 + SIMH_BUILD_FLAVOR: unix + + - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu1604 + SIMH_BUILD_FLAVOR: unix + + ## These images have cmake 3.12, which is too old. Could build if + ## cmake were upgraded in the image in the before_build stanza, but + ## that subverts the purpose of the image. + + # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 + # SIMH_BUILD_FLAVOR: vs2013 + # + # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 + # SIMH_BUILD_FLAVOR: vs2012 + # + # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 + # SIMH_BUILD_FLAVOR: vs2008 + + ## - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 + ## SIMH_BUILD_FLAVOR: mingw + ## MINGW: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0 + + ## Here's how you would build with Ninja. It's going to build the same executables + ## as the MinGW flavor, which is why it's skipped here. + # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + # SIMH_BUILD_FLAVOR: ninja + # MINGW: C:\msys64\mingw32\bin + # + # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + # SIMH_BUILD_FLAVOR: 2017 + # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + # SIMH_BUILD_FLAVOR: 2015 + +matrix: + ## Bail if a job fails, don't start new ones. + fast_finish: true + skip_commits: files: - - doc/* + - 'doc/*' - '**/*.md' - - '**/*.txt' + +configuration: + - Debug + - Release + +build: + parallel: true # enable MSBuild parallel builds + verbosity: minimal + before_build: - "\"C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\vcvarsall.bat\"" + - ps: | + if ($isWindows) { + if (${env:SIMH_BUILD_FLAVOR} -eq "ninja") { choco install ninja; } + if (!(Test-Path -Path cmake\dependencies)) { New-Item -ItemType Directory -Path cmake\dependencies } + } + - sh: | + case "${APPVEYOR_BUILD_WORKER_IMAGE}" in + Ubuntu*) + ## .travis/deps.sh will try to install cmake, but that's not desirable + sudo apt-get update -yqqm + sudo apt-get install -ym pkg-config + sudo apt-get install -ym libpcre3-dev + sudo apt-get install -ym libegl1-mesa-dev libgles2-mesa-dev + sudo apt-get install -ym libsdl2-dev libpcap-dev libvdeplug-dev + sudo apt-get install -ym libsdl2-ttf-dev + sudo apt-get install -ym libedit-dev + ;; + *) + echo "Update before_build for ${APPVEYOR_BUILD_WORKER_IMAGE}" + exit 99 + esac + build_script: - cmd: cd "Visual Studio Projects" & vcbuild /M%NUMBER_OF_PROCESSORS% /useenv /rebuild Simh.sln "Release|Win32" -notifications: - - provider: Email - to: - - Mark@infocomm.com - - lars@nocrew.org - on_build_success: false \ No newline at end of file + # Run the cmake-builder script all the way through: generate, build, test. + - ps: | + if ($isWindows) { + $ErrorActionPreference="Stop" + $WarningPreference="Continue" + if (!([string]::IsNullOrEmpty($env:MINGW))) { $env:PATH=$(@(${env:MINGW}, ${env:PATH}) -join ";"); }; + cmake\cmake-builder.ps1 ` + -flavor ${env:SIMH_BUILD_FLAVOR} ` + -config ${env:CONFIGURATION} ` + -lto -parallel -clean -notest -noinstall -verbose + } + - sh: | + case "${APPVEYOR_BUILD_WORKER_IMAGE}" in + Ubuntu1604) + ## LTO support is either incompletely installed or not installed at all. + LTO= + ;; + *) + LTO="--lto" + ;; + esac + cmake/cmake-builder.sh --flavor ${SIMH_BUILD_FLAVOR} --config ${CONFIGURATION} ${LTO} \ + --verbose --parallel --clean --notest --noinstall + +test_script: + - ps: | + if ($isWindows) { + Write-Output "cmake\cmake-builder.ps1 -testonly -config ${env:CONFIGURATION} -flavor ${env:SIMH_BUILD_FLAVOR}" + cmake\cmake-builder.ps1 -testonly -config ${env:CONFIGURATION} -flavor ${env:SIMH_BUILD_FLAVOR} + } + - sh: | + cmake/cmake-builder.sh --testonly --config ${CONFIGURATION} --flavor ${SIMH_BUILD_FLAVOR} + +##+ +## Don't package artifacts -- only GitHub does this now. +##- +# after_test: +# +# artifacts: +# - path: PACKAGES\*.zip + +# notifications: +# - provider: Email +# to: +# - Mark@infocomm.com +# - lars@nocrew.org +# on_build_success: false diff --git a/cmake/.gitignore b/cmake/.gitignore new file mode 100644 index 00000000..f3fa7485 --- /dev/null +++ b/cmake/.gitignore @@ -0,0 +1,6 @@ +# Ignore captured compiler/build outputs (txt and out files) +*.txt +*.out +__pycache__/ +build-*/ +dependencies/ \ No newline at end of file diff --git a/cmake/CMake-Maintainers.md b/cmake/CMake-Maintainers.md new file mode 100644 index 00000000..786d5bd4 --- /dev/null +++ b/cmake/CMake-Maintainers.md @@ -0,0 +1,582 @@ + +**Table of Contents** + +- [CMake Maintainer Walk-through](#cmake-maintainer-walk-through) + - [Introduction](#introduction) + - [*CMake* Basics](#cmake-basics) + - [`CMAKE_SOURCE_DIR` and `CMAKE_BINARY_DIR`](#cmake_source_dir-and-cmake_binary_dir) + - [Top-level `CMakeLists.txt`](#top-level-cmakeliststxt) + - [Build Configurations](#build-configurations) + - [Code Roadmap](#code-roadmap) + - [`${CMAKE_SOURCE_DIR}/CMakeLists.txt`](#cmake_source_dircmakeliststxt) + - [The `cmake` sub-directory](#the-cmake-sub-directory) + - [`add_simulator.cmake`](#add_simulatorcmake) + - [`find_package` support](#find_package-support) + - [`platform-quirks.cmake`: Platform-specific settings/tweaks](#platform-quirkscmake-platform-specific-settingstweaks) + - [`vcpkg.cmake`: vcpkg package installer/maintainer](#vcpkgcmake-vcpkg-package-installermaintainer) + - [`dep-locate.cmake`, `dep-link.cmake`: Dependency libraries](#dep-locatecmake-dep-linkcmake-dependency-libraries) + - [`simh-simulators.cmake`](#simh-simulatorscmake) + - [`generate.py`: Automagic `makefile` → CMake infrastructure](#generatepy-automagic-makefile--cmake-infrastructure) + - [CPack configuration](#cpack-configuration) + + + +# CMake Maintainer Walk-through + +## Introduction + +This code walk-through is primarily intended for maintainers and developers interested in the +[CMake][cmake] build and packaging environment internals. + +The main idea is to make adding and compiling simulators easy for the simulator developers through a +single *CMake* function, `add_simulator`. All a simulator developer should have to do is create a +simulator `CMakeLists.txt` file, invokes the `add_simulator` function and update the +`cmake/simh-simulators.cmake` file to include the new simulator sub-directory. That's it. + +The remainder of this document explains the *CMake* infrastructure machinery that supports the +`add_simulator` function. + +## *CMake* Basics + +If you are not familiar with *CMake*, *CMake* is a meta-build platform that supports a wide cross section +of operating systems and build systems. Typical *CMake*-based development has four phases: + +- _Configure and generate_: Search for headers, dependency libraries, adjust compiler flags, add defines + and include paths, set up build targets (static, dynamic libraries and executables), setup test case + support and packaging, then generate the build system's input (e.g., a `makefile` for make, solution + hierarchy for Visual Studio, `build.ninja` for Ninja, project files for Mac OS X XCode, etc.) + +- _Build_: Invoke the build system (`make`, `ninja`, `msbuild`, ...) *CMake*'s build mode is a wrapper + around the underlying build system tool. It's perfectly acceptable to change to the build directory and + invoke the build tool directly. + +- _Test_: Execute the test cases using the CTest driver and collect test status (success, failure, failure + output logs.) + +- _Package_: Create installer packages using the CPack utility. + +### `CMAKE_SOURCE_DIR` and `CMAKE_BINARY_DIR` + +*CMake* has two variables that identify the top-level source directory, `CMAKE_SOURCE_DIR`, and the build +artifact directory, `CMAKE_BINARY_DIR`. These two directories should be separate from each other -- you +should not try to create build artifacts in the top-level source directory (this is enforced by the +top-level `CMakeLists.txt` code.) + +### Top-level `CMakeLists.txt` + +The top-level `CMakeLists.txt` file, located in `CMAKE_SOURCE_DIR`, drives the configure/generate +phase. Each simulator sub-directory has its own `CMakeLists.txt` file included by top-level +`CMakeLists.txt`. These per-simulator `CMakeLists.txt` files define one or more simulator executables +along with each executable's simulator-specific defines, include paths and needed SIMH features (i.e., +video support, 64-bit integer, 64-bit address support.) + +### Build Configurations + +*CMake* understands multi-configuration build system tools, notably _msbuild_ and _XCode_, versus single +configuration build system tools, such as _make_ and _ninja_. Multi-configuration build system tools +require an explicit configuration at the build phase, e.g. `--config Release` or `--config Debug` to build +optimized vs. debug simulators. Single configuration build system tools specify `CMAKE_BUILD_TYPE` at the +configure/generate phase. If you need to change the build configuration for a single configuration tool, +you have to reconfigure. Note that if you specify a configuration during the build phase for a single +configuration build system tool, it will be silently ignored. + +The SIMH *CMake* infrastructure has a strong preference for the *Release* and *Debug* build +configurations. The *MinSizeRel* and *RelDbgInfo* configurations are weakly supported; their compile flags +are not altered the way that the Release and Debug configurations are customized. + +## Code Roadmap + +``` +open-simh This is CMAKE_SOURCE_DIR ++-- .github/workflows +| + build.yml GitHub CI/CD driver for push, pull request +| | builds. Uses cmake-builds.yml for CMake builds. +| + cmake-builds.yml Reusable GitHub CI/CD workflow for CMake +| | builds. +| + release.yml GitHub CI/CD driver for packaging and publishing +| releases. Uses cmake-builds.yml to create the +| packaged artifacts (simulators and docs.) +| ++-- CMakeLists.txt Top-level CMake configure/generate driver. ++-- cmake CMake support code +| +-- CMake-Walkthrough.md Documentation. You're reading it. +| +-- FindEDITLINE.cmake find_package support for libeditline +| +-- FindPCAP.cmake find_package support for libpcap +| +-- FindPCRE.cmake find_package support for PCRE +| +-- FindPCRE2.cmake find_package support for PCRE2 +| +-- FindPTW.cmake Platform thread support +| +-- FindVDE.cmake find_package support for VDE networking +| +-- GitHub-release.md Pre-built binary package install instructions +| +-- add_simulator.cmake The add_simulator function, SIMH core libraries +| +-- build-* cmake-builder script output (CMAKE_BINARY_DIR) +| | directories +| +-- build_dep_matrix.cmake Release and Debug build scaffolding for +| | external dependency libraries +| +-- cmake-builder.ps1 PowerShell builder script +| +-- cmake-builder.sh Bash builder script +| +-- cpack-setup.cmake CPack packaging setup code +| +-- dep-link.cmake CMake interface library configuration from +| | previously located dependency libraries +| +-- dep-locate.cmake Dependency library location code, e.g., find +| | PCRE, SDL2, SDL2_ttf, ... +| +-- dependencies External dependency library installation +| | | hierarchy, if building dep. libraries +| | +-- Windows-10-MSVC-19.34 (Example 32-bit Windows 10 dependencies) +| | +-- Windows-10-MSVC-19.34-64 (Example 64-bit Windows 10 dependencies) +| +-- file-link-copy.cmake CMake script to symlink, hard link or copy a +| | file +| +-- fpintrin.cmake Unused. Detects SSE, SSE2 and SSE3. +| +-- generate.py Python script that generates the simulator +| | CMakeLists.txt from the makefile +| +-- git-commit-id.cmake CMake script to update .git-commit-id and +| | .git-commit-id.h +| +-- installer-customizations Installer-specific customization files +| +-- os-features.cmake Operating system feature probes, e.g., -lm +| +-- patches Patches applied to external dependency libs +| +-- platform-quirks.cmake Platform quirks: compiler flags, HomeBrew +| | includes, ... +| +-- pthreads-dep.cmake Detect platform thread support, configure the +| | thread_lib interface library +| +-- simgen generate.py script support +| +-- simh-packaging.cmake Simulator packaging, adds simulators to +| | CPack components (simulator "families") +| +-- simh-simulators.cmake Simulator add_subdirectory includes, variable +| | definitions +| +-- v141_xp_install.ps1 Experimental Powershell script to install XP +| | compatibility support in Visual Studio (unused) +| +-- vcpkg-setup.cmake vcpkg package manager setup code +``` + +## `${CMAKE_SOURCE_DIR}/CMakeLists.txt` + +The top-level `CMakeLists.txt` drives CMake's configure/generate phase, which has the following flow: + +- Initial sanity checks + - Ensure *CMake*'s version is greater or equal to version 3.14. *CMake* will terminate configuration if + the minimum version is not met. + - Check `CMAKE_SOURCE_DIR` and `CMAKE_BINARY_DIR`, terminating with an error message if + `CMAKE_SOURCE_DIR` and `CMAKE_BINARY_DIR` are the same directory. + - If *CMake*'s version is below 3.21, emit a warning that creating installers will be unsuccessful. This + doesn't prevent building simulators. This warning is only emitted once. + - Emit a fatal error message and terminate if Windows XP compatibility was requested via `-T v141_xp` on + the command line and the `VCPKG_ROOT` environment variable is set. + +- Set the SIMH version variables and call the `project` function to initiate project configuration. + +- [Configure `vcpkg`](#vcpkgcmake-vcpkg-package-installermaintainer). + +- Set [GNUInstallDirs][gnuinstalldirs] installation directory layout. + +- If the build system tool only supports a single configuration, such as _make_ and _ninja_, default to a + Release build configuration if `CMAKE_BUILD_TYPE` isn't set. + +- Generate a system identifier, `SIMH_SYSTEM_ID`. + + `SIMH_SYSTEM_ID` is used as a `dependencies` subdirectory name on platforms for which missing external + dependency libraries need to be built (Windows, exclusively.) + +- Define and process options, specified on the command line with `-DFOO=BAR` arguments. + - `NO_DEP_BUILD_OPTVAL`: This is the default value for `NO_DEP_BUILD`. + - If `NO_DEP_BUILD` has a cached value already, leave it alone. + - Initialize `NO_DEP_BUILD_OPTVAL` to `False` so that dependencies are never built. + - When the detected system is Windows and NOT a MinGW variant and NOT using [vcpkg](#vcpkg), + `NO_DEP_BUILD_OPTVAL` is set to `True` so that missing dependencies are built. + - `MAC_UNIVERSAL_OPTVAL`: This is the default value for `MAC_UNIVERSAL`. + - If `MAC_UNIVERSAL` has a cached value already, leave it alone. + - Initialize `MAC_UNIVERSAL_OPTVAL` to `False` unless `MAC_UNIVERSAL` was specified as an option on + the command line. + - This is a placeholder for future work to support macOS universal binaries. + +- Set `CMAKE_INSTALL_PREFIX` to `${CMAKE_SOURCE_DIR}/SIMH-install` as a default installation + destination. Otherwise, a platform-specific prefix such as `/usr/local` might be used and cause + unexpected surprises. + +- Set the default `CMAKE_RUNTIME_OUTPUT_DIRECTORY` value to `SIMH_LEGACY_INSTALL`. `SIMH_LEGACY_INSTALL` + is set to `${CMAKE_SOURCE_DIR}/BIN`, appending `Win32` if on Windows, to emulate the SIMH `makefile`'s + executable output structure. + +- Tweak CMake's library and include search paths so that *CMake* can find the externally built dependency + libraries, if needed. + +- [Deal with platform-specific quirkiness](#platform-quirkscmake-platform-specific-settingstweaks), such + as compiler flags, optimization levels, HomeBrew include and library directories on macOS. + +- Locate dependencies, create and populate the `os_features`, `thread_lib`, `simh_regexp`, `simh_video` + and `simh_network` interface libraries. + - *CMake* interface libraries encapsulate defines, include paths and dynamic/static link libraries as an + integrated package. + - `add_simulator` references the interface libraries via CMake's `target_link_libraries` function, which + adds the interface libary's defines and include paths to the simulator compile flags. + + Note: If the interface library is empty, i.e., nothing was added to it because particular + functionality wasn't found or undesired, the interface library adds nothing to the simulator's compile + flags or link libraries. This permits consistency and simplicity in `add_simulator`'s implementation. + - `os_features` (`os-features.cmake`): Operating-system specific features, such testing whether `-lrt` + contains the definitions for `shm_open`, tests for assorted system headers, adds the `winmm` and + Windows socket libraries on Windows. + + Note: `os-features.cmake` could potentially fold itself into `platform-quirks.cmake` in the future. It + is separate for the time being for functional clarity. + - `thread_lib` (`pthreads-dep.cmake`): Platform threading support. Usually empty for Linux and macOS + platforms, adds the _PThreads4W_ external dependency for Windows native and XP platforms. + - `simh_regexp`: Regular expression support, if the `WITH_REGEX` option is `True`. PCRE is effectively + the only regular expression library that ends up in the `simh_regexp` interface library at the + moment. There is support for PCRE2, but it requires changes to `scp.c` to actually make it useful. + - `simh_video`: Graphics, input controller and sound support, based on [SDL2][libsdl2], if the + `WITH_VIDEO` option is `True`. Empty interface library if `WITH_VIDEO` is `False`. `simh_video` also + pulls in `libpng` and `SDL_ttf`, along with their dependencies. + - `simh_network`: This interface library collects defines and include paths for network support when + *VDE* networking is enabled and used, as well as *TUN* network defines and includes. + +- Output a summary of dependencies and features. + +- If the `NO_DEP_BUILD` option is `True` (which is usually the case) and there are missing dependency + libraries, print a fatal error message with the missing libraries, suggest to the user how they might + fix this (`.travis/deps.sh`) and exit. + +- Initiate a "superbuild" if missing dependency libraries need to be built and `NO_DEP_BUILD` is `False`. + - A superbuild is CMake's terminology for building external software and libraries (see *CMake's* + [ExternalProject module][external_project]). When the superbuild successfully builds the external + projects, it will re-execute the *CMake* configure/generate phase to re-detect them and continue + building the SIMH simulators. + - The superbuild normally happens only once. A superbuild can be reinitiated if the compiler's version + changes or the dependencies subdirectory is cleaned. + +- Add the simulators (`simh-simulators.cmake`) + +- Configure packaging + - `cpack-setup.cmake`: Per-packager configuration, i.e., customizations for the [Nullsoft Scriptable + Install System][nullsoft], macOS installer, Debian `.deb` packager. + - `simh-packaging.cmake`: Define simulator package families (CPack components), add documentation to the + default runtime support component. + +- End of file. Configuration is complete and *CMake* generates the build system's files appropriate to the + specified generator, i.e., `makefile` for Unix Makefiles, `build.ninja` for the Ninja build system, etc. + + +## The `cmake` sub-directory + +### `add_simulator.cmake` + +*add_simulator* is the centerpiece around which the rest of the CMake-based infrastructure revolves. The +basic principle is to make simulator compiles very straightforward with a simple *CMake* function. The +function's full documentation for usage and options are in [README-CMake.md][cmake_readme]. + +`add_simulator.cmake` decomposes into eight (8) sections: + +- Update `${CMAKE_SOURCE_DIR}/.git-commit-id` and `${CMAKE_SOURCE_DIR}/.git-commit-id.h` with the current + Git hash identifier, if it has changed. These files are only rewritten if the hash identifier has + changed, i.e., there has been a new commit. + +- `build_simcore` function: This is the workhorse function that compiles the six (6) simulator core + libraries: `simhcore`, `simhi64`, `simhz64` and their `_video` counterparts. Network support is always + included in the core libraries. Networking is enabled by default, and must be explicitly disabled. + + Each core library includes the `simh_network`, `simh_regexp`, `os_features` and `thread_lib` interface + libraries, which causes the core library to inherit the interface libraries' command line defines, + include directories and link libraries. Consequently, a core library is a single `target_link_library` + unit from *CMake*'s perspective and simplifies `add_simulator`. + + `build_simcore` also adds a `${core_libray}_cppcheck`, e.g., `simhcore_cppcheck`, to execute `cppcheck` + static analysis on the library's source. `cppcheck` rules are only added if the `ENABLE_CPPCHECK` option + is `True` (*CMake* configuration option) and the `cppcheck` executable is available. + +- `simh_executable_template`: Common code used by the `add_simulator` and `add_unit_test` functions to + compile an executable. The basic flow is: + + - `add_executable` to create the simulator's executable target in the build system, add the simulator's + sources to get executable target. + - Set the C dialect to C99, which causes the generator to add the necessary flags to the compile + command line to request the C99 dialect. Note that some compilers can ignore the request. + - Set `${CMAKE_RUNTIME_OUTPUT_DIRECTORY}` to `${SIMH_LEGACY_INSTALL}` to mimic the SIMH `makefile`'s + binary output structure. + - Add extra target compiler flags and linker flags; these flags are usually set or modified in + `platform_quirks.cmake`. + - MINGW and MSVC: Set the console subsystem linker option. + - Add simulator-specific defines and includes, define `USE_DISPLAY` on the command line if video + support requested. + - Add the appropriate SIMH core library to executable's target link library list, i.e., select one of + the six core librarys. + +- `add_simulator`: The simulator developer's "compile this simulator" function. + + - Call `simh_executable_template` to create the simulator executable target. + - Add the simulator executable target to the *CPack* installed executables list. If using *CMake* 3.21 + or later, also add the imported runtime artifacts. These are primarily Windows DLLs, but could also + include macOS shared libraries. + - *CTest* simulator test setup. Each simulator always executes `RegisterSanityCheck`. If the `TEST` + option is passed to `add_simulator` **and** the simulator's `tests` subdirectory and test script + exist, the test script will execute after `RegisterSanityCheck`. + - Create a simulator `cppcheck` static analysis target if the `ENABLE_CPPCHECK` option is `True` and the + `cppcheck` executable exists. + - Add the `DONT_USE_INTERNAL_ROM` to the executable's command line if the `DONT_USE_ROMS` option is + `True`. (Probably could move this earlier to after the call to `simh_executable_template`.) + +- `add_unit_test`: This function is intended for future use to execute non-simulator C-code unit tests, to + potentially subsume SIMH's `testlib` command. It is not currently used. These non-simulator unit tests + are supposed to utilize the [Unity test framework][unity_framework], written in "pure" C. + +- Add the SIMH core support libraries targets the `build_simcore` function. + +- Add the `BuildROMs` executable, add the ROM header files as outputs from `BuildROMs`. Future **FIXME**: + Add the ROM header files as build targets that depend on their respective ROM binary files so that + they're automagically rebuilt. However, there is no corresponding rule or set of rules in the SIMH + `makefile`, which is why this is a **FIXME**. + +- Add the `frontpaneltest` executable. `frontpaneltest` provides its own `main` function, which prevents + it from being linked directly with a SIMH core library, e.g., `simhcore`. It has to be its own special + executable target. + +### `find_package` support + +[`find_package`][find_package] is *CMake*'s functionality to find a package and set variables for compile +defines, includes and link libraries, when found. *CMake* has [a collection][cmake_modules] of +`find_package` modules for well known, commonly used packages. *CMake* searches `${CMAKE_MODULE_PATH}` +for modules outside of its packaged collection; SIMH adds `${CMAKE_SOURCE_DIR}/cmake` to +`${CMAKE_MODULE_PATH}`. + +The `Find.cmake` modules used by SIMH and provided by *CMake* include: + +- ZLIB: The zlib compression library +- Freetype: The Freetype font library +- PNG: The PNG graphics library + +SIMH includes six `find_package` scripts: + +- `FindEDITLINE.cmake`: Locates *libeditline*, adds *termcap* to the linker's library list. Applicable to + non-Windows systems to provide command line history. + +- `FindPCAP.cmake`: Locates the packet capture library's headers. SIMH does not need the `libpcap` packet + capture library; `libpcap` and it's Win32 equivalent are dynamically loaded at run time. The headers are + only needed for `libpcap`'s function prototypes. + +- `FindPCRE.cmake`, `FindPCRE2.cmake`: Locate PCRE and PCRE2 libraries and headers. SIMH does not support + PCRE2 yet, however, finding the PCRE2 headers and library are included to make PCRE2 support easier at + some point in the future. + +- `FindPTW.cmake`: "PTW" is shorthand for the Windows PThreads4w POSIX threads compatibility library. + +- `FindVDE.cmake`: Locates the VDE networking headers and library if the `WITH_VDE` option is `True`. + +In addition to `Find.cmake` modules, packages can also supply *CMake* configuration +modules. SDL2 and SDL2-ttf generate and install *CMake* cofiguration files that are used in lieu of a +`find_package` module. + +### `platform-quirks.cmake`: Platform-specific settings/tweaks + +`platform_quirks.cmake` is the code container for managing platform-specific compiler and linker +settings. Specific "quirks": + +- Set *CMake*'s libary architecture variables (`CMAKE_C_LIBRARY_ARCHITECTURE`, + `CMAKE_LIBRARY_ARCHITECTURE`) on Linux. + +- Windows compiler-specific quirks: + - Ensure that SIMH links with the correct multi-threaded Visual C runtime. + - Ensure that SIMH's source compiles with single byte character sets. + - Increase warning verbosity if the `DEBUG_WALL` configuration option is `True`. + - Make warnings fatal if the `WARNINGS_FATAL` configuration option is `True`. + +- There are no specific quirks for Linux. + +- Adjust the GNU and Clang compilers' `Release` build configuration flags, such as link-time optimization + (LTO) and *-O2* optimization, fatal warnings, ... + +- Construct the macOS *HomeBrew* and *MacPorts* header and library search paths so that `find_package` + succeeds. + +### `vcpkg.cmake`: vcpkg package installer/maintainer + +Setting the `VCPKG_ROOT` environment variable enables [vcpkg][vcpkg] support in SIMH. _vcpkg_ is a package +management system designed primarily for Windows Visual C/C++ software development with integrated *CMake* +support. _vcpkg_ also supports [MinGW-w64][mingw-w64], Linux and macOS. The GitHub CI/CD pipeline does not +use _vcpkg_ for either the Linux or macOS builds. [MinGW-w64][mingw-w64] is a SIMH CMake-supported +platform, but is not normally targeted in a CI/CD pipeline. Also, [MinGW-w64][mingw-w64] uses the +[Pacman][pacman] package manager, which makes _vcpkg_ redundant. + +_vcpkg_ does not support producing Windows XP binaries. *CMake* will emit a fatal error message if +`VCPKG_ROOT` is present __and__ the *CMake* configure/generate command line specified the Windows +XP-compatible toolset `-T vc141_xp`. + +`CMakeLists.txt` sets the globally visible variable `USING_VCPKG`. This makes better shorthand than having +to use `DEFINED VCPKG_ROOT` in conditionals and makes those tests more readable. + +Functional flow: +- If `USING_VCPKG` is `False`, return from `vcpkg-setup.cmake` immediately. + +- Construct the _vcpkg_ "(architecture)-(platform)-(runtime)" triplet + - Use the user's desired triplet if `VCPKG_DEFAULT_TRIPLET` exists as an environment variable. + - Windows: Always choose a statically linked, static runtime triple for MS Visual C/C++ or Clang -- + "(x64|x86|arm|arm64)-windows-static". + - MinGW-w64: Triplets are "(x64|x86)-mingw-dynamic". Note: Waiting for a new community triplet that + supports the statically linked runtime. + +- Set `VCPKG_CRT_LINKAGE` to "static" if the triplet ends in "-static". If not, set `VCPKG_CRT_LINKAGE` to + "dynamic". + +- Execute the _vcpkg_ *CMake* toolchain initialization. This installs the packages listed as dependencies + in `vcpkg.json`: + - pthreads + - pcre + - libpng + - sdl2 + - sdl2-ttf + +### `dep-locate.cmake`, `dep-link.cmake`: Dependency libraries + +`dep-locate.cmake` is the consolidated code container for locating SIMH's dependency libraries: +*PCRE/PCRE2* regular expressions; *libpng* graphics for screen captures; *SDL2*, *SDL2-ttf*, *freetype* +video support, *VDE* network support, the *zlib* compression needed by *libpng* and *PCRE/PCRE2*, +etc. It is divided into two sections: + +- Locate packages: First try `find_package` to locate required packages, falling back to `pkgconfig` if + `pkgconfig` is available. `dep-locate.cmake` also understands how to use `vcpkg`-based packages, since + some of the package names differ from what would normally be expected. *PCRE*, in particular, is named + *unofficial-pcre* vs. *PCRE*. + +- Superbuild setup: `dep-locate.cmake` constructs the external project builds for missing dependency + libraries in preparation for the *superbuild*. Currently, this only applies to Windows. There is a list + of source URL variables that immediately follows `include (ExternalProject)` that specify where the + *superbuild*'s external projects download the dependency's source code. + + - *The source URL list needs to be periodically reviewed to bump library version numbers as new library + versions are released.* + - `sourceforce.net` mirrors' SSL responses are **very** quirky and requires multiple mirror URLs to + succeed. + + **Future FIXME**: The superbuild would be entirely unnecessary if SIMH didn't have to support Windows XP + binaries. `vcpkg` should be the future dependency library package manager for Windows, but it does not + support the XP toolkit and likely never will. + +`dep-link.cmake` is the consolidated code container that populates the `simh_regexp`, `simh_video` and +`simh_network` interface libraries. Note that the order in which dependency libraries are added to these +interface libraries is important: *SDL2-ttf* must precede *freetype* and *SDL2*, for example. This reverse +ordering is standard library linking practice, given that linkers only make a single pass through each +library to resolve symbols. + +### `simh-simulators.cmake` + +`simh-simulators.cmake` is the list of SIMH simulator subdirectories added as *CMake* subprojects. Each +simulator subdirectory has its own `CMakeLists.txt` file that contains calls to +`add_simulator`. Subprojects are a *CMake* idiom and maps well to build system generators, such as +Visual Studio and XCode, which assume a subdirectory-subproject organization. + +This file is currently autogenerated by the `generate.py` Python script, although, this may not the the +case in the future. + +### `generate.py`: Automagic `makefile` → CMake infrastructure + +The SIMH `makefile` is still considered the authoritative source for simulator compiler command lines and +source code. `generate.py` was built to scrape the `makefile`'s `all` and `exp` rules, gather simulator +source code lists, simulator-specific defines, and emit the simulator subdirectory `CMakeLists.txt` and +the `simh-simulators.cmake` files. To synchronize the SIMH *CMake* infrastructure with the SIMH +`makefile` when new simulators are added to the `makefile`, when compiler command lines change or new +simulator source code is added: + +``` shell +$ cd cmake; python3 -m generate +``` + +Internally, `generate.py` has three principal classes defined in the `cmake/simgen` subdirectory: +`CMakeBuildSystem` (`cmake_container.py`), `SimCollection` (`sim_collection.py`) and `SIMHBasicSimulator` +(`basic_simulator.py`). + +- `CMakeBuildSystem`: The top-level container for the entire SIMH simulator collection scraped from the + `makefile`. It's a container that maps a `SimCollection` simulator group to a subdirectory. The + `CMakeBuildSystem.extract` method interprets the `makefile`'s parsed contents, and builds up the + per-subdirectory `SimCollection` simulator groups. + +- `SimCollection`: A group of simulators, e.g., all of the VAX or PDP-11 simulators, or the PDP-8 + simulator. It also maps simulator source macro names to source lists that become *CMake* variables to + make the emitted `CMakeLists.txt` files more readable. The `SimCollection.write_simulators` method emits + the simulator subdirectory `CMakeLists.txt` file. + +- `SIMHBasicSimulator`: An individual SIMH simulator stored inside a `SimCollection`. This class keeps + track of the simulator's sources, simulator-specific defines and include paths, as well as detects when + the simulator requires 64-bit address and 64-bit data, when the simulator requires video support. The + `SIMHBasicSimulator.write_section` method emits the individual simulator's `add_simulator` function call + to the `CMakeLists.txt` file stream passed by the parent `SimCollection`. + + `SIMHBasicSimulator` has several subclasses that specialize the `write_section` method. For example, the + *BESM6* simulator requires a Cyrillic font, which requires additional *CMake* code to search for an + available font from a list of known Cyrillic-supporting fonts. The `VAXSimulator` class injects *CMake* + code to symlink, hard link or copy the `vax` executable to `microvax3900`. The + `SimCollection.special_simulators` dictionary maps simulator names to specialized `SIMHBasicSimulator` + subclasses. If the simulator's name is not present in the `special_simulators` dictionary, + `SIMHBasicSimulator` is used. + +### CPack configuration + +[*CPack*][cpack] is the *CMake* utility for packaging SIMH's pre-built binaries. Like *CMake*, *CPack* has +its own generators that support different packaging systems. Some packaging systems only support a single, +all-in-one package, like Debian `.deb` packages. Other packaging systems support a finer grained approach +with individually selectable package components, like the NullSoft Installation System (NSIS) and macOS' +"productbuild" packagers. + +`cpack-setup.cmake` imports the *CPack* module and customizes *CPack* variables and generator +settings. Principally, `cpack-setup.cmake` sets the output name for the package, which is +`simh-major.minor-suffix`. The suffix defaults to the system's name, `${CMAKE_SYSTEM_NAME}` for +non-Windows operating systems, and `(win64|win32)-(Debug|Release)-(vs2022|vs2019|vs2017|vs2015)[-xp]` for +Windows systems. The `-xp` suffix is only appended when building Windows XP-compatible binaries. Setting +the `SIMH_PACKAGE_SUFFIX` environment variable overrides the default suffix. + +Platform and generator-specific settings in `cpack-setup.cmake` include: + +- Runtime installation exclusions: A list of files that should be excluded from the resulting installation + package. For Windows, *CPack* should not install well known DLLs or anything from the `system32` + directory. Linux and macOS do not currently have a runtime exclusion list. If that changes, edit the + `pre_runtime_exclusions` and `post_runtime_exclusions` variables' regular expressions. + +- NullSoft Installation System (NSIS): Arrange to use the `installer-customizations/NSIS.template.in` + script timeplate (see below.) NSIS also uses "SIMH-major.minor" (e.g., "SIMH-4.0") as the installation + directory's name and defaults to installing SIMH in the user's `$LocalAppData\Programs". + +- WIX Windows Installer: Sets the WIX GUID for SIMH. This GUID was entirely fabricated by a GUID + generator. + +- Debian: Adds Debian package dependencies for *libsd2*, *libsd2-ttf*, *libpcap*, *libvdeplug2* and + *libedit2*. **This dependency list needs to be periodically revisited when dependencies change.** + +`simh-packaging.cmake` defines package components and basic runtime support installation common to all +simulators. Package components are groups of SIMH simulator "families" -- there is a strong correlation +between a simulator family and the SIMH simulator subdirectories. For example, all of the VAX simulators +belong to the `vax_family` component. `simh-packaging.cmake` creates the `vax_family` *CPack* component +and `add_simulator` adds a simulator to its package family via its `PKG_FAMILY ` option. + +The `experimental_family` is the exception to the simulator family-subdirectory rule, serving as the +package family for the currently experimental simulators. + +The `runtime_support` family is intended for executables and documentation common to all +simulators. Currently, only the `simh.doc` SIMH documentation is part of this family. Future **FIXME**: +populate this family with additional, non-simulator-specific documentation. + +The `cmake/installer-customizations` subdirectory is where *CPack*-specific generator customizations +should be kept. The NSIS installer template was altered so that the resulting SIMH installer executable +only required user privileges to installer; the default escalates to "admin" privileges, which are +unnecessary for SIMH. + + +[cmake]: https://cmake.org +[cmake_modules]: https://gitlab.kitware.com/cmake/cmake/-/tree/master/Modules +[cmake_readme]: ../README-CMake.md +[cpack]: https://cmake.org/cmake/help/latest/module/CPack.html +[cpack_generators]: https://cmake.org/cmake/help/latest/manual/cpack-generators.7.html#manual:cpack-generators(7) +[external_project]: https://cmake.org/cmake/help/latest/module/ExternalProject.html +[find_package]: https://cmake.org/cmake/help/latest/command/find_package.html +[gnuinstalldirs]: https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html +[libsdl2]: https://github.com/libsdl-org/SDL +[mingw-w64]: https://www.mingw-w64.org/ +[nullsoft]: https://sourceforge.net/projects/nsis/ +[pacman]: https://archlinux.org/pacman/ +[unity_framework]: http://www.throwtheswitch.org/unity +[vcpkg]: https://vcpkg.io +[vde_network]: https://wiki.virtualsquare.org/#!index.md + + diff --git a/cmake/FindEDITLINE.cmake b/cmake/FindEDITLINE.cmake new file mode 100644 index 00000000..2ab7b5c3 --- /dev/null +++ b/cmake/FindEDITLINE.cmake @@ -0,0 +1,142 @@ +# +# This module is designed to find/handle editline library +# +# Requirements: +# - CMake >= 2.8.3 (for new version of find_package_handle_standard_args) +# +# The following variables will be defined for your use: +# - EDITLINE_INCLUDE_DIRS : editline include directory +# - EDITLINE_LIBRARIES : editline libraries +# - EDITLINE_VERSION : complete version of editline (x.y) +# - EDITLINE_MAJOR_VERSION : major version of editline +# - EDITLINE_MINOR_VERSION : minor version of editline +# +# How to use: +# 1) Copy this file in the root of your project source directory +# 2) Then, tell CMake to search this non-standard module in your project directory by adding to your CMakeLists.txt: +# set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) +# 3) Finally call find_package(EditLine) once +# +# Here is a complete sample to build an executable: +# +# set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) +# +# find_package(EditLine REQUIRED) # Note: name is case sensitive +# +# include_directories(${EDITLINE_INCLUDE_DIRS}) +# add_executable(myapp myapp.c) +# target_link_libraries(myapp ${EDITLINE_LIBRARIES}) +# + + +#============================================================================= +# Copyright (c) 2014, julp +# +# Distributed under the OSI-approved BSD License +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +#============================================================================= + +########## Private ########## +if(NOT DEFINED EDITLINE_PUBLIC_VAR_NS) + set(EDITLINE_PUBLIC_VAR_NS "EDITLINE") +endif(NOT DEFINED EDITLINE_PUBLIC_VAR_NS) +if(NOT DEFINED EDITLINE_PRIVATE_VAR_NS) + set(EDITLINE_PRIVATE_VAR_NS "_${EDITLINE_PUBLIC_VAR_NS}") +endif(NOT DEFINED EDITLINE_PRIVATE_VAR_NS) + +function(editline_debug _VARNAME) + if(${EDITLINE_PUBLIC_VAR_NS}_DEBUG) + if(DEFINED ${EDITLINE_PUBLIC_VAR_NS}_${_VARNAME}) + message("${EDITLINE_PUBLIC_VAR_NS}_${_VARNAME} = ${${EDITLINE_PUBLIC_VAR_NS}_${_VARNAME}}") + else(DEFINED ${EDITLINE_PUBLIC_VAR_NS}_${_VARNAME}) + message("${EDITLINE_PUBLIC_VAR_NS}_${_VARNAME} = ") + endif() + endif() +endfunction() + +# Alias all EditLine_FIND_X variables to EDITLINE_FIND_X +# Workaround for find_package: no way to force case of variable's names it creates (I don't want to change MY coding standard) +# --- +# NOTE: only prefix is considered, not full name of the variables to minimize conflicts with string(TOUPPER) for example +# EditLine_foo becomes EDITLINE_foo not EditLine_FOO as this is two different variables +set(${EDITLINE_PRIVATE_VAR_NS}_FIND_PKG_PREFIX "EditLine") +get_directory_property(${EDITLINE_PRIVATE_VAR_NS}_CURRENT_VARIABLES VARIABLES) +foreach(${EDITLINE_PRIVATE_VAR_NS}_VARNAME ${${EDITLINE_PRIVATE_VAR_NS}_CURRENT_VARIABLES}) + if(${EDITLINE_PRIVATE_VAR_NS}_VARNAME MATCHES "^${${EDITLINE_PRIVATE_VAR_NS}_FIND_PKG_PREFIX}") + string(REGEX REPLACE "^${${EDITLINE_PRIVATE_VAR_NS}_FIND_PKG_PREFIX}" "${EDITLINE_PUBLIC_VAR_NS}" ${EDITLINE_PRIVATE_VAR_NS}_NORMALIZED_VARNAME ${${EDITLINE_PRIVATE_VAR_NS}_VARNAME}) + set(${${EDITLINE_PRIVATE_VAR_NS}_NORMALIZED_VARNAME} ${${${EDITLINE_PRIVATE_VAR_NS}_VARNAME}}) + endif() +endforeach() + +########## Public ########## +find_path( + ${EDITLINE_PUBLIC_VAR_NS}_INCLUDE_DIRS + NAMES histedit.h +) + +if(${EDITLINE_PUBLIC_VAR_NS}_INCLUDE_DIRS) + + find_library( + ${EDITLINE_PUBLIC_VAR_NS}_LIBRARIES + NAMES edit + ) + + find_library( + ${EDITLINE_PUBLIC_VAR_NS}_TERMCAP + NAMES termcap + ) + +# file(READ "${${EDITLINE_PUBLIC_VAR_NS}_INCLUDE_DIRS}/histedit.h" ${EDITLINE_PRIVATE_VAR_NS}_H_CONTENT) +# string(REGEX REPLACE ".*# *define +LIBEDIT_MAJOR +([0-9]+).*" "\\1" ${EDITLINE_PUBLIC_VAR_NS}_MAJOR_VERSION ${${EDITLINE_PRIVATE_VAR_NS}_H_CONTENT}) +# string(REGEX REPLACE ".*# *define +LIBEDIT_MINOR +([0-9]+).*" "\\1" ${EDITLINE_PUBLIC_VAR_NS}_MINOR_VERSION ${${EDITLINE_PRIVATE_VAR_NS}_H_CONTENT}) +# set(${EDITLINE_PUBLIC_VAR_NS}_VERSION "${${EDITLINE_PUBLIC_VAR_NS}_MAJOR_VERSION}.${${EDITLINE_PUBLIC_VAR_NS}_MINOR_VERSION}") + + include(FindPackageHandleStandardArgs) + if(${EDITLINE_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${EDITLINE_PUBLIC_VAR_NS}_FIND_QUIETLY) + find_package_handle_standard_args( + ${EDITLINE_PUBLIC_VAR_NS} + REQUIRED_VARS ${EDITLINE_PUBLIC_VAR_NS}_LIBRARIES ${EDITLINE_PUBLIC_VAR_NS}_INCLUDE_DIRS +# VERSION_VAR ${EDITLINE_PUBLIC_VAR_NS}_VERSION + ) + else(${EDITLINE_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${EDITLINE_PUBLIC_VAR_NS}_FIND_QUIETLY) + find_package_handle_standard_args(${EDITLINE_PUBLIC_VAR_NS} "editline not found" ${EDITLINE_PUBLIC_VAR_NS}_LIBRARIES ${EDITLINE_PUBLIC_VAR_NS}_INCLUDE_DIRS) + endif() + +else() + + if(${EDITLINE_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${EDITLINE_PUBLIC_VAR_NS}_FIND_QUIETLY) + message(FATAL_ERROR "Could not find editline include directory") + endif(${EDITLINE_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${EDITLINE_PUBLIC_VAR_NS}_FIND_QUIETLY) + +endif() + +mark_as_advanced( + ${EDITLINE_PUBLIC_VAR_NS}_INCLUDE_DIRS + ${EDITLINE_PUBLIC_VAR_NS}_LIBRARIES +) + +if (${EDITLINE_PUBLIC_VAR_NS}_FOUND) + add_library(Editline::Editline UNKNOWN IMPORTED) + set_target_properties(Editline::Editline PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${${EDITLINE_PUBLIC_VAR_NS}_INCLUDE_DIRS}" + INTERFACE_COMPILE_DEFINITIONS "HAVE_EDITLINE" + INTERFACE_LINK_LIBRARIES "$<$:${${EDITLINE_PUBLIC_VAR_NS}_TERMCAP}>") + set_property(TARGET Editline::Editline APPEND PROPERTY + IMPORTED_LOCATION "${${EDITLINE_PUBLIC_VAR_NS}_LIBRARIES}") +endif () + +# IN (args) +editline_debug("FIND_REQUIRED") +editline_debug("FIND_QUIETLY") +editline_debug("FIND_VERSION") +# OUT +# Linking +editline_debug("INCLUDE_DIRS") +editline_debug("LIBRARIES") +editline_debug("TERMCAP") +# Version +# editline_debug("MAJOR_VERSION") +# editline_debug("MINOR_VERSION") +# editline_debug("VERSION") diff --git a/cmake/FindPCAP.cmake b/cmake/FindPCAP.cmake new file mode 100644 index 00000000..c3250046 --- /dev/null +++ b/cmake/FindPCAP.cmake @@ -0,0 +1,76 @@ +# Locate the PCAP library +# +# This module defines: +# +# :: +# +# PCAP_LIBRARIES, the name of the library to link against +# PCAP_INCLUDE_DIRS, where to find the headers +# PCAP_FOUND, if false, do not try to link against +# PCAP_VERSION_STRING - human-readable string containing the version of SDL_ttf +# +# Tweaks: +# 1. PCAP_PATH: A list of directories in which to search +# 2. PCAP_DIR: An environment variable to the directory where you've unpacked or installed PCAP. +# +# "scooter me fecit" + +find_path(PCAP_INCLUDE_DIR + NAMES + pcap.h + HINTS + ENV PCAP_DIR + PATHS + pcap + PCAP + ${PCAP_PATH} + ) + +# if (CMAKE_SIZEOF_VOID_P EQUAL 8) +# set(LIB_PATH_SUFFIXES lib64 x64 amd64 x86_64-linux-gnu aarch64-linux-gnu lib) +# else () +# set(LIB_PATH_SUFFIXES x86) +# endif () + +# find_library(PCAP_LIBRARY +# NAMES +# pcap pcap_static libpcap libpcap_static +# HINTS +# ENV PCAP_DIR +# PATH_SUFFIXES +# ${LIB_PATH_SUFFIXES} +# PATHS +# ${PCAP_PATH} +# ) +# ## message(STATUS "LIB_PATH_SUFFIXES ${LIB_PATH_SUFFIXES}") +# ## message(STATUS "PCAP_LIBRARY is ${PCAP_LIBRARY}") + +# if (WIN32 AND PCAP_LIBRARY) +# ## Only worry about the packet library on Windows. +# find_library(PACKET_LIBRARY +# NAMES +# packet Packet +# HINTS +# ENV PCAP_DIR +# PATH_SUFFIXES +# ${LIB_PATH_SUFFIXES} +# PATHS +# ${PCAP_PATH} +# ) +# else (WIN32 AND PCAP_LIBRARY) +# set(PACKET_LIBRARY) +# endif (WIN32 AND PCAP_LIBRARY) +# ## message(STATUS "PACKET_LIBRARY is ${PACKET_LIBRARY}") + +# set(PCAP_LIBRARIES ${PCAP_LIBRARY} ${PACKET_LIBRARY}) +set(PCAP_INCLUDE_DIRS ${PCAP_INCLUDE_DIR}) +unset(PCAP_LIBRARY) +unset(PCAP_INCLUDE_DIR) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + PCAP + REQUIRED_VARS + ## PCAP_LIBRARIES + PCAP_INCLUDE_DIRS +) diff --git a/cmake/FindPCRE.cmake b/cmake/FindPCRE.cmake new file mode 100644 index 00000000..fa9c1a23 --- /dev/null +++ b/cmake/FindPCRE.cmake @@ -0,0 +1,102 @@ +# Locate the PCRE library +# +# This module defines: +# +# :: +# +# PCRE_LIBRARIES, the name of the library to link against +# PCRE_INCLUDE_DIRS, where to find the headers +# PCRE_FOUND, if false, do not try to link against +# +# Tweaks: +# 1. PCRE_PATH: A list of directories in which to search +# 2. PCRE_DIR: An environment variable to the directory where you've unpacked or installed PCRE. +# +# "scooter me fecit" + +function(findpcre_debug _VARNAME) + if(FINDPCRE_DEBUG) + if(DEFINED PCRE_${_VARNAME}) + message("PCRE_${_VARNAME} = ${PCRE_${_VARNAME}}") + else(DEFINED PCRE_${_VARNAME}) + message("PCRE_${_VARNAME} = ") + endif(DEFINED PCRE_${_VARNAME}) + endif() +endfunction(findpcre_debug) + +## Normal path to find the PCRE header and library: +find_path(PCRE_INCLUDE_DIR pcre.h + HINTS + ${PC_PCRE_INCLUDEDIR} + ${PC_PCRE_INCLUDE_DIRS} + ENV PCRE_DIR + # path suffixes to search inside ENV{PCRE_DIR} + PATHS ${PCRE_PATH} + PATH_SUFFIXES + pcre + PCRE + ) + +find_library(PCRE_LIBRARY_RELEASE + NAMES + pcre + libpcre + HINTS + ${PC_PCRE_LIBDIR} + ${PC_PCRE_LIBRARY_DIRS} + ENV PCRE_DIR + PATH_SUFFIXES + ${LIB_PATH_SUFFIXES} + PATHS + ${PCRE_PATH} +) + +find_library(PCRE_LIBRARY_DEBUG + NAMES + pcred + libpcred + HINTS + ENV PCRE_DIR + PATH_SUFFIXES + ${LIB_PATH_SUFFIXES} + PATHS + ${PCRE_PATH} +) + +if (PCRE_INCLUDE_DIR) + if (EXISTS "${PCRE_INCLUDE_DIR}/pcre.h") + file(STRINGS "${PCRE_INCLUDE_DIR}/pcre.h" PCRE_VERSION_MAJOR_LINE REGEX "^#define[ \t]+PCRE_MAJOR[ \t]+[0-9]+$") + file(STRINGS "${PCRE_INCLUDE_DIR}/pcre.h" PCRE_VERSION_MINOR_LINE REGEX "^#define[ \t]+PCRE_MINOR[ \t]+[0-9]+$") + endif () + + string(REGEX REPLACE "^#define[ \t]+PCRE?_MAJOR[ \t]+([0-9]+)$" "\\1" PCRE_VERSION_MAJOR "${PCRE_VERSION_MAJOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+PCRE?_MINOR[ \t]+([0-9]+)$" "\\1" PCRE_VERSION_MINOR "${PCRE_VERSION_MINOR_LINE}") + + set(PCRE_VERSION_STRING "${PCRE_VERSION_MAJOR}.${PCRE_VERSION_MINOR}") + unset(PCRE_VERSION_MAJOR_LINE) + unset(PCRE_VERSION_MINOR_LINE) + unset(PCRE_VERSION_MAJOR) + unset(PCRE_VERSION_MINOR) +endif () + +include(SelectLibraryConfigurations) +select_library_configurations(PCRE) + +set(PCRE_LIBRARIES ${PCRE_LIBRARY}) +set(PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR}) + +findpcre_debug(LIBRARY) +findpcre_debug(LIBRARIES) +findpcre_debug(LIBRARY_DEBUG) +findpcre_debug(LIBRARY_RELEASE) +findpcre_debug(VERSION_STRING) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + PCRE + REQUIRED_VARS + PCRE_LIBRARY + PCRE_INCLUDE_DIR + VERSION_VAR + PCRE_VERSION_STRING +) diff --git a/cmake/FindPCRE2.cmake b/cmake/FindPCRE2.cmake new file mode 100644 index 00000000..6ab092b6 --- /dev/null +++ b/cmake/FindPCRE2.cmake @@ -0,0 +1,97 @@ +# Locate the PCRE library +# +# This module defines: +# +# :: +# +# PCRE2_LIBRARIES, the name of the pcre2 library to link against +# PCRE2_INCLUDE_DIRS, where to find the pcre2 headers +# PCRE2_FOUND, if false, do not try to compile or link with pcre2 +# PCRE2_VERSION_STRING - human-readable string containing the version of pcre or pcre2 +# +# Tweaks: +# 1. PCRE_PATH: A list of directories in which to search +# 2. PCRE_DIR: An environment variable to the directory where you've unpacked or installed PCRE. +# +# "scooter me fecit" + +find_path(PCRE2_INCLUDE_DIR pcre2.h + HINTS + ENV PCRE_DIR + # path suffixes to search inside ENV{PCRE_DIR} + PATHS ${PCRE_PATH} + PATH_SUFFIXES + include/pcre + include/PCRE + include + ) + +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(LIB_PATH_SUFFIXES lib64 x64 amd64 x86_64-linux-gnu aarch64-linux-gnu lib) +else () + set(LIB_PATH_SUFFIXES x86) +endif () + +find_library(PCRE2_LIBRARY_RELEASE + NAMES + pcre2-8 + pcre2-8-static + HINTS + ENV PCRE_DIR + PATH_SUFFIXES + ${LIB_PATH_SUFFIXES} + PATHS + ${PCRE_PATH} + ) + +find_library(PCRE2_LIBRARY_DEBUG + NAMES + pcre2-8d + pcre2-8-staticd + HINTS + ENV PCRE_DIR + PATH_SUFFIXES + ${LIB_PATH_SUFFIXES} + PATHS + ${PCRE_PATH} + ) + +if (PCRE2_INCLUDE_DIR) + if (EXISTS "${PCRE2_INCLUDE_DIR}/pcre2.h") + file(STRINGS "${PCRE2_INCLUDE_DIR}/pcre2.h" PCRE2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+PCRE2_MAJOR[ \t]+[0-9]+$") + file(STRINGS "${PCRE2_INCLUDE_DIR}/pcre2.h" PCRE2_VERSION_MINOR_LINE REGEX "^#define[ \t]+PCRE2_MINOR[ \t]+[0-9]+$") + endif () + + string(REGEX REPLACE "^#define[ \t]+PCRE2?_MAJOR[ \t]+([0-9]+)$" "\\1" PCRE2_VERSION_MAJOR "${PCRE2_VERSION_MAJOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+PCRE2?_MINOR[ \t]+([0-9]+)$" "\\1" PCRE2_VERSION_MINOR "${PCRE2_VERSION_MINOR_LINE}") + + set(PCRE2_VERSION_STRING "${PCRE2_VERSION_MAJOR}.${PCRE2_VERSION_MINOR}") + unset(PCRE2_VERSION_MAJOR_LINE) + unset(PCRE2_VERSION_MINOR_LINE) + unset(PCRE2_VERSION_MAJOR) + unset(PCRE2_VERSION_MINOR) +endif () + +include(SelectLibraryConfigurations) + +SELECT_LIBRARY_CONFIGURATIONS(PCRE2) + +## message("== PCRE_INCLUDE_DIR ${PCRE_INCLUDE_DIR}") +## message("== PCRE2_LIBRARY ${PCRE2_LIBRARY}") +## message("== PCRE2_LIBRARIES ${PCRE2_LIBRARIES}") +## message("== PCRE2_LIBRARY_DEBUG ${PCRE2_LIBRARY_DEBUG}") +## message("== PCRE2_LIBRARY_RELEASE ${PCRE2_LIBRARY_RELEASE}") + +set(PCRE2_INCLUDE_DIRS ${PCRE2_INCLUDE_DIR}) +set(PCRE2_LIBRARIES ${PCRE2_LIBRARY}) + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS( + PCRE2 + REQUIRED_VARS + PCRE2_LIBRARY + PCRE2_INCLUDE_DIR + VERSION_VAR + PCRE2_VERSION_STRING +) diff --git a/cmake/FindPTW.cmake b/cmake/FindPTW.cmake new file mode 100644 index 00000000..8581f92b --- /dev/null +++ b/cmake/FindPTW.cmake @@ -0,0 +1,75 @@ +# Locate the pthreads4w library and pthreads.h header +# +# This module defines: +# +# :: +# +# PTW_C_LIBRARY, the "pthread[GV]C3" library +# PTW_CE_LIBRARY, the "pthread[GV]CE3" library +# PTW_SE_LIBRARY, the "pthread[GV]SE3" library +# PTW_INCLUDE_DIR, where to find the headers +# PTW_FOUND, if false, do not try to link against +# +# Tweaks: +# 1. PTW_PATH: A list of directories in which to search +# 2. PTW_DIR: An environment variable to the directory where you've unpacked or installed PCRE. +# +# "scooter me fecit" + +if (WIN32) + include(SelectLibraryConfigurations) + + find_path(PTW_INCLUDE_DIR pthread.h + HINTS + ENV PTW_DIR + # path suffixes to search inside ENV{PTW_DIR} + PATH_SUFFIXES include include/pthreads4w + PATHS ${PTW_PATH} + ) + + # if (CMAKE_SIZEOF_VOID_P EQUAL 8) + # set(LIB_PATH_SUFFIXES lib64 x64 amd64 x86_64-linux-gnu) + # else () + # set(LIB_PATH_SUFFIXES x86) + # endif () + + foreach (flavor C CE SE) + if (MSVC) + set(libflavor V${flavor}3) + elseif (MINGW) + set(libflavor G${flavor}3) + endif (MSVC) + + find_library(PTW_${flavor}_LIBRARY_RELEASE + NAMES + libpthread${libflavor} pthread${libflavor} + HINTS + ENV PTW_ DIR + PATH_SUFFIXES + ${LIB_PATH_SUFFIXES} + PATHS + ${PTW_PATH} + ) + + find_library(PTW_${flavor}_LIBRARY_DEBUG + NAMES + libpthread${libflavor}d pthread${libflavor}d + HINTS + ENV PTW_ DIR + PATH_SUFFIXES + ${LIB_PATH_SUFFIXES} + PATHS + ${PTW_PATH} + ) + + SELECT_LIBRARY_CONFIGURATIONS(PTW_${flavor}) + endforeach () + + include(FindPackageHandleStandardArgs) + + # Minimally, we want the include directory and the C library... + find_package_handle_standard_args( + PTW + REQUIRED_VARS PTW_C_LIBRARY PTW_INCLUDE_DIR + ) +endif () diff --git a/cmake/FindVDE.cmake b/cmake/FindVDE.cmake new file mode 100644 index 00000000..3ee3c295 --- /dev/null +++ b/cmake/FindVDE.cmake @@ -0,0 +1,64 @@ +## Locate the VDE2/VDE4 libvdeplug headers and library. +## +## ::: +## +## Author: B. Scott Michel +## "scooter me fecit" + +if (WITH_VDE) + find_package(PkgConfig) + if (PKG_CONFIG_FOUND) + pkg_check_modules(PC_VDE QUIET VDEPLUG) + + if (PC_VDE_VERSION) + set(VDEPLUG_VERSION "${PC_VDE_VERSION}") + endif (PC_VDE_VERSION) + endif () + + find_path(VDEPLUG_INCLUDE_DIR libvdeplug.h + HINTS + ${PC_VDE_INCLUDE_DIRS} + PATH_SUFFIXES + include/libvdeplug + include/vde2 + include/VDE2 + include + ) + + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(LIB_PATH_SUFFIXES lib64 x64 amd64 x86_64-linux-gnu aarch64-linux-gnu) + else () + set(LIB_PATH_SUFFIXES x86) + endif () + + find_library(VDEPLUG_LIBRARY_RELEASE + NAMES + vdeplug + HINTS + ${PC_VDE_LIBRARY_DIRS} + PATH_SUFFIXES + ${LIB_PATH_SUFFIXES} + ) + + if (VDEPLUG_INCLUDE_DIR) + ## TBD: Get version info. The header file doesn't provide a way to grep + ## for it. vde_switch will output a version number, but can't really + ## depend on the user having installed the whole VDE package. + endif () + + include(SelectLibraryConfigurations) + + select_library_configurations(VDEPLUG) + + set(VDEPLUG_LIBRARIES ${VDEPLUG_LIBRARY}) + set(VDEPLUG_INCLUDE_DIRS ${VDEPLUG_INCLUDE_DIR}) + + include(FindPackageHandleStandardArgs) + + FIND_PACKAGE_HANDLE_STANDARD_ARGS(VDE + REQUIRED + VDEPLUG_LIBRARY + VDEPLUG_INCLUDE_DIR + # VERSION_VAR VDEPLUG_VERSION_STRING + ) +endif (WITH_VDE) diff --git a/cmake/GitHub-release.md b/cmake/GitHub-release.md new file mode 100644 index 00000000..2ce7db05 --- /dev/null +++ b/cmake/GitHub-release.md @@ -0,0 +1,41 @@ +# SIMH pre-built binaries + +Welcome to SIMH's pre-built binaries! + +- `.deb`: Debian packages for Linux. To install: + + ``` + $ sudo dpkg -i + ``` + +- `.zip`: ZIP-ed executable archive. Use your favorite or appropriate ZIP + software to unzip the archive. The `simh-/bin` subdirectory is the + location of the simulators. + +- `.exe`: Nullsoft Scriptable Install System (NSIS)-created Windows installer. + + NOTE: The executble is not code-signed. DO NOT DOUBLE CLICK ON THE EXECUTABLE + TO INSTALL. If you do, you are likely to get a Windows Defender popup box that + will prevent you from installing SIMH. Instead, use a CMD or PowerShell + command window and execute the `.exe` from the command line prompt. For + example, to install `simh-4.0.0-win32-native.exe`: + + ``` + ## PowerShell: + PS> .\simh-4.0.0-win32-native + + ## CMD: + > .\simh-4.0.0-win32-native + ``` + +- `.msi`: WiX toolkit-created Windows MSI installer. + + These MSI files are not code-signed. DO NOT DOUBLE CLICK ON THE EXECUTABLE TO + INSTALL. If you do, you are likely to get a Windows Defender popup box that + will prevent you from installing SIMH. Instead, use a CMD or PowerShell command + window to manually invoke `msiexec` to install SIMH. From either a PowerShell + or CMD command window: + + ``` + > msiexec /qf /i simh-4.0.0-win32-native.msi + ``` diff --git a/cmake/add_simulator.cmake b/cmake/add_simulator.cmake new file mode 100644 index 00000000..301139a5 --- /dev/null +++ b/cmake/add_simulator.cmake @@ -0,0 +1,426 @@ +## Put everything together into one nice function. + +include (CTest) + +## Regenerate the git commit ID if git exists. +find_program(GIT_COMMAND git) +if (GIT_COMMAND) + message(STATUS "Git command is ${GIT_COMMAND}") +else () + message(STATUS "Git not found -- will not update or include .git-commit-id.h") +endif () + +add_custom_target(update_sim_commit ALL + COMMAND ${CMAKE_COMMAND} + -D GIT_COMMIT_DEST=${CMAKE_SOURCE_DIR} + -P ${CMAKE_SOURCE_DIR}/cmake/git-commit-id.cmake + BYPRODUCTS + ${CMAKE_SOURCE_DIR}/.git-commit-id + ${CMAKE_SOURCE_DIR}/.git-commit-id.h + WORKING_DIRECTORY + ${CMAKE_SOURCE_DIR} +) + +## Simulator sources and library: +set(SIM_SOURCES + ${CMAKE_SOURCE_DIR}/scp.c + ${CMAKE_SOURCE_DIR}/sim_card.c + ${CMAKE_SOURCE_DIR}/sim_console.c + ${CMAKE_SOURCE_DIR}/sim_disk.c + ${CMAKE_SOURCE_DIR}/sim_ether.c + ${CMAKE_SOURCE_DIR}/sim_fio.c + ${CMAKE_SOURCE_DIR}/sim_imd.c + ${CMAKE_SOURCE_DIR}/sim_scsi.c + ${CMAKE_SOURCE_DIR}/sim_serial.c + ${CMAKE_SOURCE_DIR}/sim_sock.c + ${CMAKE_SOURCE_DIR}/sim_tape.c + ${CMAKE_SOURCE_DIR}/sim_timer.c + ${CMAKE_SOURCE_DIR}/sim_tmxr.c + ${CMAKE_SOURCE_DIR}/sim_video.c) + +set(SIM_VIDEO_SOURCES + ${CMAKE_SOURCE_DIR}/display/display.c + ${CMAKE_SOURCE_DIR}/display/sim_ws.c) + +function(build_simcore _targ) + cmake_parse_arguments(SIMH "VIDEO;INT64;ADDR64;BESM6_SDL_HACK" "" "" ${ARGN}) + + add_library(${_targ} STATIC ${SIM_SOURCES}) + + # Components that need to be turned on while building the library, but + # don't export out to the dependencies (hence PRIVATE.) + set_target_properties(${_targ} PROPERTIES + C_STANDARD 99 + ) + target_compile_definitions(${_targ} PRIVATE USE_SIM_CARD USE_SIM_IMD) + target_compile_options(${_targ} PRIVATE ${EXTRA_TARGET_CFLAGS}) + target_link_options(${_targ} PRIVATE ${EXTRA_TARGET_LFLAGS}) + + # Make sure that the top-level directory is part of the libary's include path: + target_include_directories("${_targ}" PUBLIC "${CMAKE_SOURCE_DIR}") + + if (SIMH_INT64) + target_compile_definitions(${_targ} PUBLIC USE_INT64) + endif (SIMH_INT64) + + if (SIMH_ADDR64) + target_compile_definitions(${_targ} PUBLIC USE_ADDR64) + endif (SIMH_ADDR64) + + if (SIMH_VIDEO) + if (WITH_VIDEO) + # It's the video library + target_sources(${_targ} PRIVATE ${SIM_VIDEO_SOURCES}) + target_link_libraries(${_targ} PUBLIC simh_video) + endif () + if (CMAKE_HOST_APPLE AND NOT SIMH_BESM6_SDL_HACK) + ## (a) The BESM6 SDL hack is temporary. If SDL_MAIN_AVAILABLE needs + ## to be defined, it belongs in the simh_video interface library. + ## (b) BESM6 doesn't use SIMH's video capabilities correctly and + ## the makefile filters out SDL_MAIN_AVAILABLE on macOS. + ## (c) This shouldn't be just an Apple platform quirk; SDL_main should + ## be used by all platforms. + target_compile_definitions("${_targ}" PUBLIC SDL_MAIN_AVAILABLE) + endif () + endif () + + target_link_libraries(${_targ} PUBLIC + simh_network + simh_regexp + os_features + thread_lib + ) + + # Define SIM_BUILD_TOOL for the simulator' + target_compile_definitions("${_targ}" PRIVATE + "SIM_BUILD_TOOL=CMake (${CMAKE_GENERATOR})" + ) + + # Ensure that sim_rev.h picks up .git-commit-id.h if the git command is + # available. + if (GIT_COMMAND) + target_compile_definitions("${_targ}" PRIVATE SIM_NEED_GIT_COMMIT_ID) + endif () + + add_dependencies(${_targ} update_sim_commit) + + # Create target cppcheck rule, if detected. + if (ENABLE_CPPCHECK AND cppcheck_cmd) + get_property(cppcheck_includes TARGET ${_targ} PROPERTY INCLUDE_DIRECTORIES) + get_property(cppcheck_defines TARGET ${_targ} PROPERTY COMPILE_DEFINITIONS) + list(TRANSFORM cppcheck_includes PREPEND "-I") + list(TRANSFORM cppcheck_defines PREPEND "-D") + + add_custom_target("${_targ}_cppcheck" + COMMAND ${cppcheck_cmd} ${cppcheck_defines} ${cppcheck_includes} ${SIM_SOURCES} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + VERBATIM + ) + + add_dependencies(cppcheck "${_targ}_cppcheck") + endif (ENABLE_CPPCHECK AND cppcheck_cmd) +endfunction(build_simcore _targ) + + +##+ +## Basic template for simh executables and unit tests. +##- +## FEATURE_INT64: Use the simhi64 library (defines USE_INT64) +## FEATURE_FULL64: Use the simhz64 library (defines USE_INT64, USE_ADDR64) +## BUILDROMS: Build the hardcoded boot rooms +## FEATURE_VIDEO: Add video support +## FEATURE_DISPLAY: Add display support +## +## BESM6_SDL_HACK: A TEMPORARY feature to work around issues with BESM6 and +## SDL and SIMH video. Because it's a day ending in "y", there's going to +## be another makefile quirk. +list(APPEND ADD_SIMULATOR_OPTIONS + "FEATURE_INT64" + "FEATURE_FULL64" + "BUILDROMS" + "FEATURE_VIDEO" + "FEATURE_DISPLAY" + "NO_INSTALL" + "BESM6_SDL_HACK" +) + +## TEST: The test script name that will be executed by the simulator within CTest. +## LABEL: The test name label, used to group tests, e.g., "VAX" for all of the +## VAX simulator tests. If you want to run a subset of tests, add the "-L " +## argument to the ctest command line. +## PKG_FAMILY: The simulator family to which a simulator belongs. If not specificed, +## defaults to "default_family". +list(APPEND ADD_SIMULATOR_1ARG + "TEST" + "LABEL" + "PKG_FAMILY" +) + +## DEFINES: List of extra command line manifest constants ("-D" items) +## INCLUDES: List of extra include directories +## SOURCES: List of source files +list(APPEND ADD_SIMULATOR_NARG + "DEFINES" + "INCLUDES" + "SOURCES" +) + +function (simh_executable_template _targ) + cmake_parse_arguments(SIMH "${ADD_SIMULATOR_OPTIONS}" "${ADD_SIMULATOR_1ARG}" "${ADD_SIMULATOR_NARG}" ${ARGN}) + + if (NOT DEFINED SIMH_SOURCES) + message(FATAL_ERROR "${_targ}: No source files?") + endif (NOT DEFINED SIMH_SOURCES) + + add_executable("${_targ}" "${SIMH_SOURCES}") + set_target_properties(${_targ} PROPERTIES + C_STANDARD 99 + RUNTIME_OUTPUT_DIRECTORY ${SIMH_LEGACY_INSTALL} + ) + target_compile_options(${_targ} PRIVATE ${EXTRA_TARGET_CFLAGS}) + target_link_options(${_targ} PRIVATE ${EXTRA_TARGET_LFLAGS}) + + if (MINGW) + ## target_compile_options(${_targ} PUBLIC "-fms-extensions") + target_link_options(${_targ} PUBLIC "-mconsole") + elseif (MSVC) + target_link_options(${_targ} PUBLIC "/SUBSYSTEM:CONSOLE") + endif () + + if (DEFINED SIMH_DEFINES) + target_compile_definitions("${_targ}" PUBLIC "${SIMH_DEFINES}") + endif (DEFINED SIMH_DEFINES) + + # This is a quick cheat to make sure that all of the include paths are + # absolute paths. + if (DEFINED SIMH_INCLUDES) + set(_normalized_includes) + foreach (inc IN LISTS SIMH_INCLUDES) + if (NOT IS_ABSOLUTE "${inc}") + message(">> Fixing include for ${_targ}: ${inc} -> ${CMAKE_SOURCE_DIR}/${inc}") + get_filename_component(inc "${CMAKE_SOURCE_DIR}/${inc}" ABSOLUTE) + endif () + list(APPEND _normalized_includes "${inc}") + endforeach () + + target_include_directories("${_targ}" PUBLIC "${_normalized_includes}") + endif () + + if (WITH_VIDEO) + if (SIMH_FEATURE_DISPLAY) + target_compile_definitions(${_targ} PUBLIC USE_DISPLAY) + endif () + endif () + + set(SIMH_SIMLIB simhcore) + if (SIMH_FEATURE_INT64) + set(SIMH_SIMLIB simhi64) + elseif (SIMH_FEATURE_FULL64) + set(SIMH_SIMLIB simhz64) + endif () + + if (SIMH_FEATURE_VIDEO OR SIMH_FEATURE_DISPLAY) + if (NOT SIMH_BESM6_SDL_HACK) + string(APPEND SIMH_SIMLIB "_video") + else () + string(APPEND SIMH_SIMLIB "_besm6") + endif () + endif () + + target_link_libraries("${_targ}" PUBLIC "${SIMH_SIMLIB}") +endfunction () + + +function (add_simulator _targ) + simh_executable_template(${_targ} "${ARGN}") + cmake_parse_arguments(SIMH "${ADD_SIMULATOR_OPTIONS}" "${ADD_SIMULATOR_1ARG}" "${ADD_SIMULATOR_NARG}" ${ARGN}) + + set(pkg_family "default_family") + if (SIMH_PKG_FAMILY) + set(pkg_family ${SIMH_PKG_FAMILY}) + endif () + + set(_install_opts) + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.21") + list(APPEND _install_opts RUNTIME_DEPENDENCY_SET simhRuntime) + endif () + + install(TARGETS ${_targ} + ${_install_opts} + RUNTIME + COMPONENT ${pkg_family} + ) + + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.21") + ## Collect runtime dependencies. The simhRuntime install() is invoked by cpack-setup.cmake + install(IMPORTED_RUNTIME_ARTIFACTS ${_targ} COMPONENT ${pkg_family} BUNDLE COMPONENT ${pkg_family}) + endif() + + ## Simulator-specific tests: + list(APPEND test_cmd "${_targ}" "RegisterSanityCheck") + + if (DEFINED SIMH_TEST) + string(APPEND test_fname ${CMAKE_CURRENT_SOURCE_DIR} "/tests/${SIMH_TEST}_test.ini") + IF (EXISTS "${test_fname}") + list(APPEND test_cmd "${test_fname}" "-v") + ENDIF () + endif () + + add_test(NAME "simh-${_targ}" COMMAND ${test_cmd}) + + if (SIMH_LABEL) + set_tests_properties("simh-${_targ}" PROPERTIES LABELS "simh-${SIMH_LABEL}") + endif () + + if (BUILD_SHARED_DEPS) + ## Make sure that the tests can find the DLLs/shared objects: + file(TO_NATIVE_PATH "${SIMH_DEP_TOPDIR}/bin" native_dep_bindir) + file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}" native_binary_dir) + endif () + + ## Build up test environment: + ## - Simulators that link SDL2 need to use the dummy (null) drivers on tests within + ## the CI/CD environment. While not STRICTLY necessary, it's a good idea. + list(APPEND test_add_env "SDL_VIDEODRIVER=dummy") + list(APPEND test_add_env "SDL_AUDIODRIVER=dummy") + + if (WIN32) + if (BUILD_SHARED_DEPS) + set(test_path "PATH=${native_dep_bindir}\\\$${native_binary_dir}\\$") + string(REPLACE ";" "\\\$" escaped_path "$ENV{PATH}") + string(APPEND test_path "${escaped_path}") + list(APPEND test_add_env "${test_path}") + endif () + else () + if (BUILD_SHARED_DEPS) + list(APPEND test_add_env "LD_LIBRARY_PATH=${native_dep_bindir}:${native_binary_dir}:\$LD_LIBRARY_PATH") + endif () + endif () + + set_property(TEST "simh-${_targ}" PROPERTY ENVIRONMENT "${test_add_env}") + + if (DONT_USE_ROMS) + target_compile_definitions(DONT_USE_INTERNAL_ROM) + elseif (SIMH_BUILDROMS) + add_dependencies(${_targ} BuildROMs) + endif () + + # Create target 'cppcheck' rule, if cppcheck detected: + if (ENABLE_CPPCHECK AND cppcheck_cmd) + get_property(cppcheck_includes TARGET ${_targ} PROPERTY INCLUDE_DIRECTORIES) + get_property(cppcheck_defines TARGET ${_targ} PROPERTY COMPILE_DEFINITIONS) + list(TRANSFORM cppcheck_includes PREPEND "-I") + list(TRANSFORM cppcheck_defines PREPEND "-D") + add_custom_target("${_targ}_cppcheck" + COMMAND ${cppcheck_cmd} ${cppcheck_defines} ${cppcheck_includes} ${SIMH_SOURCES} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) + + add_dependencies(cppcheck "${_targ}_cppcheck") + endif (ENABLE_CPPCHECK AND cppcheck_cmd) +endfunction () + + +function(add_unit_test _targ) + set(UNIT_TARGET "simbase-${_targ}") + set(UNIT_TEST "simbase-${_targ}") + + simh_executable_template(${UNIT_TARGET} "${ARGN}") + cmake_parse_arguments(SIMH "FEATURE_INT64;FEATURE_FULL64;BUILDROMS;FEATURE_VIDEO,FEATURE_DISPLAY" + "SOURCE_DIR;LABEL" + "DEFINES;INCLUDES;SOURCES" + ${ARGN}) + + target_link_libraries(${UNIT_TARGET} PUBLIC unittest) + add_test(NAME ${UNIT_TEST} COMMAND ${UNIT_TARGET}) + + set(TEST_LABEL "simbase;unit") + if (SIMH_LABEL) + list(APPEND TEST_LABEL "simbase-${SIMH_LABEL}") + endif () + set_tests_properties(${UNIT_TEST} PROPERTIES LABELS "${TEST_LABEL}") +endfunction () + +##~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= +## Now build things! +##~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + +if (ENABLE_CPPCHECK AND cppcheck_cmd) + add_custom_target(cppcheck) +endif () + +build_simcore(simhcore) +build_simcore(simhi64 INT64) +build_simcore(simhz64 INT64 ADDR64) +build_simcore(simhcore_video VIDEO) +build_simcore(simhi64_video VIDEO INT64) +build_simcore(simhz64_video VIDEO INT64 ADDR64) + +## Temporary hack for BESM6's breakage. +build_simcore(simhi64_besm6 VIDEO INT64 BESM6_SDL_HACK) + +if (NOT DONT_USE_ROMS) + add_executable(BuildROMs sim_BuildROMs.c) + target_include_directories(BuildROMs PUBLIC "${CMAKE_SOURCE_DIR}") + target_link_libraries(BuildROMs os_features) + add_custom_command( + OUTPUT + ${CMAKE_SOURCE_DIR}/VAX/vax_ka655x_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka620_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka630_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka610_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka410_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka411_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka412_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka41a_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka41d_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka42a_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka42b_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka43a_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka46a_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka47a_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka48a_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_is1000_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka410_xs_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka420_rdrz_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka420_rzrz_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka4xx_4pln_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka4xx_8pln_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka4xx_dz_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka4xx_spx_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka750_bin_new.h + ${CMAKE_SOURCE_DIR}/VAX/vax_ka750_bin_old.h + ${CMAKE_SOURCE_DIR}/VAX/vax_vcb02_bin.h + ${CMAKE_SOURCE_DIR}/VAX/vax_vmb_exe.h + ${CMAKE_SOURCE_DIR}/PDP11/pdp11_vt_lunar_rom.h + ${CMAKE_SOURCE_DIR}/PDP11/pdp11_dazzle_dart_rom.h + ${CMAKE_SOURCE_DIR}/PDP11/pdp11_11logo_rom.h + ${CMAKE_SOURCE_DIR}/swtp6800/swtp6800/swtp_swtbugv10_bin.h + MAIN_DEPENDENCY BuildROMs + COMMAND BuildROMS + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) +endif () + +## Front panel test. +## +## From all evidence in makefile, sim_frontpanel isn't used yet by any targets. +## +## Needs curses... +add_executable(frontpaneltest + ${CMAKE_SOURCE_DIR}/frontpanel/FrontPanelTest.c + ${CMAKE_SOURCE_DIR}/sim_sock.c + ${CMAKE_SOURCE_DIR}/sim_frontpanel.c) + +target_include_directories(frontpaneltest PUBLIC "${CMAKE_SOURCE_DIR}") +target_link_libraries(frontpaneltest PUBLIC os_features thread_lib) + +if (WIN32) + target_link_libraries(frontpaneltest PUBLIC simh_network) + + if (MSVC) + target_link_options(frontpaneltest PUBLIC "/SUBSYSTEM:CONSOLE") + elseif (MINGW) + target_link_options(frontpaneltest PUBLIC "-mconsole") + endif () +endif (WIN32) diff --git a/cmake/build_dep_matrix.cmake b/cmake/build_dep_matrix.cmake new file mode 100644 index 00000000..cc85fdbf --- /dev/null +++ b/cmake/build_dep_matrix.cmake @@ -0,0 +1,85 @@ +#~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= +# build_dep_matrix.cmake +# +# This is a minor hack to build all of the various library compile +# configurations. Might take a bit more time upfront to build the +# dependencies, but the user doesn't have to go backward and attempt +# to build the dependencies themselves. +# +# Author: B. Scott Michel +# "scooter me fecit" +#~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + + +function(BuildDepMatrix dep pretty) + cmake_parse_arguments(_BDM "" "RELEASE_BUILD;DEBUG_BUILD" "CMAKE_ARGS" ${ARGN}) + + set(cmake_cfg_args + "-G${CMAKE_GENERATOR}" + "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}" + "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}") + + if (CMAKE_GENERATOR_PLATFORM) + list(APPEND cmake_cfg_args "-A" "${CMAKE_GENERATOR_PLATFORM}") + endif () + if (CMAKE_GENERATOR_TOOLSET) + list(APPEND cmake_cfg_args "-T" "${CMAKE_GENERATOR_TOOLSET}") + endif () + string(REPLACE ";" "$" _amend_cmake_prefix_path "${SIMH_PREFIX_PATH_LIST}") + string(REPLACE ";" "$" _amend_cmake_include_path "${SIMH_INCLUDE_PATH_LIST}") + + list(APPEND cmake_cfg_args ${DEP_CMAKE_ARGS}) + list(APPEND cmake_cfg_args -DCMAKE_PREFIX_PATH=${_amend_cmake_prefix_path} + -DCMAKE_INCLUDE_PATH=${_amend_cmake_include_path} + ${_BDM_CMAKE_ARGS} + "" + ) + + if (NOT _BDM_RELEASE_BUILD) + set(_BDM_RELEASE_BUILD "Release") + endif (NOT _BDM_RELEASE_BUILD) + + if (NOT _BDM_DEBUG_BUILD) + set(_BDM_DEBUG_BUILD "Debug") + endif (NOT _BDM_DEBUG_BUILD) + + set(dep_cmds) + foreach (cfg IN ITEMS ${_BDM_DEBUG_BUILD} ${_BDM_RELEASE_BUILD}) + ## Set the MSVC runtime. Can't use a generator expression here, + ## have to "nail it down." + set(use_msvcrt "MultiThreaded") + if (cfg STREQUAL ${_BDM_DEBUG_BUILD}) + string(APPEND use_msvcrt "Debug") + endif () + if (BUILD_SHARED_DEPS) + string(APPEND use_msvcrt "DLL") + endif () + list(APPEND dep_cmds COMMAND ${CMAKE_COMMAND} -E echo "-- Building ${pretty} '${cfg}' configuration") + list(APPEND dep_cmds COMMAND ${CMAKE_COMMAND} -E remove -f CMakeCache.txt) + list(APPEND dep_cmds COMMAND ${CMAKE_COMMAND} -E remove_directory CMakeFiles) + list(APPEND dep_cmds COMMAND ${CMAKE_COMMAND} + ${cmake_cfg_args} + -DCMAKE_BUILD_TYPE:STRING=${cfg} + -DCMAKE_INSTALL_PREFIX:STRING=${SIMH_DEP_TOPDIR} + -DCMAKE_POLICY_DEFAULT_CMP0091:STRING=NEW + -DCMAKE_MSVC_RUNTIME_LIBRARY:STRING=${use_msvcrt} + ) + list(APPEND dep_cmds COMMAND ${CMAKE_COMMAND} --build --config "${cfg}" --clean-first) + list(APPEND dep_cmds COMMAND ${CMAKE_COMMAND} --install --config ${cfg}) + endforeach () + + ## Unset CMAKE_MODULE_PATH temporarily for external projects + set(_saved_cmake_module_path ${CMAKE_MODULE_PATH}) + set(CMAKE_MODULE_PATH "") + + ## message("${dep_cmds}") + ExternalProject_Add_Step(${dep} build-dbg-release + DEPENDEES configure + WORKING_DIRECTORY + ${dep_cmds} + ) + + set(CMAKE_MODULE_PATH ${_saved_cmake_module_path}) + unset(_saved_cmake_module_path) +endfunction () + diff --git a/cmake/cmake-builder.ps1 b/cmake/cmake-builder.ps1 new file mode 100644 index 00000000..a303f0a8 --- /dev/null +++ b/cmake/cmake-builder.ps1 @@ -0,0 +1,570 @@ +# Author: B. Scott Michel (scooter.phd@gmail.com) +# "scooter me fecit" + +<# +.SYNOPSIS +Configure and build SIMH's dependencies and simulators using the Microsoft Visual +Studio C compiler or MinGW-W64-based gcc compiler. + +.DESCRIPTION +This script executes the three (3) phases of building the entire suite of SIMH +simulators using the CMake meta-build tool. The phases are: + +1. Configure and generate the build environment selected by '-flavor' option. +2. Build missing runtime dependencies and the simulator suite with the compiler + configuration selected by the '-config' option. The "Release" configuration + generates optimized executables; the "Debug" configuration generates + development executables with debugger information. +3. Test the simulators + +There is an install phase that can be invoked separately as part of the SIMH +packaging process. + +The test and install phases can be enabled or disabled by the appropriate command line +flag (e.g., '-noInstall', '-noTest', '-testOnly', '-installOnly'.) + +Build environment and artifact locations: +----------------------------------------- +cmake/build-vs* MSVC build products and artifacts +cmake/build-mingw MinGW-W64 products and artifacts +cmake/build-ninja Ninja builder products and artifacts + +.EXAMPLE +PS> cmake-builder.ps1 -flavor vs2022 -config Release + +Generate/configure, build, test and install the SIMH simulator suite using +the Visual Studio 2022 toolchain in the Release (optimized) compile +configuration. + +.EXAMPLE +PS> cmake-builder.ps1 vs2022 Release + +Another way to generate/configure, build, test and install the SIMH simulator +suite using the Visual Studio 2022 toolchain in the Release (optimized) +compile configuration. + +.EXAMPLE +PS> cmake-builder.ps1 vs2019 Debug -notest -noinstall + +Generate/configure and build the SIMH simulator suite with the Visual Studio +2019 toolchain in the Debug compile configuration. Does not execute tests and +does not install the simulators under the BIN subdirectory in the top of the +source tree. + +.EXAMPLE + +PS> cmake-builder.ps1 -flavor vs2019 -config Release -installonly + +Install the simulators under the BIN subdirectory in the top of the source +tree. Does not generate/configure, but will build to ensure that compile +targets (simulator executables) are up-to-date. +#> + +param ( + ## String arguments are positional, so if the user invokes this script + ## as "cmake-builder.ps1 vs2022 Debug", it's the same as saying + ## "cmake-builder.ps1 -flavor vs2022 -config Debug" + + + ## The build environment's "flavor" that determines which CMake generator is used + ## to create all of the build machinery to compile the SIMH simulator suite + ## and the target compiler. + ## + ## Supported flavors: + ## ------------------ + ## vs2022 Visual Studio 2022 (default) + ## vs2022-xp Visual Studio 2022 XP compat + ## vs2019 Visual Studio 2019 + ## vs2019-xp Visual Studio 2019 XP compat + ## vs2017 Visual Studio 2017 + ## vs2017-xp Visual Studio 2017 XP compat + ## vs2015 Visual Studio 2015 + ## mingw-make MinGW GCC/mingw32-make + ## mingw-ninja MinGW GCC/ninja + [Parameter(Mandatory=$false)] + [string] $flavor = "vs2022", + + ## The target build configuration. Valid values: "Release" and "Debug" + [Parameter(Mandatory=$false)] + [string] $config = "Release", + + ## Supply a suffix for CPack package names via -DSIMH_PACKAGE_SUFFIX + [Parameter(Mandatory=$false)] + [string] $cpack_suffix = "", + + ## (optional) Simulator to build (e.g., 'vax', 'pdp11', 'pdp8', ...) + [Parameter(Mandatory=$false)] + [string] $target = "", + + ## The rest are flag arguments + + ## Clean (remove) the CMake build directory before configuring + [Parameter(Mandatory=$false)] + [switch] $clean = $false, + + ## Get help. + [Parameter(Mandatory=$false)] + [switch] $help = $false, + + ## Compile the SIMH simulator suite without network support. + [Parameter(Mandatory=$false)] + [switch] $nonetwork = $false, + + ## Compile the SIMH simulator suite without video support. + [Parameter(Mandatory=$false)] + [switch] $novideo = $false, + + ## Disable the build's tests. + [Parameter(Mandatory=$false)] + [switch] $notest = $false, + + ## Do not install the simulator suite in the source directory's BIN + ## subdirectory. + [Parameter(Mandatory=$false)] + [switch] $noinstall = $false, + + ## Enable parallel builds. + [Parameter(Mandatory=$false)] + [switch] $parallel = $false, + + ## Configure and generate the build environment. Don't compile, test or install. + [Parameter(Mandatory=$false)] + [switch] $generate = $false, + + ## Delete the CMake cache, configure and regenerate the build environment. + ## Don't compile, test or install. + [Parameter(Mandatory=$false)] + [switch] $regenerate = $false, + + ## Only run the tests. + [Parameter(Mandatory=$false)] + [switch] $testonly = $false, + + ## Only install the SIMH simulator suite in the source directory's BIN + ## subdirectory. + [Parameter(Mandatory=$false)] + [switch] $installOnly = $false, + + ## Turn on Windows API deprecation warnings. NOTE: These warnings are OFF by + ## default. + [Parameter(Mandatory=$false)] + [switch] $windeprecation = $false, + + ## Enable Link-Time Optimization (LTO). + [Parameter(Mandatory=$false)] + [switch] $lto = $false, + + ## Turn on maximal compiler warnings for Debug builds (e.g. "-Wall" or "/W3") + [Parameter(Mandatory=$false)] + [switch] $debugWall = $false, + + ## Enable the cppcheck static code analysis rules + [Parameter(Mandatory=$false)] + [switch] $cppcheck = $false +) + +$scriptName = $(Split-Path -Leaf $PSCommandPath) +$scriptCmd = ${PSCommandPath} + +function Show-Help +{ + Get-Help -full ${scriptCmd} + exit 0 +} + + +## CMake generator info: +class GeneratorInfo +{ + [string] $Generator + [bool] $SingleConfig + [bool] $UCRT + [string] $UCRTVersion + [string[]]$ArchArgs + + GeneratorInfo([string]$gen, $configFlag, $ucrtFlag, $ucrtVer, [string[]]$arch) + { + $this.Generator = $gen + $this.SingleConfig = $configFlag + $this.UCRT = $ucrtFlag + $this.UCRTVersion = $ucrtVer + $this.ArchArgs = $arch + } +} + +## Multiple build configurations selected at compile time +$multiConfig = $false +## Single configuration selected at configuration time +$singleConfig = $true + +$cmakeGenMap = @{ + "vs2022" = [GeneratorInfo]::new("Visual Studio 17 2022", $multiConfig, $false, "", @("-A", "Win32")); + "vs2022-xp" = [GeneratorInfo]::new("Visual Studio 17 2022", $multiConfig, $false, "", @("-A", "Win32", "-T", "v141_xp")); + "vs2019" = [GeneratorInfo]::new("Visual Studio 16 2019", $multiConfig, $false, "", @("-A", "Win32")); + "vs2019-xp" = [GeneratorInfo]::new("Visual Studio 16 2019", $multiConfig, $false, "", @("-A", "Win32", "-T", "v141_xp")); + "vs2017" = [GeneratorInfo]::new("Visual Studio 15 2017", $multiConfig, $false, "", @("-A", "Win32")); + "vs2017-xp" = [GeneratorInfo]::new("Visual Studio 15 2017", $multiConfig, $false, "", @("-A", "Win32", "-T", "v141_xp")); + "vs2015" = [GeneratorInfo]::new("Visual Studio 14 2015", $multiConfig, $false, "", @()); + "mingw-make" = [GeneratorInfo]::new("MinGW Makefiles", $singleConfig, $false, "", @()); + "mingw-ninja" = [GeneratorInfo]::new("Ninja", $singleConfig, $false, "", @()) +} + + +function Get-GeneratorInfo([string]$flavor) +{ + return $cmakeGenMap[$flavor] +} + +function Quote-Args([string[]]$arglist) +{ + return ($arglist | foreach-object { if ($_ -like "* *") { "`"$_`"" } else { $_ } }) +} + + +## Output help early and exit. +if ($help) +{ + Show-Help +} + +### CTest params: +## timeout is 180 seconds +$ctestTimeout = "300" + +## Sanity checking: Check that utilities we expect exist... +## CMake: Save the location of the command because we'll invoke it later. Same +## with CTest +$cmakeCmd = $(Get-Command -Name cmake.exe -ErrorAction Ignore).Path +$ctestCmd = $(Get-Command -Name ctest.exe -ErrorAction Ignore).Path +if ($cmakeCmd.Length -gt 0) +{ + Write-Host "** ${scriptName}: cmake is '${cmakeCmd}'" + Write-Host "** $(& ${cmakeCmd} --version)" +} +else { + @" +!! ${scriptName} error: + +The 'cmake' command was not found. Please ensure that you have installed CMake +and that your PATH environment variable references the directory in which it +was installed. +"@ + + exit 1 +} + +if (!$testonly) +{ + ## Check for GCC and mingw32-make if user wants the mingw flavor build. + if ($flavor -eq "mingw" -or $flavor -eq "ninja") + { + if ($(Get-Command gcc -ErrorAction Ignore).Path.Length -eq 0) { + @" + !! ${scriptName} error: + + Did not find 'gcc', the GNU C/C++ compiler toolchain. Please ensure you have + installed gcc and that your PATH environment variables references the directory + in which it was installed. +"@ + exit 1 + } + + if ($(Get-Command mingw32-make -ErrorAction Ignore).Path.Length -eq 0) { + @" + !! ${scriptName} error: + + Did not find 'mingw32-make'. Please ensure you have installed mingw32-make and + that your PATH environment variables references the directory in which it was + installed. + + See the .travis/deps.sh functions mingw64() and ucrt64() for the pacman packages + that should be installed. +"@ + exit 1 + } + } +} + +## Validate the requested configuration. +if (!@("Release", "Debug").Contains($config)) +{ + @" +${scriptName}: Invalid configuration: "${config}". + +"@ + Show-Help +} + +## Look for Git's /usr/bin subdirectory: CMake (and other utilities) have issues +## with the /bin/sh installed there (Git's version of MinGW.) + +$tmp_path = $env:PATH +$git_usrbin = "${env:ProgramFiles}\Git\usr\bin" +$tmp_path = ($tmp_path.Split(';') | Where-Object { $_ -ne "${git_usrbin}"}) -join ';' +if ($tmp_path -ne ${env:PATH}) +{ + Write-Host "** ${scriptName}: Removed ${git_usrbin} from PATH (Git MinGW problem)" + $env:PATH = $tmp_path +} + +## Also make sure that none of the other cmake-* directories are in the user's PATH +## because CMake's find_package does traverse PATH looking for potential candidates +## for dependency libraries. + +$origPath = $env:PATH +$modPath = $origPath + +if (Test-Path -Path cmake\dependencies) { + $bdirs = $(Get-ChildItem -Attribute Directory cmake\dependencies\*).ForEach({ $_.FullName + "\bin" }) + $modPath = (${env:Path}.Split(';') | Where-Object { $bdirs -notcontains $_ }) -join ';' + if ($modPath -ne $origPath) { + Write-Host "** ${scriptName}: Removed cmake\dependencies 'bin' directories from PATH." + } +} + +## Setup: +$simhTopDir = $(Split-Path -Parent $(Resolve-Path -Path $PSCommandPath).Path) +While (!([String]::IsNullOrEmpty($simhTopDir) -or (Test-Path -Path ${simhTopDir}\CMakeLists.txt))) { + $simhTopDir = $(Split-Path -Parent $simhTopDir) +} +if ([String]::IsNullOrEmpty($simhTopDir)) { + @" +!! ${scriptName}: Cannot locate SIMH top-level source directory from +the script's path name. You should really not see this message. +"@ + + exit 1 +} else { + Write-Host "** ${scriptName}: SIMH top-level source directory is ${simhTopDir}" +} + +$buildDir = "${simhTopDir}\cmake\build-${flavor}" +$genInfo = $(Get-GeneratorInfo $flavor) +if ($null -eq $genInfo) +{ + Write-Host "" + Write-Host "!! ${scriptName}: Unrecognized build flavor '${flavor}'." + Write-Host "" + Show-Help +} + +if ($regenerate) +{ + $generate = $true; +} + +if ($testonly) +{ + $scriptPhases = @("test") +} +elseif ($generate) +{ + $scriptPhases = @("generate") +} +elseif ($installOnly) +{ + $scriptPhases = @("install") +} +else +{ + $scriptPhases = @( "generate", "build", "test") + if ($notest) + { + $scriptPhases = $scriptPhases | Where-Object { $_ -ne 'test' } + } + if ($noinstall -or ![String]::IsNullOrEmpty($target)) + { + $scriptPhases = $scriptPhases | Where-Object { $_ -ne 'install' } + } +} + +if (($scriptPhases -contains "generate") -or ($scriptPhases -contains "build")) +{ + ## Clean out the build subdirectory + if ((Test-Path -Path ${buildDir}) -and $clean) + { + Write-Host "** ${scriptName}: Removing ${buildDir}" + Remove-Item -recurse -force -Path ${buildDir} -ErrorAction SilentlyContinue | Out-Null + } + + if (!(Test-Path -Path ${buildDir})) + { + Write-Host "** ${scriptName}: Creating ${buildDir} subdirectory" + New-Item -Path ${buildDir} -ItemType Directory | Out-Null + } + else + { + Write-Host "** ${scriptName}: ${buildDir} exists." + } + + ## Need to regenerate? + if ($regenerate) + { + Remove-Item -Force -Path ${buildDir}/CMakeCache.txt -ErrorAction SilentlyContinue | Out-Null + Remove-Item -Recurse -Force -Path ${buildDir}/CMakeFiles -ErrorAction SilentlyContinue | Out-Null + } + + ## Where we do the heaving lifting: + $generateArgs = @("-G", $genInfo.Generator) + if ($genInfo.SingleConfig) { + ## Single configuration set at compile time: + $generateArgs += @("-DCMAKE_BUILD_TYPE=${config}") + } + if ($genInfo.UCRT) { + ## Universal Windows Platform + $generateArgs += @("-DCMAKE_SYSTEM_NAME=WindowsStore", "-DCMAKE_SYSTEM_VERSION=$($genInfo.UCRTVersion)") + } + $generateArgs += $genInfo.ArchArgs + @("-Wno-dev", "--no-warn-unused-cli") + if ($nonetwork) + { + $generateArgs += @("-DWITH_NETWORK:Bool=Off") + } + if ($novideo) + { + $generateArgs += @("-DWITH_VIDEO:Bool=Off") + } + if ($lto) + { + $generateArgs += @("-DRELEASE_LTO:Bool=On") + } + if ($debugWall) + { + $generateArgs += @("-DDEBUG_WALL:Bool=On") + } + if ($cppcheck) + { + $generateArgs += @("-DENABLE_CPPCHECK:Bool=On") + } + if (![String]::IsNullOrEmpty($cpack_suffix)) + { + $generateArgs += @("-DSIMH_PACKAGE_SUFFIX:Bool=${cpack_suffix}") + } + + $buildArgs = @("--build", "${buildDir}", "--config", "${config}") + if ($parallel) + { + $buildArgs += "--parallel" + } + if ($verbose) + { + $buildArgs += "--verbose" + } + if ($windeprecation) + { + $buildArgs += "-DWINAPI_DEPRECATION:Bool=TRUE" + } + if (![String]::IsNullOrEmpty($target)) { + $buildArgs += @("--target", "$target") + } + + $buildSpecificArgs = @() + if ($flavor -eq "mingw" -and $parallel) + { + ## Limit the number of parallel jobs mingw32-make can spawn. Otherwise + ## it'll overwhelm the machine. + $buildSpecificArgs += @("-j", "8") + } +} + +$exitval = 0 + +foreach ($phase in $scriptPhases) { + $savedPATH = $env:PATH + $argList = @() + $phaseCommand = "Write-Output" + + switch -exact ($phase) + { + "generate" { + $generateArgs += @("-S", ${simhTopDir}) + $generateArgs += @("-B", ${buildDir}) + + Write-Host "** ${scriptName}: Configuring and generating" + + $phaseCommand = ${cmakeCmd} + $argList = Quote-Args $generateArgs + } + + "build" { + Write-Host "** ${scriptName}: Building simulators." + + $phaseCommand = ${cmakeCmd} + $argList = $(Quote-Args $buildArgs) + $(Quote-Args $buildSpecificArgs) + } + + "test" { + Write-Host "** ${scriptName}: Testing simulators." + + ## CTest arguments: + $testArgs = @("-C", $config, "--timeout", $ctestTimeout, "-T", "test", + "--output-on-failure") + + ## Output gets confusing (and tests can time out when executing in parallel) + ## if ($parallel) + ## { + ## $testArgs += @("--parallel", $ctestParallel) + ## } + + if ($verbose) + { + $testArgs += @("--verbose") + } + + if (![String]::IsNullOrEmpty($target)) { + $testArgs += @("-R", "simh-${target}`$") + } + + $phaseCommand = ${ctestCmd} + $argList = Quote-Args $testArgs + + $env:PATH = $modPath + + $depTopDir = $(& $cmakeCmd -L -N ${buildDir} | Select-String "SIMH_DEP_TOPDIR") + if ($depTopDir) { + ## RHS of the cached variable's value. + $depTopDir = $depTopDir.Line.Split('=')[1] + $env:PATH = "${depTopdir}\bin;${env:PATH}" + } + } + + "install" { + Write-Host "** ${scriptName}: Installing simulators." + + $installPrefix = $(& $cmakeCmd -L -N ${buildDir} | Select-String "CMAKE_INSTALL_PREFIX") + $installPrefix = $installPrefix.Line.Split('=')[1] + $installPath = $installPrefix + + Write-Host "** ${scriptName}: Install directory ${installPath}" + if (!(Test-Path -Path ${installPath})) + { + Write-Host "** ${scriptName}: Creating ${installPath}" + New-Item -${installPath} -ItemType Directory -ErrorAction SilentlyContinue + } + + $phaseCommand = ${cmakeCmd} + $argList = Quote-Args @( "--install", "${buildDir}", "--config", "${config}") + } + } + + try { + Push-Location ${buildDir} + Write-Host "** ${phaseCommand} ${argList}" + & $phaseCommand @arglist + if ($LastExitCode -gt 0) { + $printPhase = (Get-Culture).TextInfo.ToTitleCase($phase) + Write-Error $("${printPhase} phase exited with non-zero status: " + $LastExitCode) + exit 1 + } + } + catch { + Write-Host "Error running '${phaseCommand} ${argList}' command: $($_.Exception.Message)" -ForegroundColor Red + throw $_ + } + finally { + Pop-Location + } + + $env:PATH = $savedPATH +} + +exit $exitval diff --git a/cmake/cmake-builder.sh b/cmake/cmake-builder.sh new file mode 100755 index 00000000..2ed9763b --- /dev/null +++ b/cmake/cmake-builder.sh @@ -0,0 +1,394 @@ +#!/bin/bash + +##-- Bash functions -- +showHelp() +{ + [ x"$1" != x ] && { echo "${scriptName}: $1"; echo ""; } + cat < /dev/null 2>&1 + if [[ $? -eq 4 ]]; then + getopt_prog="${p}/getopt" + break + fi +done +IFS="${IFS_SAVE}" + +if [[ "x${getopt_prog}" = "x" ]]; then + echo "${scriptName}: GNU getopt needed for this script to function properly." + echo "${scriptName}: Specifically, a 'getopt' that supports the '-T' flag (enhanced getopt)" + exit 1 +fi + +## This script also needs GNU coreutils +realpath=$(which realpath) || { + echo "${scriptName}: Could not find 'realpath'. Please install and re-execute this script." + echo "${scriptName}: 'realpath' is a component of the GNU coreutils collection." +} +dirname=$(which dirname) || { + echo "${scriptName}: Could not find 'dirname'. Please install and re-execute this script." + echo "${scriptName}: 'dirname' is a component of the GNU coreutils collection." +} + +## Check if CMake supports parallel +cmake=$(which cmake) || { + echo "${scriptName}: Could not find 'cmake'. Please install and re-execute this script." + exit 1 +} + +ctest=$(which ctest) || { + echo "${scriptName}: Could not find 'ctest'. Please check your 'cmake' installation." + exit 1 +} + +echo "** $(${cmake} --version)" + +$(${cmake} -h 2>&1 | grep -- "-S" > /dev/null) && { + cmakeSFlag=yes +} + +canParallel=no +(${cmake} --build /tmp --help 2>&1 | grep parallel > /dev/null) && { + canParallel=yes +} + +canTestParallel=no +# (${ctest} --help 2>&1 | grep parallel > /dev/null) && { +# canTestParallel=yes +# } + +if [[ "x${MSYSTEM}" != x ]]; then + case "${MSYSTEM}" in + MSYS|MINGW64) + buildFlavor="MinGW Makefiles" + buildSubdir=build-mingw + ;; + UCRT64) + buildFlavor="Ninja" + buildSubdir=build-ninja + ;; + esac +fi + +longopts=clean,help,flavor:,config:,nonetwork,novideo,notest,parallel,generate,testonly,regenerate +longopts=${longopts},noinstall,installonly,verbose,target:,lto,debugWall,cppcheck,cpack_suffix: + +ARGS=$(${getopt_prog} --longoptions $longopts --options xhf:cpg -- "$@") +if [ $? -ne 0 ] ; then + showHelp "${scriptName}: Usage error (use -h for help.)" +fi + +eval set -- ${ARGS} +while true; do + case $1 in + -x | --clean) + buildClean=yes; shift + ;; + -h | --help) + showHelp + ;; + -f | --flavor) + case "$2" in + unix) + buildFlavor="Unix Makefiles" + buildSubdir=build-unix + shift 2 + ;; + ninja|ucrt64) + buildFlavor=Ninja + buildSubdir=build-ninja + shift 2 + ;; + xcode) + buildFlavor=Xcode + buildSubdir=build-xcode + shift 2 + ;; + xcode-universal) + buildFlavor=Xcode + buildSubdir=build-xcode-universal + generateArgs="${generateArgs} -DMAC_UNIVERSAL:Bool=On" + shift 2 + ;; + mingw|mingw64|msys|msys2) + buildFlavor="MinGW Makefiles" + buildSubdir=build-mingw + shift 2 + ;; + *) + showHelp "Invalid build flavor: $2" + ;; + esac + ;; + -c | --config) + case "$2" in + Release|Debug) + buildConfig=$2 + shift 2 + ;; + *) + showHelp "Invalid build configuration: $2" + ;; + esac + ;; + --nonetwork) + generateArgs="${generateArgs} -DWITH_NETWORK:Bool=Off" + shift + ;; + --novideo) + generateArgs="${generateArgs} -DWITH_VIDEO:Bool=Off" + shift + ;; + --notest) + notest=yes + shift + ;; + --noinstall) + noinstall=yes + shift + ;; + --lto) + generateArgs="${generateArgs} -DRELEASE_LTO:Bool=On" + shift + ;; + --debugWall) + generateArgs="${generateArgs} -DDEBUG_WALL:Bool=On" + shift + ;; + --cppcheck) + generateArgs="${generateArgs} -DENABLE_CPPCHECK:Bool=On" + shift + ;; + --cpack_suffix) + generateArgs="${generateArgs} -DSIMH_PACKAGE_SUFFIX=$2" + shift 2 + ;; + -p | --parallel) + buildParallel=yes + shift + ;; + -g | --generate) + generateOnly=yes + shift + ;; + -r | --regenerate) + generateOnly=yes + regenerateFlag=yes + shift + ;; + --testonly) + testOnly=yes + shift + ;; + --installonly) + installOnly=yes + shift + ;; + --verbose) + verboseMode="--verbose" + shift + ;; + --target) + noinstall=yes + simTarget="$2" + shift 2 + ;; + --) + ## End of options. we'll ignore. + shift + break + ;; + esac +done + +## Determine the SIMH top-level source directory: +simhTopDir=$(${dirname} $(${realpath} $0)) +while [ "x${simhTopDir}" != x -a ! -f "${simhTopDir}/CMakeLists.txt" ]; do + simhTopDir=$(${dirname} "${simhTopDir}") +done + +if [[ "x${simhTopDir}" = x ]]; then + echo "${scriptName}: Can't determine SIMH top-level source directory." + echo "Did this really happen?" + exit 1 +else + buildSubdir=$(${realpath} "${simhTopDir}/cmake/${buildSubdir}") + echo "${scriptName}: SIMH top-evel directory: ${simhTopDir}" + echo "${scriptName}: Build directory: ${buildSubdir}" +fi + +if [[ x"$buildClean" != x ]]; then + echo "${scriptName}: Cleaning ${buildSubdir}" + rm -rf ${buildSubdir} +fi +if [[ ! -d ${buildSubdir} ]]; then + mkdir ${buildSubdir} +fi + +## Setup test arguments (and add parallel later) +testArgs="-C ${buildConfig} --timeout 180 --output-on-failure" + +## Parallel only applies to the unix flavor. GNU make will overwhelm your +## machine if the number of jobs isn't capped. +if [[ x"$canParallel" = xyes ]] ; then + if [ x"$buildParallel" = xyes -a "$buildFlavor" != Ninja ] ; then + (${cmake} --build . --help 2>&1 | grep parallel 2>&1 > /dev/null) && { + buildArgs="${buildArgs} --parallel" + buildPostArgs="${buildPostArgs} -j 8" + } + # Don't execute ctest in parallel... + # [ x${canTestParallel} = xyes ] && { + # testArgs="${testArgs} --parallel 4" + # } + fi +else + buildParallel= +fi + +if [[ x"${simTarget}" != x ]]; then + buildArgs="${buildArgs} --target ${simTarget}" + testArgs="${testArgs} -R simh-${simTarget}\$" +fi + +buildArgs="${buildArgs} --config ${buildConfig}" + +if [[ x$generateOnly = xyes ]]; then + phases=generate +elif [[ x$testOnly = xyes ]]; then + phases=test +elif [[ x$installOnly = xyes ]]; then + phases=install +else + phases="generate build" + if [[ x${notest} != xyes ]]; then + phases="${phases} test" + fi +fi + +for ph in ${phases}; do + case $ph in + generate) + [ x$regenerateFlag = xyes ] && { + echo "${scriptName}: Removing CMakeCache.txt and CMakeFiles" + rm -rf ${buildSubdir}/CMakeCache.txt ${buildSubdir}/CMakefiles + } + if [[ "x${cmakeSFlag}" != x ]]; then + echo "${cmake} -G "\"${buildFlavor}\"" -DCMAKE_BUILD_TYPE="${buildConfig}" -S "${simhTopDir}" -B ${buildSubdir} ${generateArgs}" + ${cmake} -G "${buildFlavor}" -DCMAKE_BUILD_TYPE="${buildConfig}" -S "${simhTopDir}" -B "${buildSubdir}" ${generateArgs} || { \ + echo "*** ${scriptName}: Errors detected during environment generation. Exiting." + exit 1 + } + else + echo "${cmake} -G "\"${buildFlavor}\"" -DCMAKE_BUILD_TYPE="${buildConfig}" "${simhTopDir}" ${generateArgs}" + ( cd "${buildSubdir}"; \ + ${cmake} -G "${buildFlavor}" -DCMAKE_BUILD_TYPE="${buildConfig}" "${simhTopDir}" ${generateArgs}) || { \ + echo "*** ${scriptName}: Errors detected during environment generation. Exiting."; + exit 1 + } + fi + ;; + build) + ${cmake} --build "${buildSubdir}" ${buildArgs} ${verboseMode} -- ${buildPostArgs} || { + echo "*** ${scriptName}: Build errors detected. Exiting." + exit 1 + } + ;; + test) + (cd "${buildSubdir}" \ + && echo ${ctest} ${testArgs} ${verboseMode} \ + && ${ctest} ${testArgs} ${verboseMode}) || { + echo "*** ${scriptName}: Errors detected during testing. Exiting." + exit 1 + } + ;; + install) + ${cmake} --build "${buildSubdir}" --target install --config "${buildConfig}" + ;; + package) + (cd "${buildSubdir}" \ + && ${cpack} -G ZIP -C ${buildConfig} ${verboseMode} \ + && mv *.zip ${simhTopDir}/PACKAGES \ + ) + ;; + esac +done diff --git a/cmake/cpack-setup.cmake b/cmake/cpack-setup.cmake new file mode 100644 index 00000000..400c2aad --- /dev/null +++ b/cmake/cpack-setup.cmake @@ -0,0 +1,139 @@ +## CPack setup -- sets the CPACK_* variables for the sundry installers +## +## Author: B. Scott Michel (scooter.phd@gmail.com) +## "scooter me fecit" + + +## pre_runtime_exclusions: These are the names of dependency libraries, esp. on Windows +## that should not get installed as runtime or library dependencies. +## +## post_runtime_exclusions: These are regex expressions for the dependency paths to filter out, +## notably Windows system32 DLLs. +set(pre_runtime_exclusions) +list(APPEND pre_runtime_exclusions + ## Windows: + "(ext|api)-ms-.*" + "hvsifiletrust.dll" + "pdmutilities.dll" +) +set(post_runtime_exclusions) +list(APPEND post_runtime_exclusions + ".*system32/.*\\.dll" +) + +## Make runtime_support the default component (vice "Unspecified") +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "runtime_support") + +# After we know where everything will install, let CPack figure out +# how to assemble it into a package file. +set(CPACK_PACKAGE_VENDOR "The Open-SIMH project") + +if (SIMH_PACKAGE_SUFFIX) + set(buildSuffix "${SIMH_PACKAGE_SUFFIX}") +else () + set(buildSuffix "") + if (WIN32) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + list(APPEND buildSuffix "win64") + else () + list(APPEND buildSuffix "win32") + endif () + + list(APPEND buildSuffix "\${CPACK_BUILD_CONFIG}") + ## If using Visual Studio, append the compiler and toolkit: + if (CMAKE_GENERATOR MATCHES "Visual Studio 17 .*") + list(APPEND buildSuffix "vs2022") + elseif (CMAKE_GENERATOR MATCHES "Visual Studio 16 .*") + list(APPEND buildSuffix "vs2019") + elseif (CMAKE_GENERATOR MATCHES "Visual Studio 15 .*") + list(APPEND buildSuffix "vs2017") + elseif (CMAKE_GENERATOR MATCHES "Visual Studio 14 .*") + list(APPEND buildSuffix "vs2015") + endif () + if (CMAKE_GENERATOR_TOOLSET MATCHES "v[0-9][0-9][0-9]_xp") + string(APPEND buildSuffix "xp") + endif () + else () + list(APPEND buildSuffix ${CMAKE_SYSTEM_NAME}) + endif () + + list(JOIN buildSuffix "-" buildSuffix) + + message(STATUS "No SIMH_PACKAGE_SUFFIX supplied, default is ${buildSuffix}.") +endif () + +string(JOIN "-" CPACK_PACKAGE_FILE_NAME + "${CMAKE_PROJECT_NAME}" + "${CMAKE_PROJECT_VERSION}" + "${buildSuffix}" +) + +message(STATUS "CPack output file name: ${CPACK_PACKAGE_FILE_NAME}") +unset(buildSuffix) + +## When applicable (e.g., NSIS Windows), install under the SIMH-x.y directory: +set(CPACK_PACKAGE_INSTALL_DIRECTORY "SIMH-${SIMH_VERSION_MAJOR}.${SIMH_VERSION_MINOR}") +## License file: +set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE.txt) + +set(CPACK_PACKAGE_CONTACT "open-simh@nowhere.org") +set(CPACK_PACKAGE_MAINTAINER "open-simh@nowhere.org") + +## Runtime dependencies: +if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.21") + ## Don't install runtime dependencies on Linux platforms. The platform's + ## package management system will take care of this for us. + if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") + install(RUNTIME_DEPENDENCY_SET simhRuntime + COMPONENT runtime_support + PRE_EXCLUDE_REGEXES ${pre_runtime_exclusions} + POST_EXCLUDE_REGEXES ${post_runtime_exclusions} + ) + endif () +endif () + + +## Extra properties and variables: +set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_BINARY_DIR}/CPackSimhCustom.cmake) +configure_file(${CMAKE_SOURCE_DIR}/cmake/installer-customizations/CPackSimhCustom.cmake.in + ${CMAKE_BINARY_DIR}/CPackSimhCustom.cmake + @ONLY) + +## CPack generator-specific configs: + +##+ +## NullSoft Installation System (NSIS) Windows installer. Creates an installer EXE. +##- +set(CPACK_NSIS_PACKAGE_NAME ${CPACK_PACKAGE_INSTALL_DIRECTORY}) +set(CPACK_NSIS_INSTALL_ROOT "$LocalAppData\\\\Programs") + +## CPack does this configure_file on its own to genreate the project.nsi file. +## Keeping these lines for history. +# configure_file(${CMAKE_SOURCE_DIR}/cmake/installer-customizations/NSIS.template.in +# ${CMAKE_BINARY_DIR}/NSIS.template +# @ONLY) + +###+ +### WIX MSI Windows installer. +### +### +### Upgrade GUID shouldn't really change. +###- +set(CPACK_WIX_UPGRADE_GUID "ed5dba4c-7c9e-4af8-ac36-37e14c637696") + +##+ +## Debian: +##- + +list(APPEND debian_depends + libsdl2-2.0-0 + libsdl2-ttf-2.0-0 + libpcap0.8 + libvdeplug2 + libedit2 +) + +string(JOIN ", " CPACK_DEBIAN_PACKAGE_DEPENDS ${debian_depends}) + + +include(CPack) diff --git a/cmake/dep-link.cmake b/cmake/dep-link.cmake new file mode 100644 index 00000000..56e5bfa4 --- /dev/null +++ b/cmake/dep-link.cmake @@ -0,0 +1,346 @@ +##+ +## dep-link.cmake: Create the dependency interface libraries +##- + +add_library(simh_regexp INTERFACE) +add_library(simh_video INTERFACE) +add_library(simh_network INTERFACE) + +## LIBPCAP is a special case +set(LIBPCAP_PROJECT "libpcap") +set(LIBPCAP_ARCHIVE_NAME "libpcap") +set(LIBPCAP_RELEASE "1.10.1") +set(LIBPCAP_ARCHIVE_TYPE "tar.gz") +set(LIBPCAP_TAR_ARCHIVE "${LIBPCAP_ARCHIVE_NAME}-${LIBPCAP_RELEASE}.${LIBPCAP_ARCHIVE_TYPE}") +set(LIBPCAP_SOURCE_URL "https://github.com/the-tcpdump-group/libpcap/archive/refs/tags/${LIBPCAP_TAR_ARCHIVE}") + +function(fix_interface_libs _targ) +get_target_property(_aliased ${_targ} ALIASED_TARGET) + if(NOT _aliased) + set(fixed_libs) + get_property(orig_libs TARGET ${_targ} PROPERTY INTERFACE_LINK_LIBRARIES) + foreach(each_lib IN LISTS ${_lib}) + string(STRIP ${each_lib} stripped_lib) + list(APPEND fixed_libs ${stripped_lib}) + message("** \"${each_lib}\" -> \"${stripped_lib}\"") + endforeach () + set_property(TARGET ${_targ} PROPERTY INTERFACE_LINK_LIBRARIES ${fixed_libs}) + endif () +endfunction () + +## Ubuntu 16.04 -- when we find the SDL2 library, there are trailing spaces. Strip +## spaces from SDL2_LIBRARIES (and potentially others as we find them). +function (fix_libraries _lib) + set(fixed_libs) + foreach(each_lib IN LISTS ${_lib}) + string(STRIP ${each_lib} stripped_lib) + list(APPEND fixed_libs ${stripped_lib}) + endforeach () + set(${_lib} ${fixed_libs} PARENT_SCOPE) +endfunction () + +set(BUILD_WITH_VIDEO FALSE) +IF (WITH_VIDEO) + ## +10 chaotic neutral hack: The SDL2_ttf CMake configuration include "-lfreetype" and + ## "-lharfbuzz", but, if you're on MacOS, you need to tell the linker where these libraries + ## are located... + set(ldirs) + foreach (lname ${FREETYPE_LIBRARIES} ${FREETYPE_LIBRARY} ${HARFBUZZ_LIBRARIES} ${HARFBUZZ_LIBRARY}) + get_filename_component(dirname "${lname}" DIRECTORY) + if (dirname) + list(APPEND ldirs ${dirname}) + endif() + endforeach () + get_property(ilink_dirs TARGET simh_video PROPERTY INTERFACE_LINK_DIRECTORIES) + list(APPEND ilink_dirs ${ldirs}) + set_property(TARGET simh_video PROPERTY INTERFACE_LINK_DIRECTORIES ${ilink_dirs}) + unset(ilink_dirs) + unset(ldirs) + + IF (SDL2_ttf_FOUND) + IF (WIN32 AND TARGET SDL2_ttf::SDL2_ttf-static) + target_link_libraries(simh_video INTERFACE SDL2_ttf::SDL2_ttf-static) + list(APPEND VIDEO_PKG_STATUS "SDL2_ttf static") + ELSEIF (TARGET SDL2_ttf::SDL2_ttf) + target_link_libraries(simh_video INTERFACE SDL2_ttf::SDL2_ttf) + list(APPEND VIDEO_PKG_STATUS "SDL2_ttf dynamic") + ELSEIF (TARGET PkgConfig::SDL2_ttf) + target_link_libraries(simh_video INTERFACE PkgConfig::SDL2_ttf) + list(APPEND VIDEO_PKG_STATUS "pkg-config SDL2_ttf") + ELSEIF (DEFINED SDL_ttf_LIBRARIES AND DEFINED SDL_ttf_INCLUDE_DIRS) + target_link_libraries(simh_video INTERFACE ${SDL_ttf_LIBRARIES}) + target_include_directories(simh_video INTERFACE ${SDL_ttf_INCLUDE_DIRS}) + list(APPEND VIDEO_PKG_STATUS "detected SDL2_ttf") + ELSE () + message(FATAL_ERROR "SDL2_ttf_FOUND set but no SDL2_ttf::SDL2_ttf import library or SDL_ttf_LIBRARIES/SDL_ttf_INCLUDE_DIRS? ") + ENDIF () + ENDIF (SDL2_ttf_FOUND) + + IF (SDL2_FOUND) + target_compile_definitions(simh_video INTERFACE USE_SIM_VIDEO HAVE_LIBSDL) + ## + ## Hopefully this hack can go away. Had to move the target_compile_definitions + ## over to add_simulator.cmake to accomodate the BESM6 SDL irregularity. + ## + ## (keep) if (CMAKE_HOST_APPLE) + ## (keep) ## NOTE: This shouldn't be just an Apple platform quirk; SDL_main should + ## (keep) ## be used by all platforms. + ## (keep) target_compile_definitions(simh_video INTERFACE SDL_MAIN_AVAILABLE) + ## (keep) endif () + + ## Link to SDL2main if defined for this platform. + target_link_libraries(simh_video INTERFACE $) + + IF (WIN32 AND TARGET SDL2::SDL2-static AND TARGET SDL2_ttf::SDL2_ttf-static) + ## Prefer the static version on Windows, but only if SDL2_ttf is also static. + target_link_libraries(simh_video INTERFACE SDL2::SDL2-static) + list(APPEND VIDEO_PKG_STATUS "SDL2 static") + ELSEIF (TARGET SDL2::SDL2) + fix_interface_libs(SDL2::SDL2) + target_link_libraries(simh_video INTERFACE SDL2::SDL2) + list(APPEND VIDEO_PKG_STATUS "SDL2 dynamic") + ELSEIF (TARGET PkgConfig::SDL2) + fix_interface_libs(PkgConfig::SDL2) + target_link_libraries(simh_video INTERFACE PkgConfig::SDL2) + list(APPEND VIDEO_PKG_STATUS "pkg-config SDL2") + ELSEIF (DEFINED SDL2_LIBRARIES AND DEFINED SDL2_INCLUDE_DIRS) + fix_libraries(SDL2_LIBRARIES) + target_link_libraries(simh_video INTERFACE ${SDL2_LIBRARIES}) + target_include_directories(simh_video INTERFACE ${SDL2_INCLUDE_DIRS}) + list(APPEND VIDEO_PKG_STATUS "detected SDL2") + ELSE () + message(FATAL_ERROR "SDL2_FOUND set but no SDL2::SDL2 import library or SDL2_LIBRARIES/SDL2_INCLUDE_DIRS?") + ENDIF () + ENDIF (SDL2_FOUND) + + IF (NOT USING_VCPKG AND FREETYPE_FOUND) + if (TARGET Freetype::Freetype) + target_link_libraries(simh_video INTERFACE freetype) + list(APPEND VIDEO_PKG_STATUS "Freetype::Freetype") + ELSEIF (TARGET PkgConfig::Freetype) + target_link_libraries(simh_video INTERFACE PkgConfig::Freetype) + list(APPEND VIDEO_PKG_STATUS "pkg-config Freetype") + ELSE () + target_link_libraries(simh_video INTERFACE ${FREETYPE_LIBRARIES}) + target_include_directories(simh_video INTERFACE ${FREETYPE_INCLUDE_DIRS}) + list(APPEND VIDEO_PKG_STATUS "detected Freetype") + ENDIF () + ENDIF () + + IF (PNG_FOUND) + if (TARGET PNG::PNG) + target_link_libraries(simh_video INTERFACE PNG::PNG) + list(APPEND VIDEO_PKG_STATUS "interface PNG") + elseif (TARGET PkgConfig::PNG) + target_link_libraries(simh_video INTERFACE PkgConfig::PNG) + list(APPEND VIDEO_PKG_STATUS "pkg-config PNG") + else () + target_include_directories(simh_video INTERFACE ${PNG_INCLUDE_DIRS}) + target_link_libraries(simh_video INTERFACE ${PNG_LIBRARIES}) + list(APPEND VIDEO_PKG_STATUS "detected PNG") + endif () + ENDIF (PNG_FOUND) + + set(BUILD_WITH_VIDEO TRUE) +ELSE () + set(VIDEO_PKG_STATUS "video support disabled") +ENDIF() + +if (WITH_REGEX) + ## TEMP: Use PCRE until patches for PCRE2 are avaiable. + ## + ## 1. Prefer PCRE2 over PCRE (unless PREFER_PCRE is set) + ## 2. Prefer interface libraries before using detected find_package + ## variables. + IF (TARGET PkgConfig::PCRE) + target_link_libraries(simh_regexp INTERFACE PkgConfig::PCRE) + if (PREFER_PCRE) + target_compile_definitions(simh_regexp INTERFACE HAVE_PCRE_H) + set(PCRE_PKG_STATUS "pkg-config pcre") + else () + target_compile_definitions(simh_regexp INTERFACE HAVE_PCRE2_H) + if (WIN32) + ## Use static linkage (vice DLL) on Windows: + target_compile_definitions(simh_regexp INTERFACE PCRE2_STATIC) + endif () + set(PCRE_PKG_STATUS "pkg-config pcre2") + endif () + ELSEIF (TARGET unofficial::pcre::pcre) + ## vcpkg: + target_link_libraries(simh_regexp INTERFACE unofficial::pcre::pcre) + target_compile_definitions(simh_regexp INTERFACE HAVE_PCRE_H) + target_compile_definitions(simh_regexp INTERFACE PCRE_STATIC) + set(PCRE_PKG_STATUS "vcpkg pcre") + ELSEIF (NOT PREFER_PCRE AND PCRE2_FOUND) + target_compile_definitions(simh_regexp INTERFACE HAVE_PCRE2_H) + target_include_directories(simh_regexp INTERFACE ${PCRE2_INCLUDE_DIRS}) + if (NOT WIN32) + target_link_libraries(simh_regexp INTERFACE ${PCRE2_LIBRARY}) + else () + ## Use static linkage (vice DLL) on Windows: + target_compile_definitions(simh_regexp INTERFACE PCRE2_STATIC) + endif () + + set(PCRE_PKG_STATUS "detected pcre2") + ELSEIF (PCRE_FOUND) + target_compile_definitions(simh_regexp INTERFACE HAVE_PCRE_H) + target_include_directories(simh_regexp INTERFACE ${PCRE_INCLUDE_DIRS}) + target_link_libraries(simh_regexp INTERFACE ${PCRE_LIBRARY}) + if (WIN32) + target_compile_definitions(simh_regexp INTERFACE PCRE_STATIC) + endif () + set(PCRE_PKG_STATUS "detected pcre") + endif () +endif () + +if ((WITH_REGEX OR WITH_VIDEO) AND ZLIB_FOUND) + target_compile_definitions(simh_regexp INTERFACE HAVE_ZLIB) + target_compile_definitions(simh_video INTERFACE HAVE_ZLIB) + if (TARGET ZLIB::ZLIB) + target_link_libraries(simh_regexp INTERFACE ZLIB::ZLIB) + target_link_libraries(simh_video INTERFACE ZLIB::ZLIB) + set(ZLIB_PKG_STATUS "interface ZLIB") + elseif (TARGET PkgConfig::ZLIB) + target_link_libraries(simh_regexp INTERFACE PkgConfig::ZLIB) + target_link_libraries(simh_video INTERFACE PkgConfig::ZLIB) + set(ZLIB_PKG_STATUS "pkg-config ZLIB") + else () + target_include_directories(simh_regexp INTERFACE ${ZLIB_INCLUDE_DIRS}) + target_link_libraries(simh_regexp INTERFACE ${ZLIB_LIBRARIES}) + target_include_directories(simh_video INTERFACE ${ZLIB_INCLUDE_DIRS}) + target_link_libraries(simh_video INTERFACE ${ZLIB_LIBRARIES}) + set(ZLIB_PKG_STATUS "detected ZLIB") + endif () +endif () + + +if (WITH_NETWORK) + set(network_runtime USE_SHARED) + ## pcap is special: Headers only and dynamically loaded. + if (WITH_PCAP) + find_package(PCAP) + + if (NOT PCAP_FOUND) + list(APPEND NETWORK_PKG_STATUS "PCAP dynamic (unpacked)") + + message(STATUS "Downloading ${LIBPCAP_SOURCE_URL}") + message(STATUS "Destination ${CMAKE_BINARY_DIR}/libpcap") + execute_process( + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/libpcap" + RESULT_VARIABLE LIBPCAP_MKDIR + ) + if (NOT (${LIBPCAP_MKDIR} EQUAL 0)) + message(FATAL_ERROR "Could not create ${CMAKE_CMAKE_BINARY_DIR}/libpcap") + endif (NOT (${LIBPCAP_MKDIR} EQUAL 0)) + + file(DOWNLOAD "${LIBPCAP_SOURCE_URL}" "${CMAKE_BINARY_DIR}/libpcap/libpcap.${LIBPCAP_ARCHIVE_TYPE}" + STATUS LIBPCAP_DOWNLOAD + ) + list(GET LIBPCAP_DOWNLOAD 0 LIBPCAP_DL_STATUS) + if (NOT (${LIBPCAP_DL_STATUS} EQUAL 0)) + list(GET LIBPCAP_DOWNLOAD 1 LIBPCAP_DL_ERROR) + message(FATAL_ERROR "Download failed: ${LIBPCAP_DL_ERROR}") + endif (NOT (${LIBPCAP_DL_STATUS} EQUAL 0)) + + message(STATUS "Extracting headers ${LIBPCAP_SOURCE_URL}") + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xvf "${CMAKE_BINARY_DIR}/libpcap/libpcap.${LIBPCAP_ARCHIVE_TYPE}" + "${LIBPCAP_PROJECT}-${LIBPCAP_ARCHIVE_NAME}-${LIBPCAP_RELEASE}/pcap.h" + "${LIBPCAP_PROJECT}-${LIBPCAP_ARCHIVE_NAME}-${LIBPCAP_RELEASE}/pcap/*.h" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/libpcap" + RESULT_VARIABLE LIBPCAP_EXTRACT + ) + if (NOT (${LIBPCAP_EXTRACT} EQUAL 0)) + message(FATAL_ERROR "Extract failed.") + endif (NOT (${LIBPCAP_EXTRACT} EQUAL 0)) + + message(STATUS "Copying headers from ${CMAKE_BINARY_DIR}/libpcap/${LIBPCAP_PROJECT}-${LIBPCAP_ARCHIVE_NAME}-${LIBPCAP_RELEASE}/pcap") + message(STATUS "Destination ${CMAKE_BINARY_DIR}/include/pcap") + execute_process( + COMMAND "${CMAKE_COMMAND}" -E copy_directory + "${LIBPCAP_PROJECT}-${LIBPCAP_ARCHIVE_NAME}-${LIBPCAP_RELEASE}/" + "${CMAKE_BINARY_DIR}/include/" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/libpcap" + RESULT_VARIABLE LIBPCAP_COPYDIR + ) + if (NOT (${LIBPCAP_COPYDIR} EQUAL 0)) + message(FATAL_ERROR "Copy failed.") + endif (NOT (${LIBPCAP_COPYDIR} EQUAL 0)) + + ## And try finding it again... + find_package(PCAP) + else () + list (APPEND NETWORK_PKG_STATUS "PCAP dynamic") + endif () + + + if (PCAP_FOUND) + set(network_runtime USE_SHARED) + foreach(hdr "${PCAP_INCLUDE_DIRS}") + file(STRINGS ${hdr}/pcap/pcap.h hdrcontent REGEX "pcap_compile *\\(.*const") + # message("hdrcontent: ${hdrcontent}") + list(LENGTH hdrcontent have_bpf_const) + if (${have_bpf_const} GREATER 0) + message(STATUS "pcap_compile requires BPF_CONST_STRING") + list(APPEND network_runtime BPF_CONST_STRING) + endif() + endforeach() + + target_include_directories(simh_network INTERFACE "${PCAP_INCLUDE_DIRS}") + target_compile_definitions(simh_network INTERFACE HAVE_PCAP_NETWORK) + endif () + endif () + + ## TAP/TUN devices + if (WITH_TAP) + target_compile_definitions(simh_network INTERFACE ${NETWORK_TUN_DEFS}) + endif (WITH_TAP) + + if (WITH_VDE AND VDE_FOUND) + if (TARGET PkgConfig::VDE) + target_compile_definitions(simh_network INTERFACE $) + target_include_directories(simh_network INTERFACE $) + target_link_libraries(simh_network INTERFACE PkgConfig::VDE) + list(APPEND NETWORK_PKG_STATUS "pkg-config VDE") + else () + target_include_directories(simh_network INTERFACE "${VDEPLUG_INCLUDE_DIRS}") + target_link_libraries(simh_network INTERFACE "${VDEPLUG_LIBRARY}") + list(APPEND NETWORK_PKG_STATUS "detected VDE") + endif () + + target_compile_definitions(simh_network INTERFACE HAVE_VDE_NETWORK) + endif () + + if (WITH_TAP) + if (HAVE_TAP_NETWORK) + target_compile_definitions(simh_network INTERFACE HAVE_TAP_NETWORK) + + if (HAVE_BSDTUNTAP) + target_compile_definitions(simh_network INTERFACE HAVE_BSDTUNTAP) + list(APPEND NETWORK_PKG_STATUS "BSD TUN/TAP") + else (HAVE_BSDTUNTAP) + list(APPEND NETWORK_PKG_STATUS "TAP") + endif (HAVE_BSDTUNTAP) + + endif (HAVE_TAP_NETWORK) + endif (WITH_TAP) + + if (WITH_SLIRP) + target_link_libraries(simh_network INTERFACE slirp) + list(APPEND NETWORK_PKG_STATUS "NAT(SLiRP)") + endif (WITH_SLIRP) + + ## Finally, set the network runtime + if (NOT network_runtime) + ## Default to USE_SHARED... USE_NETWORK is deprecated. + set(network_runtime USE_SHARED) + endif (NOT network_runtime) + + target_compile_definitions(simh_network INTERFACE ${network_runtime}) + + set(BUILD_WITH_NETWORK TRUE) +else (WITH_NETWORK) + set(NETWORK_STATUS "networking disabled") + set(NETWORK_PKG_STATUS "network disabled") + set(BUILD_WITH_NETWORK FALSE) +endif (WITH_NETWORK) diff --git a/cmake/dep-locate.cmake b/cmake/dep-locate.cmake new file mode 100644 index 00000000..f80dc7c9 --- /dev/null +++ b/cmake/dep-locate.cmake @@ -0,0 +1,361 @@ +##=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= +## dep-locate.cmake +## +## Consolidated list of runtime dependencies for simh, probed/found via +## CMake's find_package() and pkg_check_modules() when 'pkgconfig' is +## available. +##=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + +##-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ +## Find packages: +##-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ + +if (WITH_REGEX) + if (PREFER_PCRE) + if (USING_VCPKG) + find_package(unofficial-pcre CONFIG) + else () + ## LEGACY strategy: + find_package(PCRE) + endif () + else () + find_package(PCRE2) + endif () +endif () + +if (WITH_REGEX OR WITH_VIDEO) + set(ZLIB_USE_STATIC_LIBS ON) + find_package(ZLIB) +endif () + +if (WITH_VIDEO) + if (NOT USING_VCPKG) + ## LEGACY strategy: + find_package(PNG) + find_package(Freetype) + find_package(SDL2 NAMES sdl2 SDL2) + find_package(SDL2_ttf NAMES sdl2_ttf SDL2_ttf) + else () + ## vcpkg strategy: + find_package(PNG REQUIRED) + find_package(SDL2 CONFIG) + find_package(SDL2_ttf CONFIG) + endif () +endif () + +if (WITH_NETWORK) + if (WITH_VDE) + find_package(VDE) + endif () + + ## pcap is special: Headers only and dynamically loaded. + if (WITH_PCAP) + find_package(PCAP) + endif (WITH_PCAP) +endif (WITH_NETWORK) + +if (NOT WIN32 OR MINGW) + find_package(PkgConfig) + if (PKG_CONFIG_FOUND) + if (WITH_REGEX) + if (PREFER_PCRE AND NOT PCRE_FOUND) + pkg_check_modules(PCRE IMPORTED_TARGET libpcre) + elseif (NOT PREFER_PCRE AND NOT PCRE2_FOUND) + pkg_check_modules(PCRE IMPORTED_TARGET libpcre2-8) + endif () + endif (WITH_REGEX) + + if (WITH_REGEX OR WITH_VIDEO) + if (NOT ZLIB_FOUND) + pkg_check_modules(ZLIB IMPORTED_TARGET zlib) + endif () + endif () + + if (WITH_VIDEO) + if (NOT PNG_FOUND) + pkg_check_modules(PNG IMPORTED_TARGET libpng16) + endif () + if (NOT SDL2_FOUND) + pkg_check_modules(SDL2 IMPORTED_TARGET sdl2) + if (NOT SDL2_FOUND) + pkg_check_modules(SDL2 IMPORTED_TARGET SDL2) + endif () + endif () + + if (NOT SDL2_ttf_FOUND) + pkg_check_modules(SDL2_ttf IMPORTED_TARGET SDL2_ttf) + if (NOT SDL2_ttf_FOUND) + pkg_check_modules(SDL2_ttf IMPORTED_TARGET sdl2_ttf) + endif () + endif () + endif (WITH_VIDEO) + + if (WITH_NETWORK) + if (WITH_VDE AND NOT VDE_FOUND) + pkg_check_modules(VDE IMPORTED_TARGET vdeplug) + endif () + endif (WITH_NETWORK) + endif () +endif () + +##-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ +## Add rules for the superbuild if dependencies need to be built: +##-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ + +if (NO_DEP_BUILD) + ## Not going to build dependencies... + return () +endif () + +include (ExternalProject) + +# Source URLs (to make it easy to update versions): +set(ZLIB_SOURCE_URL "https://github.com/madler/zlib/archive/v1.2.13.zip") +set(PCRE2_SOURCE_URL "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.40/pcre2-10.40.zip") +## PCRE needs multiple URLs to chase a working SF mirror: +list(APPEND PCRE_SOURCE_URL + "https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.zip/download?use_mirror=cytranet" + "https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.zip/download?use_mirror=phoenixnap" + "https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.zip/download?use_mirror=versaweb" + "https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.zip/download?use_mirror=netactuate" + "https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.zip/download?use_mirror=cfhcable" + "https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.zip/download?use_mirror=freefr" + "https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.zip/download?use_mirror=master" +) +set(PNG_SOURCE_URL "https://github.com/glennrp/libpng/archive/refs/tags/v1.6.39.tar.gz") +## Freetype also needs multiple URLs to chase a working mirror: +list(APPEND FREETYPE_SOURCE_URL + "https://github.com/freetype/freetype/archive/refs/tags/VER-2-12-1.zip" + "https://sourceforge.net/projects/freetype/files/freetype2/2.12.1/ft2121.zip/download?use_mirror=cytranet" + "https://sourceforge.net/projects/freetype/files/freetype2/2.12.1/ft2121.zip/download?use_mirror=phoenixnap" + "https://sourceforge.net/projects/freetype/files/freetype2/2.12.1/ft2121.zip/download?use_mirror=versaweb" + "https://sourceforge.net/projects/freetype/files/freetype2/2.12.1/ft2121.zip/download?use_mirror=netactuate" + "https://sourceforge.net/projects/freetype/files/freetype2/2.12.1/ft2121.zip/download?use_mirror=cfhcable" + "https://sourceforge.net/projects/freetype/files/freetype2/2.12.1/ft2121.zip/download?use_mirror=freefr" + "https://sourceforge.net/projects/freetype/files/freetype2/2.12.1/ft2121.zip/download?use_mirror=master" + "https://download.savannah.gnu.org/releases/freetype/freetype-2.12.1.tar.xz" + "https://gitlab.freedesktop.org/freetype/freetype/-/archive/VER-2-12-1/freetype-VER-2-12-1.zip" +) +set(SDL2_SOURCE_URL "https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.26.3.zip") +set(SDL2_TTF_SOURCE_URL "https://github.com/libsdl-org/SDL_ttf/archive/refs/tags/release-2.20.2.zip") + +## Need to build ZLIB for both PCRE and libpng16: +if ((WITH_REGEX OR WITH_VIDEO) AND NOT ZLIB_FOUND) + ExternalProject_Add(zlib-dep + URL ${ZLIB_SOURCE_URL} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ## These patches come from vcpkg so that only the static libraries are built and + ## installed. If the patches don't apply cleanly (and there's a build error), that + ## means a version number got bumped and need to see what patches, if any, are + ## still applicable. + PATCH_COMMAND + git -c core.longpaths=true -c core.autocrlf=false --work-tree=. --git-dir=.git + apply + "${SIMH_DEP_PATCHES}/zlib/0001-Prevent-invalid-inclusions-when-HAVE_-is-set-to-0.patch" + "${SIMH_DEP_PATCHES}/zlib/0002-skip-building-examples.patch" + "${SIMH_DEP_PATCHES}/zlib/0003-build-static-or-shared-not-both.patch" + "${SIMH_DEP_PATCHES}/zlib/0004-android-and-mingw-fixes.patch" + --ignore-whitespace --whitespace=nowarn --verbose + ) + + BuildDepMatrix(zlib-dep zlib CMAKE_ARGS -DBUILD_SHARED_LIBS:Bool=${BUILD_SHARED_DEPS}) + + list(APPEND SIMH_BUILD_DEPS zlib) + list(APPEND SIMH_DEP_TARGETS zlib-dep) + message(STATUS "Building ZLIB from ${ZLIB_SOURCE_URL}.") + set(ZLIB_PKG_STATUS "ZLIB source build") +endif () + +IF (WITH_REGEX AND NOT (PCRE_FOUND OR PCRE2_FOUND OR TARGET unofficial::pcre::pcre)) + set(PCRE_DEPS) + IF (TARGET zlib-dep) + list(APPEND PCRE_DEPS zlib-dep) + ENDIF (TARGET zlib-dep) + + set(PCRE_CMAKE_ARGS -DBUILD_SHARED_LIBS:Bool=${BUILD_SHARED_DEPS}) + if (NOT PREFER_PCRE) + set(PCRE_URL ${PCRE2_SOURCE_URL}) + list(APPEND PCRE_CMAKE_ARGS + -DPCRE2_BUILD_PCREGREP:Bool=Off + -DPCRE2_SUPPORT_LIBEDIT:Bool=Off + -DPCRE2_SUPPORT_LIBREADLINE:Bool=Off + ) + + # IF(MSVC) + # list(APPEND PCRE_CMAKE_ARGS -DINSTALL_MSVC_PDB=On) + # ENDIF(MSVC) + + message(STATUS "Building PCRE2 from ${PCRE_URL}") + set(PCRE_PKG_STATUS "pcre2 source build") + ELSE () + set(PCRE_URL ${PCRE_SOURCE_URL}) + list(APPEND PCRE_CMAKE_ARGS + -DPCRE_BUILD_PCREGREP:Bool=Off + -DPCRE_SUPPORT_LIBEDIT:Bool=Off + -DPCRE_SUPPORT_LIBREADLINE:Bool=Off + ) + if (WIN32) + list(APPEND PCRE_CMAKE_ARGS + -DBUILD_SHARED_LIBS:Bool=Off + -DPCRE_STATIC_RUNTIME:Bool=On + ) + endif () + + message(STATUS "Building PCRE from ${PCRE_URL}") + set(PCRE_PKG_STATUS "pcre source build") + ENDIF () + + ExternalProject_Add(pcre-ext + URL + ${PCRE_URL} + DEPENDS + ${PCRE_DEPS} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) + + BuildDepMatrix(pcre-ext pcre CMAKE_ARGS ${PCRE_CMAKE_ARGS}) + + list(APPEND SIMH_BUILD_DEPS pcre) + list(APPEND SIMH_DEP_TARGETS pcre-ext) +ELSE () + set(PCRE_PKG_STATUS "regular expressions disabled") +ENDIF () + +set(BUILD_WITH_VIDEO FALSE) +IF (WITH_VIDEO) + IF (NOT PNG_FOUND) + set(PNG_DEPS) + if (NOT ZLIB_FOUND) + list(APPEND PNG_DEPS zlib-dep) + endif (NOT ZLIB_FOUND) + + ExternalProject_Add(png-dep + URL + ${PNG_SOURCE_URL} + DEPENDS + ${PNG_DEPS} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) + + ## Work around the GCC 8.1.0 SEH index regression. + set(PNG_CMAKE_BUILD_TYPE_RELEASE "Release") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND + CMAKE_C_COMPILER_VERSION VERSION_EQUAL "8.1" AND + NOT CMAKE_BUILD_VERSION) + message(STATUS "PNG: Build using MinSizeRel CMAKE_BUILD_TYPE with GCC 8.1") + set(PNG_CMAKE_BUILD_TYPE_RELEASE "MinSizeRel") + endif() + + BuildDepMatrix(png-dep libpng + CMAKE_ARGS + -DPNG_SHARED:Bool=${BUILD_SHARED_DEPS} + -DPNG_STATUS:Bool=On + -DPNG_EXECUTABLES:Bool=Off + -DPNG_TESTS:Bool=Off + RELEASE_BUILD ${PNG_CMAKE_BUILD_TYPE_RELEASE} + ) + + list(APPEND SIMH_BUILD_DEPS "png") + list(APPEND SIMH_DEP_TARGETS "png-dep") + message(STATUS "Building PNG from ${PNG_SOURCE_URL}") + list(APPEND VIDEO_PKG_STATUS "PNG source build") + ENDIF (NOT PNG_FOUND) + + IF (NOT SDL2_FOUND) + ExternalProject_Add(sdl2-dep + URL ${SDL2_SOURCE_URL} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) + + BuildDepMatrix(sdl2-dep SDL2 CMAKE_ARGS "-DBUILD_SHARED_LIBS:Bool=${BUILD_SHARED_DEPS}") + + list(APPEND SIMH_BUILD_DEPS "SDL2") + list(APPEND SIMH_DEP_TARGETS "sdl2-dep") + message(STATUS "Building SDL2 from ${SDL2_SOURCE_URL}.") + list(APPEND VIDEO_PKG_STATUS "SDL2 source build") + ENDIF (NOT SDL2_FOUND) + + IF (NOT FREETYPE_FOUND) + set(FREETYPE_DEPS) + if (TARGET zlib-dep) + list(APPEND FREETYPE_DEPS zlib-dep) + endif () + if (TARGET png-dep) + list(APPEND FREETYPE_DEPS png-dep) + endif () + + ExternalProject_Add(freetype-dep + URL + ${FREETYPE_SOURCE_URL} + DEPENDS + ${FREETYPE_DEPS} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) + + BuildDepMatrix(freetype-dep Freetype + CMAKE_ARGS + "-DBUILD_SHARED_LIBS:Bool=${BUILD_SHARED_DEPS}" + "-DFT_DISABLE_BZIP2:Bool=TRUE" + "-DFT_DISABLE_HARFBUZZ:Bool=TRUE" + "-DFT_DISABLE_BROTLI:Bool=TRUE" + ) + + list(APPEND SIMH_BUILD_DEPS "Freetype") + list(APPEND SIMH_DEP_TARGETS freetype-dep) + message(STATUS "Building Freetype from ${FREETYPE_SOURCE_URL}.") + ENDIF () + + IF (NOT SDL2_ttf_FOUND) + set(SDL2_ttf_DEPS) + if (TARGET sdl2-dep) + list(APPEND SDL2_ttf_DEPS sdl2-dep) + endif (TARGET sdl2-dep) + if (TARGET freetype-dep) + list(APPEND SDL2_ttf_DEPS freetype-dep) + endif () + + ExternalProject_Add(sdl2-ttf-dep + URL + ${SDL2_TTF_SOURCE_URL} + DEPENDS + ${SDL2_ttf_DEPS} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + PATCH_COMMAND + git -c core.longpaths=true -c core.autocrlf=false --work-tree=. --git-dir=.git + apply + "${SIMH_DEP_PATCHES}/SDL_ttf/fix-pkgconfig.patch" + --ignore-whitespace --whitespace=nowarn --verbose + ) + + set(sdl2_ttf_cmake_args) + list(APPEND sdl2_ttf_cmake_args + "-DBUILD_SHARED_LIBS:Bool=${BUILD_SHARED_DEPS}" + "-DSDL2TTF_SAMPLES:Bool=Off" + "-DSDL2TTF_VENDORED:Bool=Off" + "-DSDL2TTF_HARFBUZZ:Bool=Off" + ) + + BuildDepMatrix(sdl2-ttf-dep SDL2_ttf CMAKE_ARGS ${sdl2_ttf_cmake_args}) + + list(APPEND SIMH_BUILD_DEPS "SDL2_ttf") + list(APPEND SIMH_DEP_TARGETS "sdl2-ttf-dep") + message(STATUS "Building SDL2_ttf from https://www.libsdl.org/release/SDL2_ttf-2.0.15.zip.") + list(APPEND VIDEO_PKG_STATUS "SDL2_ttf source build") + ENDIF (NOT SDL2_ttf_FOUND) + + set(BUILD_WITH_VIDEO TRUE) +ELSE () + set(VIDEO_PKG_STATUS "video support disabled") +ENDIF(WITH_VIDEO) diff --git a/cmake/diff-master.ps1 b/cmake/diff-master.ps1 new file mode 100644 index 00000000..8b8d2904 --- /dev/null +++ b/cmake/diff-master.ps1 @@ -0,0 +1,14 @@ +## Make looking at divergence from simh/master easier... + +$excludes = @( + "/*CMakeLists.txt", + "/.gitignore", + "/Visual Studio Projects/", + "/build_*.bat", + "/cmake/", + "/PDP8/tests/diags/*.pal", + "/PDP8/tests/diags/*.txt", + "/appveyor.yml" +) | % { "`":!" + $_ + "`"" } + +git diff --ignore-space-at-eol simh/master HEAD -- ${excludes} diff --git a/cmake/file-link-copy.cmake b/cmake/file-link-copy.cmake new file mode 100644 index 00000000..f686499c --- /dev/null +++ b/cmake/file-link-copy.cmake @@ -0,0 +1,50 @@ +## File link or copy +## +## Written initially for the VAX to link vax to microvax3900, this +## evolved into a more general-purpose utility. + +if (NOT SRCFILE) + message(FATAL_ERROR "SRCFILE not defined") +endif () +if (NOT DSTFILE) + mesasge(FATAL_ERROR "DSTFILE not defined") +endif () +if (NOT WORKING_DIR) + message(FATAL_ERROR "WORKING_DIR not defined") +endif () + +if (NOT EXISTS ${WORKING_DIR}) + message(FATAL_ERROR "Working directory does not exist: ${WORKING_DIR}") +endif () + +file(TO_NATIVE_PATH "${WORKING_DIR}/${SRCFILE}" _source) +file(TO_NATIVE_PATH "${WORKING_DIR}/${DSTFILE}" _dest) + +if (EXISTS ${_dest}) + message("Removing destination ${_dest}") + file(REMOVE ${_dest}) + if (EXISTS ${_dest}) + message(FATAL_ERROR "Could not remove ${_dest}") + endif () +endif () + +execute_process( + COMMAND + ${CMAKE_COMMAND} -E create_symlink ${SRCFILE} ${DSTFILE} + WORKING_DIRECTORY + ${WORKING_DIR} + RESULT_VARIABLE + _file_symlink + ERROR_QUIET +) + +if (NOT _file_symlink EQUAL 0) + file(CREATE_LINK ${_source} ${_dest} COPY_ON_ERROR RESULT _result) + if (NOT _result EQUAL 0) + message(FATAL_ERROR "Could not link or copy ${_source} to ${_dest}") + else () + message(":::: Hard link/copy ${_source} -> ${_dest}") + endif () +else () + message(":::: Symlink ${SRCFILE} -> ${DSTFILE} in ${WORKING_DIR}") +endif() diff --git a/cmake/fpintrin.cmake b/cmake/fpintrin.cmake new file mode 100644 index 00000000..7664de80 --- /dev/null +++ b/cmake/fpintrin.cmake @@ -0,0 +1,79 @@ +## Check for various GNU-specific floating point math flags +## +## Not entirely sure that they will make a huge difference to code +## generation in the simulators. + +set(EXTRA_TARGET_CFLAGS) + +set(CMAKE_REQUIRED_FLAGS "-msse") +check_c_source_compiles(" + #ifdef __MINGW32__ + #include <_mingw.h> + #ifdef __MINGW64_VERSION_MAJOR + #include + #else + #include + #endif + #else + #include + #endif + #ifndef __SSE__ + #error Assembler CPP flag not enabled + #endif + int main(int argc, char **argv) { }" HAVE_SSE) +if(HAVE_SSE) + list(APPEND EXTRA_TARGET_CFLAGS "-msse") +endif() +set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + +set(CMAKE_REQUIRED_FLAGS "-msse2") +check_c_source_compiles(" + #ifdef __MINGW32__ + #include <_mingw.h> + #ifdef __MINGW64_VERSION_MAJOR + #include + #else + #include + #endif + #else + #include + #endif + #ifndef __SSE2__ + #error Assembler CPP flag not enabled + #endif + int main(int argc, char **argv) { }" HAVE_SSE2) +if(HAVE_SSE2) + list(APPEND EXTRA_TARGET_CFLAGS "-msse2") +endif() +set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + +set(CMAKE_REQUIRED_FLAGS "-msse3") +check_c_source_compiles(" + #ifdef __MINGW32__ + #include <_mingw.h> + #ifdef __MINGW64_VERSION_MAJOR + #include + #else + #include + #endif + #else + #include + #endif + #ifndef __SSE3__ + #error Assembler CPP flag not enabled + #endif + int main(int argc, char **argv) { }" HAVE_SSE3) +if(HAVE_SSE3) + list(APPEND EXTRA_TARGET_CFLAGS "-msse3") +endif() +set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + +if(SSE OR SSE2 OR SSE3) + if(USE_GCC) + check_c_compiler_flag(-mfpmath=387 HAVE_FP_387) + if(HAVE_FP_387) + list(APPEND EXTRA_TARGET_CFLAGS "-mfpmath=387") + endif() + endif() + set(HAVE_SSEMATH TRUE) +endif() diff --git a/cmake/generate.py b/cmake/generate.py new file mode 100644 index 00000000..cfb13f98 --- /dev/null +++ b/cmake/generate.py @@ -0,0 +1,192 @@ +## generate.py +## +## Generate the simulator CMakeLists.txt from the top-level makefile. +## +## This is the top-level driver: process options, search for the +## makefile, parse the makefile and walk its dependencies, and, +## finally, output the CMakeLists.txt(s) and simh-simulators.cmake. +## +## Author: B. Scott Michel +## ("scooter me fecit") + +import sys +import os.path +import argparse +import re + +GEN_SCRIPT_DIR = os.path.dirname(__file__) +GEN_SCRIPT_NAME = os.path.basename(__file__) + +import pprint + +import simgen.cmake_container as SCC +import simgen.parse_makefile as SPM +import simgen.packaging as SPKG +## from simgen.text_file import TextFile + + +def process_makefile(makefile_dir, debug=0): + the_makefile = os.path.join(makefile_dir, "makefile") + print('{0}: Processing {1}'.format(GEN_SCRIPT_NAME, the_makefile)) + + (defs, rules, actions) = SPM.parse_makefile(the_makefile) + if debug >= 4: + pprint.pp(defs) + + all_rule = rules.get('all') + if all_rule is None: + print('{0}: "all" rule not found. Cannot process.'.format(GEN_SCRIPT_NAME)) + + simulators = SCC.CMakeBuildSystem() + for all_targ in SPM.shallow_expand_vars(all_rule, defs).split(): + print("{0}: all target {1}".format(GEN_SCRIPT_NAME, all_targ)) + walk_target_deps(all_targ, defs, rules, actions, simulators, debug=debug) + + experimental_rule = rules.get('experimental') + for experimental_targ in SPM.shallow_expand_vars(experimental_rule, defs).split(): + print("{0}: exp target {1}".format(GEN_SCRIPT_NAME, experimental_targ)) + walk_target_deps(experimental_targ, defs, rules, actions, simulators, debug=debug) + + simulators.collect_vars(defs, debug=debug) + return simulators + + +## Makefile target dependencies to filter out. +_ignored_deps = [ + '${SIM}', + '${BUILD_ROMS}' +] + +## Simulator compile/link action pattern +_compile_act_rx = re.compile(r"\$[({]CC[)}]\s*(.*)") +_test_name_rx = re.compile(r"\$@\s*\$\(call\s+find_test,\s*(.*),(.*)\)\s+\$") + +def walk_target_deps(target, defs, rules, actions, simulators, depth='', debug=0): + """ Recursively walk a target's dependencies, i.e., the right hand side of a make rule. + Descend into each dependency to find something that looks like a simulator's + source code list. Once source code list is found, extract simulator defines, includes, + source files and set flags. + """ + if debug >= 1: + print('{0}-- target: {1}'.format(depth, target)) + + target_deps = SPM.target_dep_list(target, rules, defs) + + has_buildrom = any(filter(lambda dep: dep == '${BUILD_ROMS}', target_deps)) + if debug >= 1: + print('{0} has_buildrom {1}', has_buildrom) + + deps = [dep for dep in target_deps if dep not in _ignored_deps] + targ_actions = actions.get(target) + if targ_actions: + depth3 = depth + ' ' + if debug >= 2: + print('{0}deps {1}'.format(depth3, deps)) + + # Are the dependencies a source code list? + expanded_deps = [l for slist in [ SPM.shallow_expand_vars(dep, defs).split() for dep in deps ] for l in slist] + if debug >= 3: + print('{0}expanded_deps {1}'.format(depth3, expanded_deps)) + + if any(filter(lambda f: f.endswith('.c'), expanded_deps)): + if debug >= 1: + print('{0}sim sources {1}'.format(depth3, deps)) + if debug >= 2: + print('{0}targ_actions {1}'.format(depth3, targ_actions)) + + # The simulators' compile and test actions are very regular and easy to find: + compile_act = None + test_name = None + sim_dir = None + for act in targ_actions: + m_cact = _compile_act_rx.match(act) + m_test = _test_name_rx.match(act) + if m_cact: + compile_act = m_cact.group(1) + elif m_test: + (sim_dir, test_name) = m_test.group(1, 2) + + if debug >= 2: + print('{0}sim_dir {1}'.format(depth3, sim_dir)) + print('{0}compile_act {1}'.format(depth3, compile_act)) + print('{0}test_name {1}'.format(depth3, test_name)) + + if compile_act and test_name and sim_dir: + sim_name = target.replace("${BIN}", "").replace("${EXE}", "") + # Just in case there are vestiges of old-style make variables + sim_name = sim_name.replace("$(BIN)", "").replace("$(EXE)", "") + if debug >= 2: + print('{0}sim_name {1}'.format(depth3, sim_name)) + + simulators.extract(compile_act, test_name, sim_dir, sim_name, defs, has_buildrom, debug, depth+' ') + else: + # No actions associated with the dependency(ies), which means that the dependency(ies) + # are meta-targets. Continue to walk. + for dep in deps: + walk_target_deps(dep, defs, rules, actions, simulators, depth=depth+' ', debug=debug) + + +if __name__ == '__main__': + args = argparse.ArgumentParser(description="SIMH simulator CMakeLists.txt generator.") + args.add_argument('--debug', nargs='?', const=1, default=0, type=int, + help='Debug level (0-3, 0 == off)') + args.add_argument('--srcdir', default=None, + help='makefile source directory.') + ## args.add_argument('--file', '-f', default=os.path.join(GEN_SCRIPT_DIR, 'simh_makefile.cmake'), + ## help='Output file for "all-in-one" CMakeLists.txt, default is simh_makefile.cmake') + flags = vars(args.parse_args()) + + debug_level = flags.get('debug') + makefile_dir = flags.get('srcdir') + + print('{0}: Expecting to emit {1} simulators.'.format(GEN_SCRIPT_NAME, len(SPKG.package_info.keys()))) + + found_makefile = True + if makefile_dir is None: + ## Find the makefile, which should be one directory up from this Python + ## module + makefile_dir = GEN_SCRIPT_DIR + print('{0}: Looking for makefile, starting in {1}'.format(GEN_SCRIPT_NAME, makefile_dir)) + the_makefile = '' + while makefile_dir: + the_makefile = os.path.join(makefile_dir, "makefile") + if os.path.exists(the_makefile): + break + else: + makefile_dir = os.path.dirname(makefile_dir) + print('{0}: Looking for makefile, trying {1}'.format(GEN_SCRIPT_NAME, makefile_dir)) + + if not the_makefile: + found_makefile = False + else: + the_makefile = os.path.join(makefile_dir, "makefile") + if not os.path.exists(the_makefile): + found_makefile = False + + if not found_makefile: + print('{0}: SIMH top-level makefile not found, relative to {1}'.format(GEN_SCRIPT_NAME, GEN_SCRIPT_DIR)) + sys.exit(1) + + sims = process_makefile(makefile_dir, debug=debug_level) + + ## Sanity check: Make sure that all of the simulators in SPKG.package_info have + ## been encountered + for simdir in sims.dirs.keys(): + for sim in sims.dirs[simdir].simulators.keys(): + SPKG.package_info[sim].encountered() + + orphans = [ sim for sim, pkg_info in SPKG.package_info.items() if not pkg_info.was_processed() ] + if len(orphans) > 0: + print('{0}: Simulators not extracted from makefile:'.format(GEN_SCRIPT_NAME)) + for orphan in orphans: + print('{0}{1}'.format(' ' * 4, orphan)) + sys.exit(1) + + if debug_level >= 1: + pp = pprint.PrettyPrinter() + pp.pprint(sims) + + ## Emit all of the individual CMakeLists.txt + sims.write_simulators(makefile_dir, debug=debug_level) + ## Emit the packaging data + SPKG.write_packaging(makefile_dir) \ No newline at end of file diff --git a/cmake/git-commit-id.cmake b/cmake/git-commit-id.cmake new file mode 100644 index 00000000..373f04d5 --- /dev/null +++ b/cmake/git-commit-id.cmake @@ -0,0 +1,90 @@ +## git-commit-id.cmake +## +## Get the current Git commit hash code and commit time, update +## .git-commit-id and .git-commit-id.h + +set(GIT_COMMIT_ID ${GIT_COMMIT_DEST}/.git-commit-id) +set(GIT_COMMIT_ID_H ${GIT_COMMIT_DEST}/.git-commit-id.h) + +message(STATUS "Updating GIT commit ID") + +find_program(GIT_COMMAND git) +if (GIT_COMMAND) + execute_process(COMMAND ${GIT_COMMAND} "log" "-1" "--pretty=%H" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE HAVE_GIT_COMMIT_HASH + OUTPUT_VARIABLE SIMH_GIT_COMMIT_HASH) + + execute_process(COMMAND ${GIT_COMMAND} "log" "-1" "--pretty=%aI" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE HAVE_GIT_COMMIT_TIME + OUTPUT_VARIABLE SIMH_GIT_COMMIT_TIME) + + execute_process(COMMAND ${GIT_COMMAND} "update-index" "--refresh" "--" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE HAVE_UNCOMMITTED_CHANGES + OUTPUT_VARIABLE SIMH_UNCOMMITTED_CHANGES) +endif () + +if (GIT_COMMAND AND NOT (HAVE_GIT_COMMIT_HASH OR HAVE_GIT_COMMIT_TIME)) + string(STRIP ${SIMH_GIT_COMMIT_HASH} SIMH_GIT_COMMIT_HASH) + string(STRIP ${SIMH_GIT_COMMIT_TIME} SIMH_GIT_COMMIT_TIME) + string(REPLACE "T" " " SIMH_GIT_COMMIT_TIME ${SIMH_GIT_COMMIT_TIME}) + + if (HAVE_UNCOMMITTED_CHANGES) + message(STATUS "Git detected uncommitted changes.") + string(APPEND SIMH_GIT_COMMIT_HASH "+uncommitted-changes") + else () + message(STATUS "Clean working directory, no uncommitted changes.") + endif () + + message(STATUS "SIM_GIT_COMMIT_ID: ${SIMH_GIT_COMMIT_HASH}") + message(STATUS "SIM_GIT_COMMIT_TIME: ${SIMH_GIT_COMMIT_TIME}") + + set(WRITE_GIT_COMMIT_FILES True) + if (EXISTS ${GIT_COMMIT_ID}) + set(EXISTING_GIT_COMMIT_HASH) + set(EXISTING_GIT_COMMIT_TIME) + file(STRINGS ${GIT_COMMIT_ID} git_info) + foreach (inp IN LISTS git_info) + if (inp MATCHES "SIM_GIT_COMMIT_ID (.*)") + set(EXISTING_GIT_COMMIT_HASH ${CMAKE_MATCH_1}) + elseif (inp MATCHES "SIM_GIT_COMMIT_TIME (.*)") + set(EXISTING_GIT_COMMIT_TIME ${CMAKE_MATCH_1}) + endif () + endforeach() + if (EXISTING_GIT_COMMIT_HASH STREQUAL SIMH_GIT_COMMIT_HASH AND + EXISTING_GIT_COMMIT_TIME STREQUAL SIMH_GIT_COMMIT_TIME) + message(STATUS "GIT hash and time match, not writing files.") + set(WRITE_GIT_COMMIT_FILES False) + endif () + endif () + + if (WRITE_GIT_COMMIT_FILES) + message(STATUS "Writing ${GIT_COMMIT_ID}") + file(WRITE ${GIT_COMMIT_ID} + "SIM_GIT_COMMIT_ID ${SIMH_GIT_COMMIT_HASH}\n" + "SIM_GIT_COMMIT_TIME ${SIMH_GIT_COMMIT_TIME}\n") + + message(STATUS "Writing ${GIT_COMMIT_ID_H}") + file(WRITE ${GIT_COMMIT_ID_H} + "#define SIM_GIT_COMMIT_ID ${SIMH_GIT_COMMIT_HASH}\n" + "#define SIM_GIT_COMMIT_TIME ${SIMH_GIT_COMMIT_TIME}\n") + else () + message(STATUS "No changes to ${GIT_COMMIT_ID}") + message(STATUS "No changes to ${GIT_COMMIT_ID_H}") + endif () +else () + message(STATUS "SIM_GIT_COMMIT_ID not set.") + message(STATUS "SIM_GIT_COMMIT_TIME not set.") + + if (NOT EXISTS ${GIT_COMMIT_ID_H}) + message(STATUS "Writing default ${GIT_COMMIT_ID_H}") + file(WRITE ${GIT_COMMIT_ID_H} + "#undef SIM_GIT_COMMIT_ID\n" + "#undef SIM_GIT_COMMIT_TIME\n" + ) + else () + message(STATUS "Leaving ${GIT_COMMIT_ID_H} intact") + endif () +endif() diff --git a/cmake/installer-customizations/CPackSimhCustom.cmake.in b/cmake/installer-customizations/CPackSimhCustom.cmake.in new file mode 100644 index 00000000..47741782 --- /dev/null +++ b/cmake/installer-customizations/CPackSimhCustom.cmake.in @@ -0,0 +1,3 @@ +## Additional variables needed to drive CPack: + +file(TO_NATIVE_PATH "@CMAKE_SOURCE_DIR@/cmake/installer-customizations/NSIS" SIMH_NSIS_INCLUDE_DIR) diff --git a/cmake/installer-customizations/NSIS.template.in b/cmake/installer-customizations/NSIS.template.in new file mode 100644 index 00000000..4baf8986 --- /dev/null +++ b/cmake/installer-customizations/NSIS.template.in @@ -0,0 +1,1018 @@ +; CPack install script designed for a nmake build + +;-------------------------------- +; You must define these values + + !define VERSION "@CPACK_PACKAGE_VERSION@" + !define PATCH "@CPACK_PACKAGE_VERSION_PATCH@" + !define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@" + + !addincludedir "@SIMH_NSIS_INCLUDE_DIR@" + +;-------------------------------- +;Variables + + Var MUI_TEMP + Var STARTMENU_FOLDER + Var SV_ALLUSERS + Var START_MENU + Var DO_NOT_ADD_TO_PATH + Var ADD_TO_PATH_ALL_USERS + Var ADD_TO_PATH_CURRENT_USER + Var INSTALL_DESKTOP + Var IS_DEFAULT_INSTALLDIR +;-------------------------------- +;Include Modern UI + + !include "MUI.nsh" + + ;Default installation folder + InstallDir "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" + +;-------------------------------- +;General + + ;Name and file + Name "@CPACK_NSIS_PACKAGE_NAME@" + OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" + + ;Set compression + SetCompressor @CPACK_NSIS_COMPRESSOR@ + + ; Execution level: none, access, admin, user + ; User execution level -- there's nothing in SIMH that has to install + ; in ProgramFiles or ProgramFiles (x86) + RequestExecutionLevel user + +@CPACK_NSIS_DEFINES@ +@CPACK_NSIS_MANIFEST_DPI_AWARE_CODE@ +@CPACK_NSIS_BRANDING_TEXT_CODE@ + + !include Sections.nsh + +;-------------------------------- +; Symbolic and hard file link support: + + !include "FileFunc.nsh" + !include "FileLinks.nsh" + +;--- Component support macros: --- +; The code for the add/remove functionality is from: +; https://nsis.sourceforge.io/Add/Remove_Functionality +; It has been modified slightly and extended to provide +; inter-component dependencies. +Var AR_SecFlags +Var AR_RegFlags +@CPACK_NSIS_SECTION_SELECTED_VARS@ + +; Loads the "selected" flag for the section named SecName into the +; variable VarName. +!macro LoadSectionSelectedIntoVar SecName VarName + SectionGetFlags ${${SecName}} $${VarName} + IntOp $${VarName} $${VarName} & ${SF_SELECTED} ;Turn off all other bits +!macroend + +; Loads the value of a variable... can we get around this? +!macro LoadVar VarName + IntOp $R0 0 + $${VarName} +!macroend + +; Sets the value of a variable +!macro StoreVar VarName IntValue + IntOp $${VarName} 0 + ${IntValue} +!macroend + +!macro InitSection SecName + ; This macro reads component installed flag from the registry and + ;changes checked state of the section on the components page. + ;Input: section index constant name specified in Section command. + + ClearErrors + ;Reading component status from registry + ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" "Installed" + IfErrors "default_${SecName}" + ;Status will stay default if registry value not found + ;(component was never installed) + IntOp $AR_RegFlags $AR_RegFlags & ${SF_SELECTED} ;Turn off all other bits + SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading default section flags + IntOp $AR_SecFlags $AR_SecFlags & 0xFFFE ;Turn lowest (enabled) bit off + IntOp $AR_SecFlags $AR_RegFlags | $AR_SecFlags ;Change lowest bit + + ; Note whether this component was installed before + !insertmacro StoreVar ${SecName}_was_installed $AR_RegFlags + IntOp $R0 $AR_RegFlags & $AR_RegFlags + + ;Writing modified flags + SectionSetFlags ${${SecName}} $AR_SecFlags + + "default_${SecName}:" + !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected +!macroend + +!macro FinishSection SecName + ; This macro reads section flag set by user and removes the section + ;if it is not selected. + ;Then it writes component installed flag to registry + ;Input: section index constant name specified in Section command. + + SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading section flags + ;Checking lowest bit: + IntOp $AR_SecFlags $AR_SecFlags & ${SF_SELECTED} + IntCmp $AR_SecFlags 1 "leave_${SecName}" + ;Section is not selected: + ;Calling Section uninstall macro and writing zero installed flag + !insertmacro "Remove_${${SecName}}" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \ + "Installed" 0 + Goto "exit_${SecName}" + + "leave_${SecName}:" + ;Section is selected: + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \ + "Installed" 1 + + "exit_${SecName}:" +!macroend + +!macro RemoveSection_CPack SecName + ; This macro is used to call section's Remove_... macro + ;from the uninstaller. + ;Input: section index constant name specified in Section command. + + !insertmacro "Remove_${${SecName}}" +!macroend + +; Determine whether the selection of SecName changed +!macro MaybeSelectionChanged SecName + !insertmacro LoadVar ${SecName}_selected + SectionGetFlags ${${SecName}} $R1 + IntOp $R1 $R1 & ${SF_SELECTED} ;Turn off all other bits + + ; See if the status has changed: + IntCmp $R0 $R1 "${SecName}_unchanged" + !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected + + IntCmp $R1 ${SF_SELECTED} "${SecName}_was_selected" + !insertmacro "Deselect_required_by_${SecName}" + goto "${SecName}_unchanged" + + "${SecName}_was_selected:" + !insertmacro "Select_${SecName}_depends" + + "${SecName}_unchanged:" +!macroend +;--- End of Add/Remove macros --- + +;-------------------------------- +;Interface Settings + + !define MUI_HEADERIMAGE + !define MUI_ABORTWARNING + +;---------------------------------------- +; based upon a script of "Written by KiCHiK 2003-01-18 05:57:02" +;---------------------------------------- +!verbose 3 +!include "WinMessages.NSH" +!verbose 4 +;==================================================== +; get_NT_environment +; Returns: the selected environment +; Output : head of the stack +;==================================================== +!macro select_NT_profile UN +Function ${UN}select_NT_profile + StrCmp $ADD_TO_PATH_ALL_USERS "1" 0 environment_single + DetailPrint "Selected environment for all users" + Push "all" + Return + environment_single: + DetailPrint "Selected environment for current user only." + Push "current" + Return +FunctionEnd +!macroend +!insertmacro select_NT_profile "" +!insertmacro select_NT_profile "un." +;---------------------------------------------------- +!define NT_current_env 'HKCU "Environment"' +!define NT_all_env 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' + +!ifndef WriteEnvStr_RegKey + !ifdef ALL_USERS + !define WriteEnvStr_RegKey \ + 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' + !else + !define WriteEnvStr_RegKey 'HKCU "Environment"' + !endif +!endif + +; AddToPath - Adds the given dir to the search path. +; Input - head of the stack +; Note - Win9x systems requires reboot + +Function AddToPath + Exch $0 + Push $1 + Push $2 + Push $3 + + # don't add if the path doesn't exist + IfFileExists "$0\*.*" "" AddToPath_done + + ReadEnvStr $1 PATH + ; if the path is too long for a NSIS variable NSIS will return a 0 + ; length string. If we find that, then warn and skip any path + ; modification as it will trash the existing path. + StrLen $2 $1 + IntCmp $2 0 CheckPathLength_ShowPathWarning CheckPathLength_Done CheckPathLength_Done + CheckPathLength_ShowPathWarning: + Messagebox MB_OK|MB_ICONEXCLAMATION "Warning! PATH too long installer unable to modify PATH!" + Goto AddToPath_done + CheckPathLength_Done: + Push "$1;" + Push "$0;" + Call StrStr + Pop $2 + StrCmp $2 "" "" AddToPath_done + Push "$1;" + Push "$0\;" + Call StrStr + Pop $2 + StrCmp $2 "" "" AddToPath_done + GetFullPathName /SHORT $3 $0 + Push "$1;" + Push "$3;" + Call StrStr + Pop $2 + StrCmp $2 "" "" AddToPath_done + Push "$1;" + Push "$3\;" + Call StrStr + Pop $2 + StrCmp $2 "" "" AddToPath_done + + Call IsNT + Pop $1 + StrCmp $1 1 AddToPath_NT + ; Not on NT + StrCpy $1 $WINDIR 2 + FileOpen $1 "$1\autoexec.bat" a + FileSeek $1 -1 END + FileReadByte $1 $2 + IntCmp $2 26 0 +2 +2 # DOS EOF + FileSeek $1 -1 END # write over EOF + FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n" + FileClose $1 + SetRebootFlag true + Goto AddToPath_done + + AddToPath_NT: + StrCmp $ADD_TO_PATH_ALL_USERS "1" ReadAllKey + ReadRegStr $1 ${NT_current_env} "PATH" + Goto DoTrim + ReadAllKey: + ReadRegStr $1 ${NT_all_env} "PATH" + DoTrim: + StrCmp $1 "" AddToPath_NTdoIt + Push $1 + Call Trim + Pop $1 + StrCpy $0 "$1;$0" + AddToPath_NTdoIt: + StrCmp $ADD_TO_PATH_ALL_USERS "1" WriteAllKey + WriteRegExpandStr ${NT_current_env} "PATH" $0 + Goto DoSend + WriteAllKey: + WriteRegExpandStr ${NT_all_env} "PATH" $0 + DoSend: + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + AddToPath_done: + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd + + +; RemoveFromPath - Remove a given dir from the path +; Input: head of the stack + +Function un.RemoveFromPath + Exch $0 + Push $1 + Push $2 + Push $3 + Push $4 + Push $5 + Push $6 + + IntFmt $6 "%c" 26 # DOS EOF + + Call un.IsNT + Pop $1 + StrCmp $1 1 unRemoveFromPath_NT + ; Not on NT + StrCpy $1 $WINDIR 2 + FileOpen $1 "$1\autoexec.bat" r + GetTempFileName $4 + FileOpen $2 $4 w + GetFullPathName /SHORT $0 $0 + StrCpy $0 "SET PATH=%PATH%;$0" + Goto unRemoveFromPath_dosLoop + + unRemoveFromPath_dosLoop: + FileRead $1 $3 + StrCpy $5 $3 1 -1 # read last char + StrCmp $5 $6 0 +2 # if DOS EOF + StrCpy $3 $3 -1 # remove DOS EOF so we can compare + StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine + StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine + StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine + StrCmp $3 "" unRemoveFromPath_dosLoopEnd + FileWrite $2 $3 + Goto unRemoveFromPath_dosLoop + unRemoveFromPath_dosLoopRemoveLine: + SetRebootFlag true + Goto unRemoveFromPath_dosLoop + + unRemoveFromPath_dosLoopEnd: + FileClose $2 + FileClose $1 + StrCpy $1 $WINDIR 2 + Delete "$1\autoexec.bat" + CopyFiles /SILENT $4 "$1\autoexec.bat" + Delete $4 + Goto unRemoveFromPath_done + + unRemoveFromPath_NT: + StrCmp $ADD_TO_PATH_ALL_USERS "1" unReadAllKey + ReadRegStr $1 ${NT_current_env} "PATH" + Goto unDoTrim + unReadAllKey: + ReadRegStr $1 ${NT_all_env} "PATH" + unDoTrim: + StrCpy $5 $1 1 -1 # copy last char + StrCmp $5 ";" +2 # if last char != ; + StrCpy $1 "$1;" # append ; + Push $1 + Push "$0;" + Call un.StrStr ; Find `$0;` in $1 + Pop $2 ; pos of our dir + StrCmp $2 "" unRemoveFromPath_done + ; else, it is in path + # $0 - path to add + # $1 - path var + StrLen $3 "$0;" + StrLen $4 $2 + StrCpy $5 $1 -$4 # $5 is now the part before the path to remove + StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove + StrCpy $3 $5$6 + + StrCpy $5 $3 1 -1 # copy last char + StrCmp $5 ";" 0 +2 # if last char == ; + StrCpy $3 $3 -1 # remove last char + + StrCmp $ADD_TO_PATH_ALL_USERS "1" unWriteAllKey + WriteRegExpandStr ${NT_current_env} "PATH" $3 + Goto unDoSend + unWriteAllKey: + WriteRegExpandStr ${NT_all_env} "PATH" $3 + unDoSend: + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + unRemoveFromPath_done: + Pop $6 + Pop $5 + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Uninstall stuff +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +########################################### +# Utility Functions # +########################################### + +;==================================================== +; IsNT - Returns 1 if the current system is NT, 0 +; otherwise. +; Output: head of the stack +;==================================================== +; IsNT +; no input +; output, top of the stack = 1 if NT or 0 if not +; +; Usage: +; Call IsNT +; Pop $R0 +; ($R0 at this point is 1 or 0) + +!macro IsNT un +Function ${un}IsNT + Push $0 + ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion + StrCmp $0 "" 0 IsNT_yes + ; we are not NT. + Pop $0 + Push 0 + Return + + IsNT_yes: + ; NT!!! + Pop $0 + Push 1 +FunctionEnd +!macroend +!insertmacro IsNT "" +!insertmacro IsNT "un." + +; StrStr +; input, top of stack = string to search for +; top of stack-1 = string to search in +; output, top of stack (replaces with the portion of the string remaining) +; modifies no other variables. +; +; Usage: +; Push "this is a long ass string" +; Push "ass" +; Call StrStr +; Pop $R0 +; ($R0 at this point is "ass string") + +!macro StrStr un +Function ${un}StrStr +Exch $R1 ; st=haystack,old$R1, $R1=needle + Exch ; st=old$R1,haystack + Exch $R2 ; st=old$R1,old$R2, $R2=haystack + Push $R3 + Push $R4 + Push $R5 + StrLen $R3 $R1 + StrCpy $R4 0 + ; $R1=needle + ; $R2=haystack + ; $R3=len(needle) + ; $R4=cnt + ; $R5=tmp + loop: + StrCpy $R5 $R2 $R3 $R4 + StrCmp $R5 $R1 done + StrCmp $R5 "" done + IntOp $R4 $R4 + 1 + Goto loop +done: + StrCpy $R1 $R2 "" $R4 + Pop $R5 + Pop $R4 + Pop $R3 + Pop $R2 + Exch $R1 +FunctionEnd +!macroend +!insertmacro StrStr "" +!insertmacro StrStr "un." + +Function Trim ; Added by Pelaca + Exch $R1 + Push $R2 +Loop: + StrCpy $R2 "$R1" 1 -1 + StrCmp "$R2" " " RTrim + StrCmp "$R2" "$\n" RTrim + StrCmp "$R2" "$\r" RTrim + StrCmp "$R2" ";" RTrim + GoTo Done +RTrim: + StrCpy $R1 "$R1" -1 + Goto Loop +Done: + Pop $R2 + Exch $R1 +FunctionEnd + +Function ConditionalAddToRegistry + Pop $0 + Pop $1 + StrCmp "$0" "" ConditionalAddToRegistry_EmptyString + WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \ + "$1" "$0" + ;MessageBox MB_OK "Set Registry: '$1' to '$0'" + DetailPrint "Set install registry entry: '$1' to '$0'" + ConditionalAddToRegistry_EmptyString: +FunctionEnd + +;-------------------------------- + +!ifdef CPACK_USES_DOWNLOAD +Function DownloadFile + IfFileExists $INSTDIR\* +2 + CreateDirectory $INSTDIR + Pop $0 + + ; Skip if already downloaded + IfFileExists $INSTDIR\$0 0 +2 + Return + + StrCpy $1 "@CPACK_DOWNLOAD_SITE@" + + try_again: + NSISdl::download "$1/$0" "$INSTDIR\$0" + + Pop $1 + StrCmp $1 "success" success + StrCmp $1 "Cancelled" cancel + MessageBox MB_OK "Download failed: $1" + cancel: + Return + success: +FunctionEnd +!endif + +;-------------------------------- +; Define some macro setting for the gui +@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@ +@CPACK_NSIS_INSTALLER_ICON_CODE@ +@CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE@ +@CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE@ +@CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@ + +;-------------------------------- +;Pages + @CPACK_NSIS_INSTALLER_WELCOME_TITLE_CODE@ + @CPACK_NSIS_INSTALLER_WELCOME_TITLE_3LINES_CODE@ + !insertmacro MUI_PAGE_WELCOME + + @CPACK_NSIS_LICENSE_PAGE@ + Page custom InstallOptionsPage + !insertmacro MUI_PAGE_DIRECTORY + + ;Start Menu Folder Page Configuration + !define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX" + !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" + !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" + !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER + + @CPACK_NSIS_PAGE_COMPONENTS@ + + !insertmacro MUI_PAGE_INSTFILES + @CPACK_NSIS_INSTALLER_FINISH_TITLE_CODE@ + @CPACK_NSIS_INSTALLER_FINISH_TITLE_3LINES_CODE@ + !insertmacro MUI_PAGE_FINISH + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" ;first language is the default language + !insertmacro MUI_LANGUAGE "Afrikaans" + !insertmacro MUI_LANGUAGE "Albanian" + !insertmacro MUI_LANGUAGE "Arabic" + !insertmacro MUI_LANGUAGE "Asturian" + !insertmacro MUI_LANGUAGE "Basque" + !insertmacro MUI_LANGUAGE "Belarusian" + !insertmacro MUI_LANGUAGE "Bosnian" + !insertmacro MUI_LANGUAGE "Breton" + !insertmacro MUI_LANGUAGE "Bulgarian" + !insertmacro MUI_LANGUAGE "Catalan" + !insertmacro MUI_LANGUAGE "Corsican" + !insertmacro MUI_LANGUAGE "Croatian" + !insertmacro MUI_LANGUAGE "Czech" + !insertmacro MUI_LANGUAGE "Danish" + !insertmacro MUI_LANGUAGE "Dutch" + !insertmacro MUI_LANGUAGE "Esperanto" + !insertmacro MUI_LANGUAGE "Estonian" + !insertmacro MUI_LANGUAGE "Farsi" + !insertmacro MUI_LANGUAGE "Finnish" + !insertmacro MUI_LANGUAGE "French" + !insertmacro MUI_LANGUAGE "Galician" + !insertmacro MUI_LANGUAGE "German" + !insertmacro MUI_LANGUAGE "Greek" + !insertmacro MUI_LANGUAGE "Hebrew" + !insertmacro MUI_LANGUAGE "Hungarian" + !insertmacro MUI_LANGUAGE "Icelandic" + !insertmacro MUI_LANGUAGE "Indonesian" + !insertmacro MUI_LANGUAGE "Irish" + !insertmacro MUI_LANGUAGE "Italian" + !insertmacro MUI_LANGUAGE "Japanese" + !insertmacro MUI_LANGUAGE "Korean" + !insertmacro MUI_LANGUAGE "Kurdish" + !insertmacro MUI_LANGUAGE "Latvian" + !insertmacro MUI_LANGUAGE "Lithuanian" + !insertmacro MUI_LANGUAGE "Luxembourgish" + !insertmacro MUI_LANGUAGE "Macedonian" + !insertmacro MUI_LANGUAGE "Malay" + !insertmacro MUI_LANGUAGE "Mongolian" + !insertmacro MUI_LANGUAGE "Norwegian" + !insertmacro MUI_LANGUAGE "NorwegianNynorsk" + !insertmacro MUI_LANGUAGE "Pashto" + !insertmacro MUI_LANGUAGE "Polish" + !insertmacro MUI_LANGUAGE "Portuguese" + !insertmacro MUI_LANGUAGE "PortugueseBR" + !insertmacro MUI_LANGUAGE "Romanian" + !insertmacro MUI_LANGUAGE "Russian" + !insertmacro MUI_LANGUAGE "ScotsGaelic" + !insertmacro MUI_LANGUAGE "Serbian" + !insertmacro MUI_LANGUAGE "SerbianLatin" + !insertmacro MUI_LANGUAGE "SimpChinese" + !insertmacro MUI_LANGUAGE "Slovak" + !insertmacro MUI_LANGUAGE "Slovenian" + !insertmacro MUI_LANGUAGE "Spanish" + !insertmacro MUI_LANGUAGE "SpanishInternational" + !insertmacro MUI_LANGUAGE "Swedish" + !insertmacro MUI_LANGUAGE "Tatar" + !insertmacro MUI_LANGUAGE "Thai" + !insertmacro MUI_LANGUAGE "TradChinese" + !insertmacro MUI_LANGUAGE "Turkish" + !insertmacro MUI_LANGUAGE "Ukrainian" + !insertmacro MUI_LANGUAGE "Uzbek" + !insertmacro MUI_LANGUAGE "Vietnamese" + !insertmacro MUI_LANGUAGE "Welsh" + +;-------------------------------- +;Reserve Files + + ;These files should be inserted before other files in the data block + ;Keep these lines before any File command + ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA) + + ReserveFile "NSIS.InstallOptions.ini" + !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS + + ; for UserInfo::GetName and UserInfo::GetAccountType + ReserveFile /plugin 'UserInfo.dll' + +;-------------------------------- +; Installation types +@CPACK_NSIS_INSTALLATION_TYPES@ + +;-------------------------------- +; Component sections +@CPACK_NSIS_COMPONENT_SECTIONS@ +@CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@ +;-------------------------------- +;Installer Sections + +Section "-Core installation" + ;Use the entire tree produced by the INSTALL target. Keep the + ;list of directories here in sync with the RMDir commands below. + SetOutPath "$INSTDIR" + @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@ + @CPACK_NSIS_FULL_INSTALL@ + + ;Store installation folder + WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR + + ;Create uninstaller + WriteUninstaller "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe" + Push "DisplayName" + Push "@CPACK_NSIS_DISPLAY_NAME@" + Call ConditionalAddToRegistry + Push "DisplayVersion" + Push "@CPACK_PACKAGE_VERSION@" + Call ConditionalAddToRegistry + Push "Publisher" + Push "@CPACK_PACKAGE_VENDOR@" + Call ConditionalAddToRegistry + Push "UninstallString" + Push "$\"$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe$\"" + Call ConditionalAddToRegistry + Push "NoRepair" + Push "1" + Call ConditionalAddToRegistry + + !ifdef CPACK_NSIS_ADD_REMOVE + ;Create add/remove functionality + Push "ModifyPath" + Push "$INSTDIR\AddRemove.exe" + Call ConditionalAddToRegistry + !else + Push "NoModify" + Push "1" + Call ConditionalAddToRegistry + !endif + + ; Optional registration + Push "DisplayIcon" + Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@" + Call ConditionalAddToRegistry + Push "HelpLink" + Push "@CPACK_NSIS_HELP_LINK@" + Call ConditionalAddToRegistry + Push "URLInfoAbout" + Push "@CPACK_NSIS_URL_INFO_ABOUT@" + Call ConditionalAddToRegistry + Push "Contact" + Push "@CPACK_NSIS_CONTACT@" + Call ConditionalAddToRegistry + !insertmacro MUI_INSTALLOPTIONS_READ $INSTALL_DESKTOP "NSIS.InstallOptions.ini" "Field 5" "State" + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + + ;Create shortcuts + CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" +@CPACK_NSIS_CREATE_ICONS@ +@CPACK_NSIS_CREATE_ICONS_EXTRA@ + CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe" + + ;Read a value from an InstallOptions INI file + !insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State" + !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_ALL_USERS "NSIS.InstallOptions.ini" "Field 3" "State" + !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_CURRENT_USER "NSIS.InstallOptions.ini" "Field 4" "State" + + ; Write special uninstall registry entries + Push "StartMenu" + Push "$STARTMENU_FOLDER" + Call ConditionalAddToRegistry + Push "DoNotAddToPath" + Push "$DO_NOT_ADD_TO_PATH" + Call ConditionalAddToRegistry + Push "AddToPathAllUsers" + Push "$ADD_TO_PATH_ALL_USERS" + Call ConditionalAddToRegistry + Push "AddToPathCurrentUser" + Push "$ADD_TO_PATH_CURRENT_USER" + Call ConditionalAddToRegistry + Push "InstallToDesktop" + Push "$INSTALL_DESKTOP" + Call ConditionalAddToRegistry + + !insertmacro MUI_STARTMENU_WRITE_END + +@CPACK_NSIS_EXTRA_INSTALL_COMMANDS@ + +SectionEnd + +Section "-Add to path" + Push $INSTDIR\bin + StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 doNotAddToPath + StrCmp $DO_NOT_ADD_TO_PATH "1" doNotAddToPath 0 + Call AddToPath + doNotAddToPath: +SectionEnd + +;-------------------------------- +; Create custom pages +Function InstallOptionsPage + !insertmacro MUI_HEADER_TEXT "Install Options" "Choose options for installing @CPACK_NSIS_PACKAGE_NAME@" + !insertmacro MUI_INSTALLOPTIONS_DISPLAY "NSIS.InstallOptions.ini" + +FunctionEnd + +;-------------------------------- +; determine admin versus local install +Function un.onInit + + ClearErrors + UserInfo::GetName + IfErrors noLM + Pop $0 + UserInfo::GetAccountType + Pop $1 + StrCmp $1 "Admin" 0 +3 + SetShellVarContext all + ;MessageBox MB_OK 'User "$0" is in the Admin group' + Goto done + StrCmp $1 "Power" 0 +3 + SetShellVarContext all + ;MessageBox MB_OK 'User "$0" is in the Power Users group' + Goto done + + noLM: + ;Get installation folder from registry if available + + done: + +FunctionEnd + +;--- Add/Remove callback functions: --- +!macro SectionList MacroName + ;This macro used to perform operation on multiple sections. + ;List all of your components in following manner here. +@CPACK_NSIS_COMPONENT_SECTION_LIST@ +!macroend + +Section -FinishComponents + ;Removes unselected components and writes component status to registry + !insertmacro SectionList "FinishSection" + +!ifdef CPACK_NSIS_ADD_REMOVE + ; Get the name of the installer executable + System::Call 'kernel32::GetModuleFileNameA(i 0, t .R0, i 1024) i r1' + StrCpy $R3 $R0 + + ; Strip off the last 13 characters, to see if we have AddRemove.exe + StrLen $R1 $R0 + IntOp $R1 $R0 - 13 + StrCpy $R2 $R0 13 $R1 + StrCmp $R2 "AddRemove.exe" addremove_installed + + ; We're not running AddRemove.exe, so install it + CopyFiles $R3 $INSTDIR\AddRemove.exe + + addremove_installed: +!endif +SectionEnd +;--- End of Add/Remove callback functions --- + +;-------------------------------- +; Component dependencies +Function .onSelChange + !insertmacro SectionList MaybeSelectionChanged +FunctionEnd + +;-------------------------------- +;Uninstaller Section + +Section "Uninstall" + ReadRegStr $START_MENU SHCTX \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu" + ;MessageBox MB_OK "Start menu is in: $START_MENU" + ReadRegStr $DO_NOT_ADD_TO_PATH SHCTX \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "DoNotAddToPath" + ReadRegStr $ADD_TO_PATH_ALL_USERS SHCTX \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathAllUsers" + ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathCurrentUser" + ;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS" + ReadRegStr $INSTALL_DESKTOP SHCTX \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "InstallToDesktop" + ;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP " + +@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@ + + ;Remove files we installed. + ;Keep the list of directories here in sync with the File commands above. +@CPACK_NSIS_DELETE_FILES@ +@CPACK_NSIS_DELETE_DIRECTORIES@ + +!ifdef CPACK_NSIS_ADD_REMOVE + ;Remove the add/remove program + Delete "$INSTDIR\AddRemove.exe" +!endif + + ;Remove the uninstaller itself. + Delete "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe" + DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" + + ;Remove the installation directory if it is empty. + RMDir "$INSTDIR" + + ; Remove the registry entries. + DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" + + ; Removes all optional components + !insertmacro SectionList "RemoveSection_CPack" + + !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP + + Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" +@CPACK_NSIS_DELETE_ICONS@ +@CPACK_NSIS_DELETE_ICONS_EXTRA@ + + ;Delete empty start menu parent directories + StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" + + startMenuDeleteLoop: + ClearErrors + RMDir $MUI_TEMP + GetFullPathName $MUI_TEMP "$MUI_TEMP\.." + + IfErrors startMenuDeleteLoopDone + + StrCmp "$MUI_TEMP" "$SMPROGRAMS" startMenuDeleteLoopDone startMenuDeleteLoop + startMenuDeleteLoopDone: + + ; If the user changed the shortcut, then uninstall may not work. This should + ; try to fix it. + StrCpy $MUI_TEMP "$START_MENU" + Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" +@CPACK_NSIS_DELETE_ICONS_EXTRA@ + + ;Delete empty start menu parent directories + StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" + + secondStartMenuDeleteLoop: + ClearErrors + RMDir $MUI_TEMP + GetFullPathName $MUI_TEMP "$MUI_TEMP\.." + + IfErrors secondStartMenuDeleteLoopDone + + StrCmp "$MUI_TEMP" "$SMPROGRAMS" secondStartMenuDeleteLoopDone secondStartMenuDeleteLoop + secondStartMenuDeleteLoopDone: + + DeleteRegKey /ifempty SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" + + Push $INSTDIR\bin + StrCmp $DO_NOT_ADD_TO_PATH_ "1" doNotRemoveFromPath 0 + Call un.RemoveFromPath + doNotRemoveFromPath: +SectionEnd + +;-------------------------------- +; determine admin versus local install +; Is install for "AllUsers" or "JustMe"? +; Default to "JustMe" - set to "AllUsers" if admin or on Win9x +; This function is used for the very first "custom page" of the installer. +; This custom page does not show up visibly, but it executes prior to the +; first visible page and sets up $INSTDIR properly... +; Choose different default installation folder based on SV_ALLUSERS... +; "Program Files" for AllUsers, "My Documents" for JustMe... + +Function .onInit + StrCmp "@CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL@" "ON" 0 inst + + ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "UninstallString" + StrCmp $0 "" inst + + MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \ + "@CPACK_NSIS_PACKAGE_NAME@ is already installed. $\n$\nDo you want to uninstall the old version before installing the new one?" \ + /SD IDYES IDYES uninst IDNO inst + Abort + +;Run the uninstaller +uninst: + ClearErrors + # $0 should _always_ be quoted, however older versions of CMake did not + # do this. We'll conditionally remove the begin/end quotes. + # Remove first char if quote + StrCpy $2 $0 1 0 # copy first char + StrCmp $2 "$\"" 0 +2 # if char is quote + StrCpy $0 $0 "" 1 # remove first char + # Remove last char if quote + StrCpy $2 $0 1 -1 # copy last char + StrCmp $2 "$\"" 0 +2 # if char is quote + StrCpy $0 $0 -1 # remove last char + + StrLen $2 "\@CPACK_NSIS_UNINSTALL_NAME@.exe" + StrCpy $3 $0 -$2 # remove "\@CPACK_NSIS_UNINSTALL_NAME@.exe" from UninstallString to get path + ExecWait '"$0" /S _?=$3' ;Do not copy the uninstaller to a temp file + + IfErrors uninst_failed inst +uninst_failed: + MessageBox MB_OK|MB_ICONSTOP "Uninstall failed." + Abort + + +inst: + ; Reads components status for registry + !insertmacro SectionList "InitSection" + + ; check to see if /D has been used to change + ; the install directory by comparing it to the + ; install directory that is expected to be the + ; default + StrCpy $IS_DEFAULT_INSTALLDIR 0 + StrCmp "$INSTDIR" "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" 0 +2 + StrCpy $IS_DEFAULT_INSTALLDIR 1 + + StrCpy $SV_ALLUSERS "JustMe" + ; if default install dir then change the default + ; if it is installed for JustMe + StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2 + StrCpy $INSTDIR "$DOCUMENTS\@CPACK_PACKAGE_INSTALL_DIRECTORY@" + + ClearErrors + UserInfo::GetName + IfErrors noLM + Pop $0 + UserInfo::GetAccountType + Pop $1 + StrCmp $1 "Admin" 0 +4 + SetShellVarContext all + ;MessageBox MB_OK 'User "$0" is in the Admin group' + StrCpy $SV_ALLUSERS "AllUsers" + Goto done + StrCmp $1 "Power" 0 +4 + SetShellVarContext all + ;MessageBox MB_OK 'User "$0" is in the Power Users group' + StrCpy $SV_ALLUSERS "AllUsers" + Goto done + + noLM: + StrCpy $SV_ALLUSERS "AllUsers" + ;Get installation folder from registry if available + + done: + StrCmp $SV_ALLUSERS "AllUsers" 0 +3 + StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2 + StrCpy $INSTDIR "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" + + StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 noOptionsPage + !insertmacro MUI_INSTALLOPTIONS_EXTRACT "NSIS.InstallOptions.ini" + + noOptionsPage: +FunctionEnd + +Function .onInstSuccess + MessageBox MB_OK "Installed successfully!" + +FunctionEnd \ No newline at end of file diff --git a/cmake/installer-customizations/NSIS/FileLinks.nsh b/cmake/installer-customizations/NSIS/FileLinks.nsh new file mode 100644 index 00000000..81e30b1b --- /dev/null +++ b/cmake/installer-customizations/NSIS/FileLinks.nsh @@ -0,0 +1,198 @@ +; misc +!define CreateParentFolder "!insertmacro CreateParentFolder" + +!macro CreateParentFolder Path + Push $1 + ${GetParent} "${Path}" $1 + CreateDirectory "$1" + Pop $1 +!macroend + +; info +!define IsLink "!insertmacro IsLink" +!define IsSoftLink "!insertmacro IsSoftLink" +!define IsHardLink "!insertmacro IsHardLink" + +Function IsSoftLink + Exch $0 + ${GetFileAttributes} "$0" "REPARSE_POINT" $0 + + ${If} $0 != "1" + StrCpy $0 "0" + ${EndIf} + Exch $0 +FunctionEnd + +!macro IsSoftLink Path outVar + Push "${Path}" + Call IsSoftLink + Pop ${outVar} +!macroend + +Function IsHardLink + Exch $1 + System::Call "kernel32::CreateFileW(w `$1`, i 0x40000000, i 0, i 0, i 3, i 0, i 0) i .r0" + + ${If} $0 = "-1" + StrCpy $0 "0" + goto is_hard_link_end + ${EndIf} + + System::Call "*(&i256 0) i. r1" + System::Call "kernel32::GetFileInformationByHandle(i r0, i r1) i .s" + System::Call "kernel32::CloseHandle(i r0) i.r0" + Pop $0 + + ${If} $0 == "0" + goto is_hard_link_end + ${EndIf} + + System::Call "*$1(&i40 0, &i4 .r0)" + + ${If} $0 != "0" + IntOp $0 $0 - 1 + ${EndIf} + + is_hard_link_end: + Pop $1 +FunctionEnd + +!macro IsHardLink Path outVar + Push $0 + Push "${Path}" + Call IsHardLink + StrCpy ${outVar} $0 + Pop $0 +!macroend + +!macro IsLink Path outVar + ${IsSoftLink} "${Path}" ${outVar} + + ${If} ${outVar} == 0 + ${IsHardLink} "${Path}" ${outVar} + ${EndIf} +!macroend + +; files +!define CreateHardLink "!insertmacro CreateHardLink" +!define CreateSymbolicLinkFile "!insertmacro CreateSymbolicLinkFile" +!define CreateLinkFile "!insertmacro CreateLinkFile" +!define DeleteLinkFile "!insertmacro DeleteLinkFile" + +!macro CreateSymbolicLinkFile Junction Target outVar + ${CreateParentFolder} "${Junction}" + System::Call "kernel32::CreateSymbolicLinkW(w `${Junction}`, w `${Target}`, i 0) i .s" + Pop ${outVar} + + ${If} ${outVar} == "error" + StrCpy ${outVar} "0" + ${EndIf} +!macroend + +!macro CreateHardLink Junction Target outVar + ${CreateParentFolder} "${Junction}" + System::Call "kernel32::CreateHardLinkW(w `${Junction}`, w `${Target}`, i 0) i .s" + Pop ${outVar} +!macroend + +!macro CreateLinkFile Junction Target outVar + ${CreateSymbolicLinkFile} "${Junction}" "${Target}" ${outVar} + + ${If} ${outVar} == 0 + ${CreateHardLink} "${Junction}" "${Target}" ${outVar} + ${EndIf} +!macroend + +!macro DeleteLinkFile Path outVar + ${IsLink} "${Path}" ${outVar} + + ${If} ${outVar} != 0 + SetFileAttributes "${Path}" "NORMAL" + System::Call "kernel32::DeleteFileW(w `${Path}`) i.s" + Pop ${outVar} + ${EndIf} +!macroend + +; folders +!define CreateJunction "!insertmacro CreateJunction" +!define CreateSymbolicLinkFolder "!insertmacro CreateSymbolicLinkFolder" +!define CreateLinkFolder "!insertmacro CreateLinkFolder" +!define DeleteLinkFolder "!insertmacro DeleteLinkFolder" + +Function CreateJunction + Exch $4 + Exch + Exch $5 + Push $1 + Push $2 + Push $3 + Push $6 + CreateDirectory "$5" + System::Call "kernel32::CreateFileW(w `$5`, i 0x40000000, i 0, i 0, i 3, i 0x02200000, i 0) i .r6" + + ${If} $0 = "-1" + StrCpy $0 "0" + RMDir "$5" + goto create_junction_end + ${EndIf} + + CreateDirectory "$4" ; Windows XP requires that the destination exists + StrCpy $4 "\??\$4" + StrLen $0 $4 + IntOp $0 $0 * 2 + IntOp $1 $0 + 2 + IntOp $2 $1 + 10 + IntOp $3 $1 + 18 + System::Call "*(i 0xA0000003, &i4 $2, &i2 0, &i2 $0, &i2 $1, &i2 0, &w$1 `$4`, &i2 0)i.r2" + System::Call "kernel32::DeviceIoControl(i r6, i 0x900A4, i r2, i r3, i 0, i 0, *i r4r4, i 0) i.r0" + System::Call "kernel32::CloseHandle(i r6) i.r1" + + ${If} $0 == "0" + RMDir "$5" + ${EndIf} + + create_junction_end: + Pop $6 + Pop $3 + Pop $2 + Pop $1 + Pop $5 + Pop $4 +FunctionEnd + +!macro CreateJunction Junction Target outVar + Push $0 + Push "${Junction}" + Push "${Target}" + Call CreateJunction + StrCpy ${outVar} $0 + Pop $0 +!macroend + +!macro CreateSymbolicLinkFolder Junction Target outVar + ${CreateParentFolder} "${Junction}" + System::Call "kernel32::CreateSymbolicLinkW(w `${Junction}`, w `${Target}`, i 1) i .s" + Pop ${outVar} + + ${If} ${outVar} == "error" + StrCpy ${outVar} "0" + ${EndIf} +!macroend + +!macro CreateLinkFolder Junction Target outVar + ${CreateSymbolicLinkFolder} "${Junction}" "${Target}" ${outVar} + + ${If} ${outVar} == 0 + ${CreateJunction} "${Junction}" "${Target}" ${outVar} + ${EndIf} +!macroend + +!macro DeleteLinkFolder Path outVar + ${IsSoftLink} "${Path}" ${outVar} + + ${If} ${outVar} != 0 + SetFileAttributes "${Path}" "NORMAL" + System::Call "kernel32::RemoveDirectoryW(w `${Path}`) i.s" + Pop ${outVar} + ${EndIf} +!macroend \ No newline at end of file diff --git a/cmake/os-features.cmake b/cmake/os-features.cmake new file mode 100644 index 00000000..d0741b4f --- /dev/null +++ b/cmake/os-features.cmake @@ -0,0 +1,207 @@ +## Various and sundry operating system features. +## +## Author: B. Scott Michel +## "scooter me fecit" + +include(CheckSymbolExists) +include(CMakePushCheckState) + +include(pthreads-dep) + +set(NEED_LIBRT FALSE) + +add_library(os_features INTERFACE) + +## Editline support? +find_package(EDITLINE) +if (TARGET Editline::Editline) + target_link_libraries(os_features INTERFACE Editline::Editline) +endif () + +if (WITH_ASYNC) + ## semaphores and sem_timedwait support (OS feature): + check_include_file(semaphore.h semaphore_h_found) + if (semaphore_h_found) + cmake_push_check_state() + + get_property(zz_thread_defs TARGET thread_lib PROPERTY INTERFACE_COMPILE_DEFINITIONS) + get_property(zz_thread_incs TARGET thread_lib PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + get_property(zz_thread_lopts TARGET thread_lib PROPERTY INTERFACE_LINK_OPTIONS) + get_property(zz_thread_libs TARGET thread_lib PROPERTY INTERFACE_LINK_LIBRARIES) + + list(APPEND CMAKE_REQUIRE_DEFINITIONS ${zz_thread_defs}) + list(APPEND CMAKE_REQUIRED_INCLUDES ${zz_thread_incs}) + list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${zz_thread_lopts}) + list(APPEND CMAKE_REQUIRED_LIBRARIES ${zz_thread_libs}) + + check_symbol_exists(sem_timedwait semaphore.h have_sem_timedwait) + + if (NOT have_sem_timedwait) + ## Maybe it's in librt, like shm_open (and more likely, it's not.) + list(APPEND CMAKE_REQUIRED_LIBRARIES rt) + check_symbol_exists(sem_timedwait semaphore.h have_sem_timedwait_rt) + if (have_sem_timedwait_rt) + set(NEED_LIBRT TRUE) + endif (have_sem_timedwait_rt) + endif (NOT have_sem_timedwait) + + cmake_pop_check_state() + + if (have_sem_timedwait OR have_sem_timedwait_rt) + target_compile_definitions(os_features INTERFACE HAVE_SEMAPHORE) + endif () + endif (semaphore_h_found) +endif (WITH_ASYNC) + +## Note: We could use this to enforce better type safety with file I/O. +## +## _LARGEFILE64_SOURCE and _FILE_OFFSET_BITS for Linux +## check_type_size(off_t SIZE_OFF_T) +## if (SIZE_OFF_T) +## target_compile_definitions(os_features INTERFACE SIZE_OFF_T=${SIZE_OFF_T}) +## endif () +## +## check_type_size(off64_t SIZE_OFF64_T) +## if (NOT SIZE_OFF64_T) +## set(xxx_CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}) +## list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE=1) +## check_type_size(off64_t SIZE_OFF64_T) +## set(xxx_CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}) +## +## if (SIZE_OFF64_T) +## target_compile_definitions(os_features INTERFACE _FILE_OFFSET_BITS=64 _LARGEFILE64_SOURCE=1) +## endif () +## endif() +## +## if (SIZE_OFF64_T) +## target_compile_definitions(os_features INTERFACE SIZE_OFF64_T=${SIZE_OFF64_T}) +## endif () + +if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang") + target_compile_definitions(os_features INTERFACE _GNU_SOURCE) +endif () + +## +check_include_file(sys/ioctl.h have_sys_ioctl_h) +if (have_sys_ioctl_h) + target_compile_definitions(os_features INTERFACE HAVE_SYS_IOCTL) +endif (have_sys_ioctl_h) + +## +check_include_file(linux/cdrom.h have_linux_cdrom_h) +if (have_linux_cdrom_h) + target_compile_definitions(os_features INTERFACE HAVE_LINUX_CDROM) +endif (have_linux_cdrom_h) + +## +check_include_file(utime.h have_utime_h) +if (have_utime_h) + target_compile_definitions(os_features INTERFACE HAVE_UTIME) +endif (have_utime_h) + +## +check_include_file(glob.h have_glob_h) +if (have_glob_h) + target_compile_definitions(os_features INTERFACE HAVE_GLOB) +else () + ## + check_include_file(fnmatch.h have_fnmatch_h) + if (have_fnmatch_h) + target_compile_definitions(os_features INTERFACE HAVE_FNMATCH) + endif (have_fnmatch_h) +endif (have_glob_h) + +## and shm_open +check_include_file(sys/mman.h have_sys_mman_h) +if (have_sys_mman_h) + cmake_push_check_state() + + check_symbol_exists(shm_open sys/mman.h have_shm_open) + + if (NOT have_shm_open OR NEED_LIBRT) + ## Linux: shm_open is in the rt library? + set(CMAKE_REQUIRED_LIBRARIES rt) + check_symbol_exists(shm_open sys/mman.h have_shm_open_lrt) + endif (NOT have_shm_open OR NEED_LIBRT) + + if (have_shm_open OR have_shm_open_lrt) + target_compile_definitions(os_features INTERFACE HAVE_SHM_OPEN) + endif (have_shm_open OR have_shm_open_lrt) + if (have_shm_open_lrt) + set(NEED_LIBRT TRUE) + endif (have_shm_open_lrt) + + cmake_pop_check_state() +endif (have_sys_mman_h) + +IF (NEED_LIBRT) + target_link_libraries(os_features INTERFACE rt) +ENDIF (NEED_LIBRT) + +check_include_file(dlfcn.h have_dlfcn_h) +if (have_dlfcn_h) + cmake_push_check_state() + + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS}) + check_symbol_exists(dlopen dlfcn.h have_dlopen) + + if (have_dlopen) + target_link_libraries(os_features INTERFACE ${CMAKE_DL_LIBS}) + + set(dlext ${CMAKE_SHARED_LIBRARY_SUFFIX}) + string(REPLACE "." "" dlext "${dlext}") + target_compile_definitions(os_features INTERFACE SIM_HAVE_DLOPEN=${dlext}) + endif (have_dlopen) + + cmake_pop_check_state() +endif (have_dlfcn_h) + +if (NOT MSVC AND NOT (WIN32 AND CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + # Need the math library on non-Windows platforms + target_link_libraries(os_features INTERFACE m) +endif () + +set(HAVE_TAP_NETWORK False) +set(HAVE_BSDTUNTAP False) + +if (WITH_NETWORK) + ## TAP/TUN devices + if (WITH_TAP) + check_include_file(linux/if_tun.h if_tun_found) + + if (NOT if_tun_found) + check_include_file(net/if_tun.h net_if_tun_found) + if (net_if_tun_found OR EXISTS /Library/Extensions/tap.kext) + set(HAVE_BSDTUNTAP True) + endif (net_if_tun_found OR EXISTS /Library/Extensions/tap.kext) + endif (NOT if_tun_found) + + if (if_tun_found OR net_if_tun_found) + set(HAVE_TAP_NETWORK True) + endif (if_tun_found OR net_if_tun_found) + endif (WITH_TAP) +endif (WITH_NETWORK) + +## Windows: winmm (for ms timer functions), socket functions (even when networking is +## disabled. Also squelch the deprecation warnings (these warnings can be enabled +## via the -DWINAPI_DEPRECATION:Bool=On flag at configure time.) +if (WIN32) + target_link_libraries(os_features INTERFACE ws2_32 wsock32 winmm) + target_compile_definitions(os_features INTERFACE HAVE_WINMM) + if (NOT WINAPI_DEPRECATION) + target_compile_definitions(os_features INTERFACE + _WINSOCK_DEPRECATED_NO_WARNINGS + _CRT_NONSTDC_NO_WARNINGS + _CRT_SECURE_NO_WARNINGS + ) + endif () +endif () + +## Cygwin also wants winmm. Note: Untested but should work. +if (CYGWIN) + check_library_exists(winmm timeGetTime "" HAS_WINMM) + if (HAS_WINMM) + target_link_libraries(os_features INTERFACE ws2_32 wsock32 winmm) + target_compile_definitions(os_features INTERFACE HAVE_WINMM) + endif () +endif () diff --git a/cmake/patches/SDL_ttf/fix-pkgconfig.patch b/cmake/patches/SDL_ttf/fix-pkgconfig.patch new file mode 100644 index 00000000..590eaf51 --- /dev/null +++ b/cmake/patches/SDL_ttf/fix-pkgconfig.patch @@ -0,0 +1,22 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 4ea903d..35be59d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -325,7 +325,7 @@ if(SDL2TTF_INSTALL) + COMPONENT devel + ) + +- if(SDL2TTF_BUILD_SHARED_LIBS) ++ if(1) + # Only create a .pc file for a shared SDL2_ttf + set(prefix "${CMAKE_INSTALL_PREFIX}") + set(exec_prefix "\${prefix}") +@@ -353,7 +353,7 @@ if(SDL2TTF_INSTALL) + \"${CMAKE_CURRENT_BINARY_DIR}/SDL2_ttf.pc\") + file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${PC_DESTDIR}\" + TYPE FILE +- FILES \"${CMAKE_CURRENT_BINARY_DIR}/SDL2_ttf.pc\")" CONFIG Release) ++ FILES \"${CMAKE_CURRENT_BINARY_DIR}/SDL2_ttf.pc\")") + endif() + + if(SDL2TTF_BUILD_SHARED_LIBS AND (APPLE OR (UNIX AND NOT ANDROID))) diff --git a/cmake/patches/zlib/0001-Prevent-invalid-inclusions-when-HAVE_-is-set-to-0.patch b/cmake/patches/zlib/0001-Prevent-invalid-inclusions-when-HAVE_-is-set-to-0.patch new file mode 100644 index 00000000..8fe2b2f5 --- /dev/null +++ b/cmake/patches/zlib/0001-Prevent-invalid-inclusions-when-HAVE_-is-set-to-0.patch @@ -0,0 +1,53 @@ +diff --git a/zconf.h.cmakein b/zconf.h.cmakein +index a7f24cc..a1b359b 100644 +--- a/zconf.h.cmakein ++++ b/zconf.h.cmakein +@@ -434,11 +434,19 @@ typedef uLong FAR uLongf; + #endif + + #ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +-# define Z_HAVE_UNISTD_H ++# if ~(~HAVE_UNISTD_H + 0) == 0 && ~(~HAVE_UNISTD_H + 1) == 1 ++# define Z_HAVE_UNISTD_H ++# elif HAVE_UNISTD_H != 0 ++# define Z_HAVE_UNISTD_H ++# endif + #endif + + #ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +-# define Z_HAVE_STDARG_H ++# if ~(~HAVE_STDARG_H + 0) == 0 && ~(~HAVE_STDARG_H + 1) == 1 ++# define Z_HAVE_STDARG_H ++# elif HAVE_STDARG_H != 0 ++# define Z_HAVE_STDARG_H ++# endif + #endif + + #ifdef STDC +diff --git a/zconf.h.in b/zconf.h.in +index 5e1d68a..32f53c8 100644 +--- a/zconf.h.in ++++ b/zconf.h.in +@@ -432,11 +432,19 @@ typedef uLong FAR uLongf; + #endif + + #ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +-# define Z_HAVE_UNISTD_H ++# if ~(~HAVE_UNISTD_H + 0) == 0 && ~(~HAVE_UNISTD_H + 1) == 1 ++# define Z_HAVE_UNISTD_H ++# elif HAVE_UNISTD_H != 0 ++# define Z_HAVE_UNISTD_H ++# endif + #endif + + #ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +-# define Z_HAVE_STDARG_H ++# if ~(~HAVE_STDARG_H + 0) == 0 && ~(~HAVE_STDARG_H + 1) == 1 ++# define Z_HAVE_STDARG_H ++# elif HAVE_STDARG_H != 0 ++# define Z_HAVE_STDARG_H ++# endif + #endif + + #ifdef STDC + diff --git a/cmake/patches/zlib/0002-skip-building-examples.patch b/cmake/patches/zlib/0002-skip-building-examples.patch new file mode 100644 index 00000000..8183f2ab --- /dev/null +++ b/cmake/patches/zlib/0002-skip-building-examples.patch @@ -0,0 +1,17 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b412dc7..f46c8e6 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -194,6 +194,7 @@ endif() + # Example binaries + #============================================================================ + ++if (0) + add_executable(example test/example.c) + target_link_libraries(example zlib) + add_test(example example) +@@ -211,3 +212,4 @@ if(HAVE_OFF64_T) + target_link_libraries(minigzip64 zlib) + set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") + endif() ++endif() diff --git a/cmake/patches/zlib/0003-build-static-or-shared-not-both.patch b/cmake/patches/zlib/0003-build-static-or-shared-not-both.patch new file mode 100644 index 00000000..c9f2ecf1 --- /dev/null +++ b/cmake/patches/zlib/0003-build-static-or-shared-not-both.patch @@ -0,0 +1,53 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index f46c8e6..6fa5575 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -121,9 +121,11 @@ set(ZLIB_SRCS + ) + + if(NOT MINGW) ++ if(BUILD_SHARED_LIBS) + set(ZLIB_DLL_SRCS + win32/zlib1.rc # If present will override custom build rule below. + ) ++ endif() + endif() + + # parse the full version number from zlib.h and include in ZLIB_FULL_VERSION +@@ -144,13 +146,16 @@ if(MINGW) + -I ${CMAKE_CURRENT_BINARY_DIR} + -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj + -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) ++ if(BUILD_SHARED_LIBS) + set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) ++ endif() + endif(MINGW) + +-add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +-add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) ++add_library(zlib ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) ++if (BUILD_SHARED_LIBS) + set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) + set_target_properties(zlib PROPERTIES SOVERSION 1) ++endif() + + if(NOT CYGWIN) + # This property causes shared libraries on Linux to have the full version +@@ -165,7 +170,7 @@ endif() + + if(UNIX) + # On unix-like platforms the library is almost always called libz +- set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) ++ set_target_properties(zlib PROPERTIES OUTPUT_NAME z) + if(NOT APPLE) + set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") + endif() +@@ -175,7 +180,7 @@ elseif(BUILD_SHARED_LIBS AND WIN32) + endif() + + if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) +- install(TARGETS zlib zlibstatic ++ install(TARGETS zlib + RUNTIME DESTINATION "${INSTALL_BIN_DIR}" + ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" + LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) diff --git a/cmake/patches/zlib/0004-android-and-mingw-fixes.patch b/cmake/patches/zlib/0004-android-and-mingw-fixes.patch new file mode 100644 index 00000000..e93173f2 --- /dev/null +++ b/cmake/patches/zlib/0004-android-and-mingw-fixes.patch @@ -0,0 +1,31 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 6fa5575..7c345db 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -56,7 +56,7 @@ endif() + # + check_include_file(unistd.h Z_HAVE_UNISTD_H) + +-if(MSVC) ++if(WIN32) + set(CMAKE_DEBUG_POSTFIX "d") + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) +@@ -133,7 +133,7 @@ file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) + string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" + "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) + +-if(MINGW) ++if(MINGW AND NOT ANDROID) + # This gets us DLL resource information when compiling on MinGW. + if(NOT CMAKE_RC_COMPILER) + set(CMAKE_RC_COMPILER windres.exe) +@@ -149,7 +149,7 @@ if(MINGW) + if(BUILD_SHARED_LIBS) + set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) + endif() +-endif(MINGW) ++endif(MINGW AND NOT ANDROID) + + add_library(zlib ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) + if (BUILD_SHARED_LIBS) diff --git a/cmake/platform-quirks.cmake b/cmake/platform-quirks.cmake new file mode 100644 index 00000000..527c223e --- /dev/null +++ b/cmake/platform-quirks.cmake @@ -0,0 +1,260 @@ +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the names of The Authors shall not be +# used in advertising or otherwise to promote the sale, use or other dealings +# in this Software without prior written authorization from the Authors. + +## platform_quirks.cmake +## +## This is the place where the CMake build handles various platform quirks, +## such as architecture-specific prefixes (Linux, Windows) and MacOS +## HomeBrew +## +## Author: B. Scott Michel +# "scooter me fecit" + + +set(EXTRA_TARGET_CFLAGS) +set(EXTRA_TARGET_CFLAGS) + +# For 64-bit builds (and this is especially true for MSVC), set the library +# architecture. +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + ## Strongly encourage (i.e., force) CMake to look in the x64 architecture + ## directories: + if (MSVC OR MINGW) + # set(CMAKE_C_LIBRARY_ARCHITECTURE "x64") + # set(CMAKE_LIBRARY_ARCHITECTURE "x64") + elseif (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Linux") + ## Linux has architecture-specific subdirectories where CMake needs to + ## search for headers. Currently, we know about x64 and ARM architecture + ## variants. + foreach (arch "x86_64-linux-gnu" "aarch64-linux-gnu" "arm-linux-gnueabihf") + if (EXISTS "/usr/lib/${arch}") + message(STATUS "CMAKE_LIBRARY_ARCHITECTURE set to ${arch}") + set(CMAKE_C_LIBRARY_ARCHITECTURE "${arch}") + set(CMAKE_LIBRARY_ARCHITECTURE "${arch}") + endif() + endforeach() + endif () +endif() + +if (WIN32) + ## At some point, bring this back in to deal with MS ISO C99 deprecation. + ## Right now, it's not in the code base and the warnings are squelched. + ## + ## (keep): if (MSVC_VERSION GREATER_EQUAL 1920) + ## (keep): add_compile_definitions(USE_ISO_C99_NAMES) + ## (keep): endif () + + if (MSVC) + ## Flags enabled in the SIMH VS solution (diff redution): + ## + ## /EHsc: Standard C++ exception handling, extern "C" functions never + ## throw exceptions. + ## /FC: Output full path name of source in diagnostics + ## /GF: String pooling + ## /GL: Whole program optimization + ## /Gy: Enable function-level linking + ## /Oi: Emit intrinsic functions + ## /Ot: Favor fast code + ## /Oy: Suppress generating a stack frame (??? why?) + add_compile_options("$<$:/EHsc;/GF;/Gy;/Oi;/Ot;/Oy;/Zi>") + add_compile_options("$<$:/EHsc;/FC>") + + if (RELEASE_LTO) + ## /LTCG: Link-Time Code Generation. Pair with /GL at compile time. + add_compile_options("$<$:/GL>") + add_link_options("$<$:/LTCG>") + message(STATUS "Adding LTO to Release compiler and linker flags") + endif () + + ## Set the MSVC runtime. Note CMP0091 policy is set to new early on in + ## the top-level CMakeLists.txt + if (BUILD_SHARED_DEPS) + set(use_rtdll "$<$") + else () + set(use_rtdll "") + endif () + + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>${use_rtll}") + + ## Disable automagic add for _MBCS: + add_definitions(-D_SBCS) + + if (CMAKE_VERSION VERSION_LESS "3.23") + ## -5 Evil hack to ensure that find_package() can match against an empty + ## prefix and not trigger the "CMAKE_FIND_LIBRARY_PREFIXES not set" bug. + list(APPEND CMAKE_FIND_LIBRARY_PREFIXES "lib" "|") + endif () + + list(APPEND EXTRA_TARGET_CFLAGS + "$<$,$>:/W3>" + ) + + ## Uncomment this line if you end up with /NODEFAULTLIB warninigs. You will also + ## need to build with the '--verbose' flag and check the values of "/M*" flags + ## (typically you should see /MT or /MTd for the static runtime libraries.) + ## + # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /verbose:lib") + + if (WARNINGS_FATAL) + message(STATUS "WARNINGS_FATAL: Compiler warnings are errors!! (/WX)") + list(APPEND EXTRA_TARGET_CFLAGS "/WX") + endif () + endif () +elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + # The MSVC solution builds as 32-bit, but none of the *nix platforms do. + # + # If 32-bit compiles have to be added back, uncomment the following 2 lines: + # + # add_compile_options("-m32") + # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") +endif () + + +if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang") + # include(fpintrin) + + # Turn on warnings about strict overflow/potential overflows. + ## LIST(APPEND EXTRA_TARGET_CFLAGS "-Wall" "-fno-inline" "-fstrict-overflow" "-Wstrict-overflow=3") + LIST(APPEND EXTRA_TARGET_CFLAGS + "-U__STRICT_ANSI__" + "$<$,$>:-Wall>" + ) + + # 07 NOV 2022: Apparently, -O3 is kosher now. + # + # 'O3' optimization and strict overflow cause all kinds of simulator issues, especially inside + # the VAX simulators. Reduce optimization and ensure strict overflow is turned off. + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + set(update_o2 TRUE) + if (NOT MINGW) + if (RELEASE_LTO AND (NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "Release")) + check_c_compiler_flag("-flto" GCC_LTO_FLAG) + if (GCC_LTO_FLAG) + message(STATUS "Adding LTO to Release compiler and linker flags") + set(lto_flag "$<$:-flto>") + list(APPEND EXTRA_TARGET_CFLAGS "${lto_flag}") + list(APPEND EXTRA_TARGET_LFLAGS "${lto_flag}") + set(update_o2 FALSE) + else () + message(STATUS "Compiler does not support Link Time Optimization.") + endif () + else () + message(STATUS "Link Time Optimization NOT ENABLED.") + endif () + elseif (MINGW) + message(STATUS "MinGW: Link Time Optimization BROKEN, not added to Release flags") + endif () + + if (update_o2) + message(STATUS "Replacing '-O3' with '-O2'") + string(REGEX REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") + string(REGEX REPLACE "-O3" "-O2" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}") + endif () + + if (WARNINGS_FATAL OR RELEASE_LTO) + check_c_compiler_flag("-Werror" GCC_W_ERROR_FLAG) + if (GCC_W_ERROR_FLAG) + message(STATUS "WARNINGS_FATAL: Compiler warnings are errors!! (-Werror)") + list(APPEND EXTRA_TARGET_CFLAGS "-Werror") + if (RELEASE_LTO) + list(APPEND EXTRA_TARGET_LFLAGS "-Werror") + endif () + endif () + endif () + + message(STATUS "Adding GNU-specific optimizations to CMAKE_C_FLAGS_RELEASE") + list(APPEND opt_flags "-finline-functions" "-fgcse-after-reload" "-fpredictive-commoning" + "-fipa-cp-clone" "-fno-unsafe-loop-optimizations" "-fno-strict-overflow") + elseif (CMAKE_C_COMPILER_ID MATCHES ".*Clang") + message(STATUS "Adding Clang-specific optimizations to CMAKE_C_FLAGS_RELEASE") + list(APPEND opt_flags "-fno-strict-overflow") + endif() + + foreach (opt_flag ${opt_flags}) + message(STATUS " ${opt_flag}") + string(REGEX REPLACE "${opt_flag}[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") + string(APPEND CMAKE_C_FLAGS_RELEASE " ${opt_flag}") + string(REGEX REPLACE "${opt_flag}[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}") + string(APPEND CMAKE_C_FLAGS_MINSIZEREL " ${opt_flag}") + endforeach () +else () + message(STATUS "Not changing CMAKE_C_FLAGS_RELEASE on ${CMAKE_C_COMPILER_ID}") +endif () + + +if (CMAKE_HOST_APPLE) + ## Look for app bundles and frameworks after looking for Unix-style packages: + set(CMAKE_FIND_FRAMEWORK "LAST") + set(CMAKE_FIND_APPBUNDLE "LAST") + + if (EXISTS "/usr/local/Cellar" OR EXISTS "/opt/homebrew/Cellar") + ## Smells like HomeBrew. Bulk add the includes and library subdirectories + message(STATUS "Adding HomeBrew paths to library and include search") + set(hb_topdir "/usr/local/Cellar") + if (EXISTS "/opt/homebrew/Cellar") + set(hb_topdir "/opt/homebrew/Cellar") + endif() + + file(GLOB hb_lib_candidates LIST_DIRECTORIES TRUE "${hb_topdir}/*/*/lib") + file(GLOB hb_include_candidates LIST_DIRECTORIES TRUE "${hb_topdir}/*/*/include") + + # message("@@ lib candidates ${hb_lib_candidates}") + # message("@@ inc candidates ${hb_include_candidates}") + + set(hb_libs "") + foreach (hb_path ${hb_lib_candidates}) + if (IS_DIRECTORY "${hb_path}") + # message("@@ consider ${hb_path}") + list(APPEND hb_libs "${hb_path}") + endif() + endforeach() + + set(hb_includes "") + foreach (hb_path ${hb_include_candidates}) + if (IS_DIRECTORY "${hb_path}") + # message("@@ consider ${hb_path}") + list(APPEND hb_includes "${hb_path}") + endif() + endforeach() + + # message("hb_libs ${hb_libs}") + # message("hb_includes ${hb_includes}") + + list(PREPEND CMAKE_LIBRARY_PATH ${hb_libs}) + list(PREPEND CMAKE_INCLUDE_PATH ${hb_includes}) + + unset(hb_lib_candidates) + unset(hb_include_candidates) + unset(hb_includes) + unset(hb_libs) + unset(hb_path) + elseif(EXISTS /opt/local/bin/port) + # MacPorts + list(PREPEND CMAKE_LIBRARY_PATH /opt/local/lib) + list(PREPEND CMAKE_INCLUDE_PATH /opt/local/include) + endif() + + ## Universal binaries? + if (MAC_UNIVERSAL) + set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64") + endif () +endif() diff --git a/cmake/pthreads-dep.cmake b/cmake/pthreads-dep.cmake new file mode 100644 index 00000000..1ea0723a --- /dev/null +++ b/cmake/pthreads-dep.cmake @@ -0,0 +1,75 @@ +#~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= +# Manage the pthreads dependency +# +# (a) Try to locate the system's installed pthreads library, which is very +# platform dependent (MSVC -> Pthreads4w, MinGW -> pthreads, *nix -> pthreads.) +# (b) MSVC: Build Pthreads4w as a dependent +#~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + +add_library(thread_lib INTERFACE) + +if (WITH_ASYNC) + include(ExternalProject) + + if (MSVC OR (WIN32 AND CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + # Pthreads4w: pthreads for windows. + if (USING_VCPKG) + find_package(PThreads4W REQUIRED) + target_link_libraries(thread_lib INTERFACE PThreads4W::PThreads4W) + set(THREADING_PKG_STATUS "vcpkg PThreads4W") + else () + find_package(PTW) + + if (PTW_FOUND) + target_compile_definitions(thread_lib INTERFACE PTW32_STATIC_LIB) + target_include_directories(thread_lib INTERFACE ${PTW_INCLUDE_DIRS}) + target_link_libraries(thread_lib INTERFACE ${PTW_C_LIBRARY}) + + set(THREADING_PKG_STATUS "detected PTW/PThreads4W") + else () + ## Would really like to build from the original jwinarske repo, but it + ## ends up installing in ${CMAKE_INSTALL_PREFIX}/> prefix. + ## Which completely breaks how CMake Find*.cmake works. + ## + ## set(PTHREADS4W_URL "https://github.com/jwinarske/pthreads4w") + ## set(PTHREADS4W_URL "https://github.com/bscottm/pthreads4w") + set(PTHREADS4W_URL "https://github.com/bscottm/pthreads4w/archive/refs/tags/version-3.1.0-release.zip") + + ExternalProject_Add(pthreads4w-ext + URL ${PTHREADS4W_URL} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) + + BuildDepMatrix(pthreads4w-ext pthreads4w + # CMAKE_ARGS + # -DDIST_ROOT=${SIMH_DEP_TOPDIR} + ) + + list(APPEND SIMH_BUILD_DEPS pthreads4w) + list(APPEND SIMH_DEP_TARGETS pthreads4w-ext) + message(STATUS "Building Pthreads4w from ${PTHREADS4W_URL}") + set(THREADING_PKG_STATUS "pthreads4w source build") + endif () + endif () + else () + # Let CMake determine which threading library ought be used. + set(THREADS_PREFER_PTHREAD_FLAG On) + find_package(Threads) + if (THREADS_FOUND) + target_link_libraries(thread_lib INTERFACE Threads::Threads) + endif (THREADS_FOUND) + + set(THREADING_PKG_STATUS "Platform-detected threading support") + endif () + + if (THREADS_FOUND OR PTW_FOUND) + target_compile_definitions(thread_lib INTERFACE USE_READER_THREAD SIM_ASYNCH_IO) + else () + target_compile_definitions(thread_lib INTERFACE DONT_USE_READER_THREAD) + endif () +else (WITH_ASYNC) + target_compile_definitions(thread_lib INTERFACE DONT_USE_READER_THREAD) + set(THREADING_PKG_STATUS "asynchronous I/O disabled.") +endif (WITH_ASYNC) diff --git a/cmake/simgen/basic_simulator.py b/cmake/simgen/basic_simulator.py new file mode 100644 index 00000000..39c9c64b --- /dev/null +++ b/cmake/simgen/basic_simulator.py @@ -0,0 +1,327 @@ +import pprint + +import simgen.parse_makefile as SPM +import simgen.utils as SU +import simgen.packaging as SPKG + +class SIMHBasicSimulator: + """ + """ + def __init__(self, sim_name, dir_macro, test_name, buildrom): + self.sim_name = sim_name + self.dir_macro = dir_macro + self.test_name = test_name + self.int64 = False + self.full64 = False + self.buildrom = buildrom + ## self.has_display -> True if there is a specific display used by the simulator. + self.has_display = False + ## self.uses_video -> True if USE_SIM_VIDEO appears in the simulator's preprocessor defn's. + self.uses_video = False + ## self.besm6_sdl_hack -> Only set/used by the BESM6 simulator. + self.besm6_sdl_hack = False + self.sources = [] + self.defines = [] + self.includes = [] + + def add_source(self, src): + if src not in self.sources: + self.sources.append(src) + + def add_include(self, incl): + if incl not in self.includes: + self.includes.append(incl) + + def add_define(self, define): + if define not in self.defines: + self.defines.append(define) + + def scan_for_flags(self, defs): + """Scan for USE_INT64/USE_ADDR64 in the simulator's defines and set the + 'int64' and 'full64' instance variables. If found, these defines are + removed. Also look for any of the "DISPLAY" make macros, and, if found, + set the 'video' instance variable. + """ + use_int64 = 'USE_INT64' in self.defines + use_addr64 = 'USE_ADDR64' in self.defines + if use_int64 or use_addr64: + self.int64 = use_int64 and not use_addr64 + self.full64 = use_int64 and use_addr64 + try: + self.defines.remove('USE_INT64') + except: + pass + try: + self.defines.remove('USE_ADDR64') + except: + pass + + ## Video support: + + self.has_display = any(map(lambda s: 'DISPLAY' in SPM.shallow_expand_vars(s, defs), self.sources)) + if self.has_display: + try: + self.sources.remove('${DISPLAYL}') + self.sources.remove('$(DISPLAYL)') + except: + pass + + self.uses_video = 'USE_SIM_VIDEO' in self.defines or self.has_display + + def cleanup_defines(self): + """Remove command line defines that aren't needed (because the CMake interface libraries + already define them.) + """ + for define in ['USE_SIM_CARD', 'USE_SIM_VIDEO', 'USE_NETWORK', 'USE_SHARED']: + try: + self.defines.remove(define) + except: + pass + + def get_source_vars(self): + srcvars = set() + for src in self.sources: + srcvars = srcvars.union(set(SPM.extract_variables(src))) + return srcvars + + def get_include_vars(self): + incvars = set() + for inc in self.includes: + incvars = incvars.union(set(SPM.extract_variables(inc))) + return incvars + + def write_section(self, stream, section, indent, test_label='default', additional_text=[], + section_name=None, section_srcs=None, section_incs=None): + indent4 = ' ' * (indent + 4) + indent8 = ' ' * (indent + 8) + + pkg_info = SPKG.package_info.get(section_name) + install_flag = pkg_info.install_flag if pkg_info is not None else None + pkg_family = pkg_info.family.component_name if pkg_info is not None else None + + stream.write(' ' * indent + '{}({}\n'.format(section, section_name)) + stream.write(' ' * (indent + 4) + 'SOURCES\n') + stream.write('\n'.join(map(lambda src: indent8 + src, section_srcs))) + if len(self.includes) > 0: + stream.write('\n' + indent4 + 'INCLUDES\n') + stream.write('\n'.join([ indent8 + inc for inc in section_incs])) + if len(self.defines) > 0: + stream.write('\n' + indent4 + 'DEFINES\n') + stream.write('\n'.join(map(lambda dfn: indent8 + dfn, self.defines))) + if self.int64: + stream.write('\n' + indent4 + 'FEATURE_INT64') + if self.full64: + stream.write('\n' + indent4 + 'FEATURE_FULL64') + if self.uses_video: + stream.write('\n' + indent4 + "FEATURE_VIDEO") + if self.has_display: + stream.write('\n' + indent4 + "FEATURE_DISPLAY") + if self.besm6_sdl_hack: + stream.write('\n' + indent4 + "BESM6_SDL_HACK") + if self.buildrom: + stream.write('\n' + indent4 + "BUILDROMS") + stream.write('\n' + indent4 + "LABEL " + test_label) + if install_flag: + if pkg_family: + stream.write('\n' + indent4 + "PKG_FAMILY " + pkg_family) + else: + stream.write('\n' + indent4 + "NO_INSTALL") + stream.write('\n' + '\n'.join(additional_text)) + stream.write(')\n') + + def write_simulator(self, stream, indent, test_label='default'): + ## When writing an individual CMakeList.txt, we can take advantage of the CMAKE_CURRENT_SOURCE_DIR + ## as a replacement for the SIMH directory macro. + srcs = [ src.replace(self.dir_macro + '/', '') for src in self.sources] + incs = [ inc if inc != self.dir_macro else '${CMAKE_CURRENT_SOURCE_DIR}' for inc in self.includes] + + indent4 = ' ' * (indent + 4) + + addl_text = [ + indent4 + "TEST " + self.test_name, + ] + + self.write_section(stream, 'add_simulator', indent, test_label, additional_text=addl_text, + section_name=self.sim_name, section_srcs=srcs, section_incs=incs) + + # Default: Don't generate a unit test CMakeFiles.txt. Yet. + def write_unit_test(self, stream, indent, test_label='default'): + pass + + def __repr__(self): + return '{0}({1},{2},{3},{4})'.format(self.__class__.__name__, self.sim_name.__repr__(), + self.sources.__repr__(), self.includes.__repr__(), self.defines.__repr__()) + + +class BESM6Simulator(SIMHBasicSimulator): + """The (fine Communist) BESM6 simulator needs some extra code + in the CMakeLists.txt to detect a suitable font that supports + Cyrillic. + """ + def __init__(self, sim_name, dir_macro, test_name, buildrom): + super().__init__(sim_name, dir_macro, test_name, buildrom) + + def scan_for_flags(self, defs): + super().scan_for_flags(defs) + + def write_simulator(self, stream, indent, test_label='besm6'): + ## Fixups... :-) + for macro in ['FONTFILE=$(FONTFILE)', 'FONTFILE=${FONTFILE}']: + try: + self.defines.remove(macro) + except: + pass + + ## Add the search for a font file. + stream.write('\n'.join([ + 'set(besm6_font)', + 'set(cand_fonts', + ' "DejaVuSans.ttf"', + ' "LucidaSansRegular.ttf"', + ' "FreeSans.ttf"', + ' "AppleGothic.ttf"', + ' "tahoma.ttf")', + 'set(cand_fontdirs', + ' "/usr/share/fonts"', + ' "/usr/lib/jvm"', + ' "/Library/Fonts"', + ' "/System/Library/Fonts"', + ' "/System/Library/Frameworks/JavaVM.framework/Versions"', + ' "$ENV{WINDIR}/Fonts")', + '', + 'foreach (fdir ${cand_fontdirs})', + ' foreach (font ${cand_fonts})', + ' if (EXISTS ${fdir}/${font})', + ' get_filename_component(fontfile ${fdir}/${font} ABSOLUTE)', + ' list(APPEND besm6_font ${fontfile})', + ' endif ()', + '', + ' file(GLOB besm6_font_cand_1 LIST_DIRECTORIES FALSE "${fdir}/*/${font}")', + ' file(GLOB besm6_font_cand_2 LIST_DIRECTORIES FALSE "${fdir}/*/*/${font}")', + ' file(GLOB besm6_font_cand_3 LIST_DIRECTORIES FALSE "${fdir}/*/*/*/${font}")', + ' list(APPEND besm6_font ${besm6_font_cand_1} ${besm6_font_cand_2} ${besm6_font_cand_3})', + ' endforeach()', + 'endforeach()', + '', + 'if (besm6_font)', + ' set(besm6_found_fonts "BESM6: Fonts found")', + ' foreach(bfont ${besm6_font})', + ' string(APPEND besm6_found_fonts "\n .. ${bfont}")', + ' endforeach ()', + ' message(STATUS ${besm6_found_fonts})', + ' unset(besm6_found_fonts)', + ' list(GET besm6_font 0 besm6_font)', + ' message(STATUS "BESM6: Using ${besm6_font}")', + 'else ()', + ' set(besm6_no_fonts "BESM6: No applicable Cyrillic fonts found.")', + ' string(APPEND besm6_no_fonts "\n Font names tried:")', + ' foreach (font ${cand_fonts})', + ' string(APPEND besm6_no_fonts "\n .. ${font}")', + ' endforeach ()', + ' string(APPEND besm6_no_fonts "\n\n Looked in:")', + ' foreach (fdir ${cand_fontdirs})', + ' string(APPEND besm6_no_fonts "\n .. ${fdir}")', + ' endforeach()', + ' string(APPEND besm6_no_fonts "\n\nBESM6: Not building with panel display.")', + ' message(STATUS ${besm6_no_fonts})', + ' unset(besm6_no_fonts)', + 'endif ()', + '', + 'if (NOT (besm6_font AND WITH_VIDEO))\n'])) + super().write_simulator(stream, indent + 4, test_label) + stream.write('else ()\n') + self.defines.append("FONTFILE=${besm6_font}") + self.has_display = True + self.uses_video = True + self.besm6_sdl_hack = True + super().write_simulator(stream, indent + 4, test_label) + stream.write('\n'.join([ + 'endif()', + 'unset(cand_fonts)', + 'unset(cand_fontdirs)\n'])) + +class KA10Simulator(SIMHBasicSimulator): + def __init__(self, sim_name, dir_macro, test_name, buildrom): + super().__init__(sim_name, dir_macro, test_name, buildrom) + + def write_simulator(self, stream, indent, test_label='ka10'): + super().write_simulator(stream, indent, test_label) + stream.write('\n') + stream.write('\n'.join([ + 'if (PANDA_LIGHTS)', + ' target_sources({0} PUBLIC {1}/ka10_lights.c)'.format(self.sim_name, self.dir_macro), + ' target_compile_definitions({0} PUBLIC PANDA_LIGHTS)'.format(self.sim_name), + ' target_link_libraries({0} PUBLIC usb-1.0)'.format(self.sim_name), + 'endif (PANDA_LIGHTS)' + ])) + stream.write('\n') + +class IBM650Simulator(SIMHBasicSimulator): + '''The IBM650 simulator creates relatively deep stacks, which will fail on Windows. + Adjust target simulator link flags to provide a 8M stack, similar to Linux. + ''' + def __init__(self, sim_name, dir_macro, test_name, buildrom): + super().__init__(sim_name, dir_macro, test_name, buildrom) + self.stack_size = 8 * 1024 * 1024 + + def write_simulator(self, stream, indent, test_label='ibm650'): + super().write_simulator(stream, indent, test_label) + stream.write('\n') + ## Link i650 with a 8M stack on windows + stream.write('\n'.join([ + 'if (WIN32)', + ' if (MSVC)', + ' set(I650_STACK_FLAG "/STACK:{0}")'.format(self.stack_size), + ' else ()', + ' set(I650_STACK_FLAG "-Wl,--stack,{0}")'.format(self.stack_size), + ' endif ()', + ' if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.13")', + ' target_link_options({0} PUBLIC "${{I650_STACK_FLAG}}")'.format(self.sim_name), + ' else ()', + ' set_property(TARGET {0} LINK_FLAGS " ${{I650_STACK_FLAG}}")'.format(self.sim_name), + ' endif ()', + 'endif()' + ])) + +class IBM1130Simulator(SIMHBasicSimulator): + '''The IBM650 simulator creates relatively deep stacks, which will fail on Windows. + Adjust target simulator link flags to provide a 8M stack, similar to Linux. + ''' + def __init__(self, sim_name, dir_macro, test_name, buildrom): + super().__init__(sim_name, dir_macro, test_name, buildrom) + + def write_simulator(self, stream, indent, test_label='ibm650'): + super().write_simulator(stream, indent, test_label) + stream.write('\n'.join([ + '', + 'if (WIN32)', + ' target_compile_definitions(ibm1130 PRIVATE GUI_SUPPORT)', + ' ## missing source in IBM1130?' + ' ## target_sources(ibm1130 PRIVATE ibm1130.c)', + 'endif()' + ])) + + +if '_dispatch' in pprint.PrettyPrinter.__dict__: + def sim_pprinter(pprinter, sim, stream, indent, allowance, context, level): + cls = sim.__class__ + stream.write(cls.__name__ + '(') + indent += len(cls.__name__) + 1 + pprinter._format(sim.sim_name, stream, indent, allowance + 2, context, level) + stream.write(',') + pprinter._format(sim.dir_macro, stream, indent, allowance + 2, context, level) + stream.write(',') + pprinter._format(sim.int64, stream, indent, allowance + 2, context, level) + stream.write(',') + pprinter._format(sim.full64, stream, indent, allowance + 2, context, level) + stream.write(',') + pprinter._format(sim.has_display, stream, indent, allowance + 2, context, level) + stream.write(',') + pprinter._format(sim.sources, stream, indent, allowance + 2, context, level) + stream.write(',\n' + ' ' * indent) + pprinter._format(sim.defines, stream, indent, allowance + 2, context, level) + stream.write(',\n' + ' ' * indent) + pprinter._format(sim.includes, stream, indent, allowance + 2, context, level) + stream.write(')') + + pprint.PrettyPrinter._dispatch[SIMHBasicSimulator.__repr__] = sim_pprinter diff --git a/cmake/simgen/cmake_container.py b/cmake/simgen/cmake_container.py new file mode 100644 index 00000000..053a7549 --- /dev/null +++ b/cmake/simgen/cmake_container.py @@ -0,0 +1,411 @@ +## cmake_container.py +## +## A container for a collection of SIMH simulators +## +## + +import sys +import os +import re +import pprint +import functools + +import simgen.parse_makefile as SPM +import simgen.sim_collection as SC +import simgen.utils as SU + +## Corresponding special variable uses in the makefile: +_special_sources = frozenset(['${DISPLAYL}', '$(DISPLAYL)']) + +## Banner header for individual CMakeLists.txt files: +_individual_header = [ + '##', + '## This is an automagically generated file. Do NOT EDIT.', + '## Any changes you make will be overwritten!!', + '##', + '## Make changes to the SIMH top-level makefile and then run the', + '## "cmake/generate.py" script to regenerate these files.', + '##', + '## cd cmake; python -m generate --help', + '##', + '## ' + '-' * 60 + '\n' + ] + +## Banner header for individual unit test CMakeLists.txt files: +_unit_test_header = [ + '##', + '## This is an automagically generated file. Do NOT EDIT.', + '## Any changes you make will be overwritten!!', + '##', + '## If you need to make changes, modify write_unit_test()', + '## method in the the underlying Python class in ', + '## cmake/simgen/basic_simulator.py, then execute the', + '## "cmake/generate.py" script to regenerate these files.', + '##', + '## cd cmake; python -m generate --help', + '##', + '## ' + '-' * 60 + '\n' + ] +## Unset the display variables when not building with video. A +10 +## kludge. +_unset_display_vars = ''' +if (NOT WITH_VIDEO) + ### Hack: Unset these variables so that they don't expand if + ### not building with video: + set(DISPLAY340 "") + set(DISPLAYIII "") + set(DISPLAYNG "") + set(DISPLAYVT "") +endif () +''' + +class CMakeBuildSystem: + """A container for collections of SIMH simulators and automagic + CMakeLists.txt driver. + + This is the top-level container that stores collections of SIMH simulators + in the 'SIM' + """ + + ## Compile command line elements that are ignored. + _ignore_compile_elems = frozenset(['${LDFLAGS}', '$(LDFLAGS)', + '${CC_OUTSPEC}', '$(CC_OUTSPEC)', + '${SIM}', '$(SIM)', + '-o', '$@', + '${NETWORK_OPT}', '$(NETWORK_OPT)', + '${SCSI}', '$(SCSI)', + '${DISPLAY_OPT}', '$(DISPLAY_OPT)', + '${VIDEO_CCDEFS}', '$(VIDEO_CCDEFS)', + '${VIDEO_LDFLAGS}', '$(VIDEO_LDFLAGS)', + '${BESM6_PANEL_OPT}', '$(BESM6_PANEL_OPT)']) + + def __init__(self): + # "Special" variables that we look for in source code lists and which we'll + # emit into the CMakeLists.txt files. + self.vars = SC.ignored_display_macros.copy() + # Subdirectory -> SimCollection mapping + self.dirs = {} + + + def extract(self, compile_action, test_name, sim_dir, sim_name, defs, buildrom, debug=0, depth=''): + """Extract sources, defines, includes and flags from the simulator's + compile action in the makefile. + """ + sim_dir_path = SPM.expand_vars(sim_dir, defs).replace('./', '') + simcoll = self.dirs.get(sim_dir_path) + if simcoll is None: + simcoll = SC.SimCollection(sim_dir) + self.dirs[sim_dir_path] = simcoll + + sim = simcoll.get_simulator(sim_name, sim_dir, sim_dir_path, test_name, buildrom) + + # Remove compile command line elements and do one level of variable expansion, split the resulting + # string into a list. + all_comps = [] + for comp in [ SPM.normalize_variables(act) for act in compile_action.split() if not self.compile_elems_to_ignore(act) ]: + all_comps.extend(comp.split()) + + if debug >= 3: + print('{0}all_comps after filtering:'.format(depth)) + pprint.pp(all_comps) + + # Iterate through the final compile component list and extract source files, includes + # and defines. + # + # Deferred: Looking for options that set the i64, z64, video library options. + while all_comps: + comp = all_comps[0] + # print(':: comp {0}'.format(comp)) + if self.is_source(comp): + # Source file... + ## sim.add_source(comp.replace(sim_dir + '/', '')) + sim.add_source(comp) + elif comp.startswith('-I'): + all_comps = self.process_flag(all_comps, defs, sim.add_include, depth) + elif comp.startswith('-D'): + all_comps = self.process_flag(all_comps, defs, sim.add_define, depth) + elif comp.startswith('-L') or comp.startswith('-l'): + ## It's a library path or library. Skip. + pass + else: + # Solitary variable expansion? + m = SPM._var_rx.match(comp) + if m: + varname = m.group(1) + if varname not in SC._special_vars: + if not self.is_source_macro(comp, defs): + expand = [ SPM.normalize_variables(elem) for elem in SPM.shallow_expand_vars(comp, defs).split() + if not self.source_elems_to_ignore(elem) ] + SU.emit_debug(debug, 3, '{0}var expanded {1} -> {2}'.format(depth, comp, expand)) + all_comps[1:] = expand + all_comps[1:] + else: + ## Source macro + self.collect_source_macros(comp, defs, varname, simcoll, sim, debug, depth) + else: + sim.add_source(comp) + else: + # Nope. + print('{0}unknown component: {1}'.format(depth, comp)) + all_comps = all_comps[1:] + + sim.scan_for_flags(defs) + sim.cleanup_defines() + + if debug >= 2: + pprint.pprint(sim) + + + def compile_elems_to_ignore(self, elem): + return (elem in self._ignore_compile_elems or elem.endswith('_LDFLAGS')) + + def source_elems_to_ignore(self, elem): + return self.compile_elems_to_ignore(elem) or elem in _special_sources + + + def is_source_macro(self, var, defs): + """Is the macro/variable a list of sources? + """ + expanded = SPM.expand_vars(var, defs).split() + # print('is_source_macro {}'.format(expanded)) + return all(map(lambda src: self.is_source(src), expanded)) + + + def is_source(self, thing): + return thing.endswith('.c') + + + def process_flag(self, comps, defs, process_func, depth): + if len(comps[0]) > 2: + # "-Ddef" + val = comps[0][2:] + else: + # "-D def" + val = comps[1] + comps = comps[1:] + m = SPM._var_rx.match(val) + if m: + var = m.group(1) + ## Gracefully deal with undefined variables (ATT3B2M400B2D is a good example) + if var in defs: + if var not in self.vars: + self.vars[var] = defs[var] + else: + print('{0}undefined make macro: {1}'.format(depth, var)) + + process_func(val) + return comps + + + def collect_vars(self, defs, debug=0): + """Add indirectly referenced macros and variables, adding them to the defines dictionary. + + Indirectly referenced macros and variables are macros and variables embedded in existing + variables, source macros and include lists. For example, SIMHD is an indirect reference + in "KA10D = ${SIMHD}/ka10" because KA10D might never have been expanded by 'extract()'. + """ + + def scan_var(varset, var): + tmp = var + return varset.union(set(SPM.extract_variables(tmp))) + + def replace_simhd(l, v): + l.append(v.replace('SIMHD', 'CMAKE_SOURCE_DIR')) + return l + + simvars = set() + for v in self.vars.values(): + if isinstance(v, list): + simvars = functools.reduce(scan_var, v, simvars) + else: + simvars = scan_var(simvars, v) + + for dir in self.dirs.keys(): + simvars = simvars.union(self.dirs[dir].get_simulator_vars(debug)) + + if debug >= 2: + print('Collected simvars:') + pprint.pprint(simvars) + + for var in simvars: + if var not in self.vars: + if var in defs: + self.vars[var] = defs[var] + else: + print('{0}: variable not defined.'.format(var)) + + ## Replace SIMHD with CMAKE_SOURCE_DIR + for k, v in self.vars.items(): + if isinstance(v, list): + v = functools.reduce(replace_simhd, v, []) + else: + v = v.replace('SIMHD', 'CMAKE_SOURCE_DIR') + self.vars[k] = v + + def collect_source_macros(self, comp, defs, varname, simcoll, sim, debug=0, depth=''): + def inner_sources(srcmacro): + for v in srcmacro: + if not self.source_elems_to_ignore(v): + m = SPM._var_rx.match(v) + if m is not None: + vname = m.group(1) + vardef = defs.get(vname) + if vardef is not None: + ## Convert the macro variable into a list + vardef = [ SPM.normalize_variables(v) \ + for v in vardef.split() if not self.source_elems_to_ignore(v) ] + SU.emit_debug(debug, 3, '{0}source macro: {1} -> {2}'.format(depth, vname, vardef)) + simcoll.add_source_macro(vname, vardef, sim) + ## Continue into the macro variable's definitions + inner_sources(vardef) + + vardef = defs.get(varname) + if vardef is not None: + vardef = [ SPM.normalize_variables(v) \ + for v in vardef.split() if not self.source_elems_to_ignore(v) ] + SU.emit_debug(debug, 3, '{0}source macro: {1} -> {2}'.format(depth, varname, vardef)) + simcoll.add_source_macro(varname, vardef, sim) + inner_sources(vardef) + SU.emit_debug(debug, 3, '{0}source added: {1}'.format(depth, comp)) + sim.add_source(comp) + else: + print('{0}undefined make macro: {1}'.format(depth, varname)) + + def write_vars(self, stream): + def collect_vars(varlist, var): + varlist.extend(SPM.extract_variables(var)) + return varlist + + varnames = list(self.vars.keys()) + namewidth = max(map(lambda s: len(s), varnames)) + # vardeps maps the parent variable to its dependents, e.g., + # INTELSYSD -> [ISYS8010D, ...] + vardeps = dict() + # alldeps is the set of all parent and dependents, which will be + # deleted from a copy of self.vars. The copy has variables that + # don't depend on anything (except for CMAKE_SOURCE_DIR, but we + # know that's defined by CMake.) + alldeps = set() + for var in varnames: + if isinstance(self.vars[var], list): + mvars = functools.reduce(collect_vars, self.vars[var], []) + else: + mvars = SPM.extract_variables(self.vars[var]) + mvars = [mvar for mvar in mvars if mvar != "CMAKE_SOURCE_DIR"] + if mvars: + alldeps.add(var) + for mvar in mvars: + if mvar not in vardeps: + vardeps[mvar] = [] + vardeps[mvar].append(var) + alldeps.add(mvar) + + nodeps = self.vars.copy() + ## SIMHD will never be used. + if 'SIMHD' in nodeps: + del nodeps['SIMHD'] + for dep in alldeps: + del nodeps[dep] + + varnames = list(nodeps.keys()) + varnames.sort() + for var in varnames: + self.emit_value(var, self.vars[var], stream, namewidth) + + ## Now to emit the dependencies + depnames = list(vardeps.keys()) + depnames.sort() + for dep in depnames: + self.write_dep(dep, vardeps, alldeps, namewidth, stream) + + ## stream.write('\n## ' + '-' * 40 + '\n') + + def write_dep(self, dep, vardeps, alldeps, width, stream): + # Not the most efficient, but it works + alldeps.discard(dep) + for parent in [ v for v in vardeps.keys() if dep in vardeps[v]]: + if dep in parent.values(): + self.write_dep(parent, vardeps, alldeps, width, stream) + + stream.write('\n') + self.emit_value(dep, self.vars[dep], stream, width) + + children = vardeps[dep] + children.sort() + for child in children: + if child in alldeps: + self.emit_value(child, self.vars[child], stream, width) + alldeps -= set(children) + + def emit_value(self, var, value, stream, width=0): + if isinstance(value, list): + stream.write('set({:{width}} {})\n'.format(var, ' '.join(map(lambda s: '"' + s + '"', value)), + width=width)) + else: + stream.write('set({:{width}} "{}")\n'.format(var, value, width=width)) + + def write_simulators(self, toplevel_dir, debug=0): + dirnames = list(self.dirs.keys()) + dirnames.sort() + + for subdir in dirnames: + simcoll = self.dirs[subdir] + test_label = subdir + # Group tests under subdirectories together + has_slash = test_label.find('/') + if has_slash < 0: + has_slash = test_label.find('\\') + if has_slash >= 0: + test_label = test_label[:has_slash] + ## Write out individual CMakeLists.txt: + subdir_cmake = os.path.join(toplevel_dir, subdir, 'CMakeLists.txt') + print('==== writing to {0}'.format(subdir_cmake)) + with open(subdir_cmake, "w", newline='\r\n') as stream2: + plural = '' if len(self.dirs[subdir]) == 1 else 's' + stream2.write('## {} simulator{plural}\n'.format(subdir, plural=plural)) + stream2.write('\n'.join(_individual_header)) + stream2.write('\n') + stream2.write('if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt")\n') + stream2.write(' add_subdirectory(unit-tests)\n') + stream2.write('endif ()') + stream2.write('\n') + simcoll.write_simulators(stream2, debug=debug, test_label=test_label) + + ## Write out unit tests, if the unit test subdirectory exists: + subdir_units_dir = os.path.join(toplevel_dir, subdir, 'unit-tests') + subdir_units = os.path.join(subdir_units_dir, 'CMakeLists.txt') + if os.path.exists(subdir_units): + with open(subdir_units, "w") as stream2: + plural = '' if len(self.dirs[subdir]) == 1 else 's' + stream2.write('## {} simulator{plural}\n'.format(subdir, plural=plural)) + stream2.write('\n'.join(_unit_test_header)) + stream2.write('\n') + simcoll.write_unit_tests(stream2, debug, subdir) + + simh_subdirs = os.path.join(toplevel_dir, 'cmake', 'simh-simulators.cmake') + print("==== writing {0}".format(simh_subdirs)) + with open(simh_subdirs, "w") as stream2: + stream2.write('\n'.join(_individual_header)) + self.write_vars(stream2) + stream2.write('\n## ' + '-' * 40 + '\n') + stream2.write(_unset_display_vars) + stream2.write('\n## ' + '-' * 40 + '\n\n') + stmts = [ 'add_subdirectory(' + dir + ')' for dir in dirnames ] + stream2.write('\n'.join(stmts)) + stream2.write('\n') + + ## Representation when printed + def __repr__(self): + return '{0}({1}, {2})'.format(self.__class__.__name__, self.dirs.__repr__(), self.vars.__repr__()) + + +if '_dispatch' in pprint.PrettyPrinter.__dict__: + def cmake_pprinter(pprinter, cmake, stream, indent, allowance, context, level): + cls = cmake.__class__ + stream.write(cls.__name__ + '(') + indent += len(cls.__name__) + 1 + pprinter._format(cmake.dirs, stream, indent, allowance + 2, context, level) + stream.write(',\n' + ' ' * indent) + pprinter._format(cmake.vars, stream, indent, allowance + 2, context, level) + stream.write(')') + + pprint.PrettyPrinter._dispatch[CMakeBuildSystem.__repr__] = cmake_pprinter diff --git a/cmake/simgen/packaging.py b/cmake/simgen/packaging.py new file mode 100644 index 00000000..6f088a2c --- /dev/null +++ b/cmake/simgen/packaging.py @@ -0,0 +1,247 @@ +import os +import functools + +## Initialize package_info to an empty dictionary here so +## that it's visible to write_packaging(). +package_info = {} + + +class SIMHPackaging: + def __init__(self, family, install_flag = True) -> None: + self.family = family + self.processed = False + self.install_flag = install_flag + + def was_processed(self) -> bool: + return self.processed == True + + def encountered(self) -> None: + self.processed = True + +class PkgFamily: + def __init__(self, component_name, display_name, description) -> None: + self.component_name = component_name + self.display_name = display_name + self.description = description + + def write_component_info(self, stream, indent) -> None: + pkg_description = self.description + if pkg_description[-1] != '.': + pkg_description += '.' + sims = [] + for sim, pkg in package_info.items(): + if pkg.family is self: + sims.append(sim) + sims.sort() + pkg_description += " Simulators: " + ', '.join(sims) + indent0 = ' ' * indent + indent4 = ' ' * (indent + 4) + stream.write(indent0 + "cpack_add_component(" + self.component_name + "\n") + stream.write(indent4 + "DISPLAY_NAME \"" + self.display_name + "\"\n") + stream.write(indent4 + "DESCRIPTION \"" + pkg_description + "\"\n") + stream.write(indent0 + ")\n") + + def __lt__(self, obj): + return self.component_name < obj.component_name + def __eq__(self, obj): + return self.component_name == obj.component_name + def __gt__(self, obj): + return self.component_name > obj.component_name + def __hash__(self): + return hash(self.component_name) + +def write_packaging(toplevel_dir) -> None: + families = set([sim.family for sim in package_info.values()]) + pkging_file = os.path.join(toplevel_dir, 'cmake', 'simh-packaging.cmake') + print("==== writing {0}".format(pkging_file)) + with open(pkging_file, "w") as stream: + ## Runtime support family: + stream.write("""## The default runtime support component/family: +cpack_add_component(runtime_support + DISPLAY_NAME "Runtime support" + DESCRIPTION "Required SIMH runtime support (documentation, shared libraries)" + REQUIRED +) + +## Basic documentation for SIMH +install(FILES doc/simh.doc TYPE DOC COMPONENT runtime_support) + +""") + + ## Simulators: + for family in sorted(families): + family.write_component_info(stream, 0) + + +default_family = PkgFamily("default_family", "Default SIMH simulator family.", + """The SIMH simulator collection of historical processors and computing systems that do not belong to +any other simulated system family""" +) + +att3b2_family = PkgFamily("att3b2_family", "ATT&T 3b2 collection", + """The AT&T 3b2 simulator family""" +) + +vax_family = PkgFamily("vax_family", "DEC VAX simulator collection", + """The Digital Equipment Corporation VAX (plural: VAXen) simulator family.""" +) + +pdp10_family = PkgFamily("pdp10_family", "DEC PDP-10 collection", + """DEC PDP-10 architecture simulators and variants.""" +) + +pdp11_family = PkgFamily("pdp11_family", "DEC PDP-11 collection.", + """DEC PDP-11 and PDP-11-derived architecture simulators""" +) + +experimental_family = PkgFamily("experimental", "Experimental (work-in-progress) simulators", + """Experimental or work-in-progress simulators not in the SIMH mainline simulator suite.""" +) + +altairz80_family = PkgFamily("altairz80_family", "Altair Z80 simulator.", + """The Altair Z80 simulator with M68000 support.""" +) + +b5500_family = PkgFamily("b5500_family", "Burroughs 5500", + """The Burroughs 5500 system simulator""") + +cdc1700_family = PkgFamily("cdc1700_family", "CDC 1700", + """The Control Data Corporation's systems""" +) + +dgnova_family = PkgFamily("dgnova_family", "DG Nova and Eclipse", + """Data General NOVA and Eclipse system simulators""" +) + +grisys_family = PkgFamily("grisys_family", "GRI Systems GRI-909", + """GRI Systems GRI-909 system simulator""" +) + +honeywell_family = PkgFamily("honeywell_family", "Honeywell H316", + """Honeywell H-316 system simulator""" +) + +hp_family = PkgFamily("hp_family", "HP 2100, 3000", + """Hewlett-Packard H2100 and H3000 simulators""") + +ibm_family = PkgFamily("ibm_family", "IBM", + """IBM system simulators: i650""" +) + +imlac_family = PkgFamily("imlac_family", "IMLAC", + """IMLAC system simulators""" +) + +intel_family = PkgFamily("intel_family", "Intel", + """Intel system simulators""" +) + +interdata_family = PkgFamily("interdata_family", "Interdata", + """Interdata systems simulators""" +) + +lgp_family = PkgFamily("lgp_family", "LGP", + """Librascope systems""" +) + +decpdp_family = PkgFamily("decpdp_family", "DEC PDP family", + """Digital Equipment Corporation PDP systems""" +) + +sds_family = PkgFamily("sds_family", "SDS simulators", + """Scientific Data Systems (SDS) systems""" +) + +gould_family = PkgFamily("gould_family", "Gould simulators", + """Gould Systems simulators""" +) + +swtp_family = PkgFamily("swtp_family", "SWTP simulators", + """Southwest Technical Products (SWTP) system simulators""" +) + +norsk_family = PkgFamily("norsk_family", "ND simulators", + """Norsk Data systems simulator family""") + + +package_info["3b2"] = SIMHPackaging(att3b2_family) +package_info["3b2-700"] = SIMHPackaging(att3b2_family) +package_info["altair"] = SIMHPackaging(default_family) +package_info["altairz80"] = SIMHPackaging(altairz80_family) +package_info["b5500"] = SIMHPackaging(b5500_family) +package_info["besm6"] = SIMHPackaging(default_family) +package_info["cdc1700"] = SIMHPackaging(cdc1700_family) +package_info["eclipse"] = SIMHPackaging(dgnova_family) +package_info["gri"] = SIMHPackaging(grisys_family) +package_info["h316"] = SIMHPackaging(honeywell_family) +package_info["hp2100"] = SIMHPackaging(hp_family) +package_info["hp3000"] = SIMHPackaging(hp_family) +package_info["i1401"] = SIMHPackaging(ibm_family) +package_info["i1620"] = SIMHPackaging(ibm_family) +package_info["i650"] = SIMHPackaging(ibm_family) +package_info["i701"] = SIMHPackaging(ibm_family) +package_info["i7010"] = SIMHPackaging(ibm_family) +package_info["i704"] = SIMHPackaging(ibm_family) +package_info["i7070"] = SIMHPackaging(ibm_family) +package_info["i7080"] = SIMHPackaging(ibm_family) +package_info["i7090"] = SIMHPackaging(ibm_family) +package_info["i7094"] = SIMHPackaging(ibm_family) +package_info["ibm1130"] = SIMHPackaging(ibm_family) +package_info["id16"] = SIMHPackaging(interdata_family) +package_info["id32"] = SIMHPackaging(interdata_family) +package_info["imlac"] = SIMHPackaging(imlac_family) +package_info["infoserver100"] = SIMHPackaging(vax_family) +package_info["infoserver1000"] = SIMHPackaging(vax_family) +package_info["infoserver150vxt"] = SIMHPackaging(vax_family) +package_info["intel-mds"] = SIMHPackaging(intel_family) +package_info["lgp"] = SIMHPackaging(lgp_family) +package_info["microvax1"] = SIMHPackaging(vax_family) +package_info["microvax2"] = SIMHPackaging(vax_family) +package_info["microvax2000"] = SIMHPackaging(vax_family) +package_info["microvax3100"] = SIMHPackaging(vax_family) +package_info["microvax3100e"] = SIMHPackaging(vax_family) +package_info["microvax3100m80"] = SIMHPackaging(vax_family) +package_info["nd100"] = SIMHPackaging(norsk_family) +package_info["nova"] = SIMHPackaging(dgnova_family) +package_info["pdp1"] = SIMHPackaging(decpdp_family) +## Don't install pdp10 per Rob Cromwell +package_info["pdp10"] = SIMHPackaging(pdp10_family, install_flag=False) +package_info["pdp10-ka"] = SIMHPackaging(pdp10_family) +package_info["pdp10-ki"] = SIMHPackaging(pdp10_family) +package_info["pdp10-kl"] = SIMHPackaging(pdp10_family) +package_info["pdp10-ks"] = SIMHPackaging(pdp10_family) +package_info["pdp11"] = SIMHPackaging(pdp11_family) +package_info["pdp15"] = SIMHPackaging(decpdp_family) +package_info["pdp4"] = SIMHPackaging(decpdp_family) +package_info["pdp6"] = SIMHPackaging(decpdp_family) +package_info["pdp7"] = SIMHPackaging(decpdp_family) +package_info["pdp8"] = SIMHPackaging(decpdp_family) +package_info["pdp9"] = SIMHPackaging(decpdp_family) +package_info["rtvax1000"] = SIMHPackaging(vax_family) +package_info["s3"] = SIMHPackaging(ibm_family) +package_info["scelbi"] = SIMHPackaging(intel_family) +package_info["sds"] = SIMHPackaging(sds_family) +package_info["sel32"] = SIMHPackaging(gould_family) +package_info["sigma"] = SIMHPackaging(sds_family) +package_info["ssem"] = SIMHPackaging(default_family) +package_info["swtp6800mp-a"] = SIMHPackaging(swtp_family) +package_info["swtp6800mp-a2"] = SIMHPackaging(swtp_family) +package_info["tt2500"] = SIMHPackaging(default_family) +package_info["tx-0"] = SIMHPackaging(default_family) +package_info["uc15"] = SIMHPackaging(pdp11_family) +package_info["vax"] = SIMHPackaging(vax_family) +package_info["vax730"] = SIMHPackaging(vax_family) +package_info["vax750"] = SIMHPackaging(vax_family) +package_info["vax780"] = SIMHPackaging(vax_family) +package_info["vax8200"] = SIMHPackaging(vax_family) +package_info["vax8600"] = SIMHPackaging(vax_family) +package_info["vaxstation3100m30"] = SIMHPackaging(vax_family) +package_info["vaxstation3100m38"] = SIMHPackaging(vax_family) +package_info["vaxstation3100m76"] = SIMHPackaging(vax_family) +package_info["vaxstation4000m60"] = SIMHPackaging(vax_family) +package_info["vaxstation4000vlc"] = SIMHPackaging(vax_family) + +## Experimental simulators: +package_info["alpha"] = SIMHPackaging(experimental_family) +package_info["pdq3"] = SIMHPackaging(experimental_family) +package_info["sage"] = SIMHPackaging(experimental_family) diff --git a/cmake/simgen/parse_makefile.py b/cmake/simgen/parse_makefile.py new file mode 100644 index 00000000..2923f6d7 --- /dev/null +++ b/cmake/simgen/parse_makefile.py @@ -0,0 +1,184 @@ +"""Makefile parsing and variable expansion. + +Read and collect variable, rule and action information from a [Mm]akefile. +This isn't a precise collection; for example, it does not respect GNU Makefile +directives such as 'ifeq' and 'ifneq'. +""" + +import re + +# Regexes needed for parsing Makefile (and similar syntaxes, +# like old-style Setup files). +_variable_rx = re.compile(r"\s*([A-Za-z][\w_-]+)\s*=\s*(.*)") +_rule_rx = re.compile(r"(((\$[({])*\w[\w_-]+[)}]*)+)\s*:\s*(.*)") + +# Regex that recognizes variables. Group 1 is the variable's name. +_var_rx = re.compile(r"^\$[{(]([A-Za-z][\w_-]*)[)}]$") +_var_rx2 = re.compile(r"\$[{(]([A-Za-z][\w_-]*)[)}]") +_norm_var_rx = re.compile(r"\$\(([A-Za-z][\w_-]*)\)") + +def parse_makefile(fn, g_vars=None, g_rules=None, g_actions=None): + """Parse a Makefile-style file. + + Collects all of the variable definitions, rules and actions associated with rules. + + """ + from distutils.text_file import TextFile + fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape") + + if g_vars is None: + g_vars = {} + if g_rules is None: + g_rules = {} + if g_actions is None: + g_actions = {} + done = {} + rules = {} + actions = {} + + line = fp.readline() + while line is not None: + vmatch = _variable_rx.match(line) + rmatch = _rule_rx.match(line) + if vmatch: + n, v = vmatch.group(1, 2) + v = v.strip() + + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + line = fp.readline() + elif rmatch: + n, v = rmatch.group(1, 4) + rules[n] = v + + ## Collect the actions: + collected = [] + line = fp.readline() + while line is not None: + m = _variable_rx.match(line) or _rule_rx.match(line) + if m is None: + collected.append(line.lstrip()) + line = fp.readline() + else: + break + actions[n] = collected + else: + line = fp.readline() + + fp.close() + + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip().replace('\t', ' ') + + # save the results in the global dictionary + g_vars.update(done) + g_rules.update(rules) + g_actions.update(actions) + return (g_vars, g_rules, g_actions) + + +def target_dep_list(target, rules, defs): + return (rules.get(target) or '').split() + +def expand_vars(s, defs): + """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in + 'string' according to 'defs' (a dictionary mapping variable names to + values). Variables not present in 'defs' are silently expanded to the + empty string. + + Returns a variable-expanded version of 's'. + """ + + # This algorithm does multiple expansion, so if defs['foo'] contains + # "${bar}", it will expand ${foo} to ${bar}, and then expand + # ${bar}... and so forth. This is fine as long as 'defs' comes from + # 'parse_makefile()', which takes care of such expansions eagerly, + # according to make's variable expansion semantics. + + while True: + m = _var_rx2.search(s) + if m: + (beg, end) = m.span() + s = s[0:beg] + (defs.get(m.group(1)) or '') + s[end:] + else: + break + return s + + +def shallow_expand_vars(s, defs): + """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in + 'string' according to 'defs' (a dictionary mapping variable names to + values). Variables not present in 'defs' are silently expanded to the + empty string. + + Returns a variable-expanded version of 's'. + """ + + # This algorithm does multiple expansion, so if defs['foo'] contains + # "${bar}", it will expand ${foo} to ${bar}, and then expand + # ${bar}... and so forth. This is fine as long as 'defs' comes from + # 'parse_makefile()', which takes care of such expansions eagerly, + # according to make's variable expansion semantics. + + m = _var_rx2.search(s) + if m: + (beg, end) = m.span() + return s[0:beg] + (defs.get(m.group(1)) or '') + shallow_expand_vars(s[end:], defs) + + return s + + +def extract_variables(varstr): + """Extracct all variable references, e.g., "${foo}" or "$(foo)" + from a string. + """ + retval = [] + tmp = varstr + while True: + m = _var_rx2.search(tmp) + if m: + retval.append(m[1]) + tmp = tmp[m.end():] + else: + break + return retval + + +def normalize_variables(varstr): + """Convert '$(var)' to '${var}' -- normalizes all variables to a consistent + form. + """ + retval = "" + tmp = varstr + while tmp: + m = _norm_var_rx.search(tmp) + if m: + retval += tmp[:m.start()] + "${" + m[1] + "}" + tmp = tmp[m.end():] + else: + retval += tmp + tmp = "" + return retval + + +def test_rule_rx(): + result = _rule_rx.match('${BIN}frontpaneltest${EXE} : frontpanel/FrontPanelTest.c sim_sock.c sim_frontpanel.c') + print('{0}: {1}'.format('${BIN}frontpaneltest${EXE}...', result)) + print(result.groups()) + + +def test_normalize_variables(): + result = normalize_variables('foo: bar baz') + print('{0}: {1}'.format('foo:...', result)) + result = normalize_variables('$(var): dep1 dep2') + print('{0}: {1}'.format('$(var)...', result)) + result = normalize_variables('$(var): dep1 ${var2} dep2 $(var3)') + print('{0}: {1}'.format('$(var)...', result)) diff --git a/cmake/simgen/sim_collection.py b/cmake/simgen/sim_collection.py new file mode 100644 index 00000000..d4ca850c --- /dev/null +++ b/cmake/simgen/sim_collection.py @@ -0,0 +1,158 @@ +import pprint + +import simgen.parse_makefile as SPM +import simgen.basic_simulator as SBS +import simgen.vax_simulators as VAXen +import simgen.utils as SU + +## Special variables that should __not__ expand into their definitions: +_special_vars = frozenset(['DISPLAYL', + 'DISPLAYVT', + 'DISPLAY340', + 'DISPLAYNG', + 'DISPLAYIII']) + +## Map simulator name to its class, for special cases +_special_simulators = { + "besm6": SBS.BESM6Simulator, + "i650": SBS.IBM650Simulator, + "ibm1130": SBS.IBM1130Simulator, + "pdp10-ka": SBS.KA10Simulator, + "vax": VAXen.VAXSimulator, + "vax730": VAXen.BasicVAXSimulator +} + +ignored_display_macros = { + 'DISPLAYVT': ['${DISPLAYD}/vt11.c'], + 'DISPLAY340': ['${DISPLAYD}/type340.c'], + 'DISPLAYNG': ['${DISPLAYD}/ng.c'], + 'DISPLAYIII': ['${DISPLAYD}/iii.c'] +} + +def get_simulator_ctor(name): + """Return the class object for special case simulators, otherwise + return the base 'SIMHBasicSimulator' + """ + return _special_simulators.get(name) or SBS.SIMHBasicSimulator + + +class SimCollection: + """A collection of simulators. + """ + def __init__(self, dir_macro): + self.source_macros = {} + self.macro_uses = {} + self.simulators = {} + + def get_simulator(self, name, dir_macro, _dir_path, test_name, buildrom): + sim = self.simulators.get(name) + if sim is None: + sim = (get_simulator_ctor(name))(name, dir_macro, test_name, buildrom) + self.simulators[name] = sim + return sim + + def add_source_macro(self, macro, macro_def, sim): + if macro not in self.source_macros: + self.source_macros[macro] = macro_def + + used = self.macro_uses.get(macro) + if used is None: + self.macro_uses[macro] = [] + used = self.macro_uses[macro] + used.append(sim) + + def get_simulator_vars(self, debug=0): + simvars = set() + ignored = set(self.source_macros.keys()) + for macval in self.source_macros.values(): + ## This could be replaced by a functools.reduce() + for val in macval: + simvars = simvars.union(set(SPM.extract_variables(val))) + + for sim in self.simulators.values(): + simvars = simvars.union(sim.get_source_vars().union(sim.get_include_vars())) + + simvars = simvars.difference(ignored).difference(_special_vars) + SU.emit_debug(debug, 2, 'simvars {0}'.format(simvars)) + return simvars + + def write_simulators(self, stream, debug=0, test_label='default'): + ## Emit source macros + dontexpand = set([smac for smac, uses in self.macro_uses.items() if smac not in ignored_display_macros and len(uses) > 1]) + SU.emit_debug(debug, 2, "{0}: dontexpand {1}".format(self.__class__.__name__, dontexpand)) + + if len(dontexpand) > 0: + smac_sorted = list(dontexpand) + smac_sorted.sort() + for smac in smac_sorted: + stream.write('\n\n') + stream.write('set({0}\n'.format(smac)) + stream.write('\n'.join([' ' * 4 + f for f in self.source_macros[smac]])) + stream.write(')') + stream.write('\n\n') + + ## Emit the simulators + simnames = list(self.simulators.keys()) + simnames.sort() + SU.emit_debug(debug, 2, "{0}: Writing {1}".format(self.__class__.__name__, simnames)) + for simname in simnames: + sim = self.simulators[simname] + + ## Patch up the simulator source lists, expanding macros that aren't + ## in the macro sources: + sim.sources = self.expand_sources(sim.sources, dontexpand, debug) + + stream.write('\n') + sim.write_simulator(stream, 0, test_label) + + def write_unit_tests(self, stream, debug=0, test_label='default'): + dontexpand = set([smac for smac, uses in self.macro_uses.items() if len(uses) > 1]) + + simnames = list(self.simulators.keys()) + simnames.sort() + SU.emit_debug(debug, 2, "{0}: Writing {1}".format(self.__class__.__name__, simnames)) + for simname in simnames: + sim = self.simulators[simname] + + ## Patch up the simulator source lists, expanding macros that aren't + ## in the macro sources: + sim.sources = self.expand_sources(sim.sources, dontexpand, debug) + sim.write_unit_test(stream, 0, test_label) + + def expand_sources(self, srcs, dontexpand, debug=0): + updated_srcs = [] + for src in srcs: + SU.emit_debug(debug, 2, "{0}: Source {1}".format(self.__class__.__name__, src)) + m = SPM._var_rx.match(src) + if m and m[1] not in dontexpand.union(_special_vars): + SU.emit_debug(debug, 2, "{0}: Expanding {1}".format(self.__class__.__name__, m[1])) + varexp = self.source_macros.get(m[1]) + if varexp is not None: + updated_srcs.extend(self.source_macros[m[1]]) + else: + print('!! Could not expand {0}'.format(m[1])) + else: + updated_srcs.append(src) + + if updated_srcs == srcs: + return srcs + else: + return self.expand_sources(updated_srcs, dontexpand, debug) + + def __len__(self): + return len(self.simulators) + +if '_dispatch' in pprint.PrettyPrinter.__dict__: + def simcoll_pprinter(pprinter, simcoll, stream, indent, allowance, context, level): + cls = simcoll.__class__ + stream.write(cls.__name__ + '(') + indent += len(cls.__name__) + 1 + pprinter._format(simcoll.source_macros, stream, indent, allowance + 2, context, level) + stream.write(',\n' + ' ' * indent) + uses_dict = dict([(sim, len(uses)) for (sim, uses) in simcoll.macro_uses.items()]) + pprinter._format(uses_dict, stream, indent, allowance + 2, context, level) + stream.write(',\n' + ' ' * indent) + pprinter._format(simcoll.simulators, stream, indent, allowance + 2, context, level) + stream.write(')') + + pprint.PrettyPrinter._dispatch[SimCollection.__repr__] = simcoll_pprinter diff --git a/cmake/simgen/simulators.py b/cmake/simgen/simulators.py new file mode 100644 index 00000000..71e8b406 --- /dev/null +++ b/cmake/simgen/simulators.py @@ -0,0 +1,75 @@ +"3b2" +"3b2-700" +"altair" +"altairz80" +"b5500" +"besm6" +"cdc1700" +"eclipse" +"gri" +"h316" +"hp2100" +"hp3000" +"i1401" +"i1620" +"i650" +"i701" +"i7010" +"i704" +"i7070" +"i7080" +"i7090" +"i7094" +"ibm1130" +"id16" +"id32" +"imlac" +"infoserver100" +"infoserver1000" +"infoserver150vxt" +"intel-mds" +"lgp" +"microvax1" +"microvax2" +"microvax2000" +"microvax3100" +"microvax3100e" +"microvax3100m80" +"microvax3900" +"nova" +"pdp1" +"pdp10" +"pdp10-ka" +"pdp10-ki" +"pdp10-kl" +"pdp10-ks" +"pdp11" +"pdp15" +"pdp4" +"pdp6" +"pdp7" +"pdp8" +"pdp9" +"rtvax1000" +"s3" +"scelbi" +"sds" +"sel32" +"sigma" +"ssem" +"swtp6800mp-a" +"swtp6800mp-a2" +"tt2500" +"tx-0" +"uc15" +"vax" +"vax730" +"vax750" +"vax780" +"vax8200" +"vax8600" +"vaxstation3100m30" +"vaxstation3100m38" +"vaxstation3100m76" +"vaxstation4000m60" +"vaxstation4000vlc" \ No newline at end of file diff --git a/cmake/simgen/text_file.py b/cmake/simgen/text_file.py new file mode 100644 index 00000000..27b65179 --- /dev/null +++ b/cmake/simgen/text_file.py @@ -0,0 +1,291 @@ +"""text_file + +provides the TextFile class, which gives an interface to text files +that (optionally) takes care of stripping comments, ignoring blank +lines, and joining lines with backslashes. + +NOTE: This Python source code is adapted from the distutils module. +Given that the future of distutils is uncertain, keep and maintain +a local copy here. +""" + +import sys, io + + +class TextFile: + """Provides a file-like object that takes care of all the things you + commonly want to do when processing a text file that has some + line-by-line syntax: strip comments (as long as "#" is your + comment character), skip blank lines, join adjacent lines by + escaping the newline (ie. backslash at end of line), strip + leading and/or trailing whitespace. All of these are optional + and independently controllable. + + Provides a 'warn()' method so you can generate warning messages that + report physical line number, even if the logical line in question + spans multiple physical lines. Also provides 'unreadline()' for + implementing line-at-a-time lookahead. + + Constructor is called as: + + TextFile (filename=None, file=None, **options) + + It bombs (RuntimeError) if both 'filename' and 'file' are None; + 'filename' should be a string, and 'file' a file object (or + something that provides 'readline()' and 'close()' methods). It is + recommended that you supply at least 'filename', so that TextFile + can include it in warning messages. If 'file' is not supplied, + TextFile creates its own using 'io.open()'. + + The options are all boolean, and affect the value returned by + 'readline()': + strip_comments [default: true] + strip from "#" to end-of-line, as well as any whitespace + leading up to the "#" -- unless it is escaped by a backslash + lstrip_ws [default: false] + strip leading whitespace from each line before returning it + rstrip_ws [default: true] + strip trailing whitespace (including line terminator!) from + each line before returning it + skip_blanks [default: true} + skip lines that are empty *after* stripping comments and + whitespace. (If both lstrip_ws and rstrip_ws are false, + then some lines may consist of solely whitespace: these will + *not* be skipped, even if 'skip_blanks' is true.) + join_lines [default: false] + if a backslash is the last non-newline character on a line + after stripping comments and whitespace, join the following line + to it to form one "logical line"; if N consecutive lines end + with a backslash, then N+1 physical lines will be joined to + form one logical line. + collapse_join [default: false] + strip leading whitespace from lines that are joined to their + predecessor; only matters if (join_lines and not lstrip_ws) + errors [default: 'strict'] + error handler used to decode the file content + + Note that since 'rstrip_ws' can strip the trailing newline, the + semantics of 'readline()' must differ from those of the builtin file + object's 'readline()' method! In particular, 'readline()' returns + None for end-of-file: an empty string might just be a blank line (or + an all-whitespace line), if 'rstrip_ws' is true but 'skip_blanks' is + not.""" + + default_options = { 'strip_comments': 1, + 'skip_blanks': 1, + 'lstrip_ws': 0, + 'rstrip_ws': 1, + 'join_lines': 0, + 'collapse_join': 0, + 'errors': 'strict', + } + + def __init__(self, filename=None, file=None, **options): + """Construct a new TextFile object. At least one of 'filename' + (a string) and 'file' (a file-like object) must be supplied. + They keyword argument options are described above and affect + the values returned by 'readline()'.""" + if filename is None and file is None: + raise RuntimeError("you must supply either or both of 'filename' and 'file'") + + # set values for all options -- either from client option hash + # or fallback to default_options + for opt in self.default_options.keys(): + if opt in options: + setattr(self, opt, options[opt]) + else: + setattr(self, opt, self.default_options[opt]) + + # sanity check client option hash + for opt in options.keys(): + if opt not in self.default_options: + raise KeyError("invalid TextFile option '%s'" % opt) + + if file is None: + self.open(filename) + else: + self.filename = filename + self.file = file + self.current_line = 0 # assuming that file is at BOF! + + # 'linebuf' is a stack of lines that will be emptied before we + # actually read from the file; it's only populated by an + # 'unreadline()' operation + self.linebuf = [] + + def open(self, filename): + """Open a new file named 'filename'. This overrides both the + 'filename' and 'file' arguments to the constructor.""" + self.filename = filename + self.file = io.open(self.filename, 'r', errors=self.errors) + self.current_line = 0 + + def close(self): + """Close the current file and forget everything we know about it + (filename, current line number).""" + file = self.file + self.file = None + self.filename = None + self.current_line = None + file.close() + + def gen_error(self, msg, line=None): + outmsg = [] + if line is None: + line = self.current_line + outmsg.append(self.filename + ", ") + if isinstance(line, (list, tuple)): + outmsg.append("lines %d-%d: " % tuple(line)) + else: + outmsg.append("line %d: " % line) + outmsg.append(str(msg)) + return "".join(outmsg) + + def error(self, msg, line=None): + raise ValueError("error: " + self.gen_error(msg, line)) + + def warn(self, msg, line=None): + """Print (to stderr) a warning message tied to the current logical + line in the current file. If the current logical line in the + file spans multiple physical lines, the warning refers to the + whole range, eg. "lines 3-5". If 'line' supplied, it overrides + the current line number; it may be a list or tuple to indicate a + range of physical lines, or an integer for a single physical + line.""" + sys.stderr.write("warning: " + self.gen_error(msg, line) + "\n") + + def readline(self): + """Read and return a single logical line from the current file (or + from an internal buffer if lines have previously been "unread" + with 'unreadline()'). If the 'join_lines' option is true, this + may involve reading multiple physical lines concatenated into a + single string. Updates the current line number, so calling + 'warn()' after 'readline()' emits a warning about the physical + line(s) just read. Returns None on end-of-file, since the empty + string can occur if 'rstrip_ws' is true but 'strip_blanks' is + not.""" + # If any "unread" lines waiting in 'linebuf', return the top + # one. (We don't actually buffer read-ahead data -- lines only + # get put in 'linebuf' if the client explicitly does an + # 'unreadline()'. + if self.linebuf: + line = self.linebuf[-1] + del self.linebuf[-1] + return line + + buildup_line = '' + + while True: + # read the line, make it None if EOF + line = self.file.readline() + if line == '': + line = None + + if self.strip_comments and line: + + # Look for the first "#" in the line. If none, never + # mind. If we find one and it's the first character, or + # is not preceded by "\", then it starts a comment -- + # strip the comment, strip whitespace before it, and + # carry on. Otherwise, it's just an escaped "#", so + # unescape it (and any other escaped "#"'s that might be + # lurking in there) and otherwise leave the line alone. + + pos = line.find("#") + if pos == -1: # no "#" -- no comments + pass + + # It's definitely a comment -- either "#" is the first + # character, or it's elsewhere and unescaped. + elif pos == 0 or line[pos-1] != "\\": + # Have to preserve the trailing newline, because it's + # the job of a later step (rstrip_ws) to remove it -- + # and if rstrip_ws is false, we'd better preserve it! + # (NB. this means that if the final line is all comment + # and has no trailing newline, we will think that it's + # EOF; I think that's OK.) + eol = (line[-1] == '\n') and '\n' or '' + line = line[0:pos] + eol + + # If all that's left is whitespace, then skip line + # *now*, before we try to join it to 'buildup_line' -- + # that way constructs like + # hello \\ + # # comment that should be ignored + # there + # result in "hello there". + if line.strip() == "": + continue + else: # it's an escaped "#" + line = line.replace("\\#", "#") + + # did previous line end with a backslash? then accumulate + if self.join_lines and buildup_line: + # oops: end of file + if line is None: + self.warn("continuation line immediately precedes " + "end-of-file") + return buildup_line + + if self.collapse_join: + line = line.lstrip() + line = buildup_line + line + + # careful: pay attention to line number when incrementing it + if isinstance(self.current_line, list): + self.current_line[1] = self.current_line[1] + 1 + else: + self.current_line = [self.current_line, + self.current_line + 1] + # just an ordinary line, read it as usual + else: + if line is None: # eof + return None + + # still have to be careful about incrementing the line number! + if isinstance(self.current_line, list): + self.current_line = self.current_line[1] + 1 + else: + self.current_line = self.current_line + 1 + + # strip whitespace however the client wants (leading and + # trailing, or one or the other, or neither) + if self.lstrip_ws and self.rstrip_ws: + line = line.strip() + elif self.lstrip_ws: + line = line.lstrip() + elif self.rstrip_ws: + line = line.rstrip() + + # blank line (whether we rstrip'ed or not)? skip to next line + # if appropriate + if (line == '' or line == '\n') and self.skip_blanks: + continue + + if self.join_lines: + if line[-1] == '\\': + buildup_line = line[:-1] + continue + + if line[-2:] == '\\\n': + buildup_line = line[0:-2] + '\n' + continue + + # well, I guess there's some actual content there: return it + return line + + def readlines(self): + """Read and return the list of all logical lines remaining in the + current file.""" + lines = [] + while True: + line = self.readline() + if line is None: + return lines + lines.append(line) + + def unreadline(self, line): + """Push 'line' (a string) onto an internal buffer that will be + checked by future 'readline()' calls. Handy for implementing + a parser with line-at-a-time lookahead.""" + self.linebuf.append(line) diff --git a/cmake/simgen/utils.py b/cmake/simgen/utils.py new file mode 100644 index 00000000..3c071b04 --- /dev/null +++ b/cmake/simgen/utils.py @@ -0,0 +1,9 @@ +import re + + +def emit_debug(dval, level, msg): + if dval >= level: + print(msg) + +def do_debug(dval, level, act): + pass diff --git a/cmake/simgen/vax_simulators.py b/cmake/simgen/vax_simulators.py new file mode 100644 index 00000000..e2cba2d2 --- /dev/null +++ b/cmake/simgen/vax_simulators.py @@ -0,0 +1,51 @@ + +import simgen.basic_simulator as SBS + +class BasicVAXSimulator(SBS.SIMHBasicSimulator): + """ + """ + def __init__(self, sim_name, dir_macro, test_name, buildrom): + super().__init__(sim_name, dir_macro, test_name, buildrom) + + def write_unit_test(self, stream, indent, individual=False, test_label='default'): + stream.write('\n') + self.write_section(stream, 'add_unit_test', indent, individual=False, test_label=test_label, + section_name='vax_cc_{}'.format(self.sim_name), + section_srcs=['vax_cc.c'], + section_incs=self.includes) + +class VAXSimulator(BasicVAXSimulator): + """ + """ + def __init__(self, sim_name, dir_macro, test_name, buildrom): + super().__init__(sim_name, dir_macro, test_name, buildrom) + + def write_simulator(self, stream, indent, test_label='VAX'): + super().write_simulator(stream, indent, test_label) + stream.write(''' +set(vax_binary_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +if (CMAKE_CONFIGURATION_TYPES) + string(APPEND vax_binary_dir "/$") +endif (CMAKE_CONFIGURATION_TYPES) + +add_custom_command(TARGET vax POST_BUILD + COMMAND "${CMAKE_COMMAND}" + -DSRCFILE=vax${CMAKE_EXECUTABLE_SUFFIX} + -DDSTFILE=microvax3900${CMAKE_EXECUTABLE_SUFFIX} + -DWORKING_DIR=${vax_binary_dir} + -P ${CMAKE_SOURCE_DIR}/cmake/file-link-copy.cmake + COMMENT "Symlink vax${CMAKE_EXECUTABLE_SUFFIX} to microvax3900${CMAKE_EXECUTABLE_SUFFIX}" + WORKING_DIRECTORY ${vax_binary_dir}) + +install( + CODE " + execute_process( + COMMAND ${CMAKE_COMMAND} + -DSRCFILE=vax${CMAKE_EXECUTABLE_SUFFIX} + -DDSTFILE=microvax3900${CMAKE_EXECUTABLE_SUFFIX} + -DWORKING_DIR=\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin + -P ${CMAKE_SOURCE_DIR}/cmake/file-link-copy.cmake)" + COMPONENT vax_family) +''') + stream.write('\n') + diff --git a/cmake/simh-packaging.cmake b/cmake/simh-packaging.cmake new file mode 100644 index 00000000..fdcc1448 --- /dev/null +++ b/cmake/simh-packaging.cmake @@ -0,0 +1,103 @@ +## The default runtime support component/family: +cpack_add_component(runtime_support + DISPLAY_NAME "Runtime support" + DESCRIPTION "Required SIMH runtime support (documentation, shared libraries)" + REQUIRED +) + +## Basic documentation for SIMH +install(FILES doc/simh.doc TYPE DOC COMPONENT runtime_support) + +cpack_add_component(altairz80_family + DISPLAY_NAME "Altair Z80 simulator." + DESCRIPTION "The Altair Z80 simulator with M68000 support. Simulators: altairz80" +) +cpack_add_component(att3b2_family + DISPLAY_NAME "ATT&T 3b2 collection" + DESCRIPTION "The AT&T 3b2 simulator family. Simulators: 3b2, 3b2-700" +) +cpack_add_component(b5500_family + DISPLAY_NAME "Burroughs 5500" + DESCRIPTION "The Burroughs 5500 system simulator. Simulators: b5500" +) +cpack_add_component(cdc1700_family + DISPLAY_NAME "CDC 1700" + DESCRIPTION "The Control Data Corporation's systems. Simulators: cdc1700" +) +cpack_add_component(decpdp_family + DISPLAY_NAME "DEC PDP family" + DESCRIPTION "Digital Equipment Corporation PDP systems. Simulators: pdp1, pdp15, pdp4, pdp6, pdp7, pdp8, pdp9" +) +cpack_add_component(default_family + DISPLAY_NAME "Default SIMH simulator family." + DESCRIPTION "The SIMH simulator collection of historical processors and computing systems that do not belong to +any other simulated system family. Simulators: altair, besm6, ssem, tt2500, tx-0" +) +cpack_add_component(dgnova_family + DISPLAY_NAME "DG Nova and Eclipse" + DESCRIPTION "Data General NOVA and Eclipse system simulators. Simulators: eclipse, nova" +) +cpack_add_component(experimental + DISPLAY_NAME "Experimental (work-in-progress) simulators" + DESCRIPTION "Experimental or work-in-progress simulators not in the SIMH mainline simulator suite. Simulators: alpha, pdq3, sage" +) +cpack_add_component(gould_family + DISPLAY_NAME "Gould simulators" + DESCRIPTION "Gould Systems simulators. Simulators: sel32" +) +cpack_add_component(grisys_family + DISPLAY_NAME "GRI Systems GRI-909" + DESCRIPTION "GRI Systems GRI-909 system simulator. Simulators: gri" +) +cpack_add_component(honeywell_family + DISPLAY_NAME "Honeywell H316" + DESCRIPTION "Honeywell H-316 system simulator. Simulators: h316" +) +cpack_add_component(hp_family + DISPLAY_NAME "HP 2100, 3000" + DESCRIPTION "Hewlett-Packard H2100 and H3000 simulators. Simulators: hp2100, hp3000" +) +cpack_add_component(ibm_family + DISPLAY_NAME "IBM" + DESCRIPTION "IBM system simulators: i650. Simulators: i1401, i1620, i650, i701, i7010, i704, i7070, i7080, i7090, i7094, ibm1130, s3" +) +cpack_add_component(imlac_family + DISPLAY_NAME "IMLAC" + DESCRIPTION "IMLAC system simulators. Simulators: imlac" +) +cpack_add_component(intel_family + DISPLAY_NAME "Intel" + DESCRIPTION "Intel system simulators. Simulators: intel-mds, scelbi" +) +cpack_add_component(interdata_family + DISPLAY_NAME "Interdata" + DESCRIPTION "Interdata systems simulators. Simulators: id16, id32" +) +cpack_add_component(lgp_family + DISPLAY_NAME "LGP" + DESCRIPTION "Librascope systems. Simulators: lgp" +) +cpack_add_component(norsk_family + DISPLAY_NAME "ND simulators" + DESCRIPTION "Norsk Data systems simulator family. Simulators: nd100" +) +cpack_add_component(pdp10_family + DISPLAY_NAME "DEC PDP-10 collection" + DESCRIPTION "DEC PDP-10 architecture simulators and variants. Simulators: pdp10, pdp10-ka, pdp10-ki, pdp10-kl, pdp10-ks" +) +cpack_add_component(pdp11_family + DISPLAY_NAME "DEC PDP-11 collection." + DESCRIPTION "DEC PDP-11 and PDP-11-derived architecture simulators. Simulators: pdp11, uc15" +) +cpack_add_component(sds_family + DISPLAY_NAME "SDS simulators" + DESCRIPTION "Scientific Data Systems (SDS) systems. Simulators: sds, sigma" +) +cpack_add_component(swtp_family + DISPLAY_NAME "SWTP simulators" + DESCRIPTION "Southwest Technical Products (SWTP) system simulators. Simulators: swtp6800mp-a, swtp6800mp-a2" +) +cpack_add_component(vax_family + DISPLAY_NAME "DEC VAX simulator collection" + DESCRIPTION "The Digital Equipment Corporation VAX (plural: VAXen) simulator family. Simulators: infoserver100, infoserver1000, infoserver150vxt, microvax1, microvax2, microvax2000, microvax3100, microvax3100e, microvax3100m80, rtvax1000, vax, vax730, vax750, vax780, vax8200, vax8600, vaxstation3100m30, vaxstation3100m38, vaxstation3100m76, vaxstation4000m60, vaxstation4000vlc" +) diff --git a/cmake/simh-simulators.cmake b/cmake/simh-simulators.cmake new file mode 100644 index 00000000..bd456fa5 --- /dev/null +++ b/cmake/simh-simulators.cmake @@ -0,0 +1,123 @@ +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ +set(ALPHAD "${CMAKE_SOURCE_DIR}/alpha") +set(ALTAIRD "${CMAKE_SOURCE_DIR}/ALTAIR") +set(ALTAIRZ80D "${CMAKE_SOURCE_DIR}/AltairZ80") +set(ATT3B2D "${CMAKE_SOURCE_DIR}/3B2") +set(B5500D "${CMAKE_SOURCE_DIR}/B5500") +set(BESM6D "${CMAKE_SOURCE_DIR}/BESM6") +set(CDC1700D "${CMAKE_SOURCE_DIR}/CDC1700") +set(GRID "${CMAKE_SOURCE_DIR}/GRI") +set(H316D "${CMAKE_SOURCE_DIR}/H316") +set(HP2100D "${CMAKE_SOURCE_DIR}/HP2100") +set(HP3000D "${CMAKE_SOURCE_DIR}/HP3000") +set(I1401D "${CMAKE_SOURCE_DIR}/I1401") +set(I1620D "${CMAKE_SOURCE_DIR}/I1620") +set(I650D "${CMAKE_SOURCE_DIR}/I650") +set(I7000D "${CMAKE_SOURCE_DIR}/I7000") +set(I7010D "${CMAKE_SOURCE_DIR}/I7000") +set(I7094D "${CMAKE_SOURCE_DIR}/I7094") +set(IBM1130D "${CMAKE_SOURCE_DIR}/Ibm1130") +set(ID16D "${CMAKE_SOURCE_DIR}/Interdata") +set(ID32D "${CMAKE_SOURCE_DIR}/Interdata") +set(IMLACD "${CMAKE_SOURCE_DIR}/imlac") +set(INTELSYSC "${CMAKE_SOURCE_DIR}/Intel-Systems/common") +set(KA10D "${CMAKE_SOURCE_DIR}/PDP10") +set(KI10D "${CMAKE_SOURCE_DIR}/PDP10") +set(KL10D "${CMAKE_SOURCE_DIR}/PDP10") +set(KS10D "${CMAKE_SOURCE_DIR}/PDP10") +set(LGPD "${CMAKE_SOURCE_DIR}/LGP") +set(ND100D "${CMAKE_SOURCE_DIR}/ND100") +set(NOVAD "${CMAKE_SOURCE_DIR}/NOVA") +set(PDP10D "${CMAKE_SOURCE_DIR}/PDP10") +set(PDP11D "${CMAKE_SOURCE_DIR}/PDP11") +set(PDP18BD "${CMAKE_SOURCE_DIR}/PDP18B") +set(PDP1D "${CMAKE_SOURCE_DIR}/PDP1") +set(PDP6D "${CMAKE_SOURCE_DIR}/PDP10") +set(PDP8D "${CMAKE_SOURCE_DIR}/PDP8") +set(PDQ3D "${CMAKE_SOURCE_DIR}/PDQ-3") +set(S3D "${CMAKE_SOURCE_DIR}/S3") +set(SAGED "${CMAKE_SOURCE_DIR}/SAGE") +set(SDSD "${CMAKE_SOURCE_DIR}/SDS") +set(SEL32D "${CMAKE_SOURCE_DIR}/SEL32") +set(SIGMAD "${CMAKE_SOURCE_DIR}/sigma") +set(SSEMD "${CMAKE_SOURCE_DIR}/SSEM") +set(SWTP6800C "${CMAKE_SOURCE_DIR}/swtp6800/common") +set(SWTP6800D "${CMAKE_SOURCE_DIR}/swtp6800/swtp6800") +set(TT2500D "${CMAKE_SOURCE_DIR}/tt2500") +set(TX0D "${CMAKE_SOURCE_DIR}/TX-0") +set(UC15D "${CMAKE_SOURCE_DIR}/PDP11") +set(VAXD "${CMAKE_SOURCE_DIR}/VAX") + +set(DISPLAYD "${CMAKE_SOURCE_DIR}/display") +set(DISPLAY340 "${DISPLAYD}/type340.c") +set(DISPLAYIII "${DISPLAYD}/iii.c") +set(DISPLAYNG "${DISPLAYD}/ng.c") +set(DISPLAYVT "${DISPLAYD}/vt11.c") + +set(INTELSYSD "${CMAKE_SOURCE_DIR}/Intel-Systems") +set(INTEL_MDSD "${INTELSYSD}/Intel-MDS") +set(SCELBIC "${INTELSYSD}/common") +set(SCELBID "${INTELSYSD}/scelbi") + +## ---------------------------------------- + +if (NOT WITH_VIDEO) + ### Hack: Unset these variables so that they don't expand if + ### not building with video: + set(DISPLAY340 "") + set(DISPLAYIII "") + set(DISPLAYNG "") + set(DISPLAYVT "") +endif () + +## ---------------------------------------- + +add_subdirectory(3B2) +add_subdirectory(ALTAIR) +add_subdirectory(AltairZ80) +add_subdirectory(B5500) +add_subdirectory(BESM6) +add_subdirectory(CDC1700) +add_subdirectory(GRI) +add_subdirectory(H316) +add_subdirectory(HP2100) +add_subdirectory(HP3000) +add_subdirectory(I1401) +add_subdirectory(I1620) +add_subdirectory(I650) +add_subdirectory(I7000) +add_subdirectory(I7094) +add_subdirectory(Ibm1130) +add_subdirectory(Intel-Systems/Intel-MDS) +add_subdirectory(Intel-Systems/scelbi) +add_subdirectory(Interdata) +add_subdirectory(LGP) +add_subdirectory(ND100) +add_subdirectory(NOVA) +add_subdirectory(PDP1) +add_subdirectory(PDP10) +add_subdirectory(PDP11) +add_subdirectory(PDP18B) +add_subdirectory(PDP8) +add_subdirectory(PDQ-3) +add_subdirectory(S3) +add_subdirectory(SAGE) +add_subdirectory(SDS) +add_subdirectory(SEL32) +add_subdirectory(SSEM) +add_subdirectory(TX-0) +add_subdirectory(VAX) +add_subdirectory(alpha) +add_subdirectory(imlac) +add_subdirectory(sigma) +add_subdirectory(swtp6800/swtp6800) +add_subdirectory(tt2500) diff --git a/cmake/v141_xp_install.ps1 b/cmake/v141_xp_install.ps1 new file mode 100644 index 00000000..c480c7f4 --- /dev/null +++ b/cmake/v141_xp_install.ps1 @@ -0,0 +1,84 @@ +$vsFlavor=$args[0] +$vsSetupDir="C:\Program Files (x86)\Microsoft Visual Studio\installer" +$vswhere="${vsSetupDir}\vswhere.exe" +$vsinstaller="${vsSetupDir}\vs_installer.exe" + +$vstudios = @{ + "vs2017" = @{ + names = @{ + "Visual Studio Enterprise 2019" = "Microsoft.VisualStudio.Product.Enterprise" + "Visual Studio Professional 2019" = "Microsoft.VisualStudio.Product.Professional" + "Visual Studio Community 2019" = "Microsoft.VisualStudio.Product.Community" + } + channelId = "VisualStudio.15.Release" + v141toolkit = @( "Microsoft.VisualStudio.Component.WinXP" ) + } + "vs2019" = @{ + names = @{ + "Visual Studio Enterprise 2019" = "Microsoft.VisualStudio.Product.Enterprise" + "Visual Studio Professional 2019" = "Microsoft.VisualStudio.Product.Professional" + "Visual Studio Community 2019" = "Microsoft.VisualStudio.Product.Community" + } + displayName = "Visual Studio Community 2019" + channelId = "VisualStudio.16.Release" + v141toolkit = @( "Microsoft.VisualStudio.Component.VC.v141.x86.x64", "Microsoft.VisualStudio.Component.WinXP" ) + } + "vs2022" = @{ + names = @{ + "Visual Studio Enterprise 2022" = "Microsoft.VisualStudio.Product.Enterprise" + "Visual Studio Professional 2022" = "Microsoft.VisualStudio.Product.Professional" + "Visual Studio Community 2022" = "Microsoft.VisualStudio.Product.Community" + } + installedChannelId = "VisualStudio.17.Release" + v141toolkit = @( "Microsoft.VisualStudio.Component.VC.v141.x86.x64", "Microsoft.VisualStudio.Component.WinXP" ) + } +} + +if ($args.length -eq 0) { + "Womabt!!" + exit 1 +} + +$wantedVS = $vstudios[$args[0]] +if ($wantedVS -eq $null) { + "Wibbles." + exit 1 +} + +Set-PSDebug -Trace 1 + +if (Test-Path -Path $vsinstaller) { + if (Test-Path -Path $vswhere) { + $vsinfo=$(& $vswhere -format json | ConvertFrom-JSON) + foreach ($vs in $vsinfo) { + $productId = $wantedVS.names[$vs.displayName] + if ($productId -ne $null) { + Write-Output $("Found: " + $vs.displayName) + + $args = @( "modify", "--quiet") + $args += @( "--channelId", $wantedVS.installedChannelId ) + $args += @( "--productId", $productId ) + + foreach ($c in $wantedVS.v141toolkit) { + $args += @( "--add", $c ) + } + + Write-Output $( ( @("Executing: ", $vsinstaller) + $args ) -join " " ) + + $proc = Start-Process -Verbose -NoNewWindow -PassThru $vsinstaller -ArgumentList $args + $proc.WaitForExit() + + $proc = Start-Process -NoNewWindow -PassThru $vsinstaller -ArgumentList @("export", "--channelId", $wantedVS.installedChannelId, "--productId", $productId, "--config", "vsinstall.after", "--quiet") + $proc.WaitForExit() + + if (Test-Path -Path .\vsinstall.after) { + Get-Content .\vsinstall.after + } + } + } + } else { + Write-Ouput @("vswhere not found or available. ", $vswhere) -join " " + } +} else { + Write-Ouput @("VS installer not found or available. ", $vsinstaller) -join " " +} diff --git a/cmake/vcpkg-setup.cmake b/cmake/vcpkg-setup.cmake new file mode 100644 index 00000000..a3c5c9b6 --- /dev/null +++ b/cmake/vcpkg-setup.cmake @@ -0,0 +1,86 @@ +##+=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ +## vcpkg setup for MSVC. MinGW builds should use 'pacman' to install +## required dependency libraries. +##-=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ + +if (NOT USING_VCPKG) + return () +endif () + +if (NOT DEFINED VCPKG_TARGET_TRIPLET) + if (DEFINED ENV{VCPKG_DEFAULT_TRIPLET}) + ## User has a target triplet in mind, so use it. + set(VCPKG_TARGET_TRIPLET ENV{VCPKG_DEFAULT_TRIPLET}) + else () + ## Set the target triplet: + if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + ## Default to x64, unless otherwise directed: + set(SIMH_VCPKG_ARCH "x64") + if(CMAKE_GENERATOR_PLATFORM MATCHES "Win32") + set(SIMH_VCPKG_ARCH "x86") + elseif(CMAKE_GENERATOR_PLATFORM MATCHES "ARM") + set(SIMH_VCPKG_ARCH "arm") + elseif(CMAKE_GENERATOR_PLATFORM MATCHES "ARM64") + set(SIMH_VCPKG_ARCH "arm64") + endif() + + if (MSVC OR CMAKE_C_COMPILER_ID MATCHES ".*Clang") + set(SIMH_VCPKG_PLATFORM "windows") + set(SIMH_VCPKG_RUNTIME "") + if (NOT BUILD_SHARED_DEPS) + set(SIMH_VCPKG_RUNTIME "static") + endif () + elseif (MINGW OR CMAKE_C_COMPILER_ID STREQUAL "GNU") + set(SIMH_VCPKG_PLATFORM "mingw") + set(SIMH_VCPKG_RUNTIME "dynamic") + endif () + elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux") + if (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64") + set(SIMH_VCPKG_ARCH "arm64") + else () + set(SIMH_VCPKG_ARCH "x64") + endif () + + set (SIMH_VCPKG_PLATFORM "linux") + else () + message(FATAL_ERROR "Could not determine VCPKG platform and system triplet." + "\n" + "(a) Are you sure that VCPKG is usable on this system? Check VCPKG_ROOT and ensure that" + "you have properly boostrapped VCPKG." + "\n" + "(b) If VCPKG is not usable on this system, unset the VCPKG_ROOT environment variable.") + endif () + + ## Set the default triplet in the environment; older vcpkg installs on + ## appveyor don't necessarily support the "--triplet" command line argument. + set(use_triplet "${SIMH_VCPKG_ARCH}-${SIMH_VCPKG_PLATFORM}") + if (SIMH_VCPKG_RUNTIME) + string(APPEND use_triplet "-${SIMH_VCPKG_RUNTIME}") + endif () + + set(VCPKG_TARGET_TRIPLET "${use_triplet}" CACHE STRING "Vcpkg target triplet (ex. x86-windows)" FORCE) + unset(use_triplet) + + set(ENV{VCPKG_DEFAULT_TRIPLET} ${VCPKG_TARGET_TRIPLET}) + endif () +endif () + +## Set VCPKG_CRT_LINKAGE to pass down so that SIMH matches the triplet's link +## environment. Otherwise, the build will get a lot of "/NODEFAULTLIB" warnings. +set(VCPKG_CRT_LINKAGE "dynamic") +if (VCPKG_TARGET_TRIPLET MATCHES ".*-static") + set(VCPKG_CRT_LINKAGE "static") +endif () + +message(STATUS "Executing deferred vcpkg toolchain initialization.\n" + " .. VCPKG target triplet is ${VCPKG_TARGET_TRIPLET}\n" + " .. VCPKG_CRT_LINKAGE is ${VCPKG_CRT_LINKAGE}") + +## Initialize vcpkg after CMake detects the compiler and we've to set the platform triplet. +## VCPKG_INSTALL_OPTIONS are additional args to 'vcpkg install'. Don't need to see the +## usage instructions each time... +list(APPEND VCPKG_INSTALL_OPTIONS + "--no-print-usage" +) + +include(${SIMH_CMAKE_TOOLCHAIN_FILE}) diff --git a/imlac/CMakeLists.txt b/imlac/CMakeLists.txt new file mode 100644 index 00000000..9a2e38ab --- /dev/null +++ b/imlac/CMakeLists.txt @@ -0,0 +1,33 @@ +## imlac simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(imlac + SOURCES + imlac_sys.c + imlac_cpu.c + imlac_dp.c + imlac_crt.c + imlac_kbd.c + imlac_tty.c + imlac_pt.c + imlac_bel.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + FEATURE_VIDEO + FEATURE_DISPLAY + LABEL imlac + PKG_FAMILY imlac_family + TEST imlac) diff --git a/sigma/CMakeLists.txt b/sigma/CMakeLists.txt new file mode 100644 index 00000000..829936da --- /dev/null +++ b/sigma/CMakeLists.txt @@ -0,0 +1,38 @@ +## sigma simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(sigma + SOURCES + sigma_cpu.c + sigma_sys.c + sigma_cis.c + sigma_coc.c + sigma_dk.c + sigma_dp.c + sigma_fp.c + sigma_io.c + sigma_lp.c + sigma_map.c + sigma_mt.c + sigma_pt.c + sigma_rad.c + sigma_rtc.c + sigma_tt.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + LABEL sigma + PKG_FAMILY sds_family + TEST sigma) diff --git a/sim_inttypes.h b/sim_inttypes.h new file mode 100644 index 00000000..a9fef95d --- /dev/null +++ b/sim_inttypes.h @@ -0,0 +1,27 @@ +#if !defined(SIM_INTTYPES_H) +/* Length specific integer declarations */ + +/* Handle the special/unusual cases first with everything else leveraging stdints.h */ +#if defined (VMS) +#include +#elif defined(_MSC_VER) && (_MSC_VER < 1600) +typedef __int8 int8; +typedef __int16 int16; +typedef __int32 int32; +typedef unsigned __int8 uint8; +typedef unsigned __int16 uint16; +typedef unsigned __int32 uint32; +#else +/* All modern/standard compiler environments */ +/* any other environment needa a special case above */ +#include +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +#endif /* end standard integers */ + +#define SIM_INTTYPES_H +#endif \ No newline at end of file diff --git a/sim_printf_fmts.h b/sim_printf_fmts.h new file mode 100644 index 00000000..8657bc73 --- /dev/null +++ b/sim_printf_fmts.h @@ -0,0 +1,92 @@ +/*~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ + * sim_printf_fmts.h + * + * Cross-platform printf() formats for simh data types. Refactored out to + * this header so that these formats are avaiable to more than SCP. + * + * Author: B. Scott Michel + * + * "scooter me fecit" + *~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~*/ + +#pragma once +#if !defined(SIM_PRINTF_H) + +/* cross-platform printf() format specifiers: + * + * Note: MS apparently does recognize "ll" as "l" in its printf() routines, but "I64" is + * preferred for 64-bit types. + * + * MinGW note: __MINGW64__ and __MINGW32__ are both defined by 64-bit gcc. Check + * for __MINGW64__ before __MINGW32__. + */ + +#if defined (_WIN32) || defined(_WIN64) +# if defined(__MINGW64__) +# define LL_FMT "I64" +# elif defined(_MSC_VER) || defined(__MINGW32__) +# define LL_FMT "ll" +# else +# define LL_FMT "ll" +# endif +#elif defined (__VAX) /* No 64 bit ints on VAX */ +# define LL_FMT "l" +#else +# define LL_FMT "ll" +#endif + +#if defined(_WIN32) || defined(_WIN64) + +# if defined(__MINGW64__) +# define SIZE_T_FMT "I64" +# elif defined(_MSC_VER) || defined(__MINGW32__) +# define SIZE_T_FMT "z" +# endif + +# if defined(_WIN64) +# define SOCKET_FMT "I64" +# else +# define SOCKET_FMT "I32" +# endif + +# define T_UINT64_FMT "I64" +# define T_INT64_FMT "I64" +# define NTOHL_FMT "l" +# define IP_SADDR_FMT "l" +# define POINTER_FMT "p" +#elif defined(__GNU_LIBRARY__) || defined(__GLIBC__) || defined(__GLIBC_MINOR__) +/* glibc (basically, most Linuxen) */ +# define SIZE_T_FMT "z" +# define T_UINT64_FMT "ll" +# define T_INT64_FMT "ll" +# define NTOHL_FMT "" +# define IP_SADDR_FMT "" +# define SOCKET_FMT "" +# define POINTER_FMT "p" +#else +/* 32-bit platform, no 64 bit quantities */ +# define SIZE_T_FMT "" +# define T_UINT64_FMT "" +# define T_INT64_FMT "" +# define NTOHL_FMT "l" +# define IP_SADDR_FMT "l" +# define SOCKET_FMT "l" +# define POINTER_FMT "" +#endif + +#if defined (USE_INT64) && defined (USE_ADDR64) +# define T_ADDR_FMT T_UINT64_FMT +#else +# define T_ADDR_FMT "" +#endif + +#if defined (USE_INT64) +# define T_VALUE_FMT T_UINT64_FMT +# define T_SVALUE_FMT T_INT64_FMT +#else +# define T_VALUE_FMT "" +# define T_SVALUE_FMT "" +#endif + +#define SIM_PRINTF_H +#endif diff --git a/slirp/CMakeLists.txt b/slirp/CMakeLists.txt new file mode 100644 index 00000000..4875471c --- /dev/null +++ b/slirp/CMakeLists.txt @@ -0,0 +1,56 @@ +## Compile SLirp as its own standalone library + +if (WITH_NETWORK) + set(SLIRP_SOURCES + "${CMAKE_SOURCE_DIR}/slirp/arp_table.c" + "${CMAKE_SOURCE_DIR}/slirp/bootp.c" + "${CMAKE_SOURCE_DIR}/slirp/bootp.h" + "${CMAKE_SOURCE_DIR}/slirp/cksum.c" + "${CMAKE_SOURCE_DIR}/slirp/dnssearch.c" + "${CMAKE_SOURCE_DIR}/slirp/if.c" + "${CMAKE_SOURCE_DIR}/slirp/ip_icmp.c" + "${CMAKE_SOURCE_DIR}/slirp/ip_input.c" + "${CMAKE_SOURCE_DIR}/slirp/ip_output.c" + "${CMAKE_SOURCE_DIR}/slirp/mbuf.c" + "${CMAKE_SOURCE_DIR}/slirp/misc.c" + "${CMAKE_SOURCE_DIR}/slirp/sbuf.c" + "${CMAKE_SOURCE_DIR}/slirp/slirp.c" + "${CMAKE_SOURCE_DIR}/slirp/socket.c" + "${CMAKE_SOURCE_DIR}/slirp/tcp_input.c" + "${CMAKE_SOURCE_DIR}/slirp/tcp_output.c" + "${CMAKE_SOURCE_DIR}/slirp/tcp_subr.c" + "${CMAKE_SOURCE_DIR}/slirp/tcp_timer.c" + "${CMAKE_SOURCE_DIR}/slirp/tftp.c" + "${CMAKE_SOURCE_DIR}/slirp/udp.c" + "${CMAKE_SOURCE_DIR}/slirp_glue/glib_qemu_stubs.c" + "${CMAKE_SOURCE_DIR}/slirp_glue/sim_slirp.c") + + add_library(slirp STATIC "${SLIRP_SOURCES}") + target_compile_definitions(slirp + PRIVATE + HAVE_SLIRP_NETWORK + USE_SIMH_SLIRP_DEBUG + $<$,$>>: + _WINSOCK_DEPRECATED_NO_WARNINGS + _CRT_NONSTDC_NO_WARNINGS + _CRT_SECURE_NO_WARNINGS> + INTERFACE + HAVE_SLIRP_NETWORK + USE_SIMH_SLIRP_DEBUG) + + target_include_directories(slirp + PRIVATE + "${CMAKE_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/slirp" + "${CMAKE_SOURCE_DIR}/slirp_glue/qemu" + PUBLIC + "${CMAKE_SOURCE_DIR}/slirp_glue" + $<$:${CMAKE_SOURCE_DIR}/slirp_glue/qemu/win32/include>) + + target_compile_options(slirp PRIVATE ${EXTRA_TARGET_CFLAGS}) + target_link_options(slirp PRIVATE ${EXTRA_TARGET_LFLAGS}) + target_link_libraries(slirp PUBLIC $<$:Iphlpapi>) +else (WITH_NETWORK) + # Otherwise, just make slirp an empty interface library. + add_library(slirp INTERFACE) +endif (WITH_NETWORK) diff --git a/swtp6800/swtp6800/CMakeLists.txt b/swtp6800/swtp6800/CMakeLists.txt new file mode 100644 index 00000000..4539e759 --- /dev/null +++ b/swtp6800/swtp6800/CMakeLists.txt @@ -0,0 +1,54 @@ +## swtp6800/swtp6800 simulators +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(swtp6800mp-a + SOURCES + ${SWTP6800C}/mp-a.c + ${SWTP6800C}/m6800.c + ${SWTP6800C}/m6810.c + ${SWTP6800C}/bootrom.c + ${SWTP6800C}/dc-4.c + mp-a_sys.c + ${SWTP6800C}/mp-8m.c + ${SWTP6800C}/fd400.c + ${SWTP6800C}/mp-b2.c + ${SWTP6800C}/mp-s.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + BUILDROMS + LABEL swtp6800 + PKG_FAMILY swtp_family + TEST swtp6800mp-a) + +add_simulator(swtp6800mp-a2 + SOURCES + ${SWTP6800C}/mp-a2.c + ${SWTP6800C}/m6800.c + ${SWTP6800C}/m6810.c + ${SWTP6800C}/bootrom.c + ${SWTP6800C}/dc-4.c + mp-a2_sys.c + ${SWTP6800C}/mp-8m.c + ${SWTP6800C}/i2716.c + ${SWTP6800C}/fd400.c + ${SWTP6800C}/mp-s.c + ${SWTP6800C}/mp-b2.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + BUILDROMS + LABEL swtp6800 + PKG_FAMILY swtp_family + TEST swtp6800mp-a2) diff --git a/tt2500/CMakeLists.txt b/tt2500/CMakeLists.txt new file mode 100644 index 00000000..9aace873 --- /dev/null +++ b/tt2500/CMakeLists.txt @@ -0,0 +1,33 @@ +## tt2500 simulator +## +## This is an automagically generated file. Do NOT EDIT. +## Any changes you make will be overwritten!! +## +## Make changes to the SIMH top-level makefile and then run the +## "cmake/generate.py" script to regenerate these files. +## +## cd cmake; python -m generate --help +## +## ------------------------------------------------------------ + +if (HAVE_UNITY_FRAMEWORK AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/CMakeLists.txt") + add_subdirectory(unit-tests) +endif () + +add_simulator(tt2500 + SOURCES + tt2500_sys.c + tt2500_cpu.c + tt2500_dpy.c + tt2500_crt.c + tt2500_tv.c + tt2500_key.c + tt2500_uart.c + tt2500_rom.c + INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR} + FEATURE_VIDEO + FEATURE_DISPLAY + LABEL tt2500 + PKG_FAMILY default_family + TEST tt2500) diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 00000000..b050f3db --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,14 @@ +{ + "name": "simh", + "version-string": "4.0.0", + "description": [ + "SIMH: The historical computer architecture simulation suite." + ], + "dependencies": [ + "pthreads", + "pcre", + "libpng", + "sdl2", + "sdl2-ttf" + ] +} \ No newline at end of file