/*.dmg
/*.res
/*.inf
-/list.c
/gamedesc.txt
/build.log
/build.out
set Version $(!builddate).$(vcsid)
-# Start by substituting the right version number in configure.ac.
-in puzzles do perl -i~ -pe 's/6.66/$(Version)/' configure.ac
-in puzzles do rm configure.ac~
-
-# And put it into the documentation as a versionid.
+# Put the version number into the documentation as a versionid.
# use perl to avoid inconsistent behaviour of echo '\v'
in puzzles do perl -e 'print "\n\\versionid Simon Tatham'\''s Portable Puzzle Collection, version $$ARGV[0]\n"' $(Version) >> puzzles.but
in puzzles do perl -e 'print "\n\\versionid Simon Tatham'\''s Portable Puzzle Collection, version $$ARGV[0]\n"' $(Version) >> devel.but
# icky in principle because it presumes that my version numbers don't
# need XML escaping, but frankly, if they ever do then I should fix
# them!)
-in puzzles do perl -i -pe 's/Unidentified build/$(Version)/' osx-info.plist
+in puzzles do perl -i -pe 's/Unidentified build/$(Version)/' osx/Info.plist
+
+# The very first thing we do is to make the source archive, before we
+# fill up the build directory with extra files.
+delegate -
+ # Build Windows Help and text versions of the manual for convenience.
+ in puzzles do halibut --winhelp=puzzles.hlp --text=puzzles.txt puzzles.but
+ # Build a text version of the HACKING document.
+ in puzzles do halibut --text=HACKING devel.but
+ # Get rid of some cruft that isn't really useful in a source tarball.
+ in puzzles do rm -f Buildscr CHECKLST.txt .gitignore webpage.pl
+ in . do ln -s puzzles puzzles-$(Version)
+ in . do tar -chzf puzzles-$(Version).tar.gz puzzles-$(Version)
+ return puzzles-$(Version).tar.gz
+enddelegate
ifneq "$(NOICONS)" yes then
- # First build some local binaries, to run the icon build.
- in puzzles do perl mkfiles.pl -U CFLAGS='-Wwrite-strings -Werror'
- in puzzles do make -j$(nproc)
-
- # Now build the screenshots and icons.
- in puzzles/icons do make web winicons gtkicons -j$(nproc)
-
- # Destroy the local binaries and autoconf detritus, mostly to avoid
- # wasting network bandwidth by transferring them to the delegate
- # servers.
- in puzzles do make distclean
-
+ # Run enough of a native Unix build to produce the icons needed for
+ # the Windows builds and the website.
+ in puzzles do cmake -B build-icons .
+ in puzzles/build-icons do make -j$(nproc) icons VERBOSE=1
endif
-# Re-run mkfiles.pl now that it knows the icons are there. (Or for the
-# first time, if we didn't bother building the icons.)
-in puzzles do perl mkfiles.pl
-
-# Rebuild the configure script.
-in puzzles do ./mkauto.sh
-
ifneq "$(NOMACOS)" yes then
- # Build the OS X .dmg archive.
+ # Build the OS X binaries and .dmg archive.
delegate osx
- in puzzles do make -f Makefile.osx clean
- in puzzles do make -f Makefile.osx release VER=-DVER=$(Version) XFLAGS='-Wwrite-strings -Werror' -j$(nproc)
- return puzzles/Puzzles.dmg
+ in puzzles do cmake -B build-osx -DCMAKE_BUILD_TYPE=Release .
+ in puzzles/build-osx do make -j$(nproc) package VERBOSE=1
+ return puzzles/build-osx/Puzzles.dmg
enddelegate
endif
# Build the Windows binaries and installer, and the CHM file.
in puzzles do make -f Makefile.doc clean
in puzzles do make -f Makefile.doc -j$(nproc) # build help files for installer
- in puzzles do mason.pl --args '{"version":"$(Version)","descfile":"gamedesc.txt"}' winwix.mc > puzzles.wxs
- in puzzles do perl winiss.pl $(Version) gamedesc.txt > puzzles.iss
- ifneq "$(VISUAL_STUDIO)" "yes" then
- in puzzles with clangcl64 do mkdir win64 && Platform=x64 make -f Makefile.clangcl BUILDDIR=win64/ VER=-DVER=$(Version) XFLAGS='-Wwrite-strings -Werror' -j$(nproc)
- in puzzles with clangcl32 do mkdir win32 && Platform=x86 make -f Makefile.clangcl BUILDDIR=win32/ SUBSYSVER=,5.01 VER=-DVER=$(Version) XFLAGS='-Wwrite-strings -Werror' -j$(nproc)
- # Code-sign the binaries, if the local bob config provides a script
- # to do so. We assume here that the script accepts an -i option to
- # provide a 'more info' URL, and an optional -n option to provide a
- # program name, and that it can take multiple .exe filename
- # arguments and sign them all in place.
- ifneq "$(cross_winsigncode)" "" in puzzles do $(cross_winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/puzzles/ win64/*.exe win32/*.exe
- # Build installers.
- in puzzles with wixonlinux do candle -arch x64 puzzles.wxs -dWin64=yes -dBindir=win64/ && light -ext WixUIExtension -sval puzzles.wixobj
- in puzzles with wixonlinux do candle -arch x86 puzzles.wxs -dWin64=no -dBindir=win32/ && light -ext WixUIExtension -sval puzzles.wixobj -o puzzles32.msi
- ifneq "$(cross_winsigncode)" "" in puzzles do $(cross_winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/puzzles/ -n "Simon Tatham's Portable Puzzle Collection Installer" puzzles.msi puzzles32.msi
- else
- delegate windows
- in puzzles with visualstudio do/win nmake -f Makefile.vc clean
- in puzzles with visualstudio do/win nmake -f Makefile.vc VER=-DVER=$(Version)
- ifneq "$(winsigncode)" "" in puzzles do $(winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/puzzles/ win64/*.exe
- # Build installers.
- in puzzles with wix do/win candle puzzles.wxs -dWin64=yes -dBindir=win64/ && light -ext WixUIExtension -sval puzzles.wixobj
- in puzzles with innosetup do/win iscc puzzles.iss
- return puzzles/win64/*.exe
- return puzzles/puzzles.msi
- enddelegate
- endif
- in puzzles do chmod +x win32/*.exe win64/*.exe
-endif
-# Build the Pocket PC binaries and CAB.
-#
-# NOTE: This part of the build script requires the Windows delegate
-# server to have the cabwiz program on its PATH. This will
-# typically be at
-#
-# C:\Program Files\Windows CE Tools\WCE420\POCKET PC 2003\Tools
-#
-# but it might not be if you've installed it somewhere else, or
-# have a different version.
-#
-# NOTE ALSO: This part of the build is commented out, for the
-# moment, because cabwiz does unhelpful things when run from within
-# a bob delegate process (or, more generally, when run from any
-# terminal-based remote login to a Windows machine, including
-# Cygwin opensshd and Windows Telnet). The symptom is that cabwiz
-# just beeps and sits there. Until I figure out how to build the
-# .cab from an automated process (and I'm willing to consider silly
-# approaches such as a third-party CAB generator), I don't think I
-# can sensibly enable this build.
-
-#in puzzles do perl wceinf.pl gamedesc.txt > puzzles.inf
-#delegate windows
-# in puzzles do cmd /c 'wcearmv4 & nmake -f Makefile.wce clean'
-# in puzzles do cmd /c 'wcearmv4 & nmake -f Makefile.wce VER=-DVER=$(Version)'
-# # Nasty piece of sh here which saves the return code from cabwiz,
-# # outputs its errors and/or warnings, and then propagates the
-# # return code back to bob. If only cabwiz could output to
-# # standard error LIKE EVERY OTHER COMMAND-LINE UTILITY IN THE
-# # WORLD, I wouldn't have to do this.
-# in puzzles do cat puzzles.inf
-# in puzzles do cmd /c 'wcearmv4 & bash -c cabwiz puzzles.inf /err cabwiz.err /cpu ARMV4'; a=$$?; cat cabwiz.err; exit $$a
-# return puzzles/puzzles.armv4.cab
-#enddelegate
+ in puzzles do cmake -B build-win64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_TOOLCHAIN_FILE=$(cmake_toolchain_clangcl64) .
+ in puzzles do cmake -B build-win32 -DCMAKE_BUILD_TYPE=Release -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_TOOLCHAIN_FILE=$(cmake_toolchain_clangcl32) .
+ in puzzles/build-win64 do make -j$(nproc) VERBOSE=1
+ in puzzles/build-win32 do make -j$(nproc) VERBOSE=1
+
+ in puzzles do mason.pl --args '{"version":"$(Version)","descfile":"build-win64/gamedesc.txt"}' winwix.mc > puzzles.wxs
+
+ # Code-sign the binaries, if the local bob config provides a script
+ # to do so. We assume here that the script accepts an -i option to
+ # provide a 'more info' URL, and an optional -n option to provide a
+ # program name, and that it can take multiple .exe filename
+ # arguments and sign them all in place.
+ ifneq "$(cross_winsigncode)" "" in puzzles do $(cross_winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/puzzles/ build-win64/*.exe build-win32/*.exe
+ # Build installers.
+ in puzzles with wixonlinux do candle -arch x64 puzzles.wxs -dWin64=yes -dBindir=build-win64/ && light -ext WixUIExtension -sval puzzles.wixobj
+ in puzzles with wixonlinux do candle -arch x86 puzzles.wxs -dWin64=no -dBindir=build-win32/ && light -ext WixUIExtension -sval puzzles.wixobj -o puzzles32.msi
+ ifneq "$(cross_winsigncode)" "" in puzzles do $(cross_winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/puzzles/ -n "Simon Tatham's Portable Puzzle Collection Installer" puzzles.msi puzzles32.msi
+
+ in puzzles do chmod +x build-win32/*.exe build-win64/*.exe
+endif
# Build the HTML docs.
in puzzles do mkdir doc
ifneq "$(NOWINDOWS)" yes then
# Move the deliver-worthy Windows binaries (those specified in
- # gamedesc.txt, which is generated by mkfiles.pl and helpfully
+ # gamedesc.txt, which is generated by CMakeLists.txt and helpfully
# excludes the command-line auxiliary utilities such as solosolver,
# and nullgame.exe) into a subdirectory for easy access.
in puzzles do mkdir winbin64 winbin32
- in puzzles/win64 do mv `cut -f2 -d: ../gamedesc.txt` ../winbin64
- in puzzles/win32 do mv `cut -f2 -d: ../gamedesc.txt` ../winbin32
+ in puzzles/build-win64 do mv `cut -f2 -d: gamedesc.txt` ../winbin64
+ in puzzles/build-win32 do mv `cut -f2 -d: gamedesc.txt` ../winbin32
# Make a zip file of the Windows binaries and help files.
in puzzles do zip -j puzzles.zip winbin64/*.exe puzzles.chm puzzles.hlp puzzles.cnt
in puzzles do zip -j puzzles32.zip winbin32/*.exe puzzles.chm puzzles.hlp puzzles.cnt
endif
-# Create the source archive. (That writes the archive into the
-# _parent_ directory, so be careful when we deliver it.)
-in puzzles do ./makedist.sh $(Version)
-
# Build the autogenerated pieces of the main web page.
-in puzzles do perl webpage.pl
+in puzzles do cmake -B build-gamedesc . -DCMAKE_TOOLCHAIN_FILE=../cmake/windows-dummy-toolchain.cmake
+in puzzles do perl webpage.pl build-gamedesc/gamedesc.txt
-ifneq "$(JAVA_UNFINISHED)" "" in puzzles do perl -i~ -pe 'print "!srcdir unfinished/\n" if /!srcdir icons/' Recipe
-ifneq "$(JAVA_UNFINISHED)" "" in puzzles do ln -s unfinished/group.R .
-ifneq "$(JAVA_UNFINISHED)" "" in puzzles do perl mkfiles.pl
+# Group is playable, even if still a bit unpolished and strange, so we
+# can at least make the web versions of it (which are unobtrusive if
+# you don't deliberately navigate to the web pages).
+set web_unfinished_option -DPUZZLES_ENABLE_UNFINISHED=group
ifneq "$(NOJAVA)" yes then
# Build the Java applets.
delegate nestedvm
- in puzzles do make -f Makefile.nestedvm NESTEDVM="$$NESTEDVM" VER=-DVER=$(Version) XFLAGS="-Wwrite-strings -Werror" -j$(nproc)
- return puzzles/*.jar
+ in puzzles do cmake -B build-nestedvm -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../cmake/nestedvm-toolchain.cmake -DNESTEDVM="$$NESTEDVM" $(web_unfinished_option) .
+ in puzzles/build-nestedvm do make -j$(nproc) VERBOSE=1
+ return puzzles/build-nestedvm/*.jar
+ return puzzles/build-nestedvm/unfinished/group.jar
enddelegate
endif
# have the right dependencies installed for Emscripten, I do this by a
# delegation.
ifneq "$(NOJS)" yes then
- in puzzles do mkdir js # so we can tell output .js files from emcc*.js
delegate emscripten
- in puzzles do make -f Makefile.emcc OUTPREFIX=js/ clean
- in puzzles do make -f Makefile.emcc OUTPREFIX=js/ XFLAGS="-Wwrite-strings -Werror" -j$(nproc)
- return puzzles/js/*.js
+ in puzzles do emcmake cmake -B build-emscripten -DCMAKE_BUILD_TYPE=Release $(web_unfinished_option) .
+ in puzzles/build-emscripten do make -j$(nproc) VERBOSE=1
+ return puzzles/build-emscripten/*.js
+ return puzzles/build-emscripten/unfinished/group.js
enddelegate
# Build a set of wrapping HTML pages for easy testing of the
# Phew, we're done. Deliver everything!
ifneq "$(NOICONS)" yes then
- deliver puzzles/icons/*-web.png $@
+ deliver puzzles/build-icons/icons/*-web.png $@
endif
ifneq "$(NOWINDOWS)" yes then
deliver puzzles/winbin64/*.exe $@
deliver puzzles/doc/*.html doc/$@
deliver puzzles/devel/*.html devel/$@
ifneq "$(NOMACOS)" yes then
- deliver puzzles/Puzzles.dmg $@
+ deliver puzzles/build-osx/Puzzles.dmg $@
endif
ifneq "$(NOJAVA)" yes then
- deliver puzzles/*.jar java/$@
+ deliver puzzles/build-nestedvm/*.jar java/$@
+ deliver puzzles/build-nestedvm/unfinished/*.jar java/$@
endif
ifneq "$(NOJS)" yes then
- deliver puzzles/js/*.js js/$@
+ deliver puzzles/build-emscripten/*.js js/$@
+ deliver puzzles/build-emscripten/unfinished/*.js js/$@
deliver puzzles/jstest/*.html jstest/$@
deliver puzzles/html/*.html html/$@
deliver puzzles/html/*.pl html/$@
Write the source file for the new puzzle (duhh).
-Create a .R file for it which:
- - defines a <puzzle>_EXTRA symbol for it if it requires auxiliary
- object files (make sure that symbol doesn't contain the icon)
- - adds it to the `ALL' definition, to ensure it is compiled into
- the OS X binary
- - adds it as a GTK build target, with the optional GTK icon
- - adds it as a Windows build target, with the optional resource
- file
- - adds auxiliary solver binaries if any
- - adds it to $(GAMES) in both the automake and GTK makefiles, for
- `make install'
- - adds it to list.c for the OS X binary
- - adds it to gamedesc.txt, with its Windows executable name, display
- name, and slightly longer description.
+Write a puzzle() statement in CMakeLists.txt containing all the
+necessary metadata. Optionally also a solver() statement, and any
+cliprogram() statements for extra auxiliary tools.
If the puzzle is by a new author, modify the copyright notice in
LICENCE and in puzzles.but. (Also in index.html, but that's listed
Make a screenshot:
- create an appropriate save file in `icons'
- - add the puzzle name to icons/Makefile
- - set up a REDO property in icons/Makefile if the screenshot wants
- to display a move halfway through an animation
- - set up a CROP property in icons/Makefile if the icon wants to be
- a sub-rectangle of the whole screenshot
-
-Don't forget to `git add' the new source file, the new .R file and the
-save file in `icons', the new .html file, and any other new files that
-might have been involved.
+ - define <puzzlename>_redo in icons/icons.cmake if the screenshot
+ wants to display a move halfway through an animation
+ - define <puzzlename>_crop in icons/icons.cmake if the icon wants to
+ be a sub-rectangle of the whole screenshot
Check in!
--- /dev/null
+cmake_minimum_required(VERSION 3.16)
+
+project(puzzles
+ LANGUAGES C)
+
+include(cmake/setup.cmake)
+
+add_library(common
+ combi.c divvy.c drawing.c dsf.c findloop.c grid.c latin.c
+ laydomino.c loopgen.c malloc.c matching.c midend.c misc.c penrose.c
+ ps.c random.c sort.c tdq.c tree234.c version.c
+ ${platform_common_sources})
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+puzzle(blackbox
+ DISPLAYNAME "Black Box"
+ DESCRIPTION "Ball-finding puzzle"
+ OBJECTIVE "Find the hidden balls in the box by bouncing laser beams \
+off them.")
+
+puzzle(bridges
+ DISPLAYNAME "Bridges"
+ DESCRIPTION "Bridge-placing puzzle"
+ OBJECTIVE "Connect all the islands with a network of bridges.")
+
+puzzle(cube
+ DISPLAYNAME "Cube"
+ DESCRIPTION "Rolling cube puzzle"
+ OBJECTIVE "Pick up all the blue squares by rolling the cube over them.")
+
+puzzle(dominosa
+ DISPLAYNAME "Dominosa"
+ DESCRIPTION "Domino tiling puzzle"
+ OBJECTIVE "Tile the rectangle with a full set of dominoes.")
+solver(dominosa)
+
+puzzle(fifteen
+ DISPLAYNAME "Fifteen"
+ DESCRIPTION "Sliding block puzzle"
+ OBJECTIVE "Slide the tiles around to arrange them into order.")
+solver(fifteen)
+
+puzzle(filling
+ DISPLAYNAME "Filling"
+ DESCRIPTION "Polyomino puzzle"
+ OBJECTIVE "Mark every square with the area of its containing region.")
+solver(filling)
+
+puzzle(flip
+ DISPLAYNAME "Flip"
+ DESCRIPTION "Tile inversion puzzle"
+ OBJECTIVE "Flip groups of squares to light them all up at once.")
+
+puzzle(flood
+ DISPLAYNAME "Flood"
+ DESCRIPTION "Flood-filling puzzle"
+ OBJECTIVE "Turn the grid the same colour in as few flood fills as possible.")
+
+puzzle(galaxies
+ DISPLAYNAME "Galaxies"
+ DESCRIPTION "Symmetric polyomino puzzle"
+ OBJECTIVE "Divide the grid into rotationally symmetric regions each \
+centred on a dot.")
+solver(galaxies)
+cliprogram(galaxiespicture galaxies.c
+ COMPILE_DEFINITIONS STANDALONE_PICTURE_GENERATOR)
+
+puzzle(guess
+ DISPLAYNAME "Guess"
+ DESCRIPTION "Combination-guessing puzzle"
+ OBJECTIVE "Guess the hidden combination of colours.")
+
+puzzle(inertia
+ DISPLAYNAME "Inertia"
+ DESCRIPTION "Gem-collecting puzzle"
+ OBJECTIVE "Collect all the gems without running into any of the mines.")
+
+puzzle(keen
+ DISPLAYNAME "Keen"
+ DESCRIPTION "Arithmetic Latin square puzzle"
+ OBJECTIVE "Complete the latin square in accordance with the \
+arithmetic clues.")
+solver(keen latin.c)
+
+puzzle(lightup
+ DISPLAYNAME "Light Up"
+ DESCRIPTION "Light-bulb placing puzzle"
+ OBJECTIVE "Place bulbs to light up all the squares.")
+solver(lightup)
+
+puzzle(loopy
+ DISPLAYNAME "Loopy"
+ DESCRIPTION "Loop-drawing puzzle"
+ OBJECTIVE "Draw a single closed loop, given clues about number of \
+adjacent edges.")
+solver(loopy)
+
+puzzle(magnets
+ DISPLAYNAME "Magnets"
+ DESCRIPTION "Magnet-placing puzzle"
+ OBJECTIVE "Place magnets to satisfy the clues and avoid like poles \
+touching.")
+solver(magnets)
+
+puzzle(map
+ DISPLAYNAME "Map"
+ DESCRIPTION "Map-colouring puzzle"
+ OBJECTIVE "Colour the map so that adjacent regions are never the \
+same colour.")
+solver(map)
+
+puzzle(mines
+ DISPLAYNAME "Mines"
+ DESCRIPTION "Mine-finding puzzle"
+ OBJECTIVE "Find all the mines without treading on any of them.")
+cliprogram(mineobfusc mines.c COMPILE_DEFINITIONS STANDALONE_OBFUSCATOR)
+
+puzzle(net
+ # The Windows Net shouldn't be called 'net.exe', since Windows
+ # already has a reasonably important utility program by that name!
+ WINDOWS_EXE_NAME netgame
+
+ DISPLAYNAME "Net"
+ DESCRIPTION "Network jigsaw puzzle"
+ OBJECTIVE "Rotate each tile to reassemble the network.")
+
+puzzle(netslide
+ DISPLAYNAME "Netslide"
+ DESCRIPTION "Toroidal sliding network puzzle"
+ OBJECTIVE "Slide a row at a time to reassemble the network.")
+
+puzzle(nullgame)
+
+puzzle(palisade
+ DISPLAYNAME "Palisade"
+ DESCRIPTION "Grid-division puzzle"
+ OBJECTIVE "Divide the grid into equal-sized areas in accordance with\
+ the clues.")
+
+puzzle(pattern
+ DISPLAYNAME "Pattern"
+ DESCRIPTION "Pattern puzzle"
+ OBJECTIVE "Fill in the pattern in the grid, given only the lengths \
+of runs of black squares.")
+solver(pattern)
+cliprogram(patternpicture pattern.c
+ COMPILE_DEFINITIONS STANDALONE_PICTURE_GENERATOR)
+
+puzzle(pearl
+ DISPLAYNAME "Pearl"
+ DESCRIPTION "Loop-drawing puzzle"
+ OBJECTIVE "Draw a single closed loop, given clues about corner and \
+straight squares.")
+solver(pearl)
+cliprogram(pearlbench pearl.c COMPILE_DEFINITIONS STANDALONE_SOLVER)
+
+puzzle(pegs
+ DISPLAYNAME "Pegs"
+ DESCRIPTION "Peg solitaire puzzle"
+ OBJECTIVE "Jump pegs over each other to remove all but one.")
+
+puzzle(range
+ DISPLAYNAME "Range"
+ DESCRIPTION "Visible-distance puzzle"
+ OBJECTIVE "Place black squares to limit the visible distance from \
+each numbered cell.")
+
+puzzle(rect
+ DISPLAYNAME "Rectangles"
+ DESCRIPTION "Rectangles puzzle"
+ OBJECTIVE "Divide the grid into rectangles with areas equal to the \
+numbers.")
+
+puzzle(samegame
+ DISPLAYNAME "Same Game"
+ DESCRIPTION "Block-clearing puzzle"
+ OBJECTIVE "Clear the grid by removing touching groups of the same \
+colour squares.")
+
+puzzle(signpost
+ DISPLAYNAME "Signpost"
+ DESCRIPTION "Square-connecting puzzle"
+ OBJECTIVE "Connect the squares into a path following the arrows.")
+solver(signpost)
+
+puzzle(singles
+ DISPLAYNAME "Singles"
+ DESCRIPTION "Number-removing puzzle"
+ OBJECTIVE "Black out the right set of duplicate numbers.")
+solver(singles)
+
+puzzle(sixteen
+ DISPLAYNAME "Sixteen"
+ DESCRIPTION "Toroidal sliding block puzzle"
+ OBJECTIVE "Slide a row at a time to arrange the tiles into order.")
+
+puzzle(slant
+ DISPLAYNAME "Slant"
+ DESCRIPTION "Maze-drawing puzzle"
+ OBJECTIVE "Draw a maze of slanting lines that matches the clues.")
+solver(slant)
+
+puzzle(solo
+ DISPLAYNAME "Solo"
+ DESCRIPTION "Number placement puzzle"
+ OBJECTIVE "Fill in the grid so that each row, column and square \
+block contains one of every digit.")
+solver(solo)
+
+puzzle(tents
+ DISPLAYNAME "Tents"
+ DESCRIPTION "Tent-placing puzzle"
+ OBJECTIVE "Place a tent next to each tree.")
+solver(tents)
+
+puzzle(towers
+ DISPLAYNAME "Towers"
+ DESCRIPTION "Tower-placing Latin square puzzle"
+ OBJECTIVE "Complete the latin square of towers in accordance with \
+the clues.")
+solver(towers latin.c)
+
+puzzle(tracks
+ DISPLAYNAME "Tracks"
+ DESCRIPTION "Path-finding railway track puzzle"
+ OBJECTIVE "Fill in the railway track according to the clues.")
+solver(tracks)
+
+puzzle(twiddle
+ DISPLAYNAME "Twiddle"
+ DESCRIPTION "Rotational sliding block puzzle"
+ OBJECTIVE "Rotate the tiles around themselves to arrange them into order.")
+
+puzzle(undead
+ DISPLAYNAME "Undead"
+ DESCRIPTION "Monster-placing puzzle"
+ OBJECTIVE "Place ghosts, vampires and zombies so that the right \
+numbers of them can be seen in mirrors.")
+
+puzzle(unequal
+ DISPLAYNAME "Unequal"
+ DESCRIPTION "Latin square puzzle"
+ OBJECTIVE "Complete the latin square in accordance with the > signs.")
+solver(unequal latin.c)
+
+puzzle(unruly
+ DISPLAYNAME "Unruly"
+ DESCRIPTION "Black and white grid puzzle"
+ OBJECTIVE "Fill in the black and white grid to avoid runs of three.")
+solver(unruly)
+
+puzzle(untangle
+ DISPLAYNAME "Untangle"
+ DESCRIPTION "Planar graph layout puzzle"
+ OBJECTIVE "Reposition the points so that the lines do not cross.")
+
+add_subdirectory(unfinished)
+
+cliprogram(obfusc obfusc.c)
+cliprogram(latincheck latin.c COMPILE_DEFINITIONS STANDALONE_LATIN_TEST)
+cliprogram(matching matching.c COMPILE_DEFINITIONS STANDALONE_MATCHING_TEST)
+
+build_platform_extras()
puzzle collection. The collection's web site is at
<https://www.chiark.greenend.org.uk/~sgtatham/puzzles/>.
-If you've obtained the source code by downloading a .tar.gz archive
-from the Puzzles web site, you should find several Makefiles in the
-source code. However, if you've checked the source code out from the
-Puzzles git repository, you won't find the Makefiles: they're
-automatically generated by `mkfiles.pl', so run that to create them.
+The puzzle collection is built using CMake <https://cmake.org/>. To
+compile in the simplest way (on any of Linux, Windows or Mac), run
+these commands in the source directory:
-The Makefiles include:
-
- - `Makefile.am', together with the static `configure.ac', is intended
- as input to automake. Run `mkauto.sh' to turn these into a
- configure script and Makefile.in, after which you can then run
- `./configure' to create an actual Unix Makefile.
-
- - `Makefile.vc' should work under MS Visual C++ on Windows. Run
- 'nmake /f Makefile.vc' in a Visual Studio command prompt.
-
- - `Makefile.cyg' should work under Cygwin / MinGW. With appropriate
- tweaks and setting of TOOLPATH, it should work for both compiling
- on Windows and cross-compiling on Unix.
-
- - `Makefile.osx' should work under Mac OS X, provided the Xcode
- tools are installed. It builds a single monolithic OS X
- application capable of running any of the puzzles, or even more
- than one of them at a time.
-
- - `Makefile.wce' should work under MS eMbedded Visual C++ on
- Windows and the Pocket PC SDK; it builds Pocket PC binaries.
-
-Many of these Makefiles build a program called `nullgame' in
-addition to the actual game binaries. This program doesn't do
-anything; it's just a template for people to start from when adding
-a new game to the collection, and it's compiled every time to ensure
-that it _does_ compile and link successfully (because otherwise it
-wouldn't be much use as a template). Once it's built, you can run it
-if you really want to (but it's very boring), and then you should
-ignore it.
-
-DO NOT EDIT THE MAKEFILES DIRECTLY, if you plan to send any changes
-back to the maintainer. The makefiles are generated automatically by
-the Perl script `mkfiles.pl' from the file `Recipe' and the various
-.R files. If you need to change the makefiles as part of a patch,
-you should change Recipe, *.R, and/or mkfiles.pl.
+ cmake .
+ cmake --build .
The manual is provided in Windows Help format for the Windows build;
in text format for anyone who needs it; and in HTML for the Mac OS X
+++ /dev/null
-# -*- makefile -*-
-#
-# This file describes which puzzle binaries are made up from which
-# object and resource files. It is processed into the various
-# Makefiles by means of a Perl script. Makefile changes should
-# really be made by editing this file and/or the Perl script, not
-# by editing the actual Makefiles.
-
-!name puzzles
-
-!makefile gtk Makefile.gtk
-!makefile am Makefile.am
-!makefile vc Makefile.vc
-!makefile wce Makefile.wce
-!makefile cygwin Makefile.cyg
-!makefile osx Makefile.osx
-!makefile gnustep Makefile.gnustep
-!makefile nestedvm Makefile.nestedvm
-!makefile emcc Makefile.emcc
-!makefile clangcl Makefile.clangcl
-
-!srcdir icons/
-
-WINDOWS_COMMON = printing
- + user32.lib gdi32.lib comctl32.lib comdlg32.lib winspool.lib
-WINDOWS = windows WINDOWS_COMMON
-COMMON = midend drawing misc malloc random version
-GTK = gtk printing ps
-# Objects needed for auxiliary command-line programs.
-STANDALONE = nullfe random misc malloc
-
-ALL = list
-
-LATIN_DEPS = matching tree234
-LATIN = latin LATIN_DEPS
-LATIN_SOLVER = latin[STANDALONE_SOLVER] LATIN_DEPS
-
-# First half of list.c.
-!begin >list.c
-/*
- * list.c: List of pointers to puzzle structures, for monolithic
- * platforms.
- *
- * This file is automatically generated by mkfiles.pl. Do not edit
- * it directly, or the changes will be lost next time mkfiles.pl runs.
- * Instead, edit Recipe and/or its *.R subfiles.
- */
-#include "puzzles.h"
-#define GAMELIST(A) \
-!end
-
-# Now each .R file adds part of the macro definition of GAMELIST to list.c.
-!include *.R
-
-# Then we finish up list.c as follows:
-!begin >list.c
-
-#define DECL(x) extern const game x;
-#define REF(x) &x,
-GAMELIST(DECL)
-const game *gamelist[] = { GAMELIST(REF) };
-const int gamecount = lenof(gamelist);
-!end
-
-# Unix standalone application for special-purpose obfuscation.
-obfusc : [U] obfusc STANDALONE
-
-# Test program built from latin.c.
-latincheck : [U] latin[STANDALONE_LATIN_TEST] LATIN_DEPS STANDALONE
-latincheck : [C] latin[STANDALONE_LATIN_TEST] LATIN_DEPS STANDALONE
-
-# Test program built from matching.c.
-matching : [U] matching[STANDALONE_MATCHING_TEST] tree234 STANDALONE
-matching : [C] matching[STANDALONE_MATCHING_TEST] tree234 STANDALONE
-
-puzzles : [G] windows[COMBINED] WINDOWS_COMMON COMMON ALL noicon.res
-
-# Mac OS X unified application containing all the puzzles.
-Puzzles : [MX] osx osx.icns osx-info.plist COMMON ALL
-# For OS X, we must create the online help and include it in the
-# application bundle.) Also we add -DCOMBINED to the compiler flags
-# so as to inform the code that we're building a single binary for
-# all the puzzles. Then I've also got some code in here to build a
-# distributable .dmg disk image.
-!begin osx
-Puzzles_extra = Puzzles.app/Contents/Resources/Help/index.html
-Puzzles.app/Contents/Resources/Help/index.html: \
- Puzzles.app/Contents/Resources/Help osx-help.but puzzles.but
- cd Puzzles.app/Contents/Resources/Help; \
- halibut --html ../../../../osx-help.but ../../../../puzzles.but
-Puzzles.app/Contents/Resources/Help: Puzzles.app/Contents/Resources
- mkdir -p Puzzles.app/Contents/Resources/Help
-
-release: Puzzles.dmg
-Puzzles.dmg: Puzzles
- rm -f raw.dmg
- hdiutil create -megabytes 5 -layout NONE raw.dmg
- hdid -nomount raw.dmg > devicename
- newfs_hfs -v "Simon Tatham's Puzzle Collection" `cat devicename`
- hdiutil eject `cat devicename`
- hdid raw.dmg | cut -f1 -d' ' > devicename
- cp -R Puzzles.app /Volumes/"Simon Tatham's Puzzle Collection"
- hdiutil eject `cat devicename`
- rm -f Puzzles.dmg
- hdiutil convert -format UDCO raw.dmg -o Puzzles.dmg
- rm -f raw.dmg devicename
-!end
-
-!begin am
-bin_PROGRAMS = $(GAMES)
-!end
-!begin am_begin
-GAMES =
-!end
-
-# make install for Unix.
-!begin gtk
-install:
- for i in $(GAMES); do \
- $(INSTALL_PROGRAM) -m 755 $(BINPREFIX)$$i $(DESTDIR)$(gamesdir)/$(BINPREFIX)$$i \
- || exit 1; \
- done
-!end
-!begin nestedvm
-%.tmpdir/PuzzleEngine.class: %.mips
- mkdir -p $(patsubst %.mips,%,$<).tmpdir
- cd $(patsubst %.mips,%,$<).tmpdir && \
- java -cp $(NESTEDVM)/build:$(NESTEDVM)/upstream/build/classgen/build \
- org.ibex.nestedvm.Compiler -outformat class -d . \
- PuzzleEngine ../$<
-
-org:
- mkdir -p org/ibex/nestedvm/util
- cp $(NESTEDVM)/build/org/ibex/nestedvm/Registers.class org/ibex/nestedvm
- cp $(NESTEDVM)/build/org/ibex/nestedvm/UsermodeConstants.class org/ibex/nestedvm
- cp $(NESTEDVM)/build/org/ibex/nestedvm/Runtime*.class org/ibex/nestedvm
- cp $(NESTEDVM)/build/org/ibex/nestedvm/util/Platform*.class org/ibex/nestedvm/util
- cp $(NESTEDVM)/build/org/ibex/nestedvm/util/Seekable*.class org/ibex/nestedvm/util
-
-applet.manifest:
- echo "Main-Class: PuzzleApplet" >applet.manifest
-
-PuzzleApplet.class: PuzzleApplet.java org
- javac -source 1.7 -target 1.7 PuzzleApplet.java
-
-%.jar: %.tmpdir/PuzzleEngine.class PuzzleApplet.class applet.manifest org
- cd $(patsubst %.jar,%,$@).tmpdir && ln -s ../applet.manifest ../org ../PuzzleApplet*.class .
- cd $(patsubst %.jar,%,$@).tmpdir && jar cfm ../$@ applet.manifest PuzzleEngine.class PuzzleApplet*.class org
- echo '<applet archive="'$@'" code="PuzzleApplet" width="700" height="500"></applet>' >$*.html
-!end
-
-# A benchmarking and testing target for the GTK puzzles.
-!begin gtk
-test: benchmark.html benchmark.txt
-
-benchmark.html: benchmark.txt benchmark.pl
- ./benchmark.pl benchmark.txt > $@
-
-benchmark.txt: benchmark.sh $(GAMES)
- ./benchmark.sh > $@
-
-!end
-!begin am
-test: benchmark.html benchmark.txt
-
-benchmark.html: benchmark.txt benchmark.pl
- ./benchmark.pl benchmark.txt > $@
-
-benchmark.txt: benchmark.sh $(GAMES)
- ./benchmark.sh > $@
-!end
+++ /dev/null
-# -*- makefile -*-
-
-blackbox : [X] GTK COMMON blackbox blackbox-icon|no-icon
-
-blackbox : [G] WINDOWS COMMON blackbox blackbox.res|noicon.res
-
-ALL += blackbox[COMBINED]
-
-!begin am gtk
-GAMES += blackbox
-!end
-
-!begin >list.c
- A(blackbox) \
-!end
-
-!begin >gamedesc.txt
-blackbox:blackbox.exe:Black Box:Ball-finding puzzle:Find the hidden balls in the box by bouncing laser beams off them.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-BRIDGES_EXTRA = dsf findloop
-
-bridges : [X] GTK COMMON bridges BRIDGES_EXTRA bridges-icon|no-icon
-
-bridges : [G] WINDOWS COMMON bridges BRIDGES_EXTRA bridges.res|noicon.res
-
-ALL += bridges[COMBINED] BRIDGES_EXTRA
-
-!begin am gtk
-GAMES += bridges
-!end
-
-!begin >list.c
- A(bridges) \
-!end
-
-!begin >gamedesc.txt
-bridges:bridges.exe:Bridges:Bridge-placing puzzle:Connect all the islands with a network of bridges.
-!end
--- /dev/null
+#!/usr/bin/env python3
+
+# Helper script used by the NestedVM cmake build script.
+#
+# Usage: glob-symlinks.py <srcdir> <wildcard> [<srcdir> <wildcard> ...]
+#
+# Each pair of command-line arguments is treated as a source
+# directory, followed by either a single filename or a wildcard.
+#
+# The result is to create symlinks in the program's working directory
+# mirroring all the files matched by the filenames/wildcards, each
+# pointing at the appropriate source directory.
+#
+# For example, this command
+# glob-symlinks.py /foo \*.txt /bar wibble.blah
+# might create symlinks as follows:
+# this.txt -> /foo/this.txt
+# that.txt -> /foo/that.txt
+# wibble.blah -> /bar/wibble.blah
+#
+# CMake could mostly do this itself, except that some of the files
+# that need symlinking during the NestedVM build (to make a tree that
+# we archive up into a .jar file) are Java class files with some
+# '$suffix' in the name, and CMake doesn't escape the $ signs, so that
+# the suffix vanishes during shell expansion.
+
+import sys
+import os
+import glob
+
+def get_arg_pairs():
+ args = iter(sys.argv)
+ next(args) # skip program name
+ while True:
+ try:
+ yield next(args), next(args)
+ except StopIteration:
+ break
+
+def get_globbed_pairs():
+ for srcdir, pattern in get_arg_pairs():
+ if glob.escape(pattern) == pattern:
+ # Assume that unglobbed filenames exist
+ #print("non-glob:", srcdir, pattern)
+ yield srcdir, pattern
+ else:
+ #print("globbing:", srcdir, pattern)
+ prefix = srcdir + "/"
+ for filename in glob.iglob(prefix + pattern):
+ assert filename.startswith(prefix)
+ filename = filename[len(prefix):]
+ #print(" ->", srcdir, filename)
+ yield srcdir, filename
+
+for srcdir, filename in get_globbed_pairs():
+ dirname = os.path.dirname(filename)
+ if len(dirname) > 0:
+ try:
+ os.makedirs(dirname)
+ except FileExistsError:
+ pass
+ try:
+ os.symlink(os.path.join(srcdir, filename), filename)
+ except FileExistsError:
+ pass
--- /dev/null
+SET(CMAKE_SYSTEM_NAME NestedVM)
+SET(CMAKE_SYSTEM_PROCESSOR mips)
+
+SET(CMAKE_C_COMPILER ${NESTEDVM}/upstream/install/bin/mips-unknown-elf-gcc)
+
+SET(CMAKE_FIND_ROOT_PATH ${NESTEDVM}/upstream/install)
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
--- /dev/null
+set(platform_common_sources emcc.c)
+set(platform_gui_libs)
+set(platform_libs)
+set(CMAKE_EXECUTABLE_SUFFIX ".js")
+
+set(emcc_export_list
+ # Event handlers for mouse and keyboard input
+ _mouseup
+ _mousedown
+ _mousemove
+ _key
+ # Callback when the program activates timing
+ _timer_callback
+ # Callback from button presses in the UI outside the canvas
+ _command
+ # Game-saving and game-loading functions
+ _get_save_file
+ _free_save_file
+ _load_game
+ # Callbacks to return values from dialog boxes
+ _dlg_return_sval
+ _dlg_return_ival
+ # Callbacks when the resizing controls are used
+ _resize_puzzle
+ _restore_puzzle_size
+ # Main program, run at initialisation time
+ _main)
+
+list(TRANSFORM emcc_export_list PREPEND \")
+list(TRANSFORM emcc_export_list APPEND \")
+string(JOIN "," emcc_export_string ${emcc_export_list})
+set(CMAKE_C_LINK_FLAGS "-s ASM_JS=1 -s EXPORTED_FUNCTIONS='[${emcc_export_string}]'")
+message("link=${CMAKE_C_LINK_EXECUTABLE}")
+
+set(build_cli_programs FALSE)
+
+function(get_platform_puzzle_extra_source_files OUTVAR NAME)
+ set(${OUTVAR} PARENT_SCOPE)
+endfunction()
+
+function(set_platform_puzzle_target_properties NAME TARGET)
+ em_link_pre_js(${TARGET} ${CMAKE_SOURCE_DIR}/emccpre.js)
+ em_link_js_library(${TARGET} ${CMAKE_SOURCE_DIR}/emcclib.js)
+endfunction()
+
+function(build_platform_extras)
+endfunction()
--- /dev/null
+set(platform_common_sources nestedvm.c printing.c)
+set(platform_libs -lm)
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/applet.manifest
+ "Main-Class: PuzzleApplet\n")
+
+include(FindJava)
+add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/PuzzleApplet.class
+ COMMAND ${Java_JAVAC_EXECUTABLE}
+ -source 1.7 -target 1.7 -d . -cp ${NESTEDVM}/build
+ ${CMAKE_SOURCE_DIR}/PuzzleApplet.java
+ DEPENDS ${CMAKE_SOURCE_DIR}/PuzzleApplet.java)
+
+function(get_platform_puzzle_extra_source_files OUTVAR NAME)
+ set(${OUTVAR} PARENT_SCOPE)
+endfunction()
+
+function(set_platform_puzzle_target_properties NAME TARGET)
+ set(build_subdir ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}-tmp)
+
+ add_custom_command(OUTPUT ${build_subdir}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${build_subdir})
+ add_custom_command(OUTPUT ${build_subdir}/PuzzleApplet.class
+ COMMAND ${CMAKE_SOURCE_DIR}/cmake/glob-symlinks.py
+ ${CMAKE_BINARY_DIR} applet.manifest
+ ${CMAKE_BINARY_DIR} PuzzleApplet\\*.class
+ ${NESTEDVM}/build org/ibex/nestedvm/Registers.class
+ ${NESTEDVM}/build org/ibex/nestedvm/UsermodeConstants.class
+ ${NESTEDVM}/build org/ibex/nestedvm/Runtime*.class
+ ${NESTEDVM}/build org/ibex/nestedvm/util/Platform\\*.class
+ ${NESTEDVM}/build org/ibex/nestedvm/util/Seekable\\*.class
+ WORKING_DIRECTORY ${build_subdir}
+ DEPENDS
+ ${build_subdir}
+ ${CMAKE_BINARY_DIR}/PuzzleApplet.class
+ ${CMAKE_SOURCE_DIR}/cmake/glob-symlinks.py)
+
+ add_custom_command(OUTPUT ${build_subdir}/PuzzleEngine.class
+ COMMAND ${Java_JAVA_EXECUTABLE}
+ -cp ${NESTEDVM}/build:${NESTEDVM}/upstream/build/classgen/build
+ org.ibex.nestedvm.Compiler -outformat class -d .
+ PuzzleEngine ${CMAKE_CURRENT_BINARY_DIR}/${EXENAME}
+ DEPENDS
+ ${build_subdir}
+ ${CMAKE_CURRENT_BINARY_DIR}/${EXENAME}
+ WORKING_DIRECTORY ${build_subdir})
+
+ add_custom_target(${TARGET}-jar ALL
+ COMMAND ${Java_JAR_EXECUTABLE}
+ cfm ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.jar
+ applet.manifest PuzzleEngine.class PuzzleApplet*.class org
+ WORKING_DIRECTORY ${build_subdir}
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/PuzzleApplet.class
+ ${build_subdir}/PuzzleApplet.class
+ ${build_subdir}/PuzzleEngine.class)
+endfunction()
+
+function(build_platform_extras)
+endfunction()
--- /dev/null
+set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
+find_program(HALIBUT halibut REQUIRED)
+set(CPACK_GENERATOR DragNDrop)
+set(CPACK_PACKAGE_FILE_NAME Puzzles)
+set(CPACK_DMG_VOLUME_NAME "Simon Tatham's Puzzle Collection")
+include(CPack)
+set(build_individual_puzzles FALSE)
+
+function(get_platform_puzzle_extra_source_files OUTVAR NAME)
+ set(${OUTVAR} PARENT_SCOPE)
+endfunction()
+
+function(set_platform_puzzle_target_properties NAME TARGET)
+endfunction()
+
+function(build_platform_extras)
+ write_generated_games_header()
+
+ set(resources
+ ${CMAKE_CURRENT_SOURCE_DIR}/osx/Puzzles.icns)
+ set_source_files_properties(${resources} PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources)
+
+ add_executable(puzzles MACOSX_BUNDLE
+ osx.m list.c ${puzzle_sources}
+ ${resources})
+
+ set_target_properties(puzzles PROPERTIES
+ OUTPUT_NAME Puzzles
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/osx/Info.plist)
+
+ target_compile_definitions(puzzles PRIVATE COMBINED)
+ target_include_directories(puzzles PRIVATE ${generated_include_dir})
+ target_link_libraries(puzzles common ${platform_gui_libs} ${platform_libs}
+ "-framework Cocoa")
+
+ get_property(bundle_basename TARGET puzzles PROPERTY OUTPUT_NAME)
+ set(help_dir ${CMAKE_CURRENT_BINARY_DIR}/${bundle_basename}.app/Contents/Resources/Help)
+ message(${help_dir})
+ add_custom_command(OUTPUT ${help_dir}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${help_dir}
+ DEPENDS puzzles)
+ add_custom_command(OUTPUT ${help_dir}/index.html
+ COMMAND ${HALIBUT} --html
+ ${CMAKE_CURRENT_SOURCE_DIR}/osx-help.but
+ ${CMAKE_CURRENT_SOURCE_DIR}/puzzles.but
+ DEPENDS
+ ${help_dir}
+ ${CMAKE_CURRENT_SOURCE_DIR}/osx-help.but
+ ${CMAKE_CURRENT_SOURCE_DIR}/puzzles.but
+ WORKING_DIRECTORY ${help_dir})
+ add_custom_target(osx_help ALL
+ DEPENDS ${help_dir}/index.html)
+
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Puzzles.app
+ USE_SOURCE_PERMISSIONS
+ DESTINATION .)
+endfunction()
--- /dev/null
+find_package(PkgConfig REQUIRED)
+
+set(PUZZLES_GTK_FOUND FALSE)
+macro(try_gtk_package VER PACKAGENAME)
+ if(NOT PUZZLES_GTK_FOUND AND
+ (NOT DEFINED PUZZLES_GTK_VERSION OR
+ PUZZLES_GTK_VERSION STREQUAL ${VER}))
+ pkg_check_modules(GTK ${PACKAGENAME})
+ if(GTK_FOUND)
+ set(PUZZLES_GTK_FOUND TRUE)
+ endif()
+ endif()
+endmacro()
+
+try_gtk_package(3 gtk+-3.0)
+try_gtk_package(2 gtk+-2.0)
+
+if(NOT PUZZLES_GTK_FOUND)
+ message(FATAL_ERROR "Unable to find any usable version of GTK.")
+endif()
+
+include_directories(${GTK_INCLUDE_DIRS})
+link_directories(${GTK_LIBRARY_DIRS})
+
+set(platform_common_sources gtk.c printing.c)
+set(platform_gui_libs ${GTK_LIBRARIES})
+
+set(platform_libs -lm)
+
+set(build_icons TRUE)
+
+function(try_append_cflag flag)
+ set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ try_compile(compile_passed ${CMAKE_BINARY_DIR}
+ SOURCES ${CMAKE_SOURCE_DIR}/cmake/testbuild.c
+ OUTPUT_VARIABLE test_compile_output
+ CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${GTK_INCLUDE_DIRS}")
+ if(compile_passed)
+ set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} PARENT_SCOPE)
+ endif()
+endfunction()
+if (CMAKE_C_COMPILER_ID MATCHES "GNU" OR
+ CMAKE_C_COMPILER_ID MATCHES "Clang")
+ try_append_cflag(-Wall)
+ try_append_cflag(-Werror)
+ try_append_cflag(-std=c89)
+ try_append_cflag(-pedantic)
+ try_append_cflag(-Wwrite-strings)
+endif()
+
+function(get_platform_puzzle_extra_source_files OUTVAR NAME)
+ if(build_icons AND EXISTS ${CMAKE_SOURCE_DIR}/icons/${NAME}.sav)
+ build_icon(${NAME})
+ set(c_icon_file ${CMAKE_BINARY_DIR}/icons/${NAME}-icon.c)
+ else()
+ set(c_icon_file ${CMAKE_SOURCE_DIR}/no-icon.c)
+ endif()
+
+ set(${OUTVAR} ${c_icon_file} PARENT_SCOPE)
+endfunction()
+
+function(set_platform_puzzle_target_properties NAME TARGET)
+ install(TARGETS ${TARGET})
+endfunction()
+
+function(build_platform_extras)
+endfunction()
--- /dev/null
+set(platform_common_sources windows.c printing.c)
+
+set(platform_gui_libs
+ user32.lib gdi32.lib comctl32.lib comdlg32.lib winspool.lib)
+
+set(platform_libs)
+
+add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
+
+function(get_platform_puzzle_extra_source_files OUTVAR NAME)
+ set(${OUTVAR} ${CMAKE_SOURCE_DIR}/puzzles.rc PARENT_SCOPE)
+endfunction()
+
+function(set_platform_puzzle_target_properties NAME TARGET)
+ if(DEFINED ICO_DIR AND EXISTS ${ICO_DIR}/${NAME}.ico)
+ target_compile_definitions(${TARGET} PRIVATE ICON_FILE=\"${ICO_DIR}/${NAME}.ico\")
+ endif()
+ set_target_properties(${TARGET} PROPERTIES WIN32_EXECUTABLE ON)
+endfunction()
+
+function(build_platform_extras)
+ write_generated_games_header()
+
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gamedesc.txt "")
+ list(SORT puzzle_names)
+ foreach(name ${puzzle_names})
+ file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/gamedesc.txt "\
+${name}:\
+${exename_${name}}.exe:\
+${displayname_${name}}:\
+${description_${name}}:\
+${objective_${name}}\n")
+ endforeach()
+
+ add_executable(puzzles windows.c list.c ${puzzle_sources})
+ target_compile_definitions(puzzles PRIVATE COMBINED)
+ target_include_directories(puzzles PRIVATE ${generated_include_dir})
+ target_link_libraries(puzzles common ${platform_gui_libs} ${platform_libs})
+ set_target_properties(puzzles PROPERTIES WIN32_EXECUTABLE ON)
+endfunction()
--- /dev/null
+set(build_individual_puzzles TRUE)
+set(build_cli_programs TRUE)
+set(build_icons FALSE)
+set(need_c_icons FALSE)
+
+# Include one of platforms/*.cmake to define platform-specific stuff.
+# Each of these is expected to:
+# - define get_platform_puzzle_extra_source_files(), used below
+# - define set_platform_puzzle_target_properties(), used below
+# - define build_platform_extras(), called from the top-level CMakeLists.txt
+# - override the above build_* settings, if necessary
+if(CMAKE_SYSTEM_NAME MATCHES "Windows")
+ include(cmake/platforms/windows.cmake)
+elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
+ include(cmake/platforms/osx.cmake)
+elseif(CMAKE_SYSTEM_NAME MATCHES "NestedVM")
+ include(cmake/platforms/nestedvm.cmake)
+elseif(CMAKE_C_COMPILER MATCHES "emcc")
+ include(cmake/platforms/emscripten.cmake)
+else() # assume Unix
+ include(cmake/platforms/unix.cmake)
+endif()
+
+# Accumulate lists of the puzzles' bare names and source file
+# locations, for use in build_platform_extras() implementations when
+# they want to build things based on all the puzzles at once.
+set(puzzle_names)
+set(puzzle_sources)
+
+include(icons/icons.cmake)
+
+# The main function called from the top-level CMakeLists.txt to define
+# each puzzle.
+function(puzzle NAME)
+ cmake_parse_arguments(OPT
+ "" "DISPLAYNAME;DESCRIPTION;OBJECTIVE;WINDOWS_EXE_NAME" "" ${ARGN})
+
+ if(NOT DEFINED OPT_WINDOWS_EXE_NAME)
+ set(OPT_WINDOWS_EXE_NAME ${NAME})
+ endif()
+
+ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
+ set(EXENAME ${OPT_WINDOWS_EXE_NAME})
+ else()
+ set(EXENAME ${NAME})
+ endif()
+
+ set(exename_${NAME} ${EXENAME} PARENT_SCOPE)
+ set(displayname_${NAME} ${OPT_DISPLAYNAME} PARENT_SCOPE)
+ set(description_${NAME} ${OPT_DESCRIPTION} PARENT_SCOPE)
+ set(objective_${NAME} ${OPT_OBJECTIVE} PARENT_SCOPE)
+
+ set(official TRUE)
+ if(NAME STREQUAL nullgame)
+ # nullgame is not a playable puzzle; it has to be built (to prove
+ # it still can build), but not installed, or included in the main
+ # list of puzzles, or compiled into all-in-one binaries, etc. In
+ # other words, it's not "officially" part of the puzzle
+ # collection.
+ set(official FALSE)
+ endif()
+ if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}/unfinished)
+ # The same goes for puzzles in the 'unfinished' subdirectory,
+ # although we make an exception if configured to on the command
+ # line.
+ list(FIND PUZZLES_ENABLE_UNFINISHED ${NAME} enable_this_one)
+ if(enable_this_one EQUAL -1)
+ set(official FALSE)
+ endif()
+ endif()
+
+ if (official)
+ set(puzzle_names ${puzzle_names} ${NAME} PARENT_SCOPE)
+ set(puzzle_sources ${puzzle_sources} ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.c PARENT_SCOPE)
+ endif()
+
+ get_platform_puzzle_extra_source_files(extra_files ${NAME})
+
+ if (build_individual_puzzles)
+ add_executable(${EXENAME} ${NAME}.c ${extra_files})
+ target_link_libraries(${EXENAME}
+ common ${platform_gui_libs} ${platform_libs})
+ set_platform_puzzle_target_properties(${NAME} ${EXENAME})
+ endif()
+endfunction()
+
+# The main function called from the top-level CMakeLists.txt to define
+# a command-line helper tool.
+function(cliprogram NAME)
+ cmake_parse_arguments(OPT
+ "" "COMPILE_DEFINITIONS" "" ${ARGN})
+
+ if(build_cli_programs)
+ add_executable(${NAME} ${CMAKE_SOURCE_DIR}/nullfe.c
+ ${OPT_UNPARSED_ARGUMENTS})
+ target_link_libraries(${NAME} common ${platform_libs})
+ if(OPT_COMPILE_DEFINITIONS)
+ target_compile_definitions(${NAME} PRIVATE ${OPT_COMPILE_DEFINITIONS})
+ endif()
+ endif()
+endfunction()
+
+# A small wrapper around cliprogram, taking advantage of the common
+# formula that puzzle 'foo' often comes with 'foosolver'.
+function(solver NAME)
+ cliprogram(${NAME}solver ${puzzle_src_prefix}${NAME}.c ${ARGN}
+ COMPILE_DEFINITIONS STANDALONE_SOLVER)
+endfunction()
+
+function(write_generated_games_header)
+ set(generated_include_dir ${CMAKE_CURRENT_BINARY_DIR}/include)
+ set(generated_include_dir ${generated_include_dir} PARENT_SCOPE)
+
+ file(MAKE_DIRECTORY ${generated_include_dir})
+ file(WRITE ${generated_include_dir}/generated-games.h "")
+ list(SORT puzzle_names)
+ foreach(name ${puzzle_names})
+ file(APPEND ${generated_include_dir}/generated-games.h "GAME(${name})\n")
+ endforeach()
+endfunction()
+
+# This has to be run from the unfinished subdirectory, so that the
+# updates to puzzle_names etc will be propagated to the top-level scope.
+macro(export_variables_to_parent_scope)
+ set(puzzle_names ${puzzle_names} PARENT_SCOPE)
+ set(puzzle_sources ${puzzle_sources} PARENT_SCOPE)
+ foreach(name ${puzzle_names})
+ set(exename_${name} ${exename_${name}} PARENT_SCOPE)
+ set(displayname_${name} ${displayname_${name}} PARENT_SCOPE)
+ set(description_${name} ${description_${name}} PARENT_SCOPE)
+ set(objective_${name} ${objective_${name}} PARENT_SCOPE)
+ endforeach()
+endmacro()
--- /dev/null
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+int dummy;
--- /dev/null
+# Fake CMake toolchain file, good enough to make cmake's initial
+# configuration think it's going to build for Windows, but not good
+# enough to actually do any building. The purpose is so that I can run
+# Puzzles's CMakeLists.txt in Windows mode as far as making
+# gamedesc.txt.
+
+set(CMAKE_SYSTEM_NAME Windows)
+
+set(CMAKE_C_COMPILER /bin/false)
+set(CMAKE_LINKER /bin/false)
+set(CMAKE_MT /bin/false)
+set(CMAKE_RC_COMPILER /bin/false)
+
+set(CMAKE_C_COMPILER_WORKS ON)
+++ /dev/null
-dnl Configure script for the Unix GTK build of puzzles.
-
-AC_INIT([puzzles], [6.66], [anakin@pobox.com])
-AC_CONFIG_SRCDIR([midend.c])
-AM_INIT_AUTOMAKE([foreign])
-AC_PROG_CC
-
-AC_ARG_WITH([gtk],
- [AS_HELP_STRING([--with-gtk=VER],
- [specify GTK version to use (`2' or `3')])],
- [gtk_version_desired="$withval"],
- [gtk_version_desired="any"])
-
-case "$gtk_version_desired" in
- 2 | 3 | any) ;;
- yes) gtk_version_desired="any" ;;
- *) AC_ERROR([Invalid GTK version specified])
-esac
-
-gtk=none
-
-case "$gtk_version_desired:$gtk" in
- 3:none | any:none)
- ifdef([AM_PATH_GTK_3_0],[
- AM_PATH_GTK_3_0([3.0.0], [gtk=3], [])
- ],[AC_WARNING([generating configure script without GTK 3 autodetection])])
- ;;
-esac
-
-case "$gtk_version_desired:$gtk" in
- 2:none | any:none)
- ifdef([AM_PATH_GTK_2_0],[
- AM_PATH_GTK_2_0([2.0.0], [gtk=2], [])
- ],[AC_WARNING([generating configure script without GTK 2 autodetection])])
- ;;
-esac
-
-if test "$gtk" = "none"; then
- AC_MSG_ERROR([cannot build without GTK 2 or GTK 3])
-fi
-
-if test "x$GCC" = "xyes"; then
- AC_MSG_CHECKING([for usable gcc warning flags])
- gccwarningflags=
- for flag in -Wall -Werror -std=c89 -pedantic; do
- ac_save_CFLAGS="$CFLAGS"
- ac_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS$gccwarningflags $flag $GTK_CFLAGS"
- LIBS="$GTK_LIBS $LIBS"
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
- #include <stdio.h>
- #include <assert.h>
- #include <stdlib.h>
- #include <time.h>
- #include <stdarg.h>
- #include <string.h>
- #include <errno.h>
- #include <math.h>
-
- #include <sys/time.h>
- #include <sys/resource.h>
-
- #include <gtk/gtk.h>
- #include <gdk/gdkkeysyms.h>
-
- #include <gdk-pixbuf/gdk-pixbuf.h>
-
- #include <gdk/gdkx.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/Xatom.h>
- ],[
- return 0;
- ])], [gccwarningflags="$gccwarningflags $flag"], [])
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
- done
- AC_MSG_RESULT($gccwarningflags)
- CFLAGS="$CFLAGS$gccwarningflags"
-fi
-
-AC_PROG_RANLIB
-AC_PROG_INSTALL
-AC_CONFIG_FILES([Makefile])
-AC_OUTPUT
+++ /dev/null
-# -*- makefile -*-
-
-cube : [X] GTK COMMON cube cube-icon|no-icon
-
-cube : [G] WINDOWS COMMON cube cube.res|noicon.res
-
-ALL += cube[COMBINED]
-
-!begin am gtk
-GAMES += cube
-!end
-
-!begin >list.c
- A(cube) \
-!end
-
-!begin >gamedesc.txt
-cube:cube.exe:Cube:Rolling cube puzzle:Pick up all the blue squares by rolling the cube over them.
-!end
you'll gradually add functionality until the very boring Null Game
turns into your real game.
-Next you'll need to add your puzzle to the Makefiles, in order to
-compile it conveniently. \e{Do not edit the Makefiles}: they are
-created automatically by the script \c{mkfiles.pl}, from the file
-called \c{Recipe}. Edit \c{Recipe}, and then re-run \c{mkfiles.pl}.
-
-Also, don't forget to add your puzzle to \c{list.c}: if you don't,
-then it will still run fine on platforms which build each puzzle
-separately, but Mac OS X and other monolithic platforms will not
-include your new puzzle in their single binary.
+Next you'll need to add your puzzle to the build scripts, in order to
+compile it conveniently. Puzzles is a CMake project, so you do this by
+adding a \cw{puzzle()} statement to CMakeLists.txt. Look at the
+existing ones to see what those look like, and add one that looks
+similar.
Once your source file is building, you can move on to the fun bit.
+++ /dev/null
-# -*- makefile -*-
-
-DOMINOSA_EXTRA = laydomino dsf sort findloop
-
-dominosa : [X] GTK COMMON dominosa DOMINOSA_EXTRA dominosa-icon|no-icon
-
-dominosa : [G] WINDOWS COMMON dominosa DOMINOSA_EXTRA dominosa.res|noicon.res
-
-ALL += dominosa[COMBINED] DOMINOSA_EXTRA
-
-dominosasolver : [U] dominosa[STANDALONE_SOLVER] DOMINOSA_EXTRA STANDALONE
-dominosasolver : [C] dominosa[STANDALONE_SOLVER] DOMINOSA_EXTRA STANDALONE
-
-!begin am gtk
-GAMES += dominosa
-!end
-
-!begin >list.c
- A(dominosa) \
-!end
-
-!begin >gamedesc.txt
-dominosa:dominosa.exe:Dominosa:Domino tiling puzzle:Tile the rectangle with a full set of dominoes.
-!end
+++ /dev/null
-// -*- js -*-
-//
-// List of entry points exported by the C side of the Emscripten
-// puzzle builds. Passed in to emcc via the option '-s
-// EXPORTED_FUNCTIONS=[list]'.
-//
-// This file isn't actually a valid list in its current state, since
-// emcc doesn't like comments or newlines. However, it's a nicer
-// source form to keep the comments and newlines in, so we sed them
-// away at compile time.
-[
- // Event handlers for mouse and keyboard input
- '_mouseup',
- '_mousedown',
- '_mousemove',
- '_key',
- // Callback when the program activates timing
- '_timer_callback',
- // Callback from button presses in the UI outside the canvas
- '_command',
- // Game-saving and game-loading functions
- '_get_save_file',
- '_free_save_file',
- '_load_game',
- // Callbacks to return values from dialog boxes
- '_dlg_return_sval',
- '_dlg_return_ival',
- // Callbacks when the resizing controls are used
- '_resize_puzzle',
- '_restore_puzzle_size',
- // Main program, run at initialisation time
- '_main'
-]
+++ /dev/null
-# -*- makefile -*-
-
-fifteen : [X] GTK COMMON fifteen fifteen-icon|no-icon
-
-fifteen : [G] WINDOWS COMMON fifteen fifteen.res|noicon.res
-
-fifteensolver : [U] fifteen[STANDALONE_SOLVER] STANDALONE
-fifteensolver : [C] fifteen[STANDALONE_SOLVER] STANDALONE
-
-ALL += fifteen[COMBINED]
-
-!begin am gtk
-GAMES += fifteen
-!end
-
-!begin >list.c
- A(fifteen) \
-!end
-
-!begin >gamedesc.txt
-fifteen:fifteen.exe:Fifteen:Sliding block puzzle:Slide the tiles around to arrange them into order.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-FILLING_EXTRA = dsf
-
-fillingsolver : [U] filling[STANDALONE_SOLVER] FILLING_EXTRA STANDALONE
-fillingsolver : [C] filling[STANDALONE_SOLVER] FILLING_EXTRA STANDALONE
-
-filling : [X] GTK COMMON filling FILLING_EXTRA filling-icon|no-icon
-
-filling : [G] WINDOWS COMMON filling FILLING_EXTRA filling.res|noicon.res
-
-ALL += filling[COMBINED] FILLING_EXTRA
-
-!begin am gtk
-GAMES += filling
-!end
-
-!begin >list.c
- A(filling) \
-!end
-
-!begin >gamedesc.txt
-filling:filling.exe:Filling:Polyomino puzzle:Mark every square with the area of its containing region.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-FLIP_EXTRA = tree234
-
-flip : [X] GTK COMMON flip FLIP_EXTRA flip-icon|no-icon
-
-flip : [G] WINDOWS COMMON flip FLIP_EXTRA flip.res|noicon.res
-
-ALL += flip[COMBINED] FLIP_EXTRA
-
-!begin am gtk
-GAMES += flip
-!end
-
-!begin >list.c
- A(flip) \
-!end
-
-!begin >gamedesc.txt
-flip:flip.exe:Flip:Tile inversion puzzle:Flip groups of squares to light them all up at once.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-flood : [X] GTK COMMON flood flood-icon|no-icon
-
-flood : [G] WINDOWS COMMON flood flood.res|noicon.res
-
-ALL += flood[COMBINED]
-
-!begin am gtk
-GAMES += flood
-!end
-
-!begin >list.c
- A(flood) \
-!end
-
-!begin >gamedesc.txt
-flood:flood.exe:Flood:Flood-filling puzzle:Turn the grid the same colour in as few flood fills as possible.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-GALAXIES_EXTRA = dsf
-
-galaxies : [X] GTK COMMON galaxies GALAXIES_EXTRA galaxies-icon|no-icon
-
-galaxies : [G] WINDOWS COMMON galaxies GALAXIES_EXTRA galaxies.res|noicon.res
-
-galaxiessolver : [U] galaxies[STANDALONE_SOLVER] GALAXIES_EXTRA STANDALONE m.lib
-galaxiessolver : [C] galaxies[STANDALONE_SOLVER] GALAXIES_EXTRA STANDALONE
-
-galaxiespicture : [U] galaxies[STANDALONE_PICTURE_GENERATOR] GALAXIES_EXTRA STANDALONE
- + m.lib
-galaxiespicture : [C] galaxies[STANDALONE_PICTURE_GENERATOR] GALAXIES_EXTRA STANDALONE
-
-ALL += galaxies[COMBINED] GALAXIES_EXTRA
-
-!begin am gtk
-GAMES += galaxies
-!end
-
-!begin >list.c
- A(galaxies) \
-!end
-
-!begin >gamedesc.txt
-galaxies:galaxies.exe:Galaxies:Symmetric polyomino puzzle:Divide the grid into rotationally symmetric regions each centred on a dot.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-guess : [X] GTK COMMON guess guess-icon|no-icon
-
-guess : [G] WINDOWS COMMON guess guess.res|noicon.res
-
-ALL += guess[COMBINED]
-
-!begin am gtk
-GAMES += guess
-!end
-
-!begin >list.c
- A(guess) \
-!end
-
-!begin >gamedesc.txt
-guess:guess.exe:Guess:Combination-guessing puzzle:Guess the hidden combination of colours.
-!end
+++ /dev/null
-# Makefile for Puzzles icons.
-
-PUZZLES = blackbox bridges cube dominosa fifteen filling flip flood \
- galaxies guess inertia keen lightup loopy magnets map mines \
- net netslide palisade pattern pearl pegs range rect \
- samegame signpost singles sixteen slant solo tents towers \
- twiddle tracks undead unequal unruly untangle
-
-BASE = $(patsubst %,%-base.png,$(PUZZLES))
-WEB = $(patsubst %,%-web.png,$(PUZZLES))
-
-IBASE = $(patsubst %,%-ibase.png,$(PUZZLES))
-IBASE4 = $(patsubst %,%-ibase4.png,$(PUZZLES))
-P96D24 = $(patsubst %,%-96d24.png,$(PUZZLES))
-P96D8 = $(patsubst %,%-96d8.png,$(PUZZLES))
-P96D4 = $(patsubst %,%-96d4.png,$(PUZZLES))
-P48D24 = $(patsubst %,%-48d24.png,$(PUZZLES))
-P48D8 = $(patsubst %,%-48d8.png,$(PUZZLES))
-P48D4 = $(patsubst %,%-48d4.png,$(PUZZLES))
-P32D24 = $(patsubst %,%-32d24.png,$(PUZZLES))
-P32D8 = $(patsubst %,%-32d8.png,$(PUZZLES))
-P32D4 = $(patsubst %,%-32d4.png,$(PUZZLES))
-P16D24 = $(patsubst %,%-16d24.png,$(PUZZLES))
-P16D8 = $(patsubst %,%-16d8.png,$(PUZZLES))
-P16D4 = $(patsubst %,%-16d4.png,$(PUZZLES))
-ICONS = $(patsubst %,%.ico,$(PUZZLES))
-CICONS = $(patsubst %,%-icon.c,$(PUZZLES))
-RC = $(patsubst %,%.rc,$(PUZZLES))
-
-BIN = ../
-PIC = ./
-
-# Work around newer ImageMagick unilaterally distorting colours when
-# converting to PNG.
-CSP = -set colorspace RGB
-
-base: $(BASE)
-web: $(WEB)
-pngicons: $(P96D24) $(P48D24) $(P32D24) $(P16D24)
-winicons: $(ICONS) $(RC)
-gtkicons: $(CICONS)
-all: base web pngicons winicons gtkicons
-
-# Build the base puzzle screenshots from which all the other images
-# are derived. Some of them involve showing a move animation
-# part-way through.
-fifteen-base.png : override REDO=0.3
-flip-base.png : override REDO=0.3
-netslide-base.png : override REDO=0.3
-sixteen-base.png : override REDO=0.3
-twiddle-base.png : override REDO=0.3
-$(BASE): %-base.png: $(BIN)% $(PIC)%.sav
- $(PIC)screenshot.sh $(BIN)$* $(PIC)$*.sav $@ $(REDO)
-
-# Build the screenshots for the web, by scaling the original base
-# images to a uniform size.
-$(WEB): %-web.png: %-base.png
- $(PIC)square.pl 150 5 $^ $@
-
-# Build the base _icon_ images, by careful cropping of the base
-# images: icons are very small so it's often necessary to zoom in
-# on a smaller portion of the screenshot.
-blackbox-ibase.png : override CROP=352x352 144x144+0+208
-bridges-ibase.png : override CROP=264x264 107x107+157+157
-dominosa-ibase.png : override CROP=304x272 152x152+152+0
-fifteen-ibase.png : override CROP=240x240 120x120+0+120
-filling-ibase.png : override CROP=256x256 133x133+14+78
-flip-ibase.png : override CROP=288x288 145x145+120+72
-galaxies-ibase.png : override CROP=288x288 165x165+0+0
-guess-ibase.png : override CROP=263x420 178x178+75+17
-inertia-ibase.png : override CROP=321x321 128x128+193+0
-keen-ibase.png : override CROP=288x288 96x96+24+120
-lightup-ibase.png : override CROP=256x256 112x112+144+0
-loopy-ibase.png : override CROP=257x257 113x113+0+0
-magnets-ibase.png : override CROP=264x232 96x96+36+100
-mines-ibase.png : override CROP=240x240 110x110+130+130
-net-ibase.png : override CROP=193x193 113x113+0+80
-netslide-ibase.png : override CROP=289x289 144x144+0+0
-palisade-ibase.png : override CROP=288x288 192x192+0+0
-pattern-ibase.png : override CROP=384x384 223x223+0+0
-pearl-ibase.png : override CROP=216x216 94x94+108+15
-pegs-ibase.png : override CROP=263x263 147x147+116+0
-range-ibase.png : override CROP=256x256 98x98+111+15
-rect-ibase.png : override CROP=205x205 115x115+90+0
-signpost-ibase.png : override CROP=240x240 98x98+23+23
-singles-ibase.png : override CROP=224x224 98x98+15+15
-sixteen-ibase.png : override CROP=288x288 144x144+144+144
-slant-ibase.png : override CROP=321x321 160x160+160+160
-solo-ibase.png : override CROP=481x481 145x145+24+24
-tents-ibase.png : override CROP=320x320 165x165+142+0
-towers-ibase.png : override CROP=300x300 102x102+151+6
-tracks-ibase.png : override CROP=246x246 118x118+6+6
-twiddle-ibase.png : override CROP=192x192 102x102+69+21
-undead-ibase.png : override CROP=416x480 192x192+16+80
-unequal-ibase.png : override CROP=208x208 104x104+104+104
-untangle-ibase.png : override CROP=320x320 164x164+3+116
-$(IBASE): %-ibase.png: %-base.png
- $(PIC)crop.sh $^ $@ $(CROP)
-
-# Convert the full-size icon images to 4-bit colour, because that
-# seems to work better than reducing it in 24 bits and then
-# dithering.
-$(IBASE4): %-ibase4.png: %-ibase.png
- convert -colors 16 +dither $(CSP) -map $(PIC)win16pal.xpm $^ $@
-
-# Build the 24-bit PNGs for the icons, at four sizes.
-$(P96D24): %-96d24.png: %-ibase.png
- $(PIC)square.pl 96 4 $^ $@
-$(P48D24): %-48d24.png: %-ibase.png
- $(PIC)square.pl 48 4 $^ $@
-$(P32D24): %-32d24.png: %-ibase.png
- $(PIC)square.pl 32 2 $^ $@
-$(P16D24): %-16d24.png: %-ibase.png
- $(PIC)square.pl 16 1 $^ $@
-
-# The 8-bit icon PNGs are just custom-paletted quantisations of the
-# 24-bit ones.
-$(P96D8) $(P48D8) $(P32D8) $(P16D8): %d8.png: %d24.png
- convert -colors 256 $^ $@
-
-# But the depth-4 images work better if we re-shrink from the
-# ibase4 versions of the images, and then normalise the colours
-# again afterwards. (They're still not very good, but my hope is
-# that on most modern Windows machines this won't matter too
-# much...)
-$(P96D4): %-96d4.png: %-ibase4.png
- $(PIC)square.pl 96 1 $^ $@-tmp2.png
- convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@
- rm -f $@-tmp2.png
-$(P48D4): %-48d4.png: %-ibase4.png
- $(PIC)square.pl 48 1 $^ $@-tmp2.png
- convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@
- rm -f $@-tmp2.png
-$(P32D4): %-32d4.png: %-ibase.png
- $(PIC)square.pl 32 1 $^ $@-tmp2.png
- convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@
- rm -f $@-tmp2.png
-$(P16D4): %-16d4.png: %-ibase.png
- $(PIC)square.pl 16 1 $^ $@-tmp2.png
- convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@
- rm -f $@-tmp2.png
-
-# Build the actual Windows icons themselves, by feeding all those
-# PNGs to my icon builder script.
-$(ICONS): %.ico: %-48d24.png %-48d8.png %-48d4.png \
- %-32d24.png %-32d8.png %-32d4.png \
- %-16d24.png %-16d8.png %-16d4.png
- $(PIC)icon.pl -24 $*-48d24.png $*-32d24.png $*-16d24.png \
- -8 $*-48d8.png $*-32d8.png $*-16d8.png \
- -4 $*-48d4.png $*-32d4.png $*-16d4.png > $@
-
-# Build the .RC files which bind the icons into the applications.
-$(RC): %.rc:
- echo '#include "puzzles.rc2"' > $@
- echo '200 ICON "$*.ico"' >> $@
-
-# Build the GTK icon source files.
-$(CICONS): %-icon.c: %-16d24.png %-32d24.png %-48d24.png %-96d24.png
- $(PIC)cicon.pl $^ > $@
-
-clean:
- rm -f *.png *.ico *.rc *-icon.c
$k = 0;
@xpms = ();
+$convert = shift @ARGV;
foreach $f (@ARGV) {
# XPM format is generated directly by ImageMagick, so that's easy
# enough. We just have to adjust the declaration line so that it
# has the right name, linkage and storage class.
@lines = ();
- open XPM, "convert $f xpm:- |";
+ open XPM, "-|", $convert, $f, "xpm:-";
push @lines, $_ while <XPM>;
close XPM;
die "XPM from $f in unexpected format\n" unless $lines[1] =~ /^static.*\{$/;
# this script will give a build error and alert me to the fact that
# I need to fiddle with the icon makefile.
-infile="$1"
-outfile="$2"
-insize="$3"
-crop="$4"
+identify="$1"
+convert="$2"
+infile="$3"
+outfile="$4"
+insize="$5"
+crop="$6"
# Special case: if no input size or crop parameter was specified at
# all, we just copy the input to the output file.
-if test $# -lt 3; then
+if test -z "$insize"; then
cp "$infile" "$outfile"
exit 0
fi
# Check the input image size.
-realsize=`identify -format %wx%h "$infile"`
+realsize=$("$identify" -format %wx%h "$infile")
if test "x$insize" != "x$realsize"; then
echo "crop.sh: '$infile' has wrong initial size: $realsize != $insize" >&2
exit 1
fi
# And crop.
-convert -crop "$crop" "$infile" "$outfile"
+"$convert" -crop "$crop" "$infile" "$outfile"
@dat = ();
$depth = undef;
+$convert = "convert";
foreach $_ (@ARGV) {
if (/^-(24|8|4|1)$/) {
$depth = $1;
+ } elsif (/^--convert=(.*)$/) {
+ $convert = $1;
} elsif (defined $depth) {
&readicon($_, $depth);
} else {
# point, to avoid having to do it ourselves (.BMP and hence
# .ICO are bottom-up).
my $data = [];
- open IDATA, "convert -set colorspace sRGB -flip -depth 8 $filename rgba:- |";
+ open IDATA, "-|", $convert, "-set", "colorspace", "sRGB", "-flip", "-depth", "8", $filename, "rgba:-";
push @$data, $rgb while (read IDATA,$rgb,4,0) == 4;
close IDATA;
# Check we have the right amount of data.
--- /dev/null
+if(NOT build_icons)
+ # This entire subdirectory does nothing on platforms where we can't
+ # build the icons in any case.
+ return()
+endif()
+
+find_program(CONVERT convert REQUIRED)
+find_program(IDENTIFY identify REQUIRED)
+
+# For puzzles which have animated moves, it's nice to show the sample
+# image part way through the animation of a move. This setting will
+# cause a 'redo' action immediately after loading the save file,
+# causing the first undone move in the undo chain to be redone, and
+# then it will stop this far through the move animation to take the
+# screenshot.
+set(fifteen_redo 0.3)
+set(flip_redo 0.3)
+set(netslide_redo 0.3)
+set(sixteen_redo 0.3)
+set(twiddle_redo 0.3)
+
+# For many puzzles, we'd prefer that the icon zooms in on a couple of
+# squares of the playing area rather than trying to show the whole of
+# a game. These settings configure that. Each one indicates the
+# expected full size of the screenshot image, followed by the area we
+# want to crop to.
+#
+# (The expected full size is a safety precaution: if a puzzle changes
+# its default display size, then that won't match, and we'll get a
+# build error here rather than silently continuing to take the wrong
+# subrectangle of the resized puzzle display.)
+set(blackbox_crop 352x352 144x144+0+208)
+set(bridges_crop 264x264 107x107+157+157)
+set(dominosa_crop 304x272 152x152+152+0)
+set(fifteen_crop 240x240 120x120+0+120)
+set(filling_crop 256x256 133x133+14+78)
+set(flip_crop 288x288 145x145+120+72)
+set(galaxies_crop 288x288 165x165+0+0)
+set(guess_crop 263x420 178x178+75+17)
+set(inertia_crop 321x321 128x128+193+0)
+set(keen_crop 288x288 96x96+24+120)
+set(lightup_crop 256x256 112x112+144+0)
+set(loopy_crop 257x257 113x113+0+0)
+set(magnets_crop 264x232 96x96+36+100)
+set(mines_crop 240x240 110x110+130+130)
+set(net_crop 193x193 113x113+0+80)
+set(netslide_crop 289x289 144x144+0+0)
+set(palisade_crop 288x288 192x192+0+0)
+set(pattern_crop 384x384 223x223+0+0)
+set(pearl_crop 216x216 94x94+108+15)
+set(pegs_crop 263x263 147x147+116+0)
+set(range_crop 256x256 98x98+111+15)
+set(rect_crop 205x205 115x115+90+0)
+set(signpost_crop 240x240 98x98+23+23)
+set(singles_crop 224x224 98x98+15+15)
+set(sixteen_crop 288x288 144x144+144+144)
+set(slant_crop 321x321 160x160+160+160)
+set(solo_crop 481x481 145x145+24+24)
+set(tents_crop 320x320 165x165+142+0)
+set(towers_crop 300x300 102x102+151+6)
+set(tracks_crop 246x246 118x118+6+6)
+set(twiddle_crop 192x192 102x102+69+21)
+set(undead_crop 416x480 192x192+16+80)
+set(unequal_crop 208x208 104x104+104+104)
+set(untangle_crop 320x320 164x164+3+116)
+
+add_custom_target(icons)
+
+# All sizes of icon we make for any purpose.
+set(all_icon_sizes 96 48 32 16)
+
+# Sizes of icon we put into the Windows .ico files.
+set(win_icon_sizes 48 32 16)
+
+# Border thickness for each icon size.
+set(border_96 4)
+set(border_48 4)
+set(border_32 2)
+set(border_16 1)
+
+set(icon_srcdir ${CMAKE_SOURCE_DIR}/icons)
+set(icon_bindir ${CMAKE_BINARY_DIR}/icons)
+
+function(build_icon name)
+ set(output_icon_files)
+
+ # Compile the GTK puzzle binary without an icon, so that we can run
+ # it to generate a screenshot to make the icon out of.
+ add_executable(${NAME}-icon-maker ${NAME}.c
+ ${CMAKE_SOURCE_DIR}/no-icon.c)
+ target_link_libraries(${NAME}-icon-maker
+ common ${platform_gui_libs} ${platform_libs})
+ set_target_properties(${NAME}-icon-maker PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${icon_bindir})
+
+ # Now run that binary to generate a screenshot of the puzzle in
+ # play, which will be the base image we make everything else out
+ # out.
+ if(DEFINED ${name}_redo)
+ set(redo_arg --redo ${name}_redo)
+ else()
+ set(redo_arg)
+ endif()
+ add_custom_command(OUTPUT ${icon_bindir}/${name}-base.png
+ COMMAND ${icon_bindir}/${name}-icon-maker
+ ${redo_arg}
+ --screenshot ${icon_bindir}/${name}-base.png
+ --load ${icon_srcdir}/${name}.sav
+ DEPENDS
+ ${name}-icon-maker)
+
+ # Shrink it to a fixed-size square image for the web page,
+ # trimming boring border parts of the original image in the
+ # process. Done by square.pl.
+ add_custom_command(OUTPUT ${icon_bindir}/${name}-web.png
+ COMMAND ${icon_srcdir}/square.pl
+ ${CONVERT} 150 5
+ ${icon_bindir}/${name}-base.png
+ ${icon_bindir}/${name}-web.png
+ DEPENDS
+ ${icon_srcdir}/square.pl
+ ${icon_bindir}/${name}-base.png)
+ list(APPEND output_icon_files ${icon_bindir}/${name}-web.png)
+
+ # Make the base image for all the icons, by cropping out the most
+ # interesting part of the whole screenshot.
+ add_custom_command(OUTPUT ${icon_bindir}/${name}-ibase.png
+ COMMAND ${icon_srcdir}/crop.sh
+ ${IDENTIFY} ${CONVERT}
+ ${icon_bindir}/${name}-base.png
+ ${icon_bindir}/${name}-ibase.png
+ ${${name}_crop}
+ DEPENDS
+ ${icon_srcdir}/crop.sh
+ ${icon_bindir}/${name}-base.png)
+
+ # Coerce that base image down to colour depth of 4 bits, using the
+ # fixed 16-colour Windows palette. We do this before shrinking the
+ # image, because I've found that gives better results than just
+ # doing it after.
+ add_custom_command(OUTPUT ${icon_bindir}/${name}-ibase4.png
+ COMMAND ${CONVERT}
+ -colors 16
+ +dither
+ -set colorspace RGB
+ -map ${icon_srcdir}/win16pal.xpm
+ ${icon_bindir}/${name}-ibase.png
+ ${icon_bindir}/${name}-ibase4.png
+ DEPENDS
+ ${icon_srcdir}/win16pal.xpm
+ ${icon_bindir}/${name}-ibase.png)
+
+ foreach(size ${all_icon_sizes})
+ # Make a 24-bit icon image at each size, by shrinking the base
+ # icon image.
+ add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d24.png
+ COMMAND ${icon_srcdir}/square.pl
+ ${CONVERT} ${size} ${border_${size}}
+ ${icon_bindir}/${name}-ibase.png
+ ${icon_bindir}/${name}-${size}d24.png
+ DEPENDS
+ ${icon_srcdir}/square.pl
+ ${icon_bindir}/${name}-ibase.png)
+ list(APPEND output_icon_files ${icon_bindir}/${name}-${size}d24.png)
+
+ # And reduce the colour depth of that one to make an 8-bit
+ # version.
+ add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d8.png
+ COMMAND ${CONVERT}
+ -colors 256
+ ${icon_bindir}/${name}-${size}d24.png
+ ${icon_bindir}/${name}-${size}d8.png
+ DEPENDS ${icon_bindir}/${name}-${size}d24.png)
+ list(APPEND output_icon_files ${icon_bindir}/${name}-${size}d8.png)
+ endforeach()
+
+ foreach(size ${win_icon_sizes})
+ # 4-bit icons are only needed for Windows. We make each one by
+ # first shrinking the large 4-bit image we made above ...
+ add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d4pre.png
+ COMMAND ${icon_srcdir}/square.pl
+ ${CONVERT} ${size} ${border_${size}}
+ ${icon_bindir}/${name}-ibase4.png
+ ${icon_bindir}/${name}-${size}d4pre.png
+ DEPENDS
+ ${icon_srcdir}/square.pl
+ ${icon_bindir}/${name}-ibase4.png)
+
+ # ... and then re-coercing the output back to 16 colours, since
+ # that shrink operation will have introduced intermediate colour
+ # values again.
+ add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d4.png
+ COMMAND ${CONVERT}
+ -colors 16
+ +dither
+ -set colorspace RGB
+ -map ${icon_srcdir}/win16pal.xpm
+ ${icon_bindir}/${name}-${size}d4pre.png
+ ${icon_bindir}/${name}-${size}d4.png
+ DEPENDS ${icon_bindir}/${name}-${size}d4pre.png)
+ list(APPEND output_icon_files ${icon_bindir}/${name}-${size}d4.png)
+ endforeach()
+
+ # Make the Windows icon.
+ set(icon_pl_args)
+ set(icon_pl_deps)
+ foreach(depth 24 8 4)
+ list(APPEND icon_pl_args -${depth})
+ foreach(size ${win_icon_sizes})
+ list(APPEND icon_pl_args ${icon_bindir}/${name}-${size}d${depth}.png)
+ list(APPEND icon_pl_deps ${icon_bindir}/${name}-${size}d${depth}.png)
+ endforeach()
+ endforeach()
+ add_custom_command(OUTPUT ${icon_bindir}/${name}.ico
+ COMMAND ${icon_srcdir}/icon.pl
+ --convert=${CONVERT}
+ ${icon_pl_args} > ${icon_bindir}/${name}.ico
+ DEPENDS
+ ${icon_srcdir}/icon.pl
+ ${icon_pl_deps})
+ list(APPEND output_icon_files ${icon_bindir}/${name}.ico)
+
+ # Make a C source file containing XPMs of all the 24-bit images.
+ set(cicon_pl_infiles)
+ foreach(size ${all_icon_sizes})
+ list(APPEND cicon_pl_infiles ${icon_bindir}/${name}-${size}d24.png)
+ endforeach()
+ add_custom_command(OUTPUT ${icon_bindir}/${name}-icon.c
+ COMMAND ${icon_srcdir}/cicon.pl
+ ${CONVERT} ${cicon_pl_infiles} > ${icon_bindir}/${name}-icon.c
+ DEPENDS
+ ${icon_srcdir}/cicon.pl
+ ${cicon_pl_infiles})
+
+ add_custom_target(${name}-icons DEPENDS ${output_icon_files})
+ add_dependencies(icons ${name}-icons)
+endfunction()
+++ /dev/null
-#!/bin/sh
-
-# Generate a screenshot from a puzzle save file. Takes the
-# following arguments, in order:
-#
-# - the name of the puzzle binary
-# - the name of the save file
-# - the name of the output image file
-# - (optionally) the proportion of the next move to redo before
-# taking the screenshot.
-#
-# This script requires access to an X server in order to run, but
-# seems to work fine under xvfb-run if you haven't got a real one
-# available (or if you don't want to use it for some reason).
-
-binary="$1"
-save="$2"
-image="$3"
-if test "x$4" != "x"; then
- redo="--redo $4"
-else
- redo=
-fi
-
-"$binary" $redo --screenshot "$image" --load "$save"
# - the input image file name
# - the output image file name.
-($osize, $oborder, $infile, $outfile) = @ARGV;
+($convert, $osize, $oborder, $infile, $outfile) = @ARGV;
# Determine the input image's size.
$ident = `identify -format "%w %h" $infile`;
# Read the input image data.
$data = [];
-open IDATA, "convert -depth 8 $infile rgb:- |";
+open IDATA, "-|", $convert, "-depth", "8", $infile, "rgb:-";
push @$data, $rgb while (read IDATA,$rgb,3,0) == 3;
close IDATA;
# Check we have the right amount of data.
die "internal computation problem" if $ow != $oh; # should be square
# Now write out the resulting image, and resize it appropriately.
-open IDATA, "| convert -size ${ow}x${oh} -depth 8 -resize ${osize}x${osize}! rgb:- $outfile";
+open IDATA, "|-", $convert, "-size", "${ow}x${oh}", "-depth", "8", "-resize", "${osize}x${osize}!", "rgb:-", $outfile;
for ($y = $ystart; $y <= $yend; $y++) {
for ($x = $xstart; $x <= $xend; $x++) {
if ($x >= 0 && $x < $w && $y >= 0 && $y < $h) {
+++ /dev/null
-# -*- makefile -*-
-
-inertia : [X] GTK COMMON inertia inertia-icon|no-icon
-
-inertia : [G] WINDOWS COMMON inertia inertia.res|noicon.res
-
-ALL += inertia[COMBINED]
-
-!begin am gtk
-GAMES += inertia
-!end
-
-!begin >list.c
- A(inertia) \
-!end
-
-!begin >gamedesc.txt
-inertia:inertia.exe:Inertia:Gem-collecting puzzle:Collect all the gems without running into any of the mines.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-KEEN_EXTRA = dsf LATIN
-KEEN_EXTRA_SOLVER = dsf LATIN_SOLVER
-
-keen : [X] GTK COMMON keen KEEN_EXTRA keen-icon|no-icon
-
-keen : [G] WINDOWS COMMON keen KEEN_EXTRA keen.res|noicon.res
-
-keensolver : [U] keen[STANDALONE_SOLVER] KEEN_EXTRA_SOLVER STANDALONE
-keensolver : [C] keen[STANDALONE_SOLVER] KEEN_EXTRA_SOLVER STANDALONE
-
-ALL += keen[COMBINED] KEEN_EXTRA
-
-!begin am gtk
-GAMES += keen
-!end
-
-!begin >list.c
- A(keen) \
-!end
-
-!begin >gamedesc.txt
-keen:keen.exe:Keen:Arithmetic Latin square puzzle:Complete the latin square in accordance with the arithmetic clues.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-LIGHTUP_EXTRA = combi
-
-lightup : [X] GTK COMMON lightup LIGHTUP_EXTRA lightup-icon|no-icon
-
-lightup : [G] WINDOWS COMMON lightup LIGHTUP_EXTRA lightup.res|noicon.res
-
-lightupsolver : [U] lightup[STANDALONE_SOLVER] LIGHTUP_EXTRA STANDALONE
-lightupsolver : [C] lightup[STANDALONE_SOLVER] LIGHTUP_EXTRA STANDALONE
-
-ALL += lightup[COMBINED] LIGHTUP_EXTRA
-
-!begin am gtk
-GAMES += lightup
-!end
-
-!begin >list.c
- A(lightup) \
-!end
-
-!begin >gamedesc.txt
-lightup:lightup.exe:Light Up:Light-bulb placing puzzle:Place bulbs to light up all the squares.
-!end
--- /dev/null
+/*
+ * list.c: List of pointers to puzzle structures, for monolithic
+ * platforms.
+ *
+ * This file depends on the header "generated-games.h", which is
+ * constructed by CMakeLists.txt.
+ */
+
+#include "puzzles.h"
+
+#define GAME(x) extern const game x;
+#include "generated-games.h"
+#undef GAME
+
+#define GAME(x) &x,
+const game *gamelist[] = {
+#include "generated-games.h"
+};
+#undef GAME
+
+const int gamecount = lenof(gamelist);
+++ /dev/null
-# -*- makefile -*-
-
-LOOPY_EXTRA = tree234 dsf grid penrose loopgen
-
-loopy : [X] GTK COMMON loopy LOOPY_EXTRA loopy-icon|no-icon
-
-loopy : [G] WINDOWS COMMON loopy LOOPY_EXTRA loopy.res|noicon.res
-
-loopysolver : [U] loopy[STANDALONE_SOLVER] LOOPY_EXTRA STANDALONE m.lib
-loopysolver : [C] loopy[STANDALONE_SOLVER] LOOPY_EXTRA STANDALONE
-
-#penrose : [U] penrose[TEST_PENROSE] STANDALONE m.lib
-#penrose : [C] penrose[TEST_PENROSE] STANDALONE
-
-#test-basis : [U] penrose[TEST_VECTORS] tree234 STANDALONE m.lib
-#test-basis : [C] penrose[TEST_VECTORS] tree234 STANDALONE
-
-
-ALL += loopy[COMBINED] LOOPY_EXTRA
-
-!begin am gtk
-GAMES += loopy
-!end
-
-!begin >list.c
- A(loopy) \
-!end
-
-!begin >gamedesc.txt
-loopy:loopy.exe:Loopy:Loop-drawing puzzle:Draw a single closed loop, given clues about number of adjacent edges.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-MAGNETS_EXTRA = laydomino
-
-magnets : [X] GTK COMMON magnets MAGNETS_EXTRA magnets-icon|no-icon
-
-magnets : [G] WINDOWS COMMON magnets MAGNETS_EXTRA magnets.res|noicon.res
-
-magnetssolver : [U] magnets[STANDALONE_SOLVER] MAGNETS_EXTRA STANDALONE m.lib
-magnetssolver : [C] magnets[STANDALONE_SOLVER] MAGNETS_EXTRA STANDALONE
-
-ALL += magnets[COMBINED] MAGNETS_EXTRA
-
-!begin am gtk
-GAMES += magnets
-!end
-
-!begin >list.c
- A(magnets) \
-!end
-
-!begin >gamedesc.txt
-magnets:magnets.exe:Magnets:Magnet-placing puzzle:Place magnets to satisfy the clues and avoid like poles touching.
-!end
+++ /dev/null
-#!/bin/sh
-
-# Build a Unix source distribution from the Puzzles SVN area.
-#
-# Pass a version number argument to have the archive tagged with that
-# version number. Otherwise, the script will not version-tag the
-# archive at all.
-
-version="$1"
-
-if test "x$version" != "x"; then
- arcsuffix="-$version"
- ver="-DVER=$version"
-else
- arcsuffix=
- ver=
-fi
-
-perl mkfiles.pl
-./mkauto.sh
-
-mkdir tmp.$$
-mkdir tmp.$$/puzzles$arcsuffix
-mkdir tmp.$$/puzzles$arcsuffix/icons
-
-# Build Windows Help and text versions of the manual for convenience.
-halibut --winhelp=puzzles.hlp --text=puzzles.txt puzzles.but
-
-# Build a text version of the HACKING document.
-halibut --text=HACKING devel.but
-
-for i in *.c *.m *.h *.R *.rc *.but *.plist *.icns LICENCE README Recipe \
- *.rc2 mkfiles.pl Makefile Makefile.* \
- HACKING puzzles.txt puzzles.hlp puzzles.cnt puzzles.chm \
- icons/Makefile icons/*.sav icons/*.pl icons/*.sh icons/win16pal.xpm \
- icons/*.png icons/*.ico icons/*.rc icons/*.c \
- configure.ac mkauto.sh aclocal.m4 \
- configure depcomp install-sh missing compile; do
- case $i in
- */*) ln -s ../../../$i tmp.$$/puzzles$arcsuffix/$i;;
- *) ln -s ../../$i tmp.$$/puzzles$arcsuffix/$i;;
- esac
-done
-
-tar -C tmp.$$ -chzf - puzzles$arcsuffix > ../puzzles$arcsuffix.tar.gz
-
-rm -rf tmp.$$
+++ /dev/null
-# -*- makefile -*-
-
-MAP_EXTRA = dsf
-
-map : [X] GTK COMMON map MAP_EXTRA map-icon|no-icon
-
-map : [G] WINDOWS COMMON map MAP_EXTRA map.res|noicon.res
-
-mapsolver : [U] map[STANDALONE_SOLVER] MAP_EXTRA STANDALONE m.lib
-mapsolver : [C] map[STANDALONE_SOLVER] MAP_EXTRA STANDALONE
-
-ALL += map[COMBINED] MAP_EXTRA
-
-!begin am gtk
-GAMES += map
-!end
-
-!begin >list.c
- A(map) \
-!end
-
-!begin >gamedesc.txt
-map:map.exe:Map:Map-colouring puzzle:Colour the map so that adjacent regions are never the same colour.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-MINES_EXTRA = tree234
-
-mines : [X] GTK COMMON mines MINES_EXTRA mines-icon|no-icon
-
-mines : [G] WINDOWS COMMON mines MINES_EXTRA mines.res|noicon.res
-
-mineobfusc : [U] mines[STANDALONE_OBFUSCATOR] MINES_EXTRA STANDALONE
-mineobfusc : [C] mines[STANDALONE_OBFUSCATOR] MINES_EXTRA STANDALONE
-
-ALL += mines[COMBINED] MINES_EXTRA
-
-!begin am gtk
-GAMES += mines
-!end
-
-!begin >list.c
- A(mines) \
-!end
-
-!begin >gamedesc.txt
-mines:mines.exe:Mines:Mine-finding puzzle:Find all the mines without treading on any of them.
-!end
+++ /dev/null
-#! /bin/sh
-autoreconf -i && rm -rf autom4te.cache
+++ /dev/null
-#!/usr/bin/env perl
-#
-# Cross-platform Makefile generator.
-#
-# Reads the file `Recipe' to determine the list of generated
-# executables and their component objects. Then reads the source
-# files to compute #include dependencies. Finally, writes out the
-# various target Makefiles.
-
-# PuTTY specifics which could still do with removing:
-# - Mac makefile is not portabilised at all. Include directories
-# are hardwired, and also the libraries are fixed. This is
-# mainly because I was too scared to go anywhere near it.
-# - sbcsgen.pl is still run at startup.
-
-# Other things undone:
-# - special-define objects (foo.o[PREPROCSYMBOL]) are not
-# supported in the mac or vcproj makefiles.
-
-use warnings;
-use IO::Handle;
-use Cwd;
-use File::Basename;
-
-while ($#ARGV >= 0) {
- if ($ARGV[0] eq "-U") {
- # Convenience for Unix users: -U means that after we finish what
- # we're doing here, we also run mkauto.sh and then 'configure'. So
- # it's a one-stop shop for regenerating the actual end-product
- # Unix makefile.
- #
- # Arguments supplied after -U go to configure.
- $do_unix = 1;
- shift @ARGV;
- @confargs = @ARGV;
- @ARGV = ();
- } else {
- die "unrecognised command-line argument '$ARGV[0]'\n";
- }
-}
-
-@filestack = ();
-$in = new IO::Handle;
-open $in, "Recipe" or do {
- # We want to deal correctly with being run from one of the
- # subdirs in the source tree. So if we can't find Recipe here,
- # try one level up.
- chdir "..";
- open $in, "Recipe" or die "unable to open Recipe file\n";
-};
-push @filestack, $in;
-
-# HACK: One of the source files in `charset' is auto-generated by
-# sbcsgen.pl. We need to generate that _now_, before attempting
-# dependency analysis.
-eval 'chdir "charset"; require "sbcsgen.pl"; chdir ".."';
-
-@srcdirs = ("./");
-
-$divert = undef; # ref to array of refs of scalars in which text is
- # currently being put
-$help = ""; # list of newline-free lines of help text
-$project_name = "project"; # this is a good enough default
-%makefiles = (); # maps makefile types to output makefile pathnames
-%makefile_extra = (); # maps makefile types to extra Makefile text
-%programs = (); # maps prog name + type letter to listref of objects/resources
-%groups = (); # maps group name to listref of objects/resources
-
-@allobjs = (); # all object file names
-
-readinput: while (1) {
- $in = $filestack[$#filestack];
- while (not defined ($_ = <$in>)) {
- close $filestack[$#filestack];
- pop @filestack;
- last readinput if 0 == scalar @filestack;
- $in = $filestack[$#filestack];
- }
- chomp;
- @_ = split;
-
- # If we're gathering help text, keep doing so.
- if (defined $divert) {
- if ((defined $_[0]) && $_[0] eq "!end") {
- $divert = undef;
- } else {
- for my $ref (@$divert) {
- ${$ref} .= "$_\n";
- }
- }
- next;
- }
- # Skip comments and blank lines.
- next if /^\s*#/ or scalar @_ == 0;
-
- if ($_[0] eq "!begin" and $_[1] eq "help") { $divert = [\$help]; next; }
- if ($_[0] eq "!name") { $project_name = $_[1]; next; }
- if ($_[0] eq "!srcdir") { push @srcdirs, $_[1]; next; }
- if ($_[0] eq "!makefile" and &mfval($_[1])) { $makefiles{$_[1]}=$_[2]; next;}
- if ($_[0] eq "!specialobj" and &mfval($_[1])) { $specialobj{$_[1]}->{$_[2]} = 1; next;}
- if ($_[0] eq "!cflags" and &mfval($_[1])) {
- ($rest = $_) =~ s/^\s*\S+\s+\S+\s+\S+\s*//; # find rest of input line
- $rest = 1 if $rest eq "";
- $cflags{$_[1]}->{$_[2]} = $rest;
- next;
- }
- if ($_[0] eq "!begin") {
- my @args = @_;
- shift @args;
- $divert = [];
- for my $component (@args) {
- if ($component =~ /^>(.*)/) {
- push @$divert, \$auxfiles{$1};
- } elsif ($component =~ /^([^_]*)(_.*)?$/ and &mfval($1)) {
- push @$divert, \$makefile_extra{$component};
- }
- }
- next;
- }
- if ($_[0] eq "!include") {
- @newfiles = ();
- for ($i = 1; $i <= $#_; $i++) {
- push @newfiles, (sort glob $_[$i]);
- }
- for ($i = $#newfiles; $i >= 0; $i--) {
- $file = $newfiles[$i];
- $f = new IO::Handle;
- open $f, "<$file" or die "unable to open include file '$file'\n";
- push @filestack, $f;
- }
- next;
- }
-
- # Now we have an ordinary line. See if it's an = line, a : line
- # or a + line.
- @objs = @_;
-
- if ($_[0] eq "+") {
- $listref = $lastlistref;
- $prog = undef;
- die "$.: unexpected + line\n" if !defined $lastlistref;
- } elsif ($_[1] eq "=") {
- $groups{$_[0]} = [];
- $listref = $groups{$_[0]};
- $prog = undef;
- shift @objs; # eat the group name
- } elsif ($_[1] eq "+=") {
- $groups{$_[0]} = [] if !defined $groups{$_[0]};
- $listref = $groups{$_[0]};
- $prog = undef;
- shift @objs; # eat the group name
- } elsif ($_[1] eq ":") {
- $listref = [];
- $prog = $_[0];
- shift @objs; # eat the program name
- } else {
- die "$.: unrecognised line type: '$_'\n";
- }
- shift @objs; # eat the +, the = or the :
-
- while (scalar @objs > 0) {
- $i = shift @objs;
- if ($groups{$i}) {
- foreach $j (@{$groups{$i}}) { unshift @objs, $j; }
- } elsif (($i eq "[G]" or $i eq "[C]" or $i eq "[M]" or
- $i eq "[X]" or $i eq "[U]" or $i eq "[MX]") and defined $prog) {
- $type = substr($i,1,(length $i)-2);
- } else {
- if ($i =~ /\?$/) {
- # Object files with a trailing question mark are optional:
- # the build can proceed fine without them, so we only use
- # them if their primary source files are present.
- $i =~ s/\?$//;
- $i = undef unless defined &finddep($i);
- } elsif ($i =~ /\|/) {
- # Object file descriptions containing a vertical bar are
- # lists of choices: we use the _first_ one whose primary
- # source file is present.
- @options = split /\|/, $i;
- $j = undef;
- foreach $k (@options) {
- $j=$k, last if defined &finddep($k);
- }
- die "no alternative found for $i\n" unless defined $j;
- $i = $j;
- }
- if (defined $i) {
- push @$listref, $i;
- push @allobjs, $i;
- }
- }
- }
- if ($prog and $type) {
- die "multiple program entries for $prog [$type]\n"
- if defined $programs{$prog . "," . $type};
- $programs{$prog . "," . $type} = $listref;
- }
- $lastlistref = $listref;
-}
-
-foreach $aux (sort keys %auxfiles) {
- open AUX, ">$aux";
- print AUX $auxfiles{$aux};
- close AUX;
-}
-
-# Find object file names with predefines (in square brackets after
-# the module name), and decide on actual object names for them.
-foreach $i (@allobjs) {
- if ($i !~ /\[/) {
- $objname{$i} = $i;
- $srcname{$i} = $i;
- $usedobjname{$i} = 1;
- }
-}
-foreach $i (@allobjs) {
- if ($i =~ /^(.*)\[([^\]]*)/) {
- $defs{$i} = [ split ",",$2 ];
- $srcname{$i} = $s = $1;
- $index = 1;
- while (1) {
- $maxlen = length $s;
- $maxlen = 8 if $maxlen < 8;
- $chop = $maxlen - length $index;
- $chop = length $s if $chop > length $s;
- $chop = 0 if $chop < 0;
- $name = substr($s, 0, $chop) . $index;
- $index++, next if $usedobjname{$name};
- $objname{$i} = $name;
- $usedobjname{$name} = 1;
- last;
- }
- }
-}
-
-# Now retrieve the complete list of objects and resource files, and
-# construct dependency data for them. While we're here, expand the
-# object list for each program, and complain if its type isn't set.
-@prognames = sort keys %programs;
-%depends = ();
-@scanlist = ();
-foreach $i (@prognames) {
- ($prog, $type) = split ",", $i;
- # Strip duplicate object names.
- $prev = '';
- @list = grep { $status = ($prev ne $_); $prev=$_; $status }
- sort @{$programs{$i}};
- $programs{$i} = [@list];
- foreach $jj (@list) {
- $j = $srcname{$jj};
- $file = &finddep($j);
- if (defined $file) {
- $depends{$jj} = [$file];
- push @scanlist, $file;
- }
- }
-}
-
-# Scan each file on @scanlist and find further inclusions.
-# Inclusions are given by lines of the form `#include "otherfile"'
-# (system headers are automatically ignored by this because they'll
-# be given in angle brackets). Files included by this method are
-# added back on to @scanlist to be scanned in turn (if not already
-# done).
-#
-# Resource scripts (.rc) can also include a file by means of a line
-# ending `ICON "filename"'. Files included by this method are not
-# added to @scanlist because they can never include further files.
-#
-# In this pass we write out a hash %further which maps a source
-# file name into a listref containing further source file names.
-
-%further = ();
-while (scalar @scanlist > 0) {
- $file = shift @scanlist;
- next if defined $further{$file}; # skip if we've already done it
- $further{$file} = [];
- $dirfile = &findfile($file);
- open IN, "$dirfile" or die "unable to open source file $file\n";
- while (<IN>) {
- chomp;
- /^\s*#include\s+\"([^\"]+)\"/ and do {
- push @{$further{$file}}, $1;
- push @scanlist, $1;
- next;
- };
- /ICON\s+\"([^\"]+)\"\s*$/ and do {
- push @{$further{$file}}, $1;
- next;
- }
- }
- close IN;
-}
-
-# Now we're ready to generate the final dependencies section. For
-# each key in %depends, we must expand the dependencies list by
-# iteratively adding entries from %further.
-foreach $i (keys %depends) {
- %dep = ();
- @scanlist = @{$depends{$i}};
- foreach $i (@scanlist) { $dep{$i} = 1; }
- while (scalar @scanlist > 0) {
- $file = shift @scanlist;
- foreach $j (@{$further{$file}}) {
- if (!$dep{$j}) {
- $dep{$j} = 1;
- push @{$depends{$i}}, $j;
- push @scanlist, $j;
- }
- }
- }
-# printf "%s: %s\n", $i, join ' ',@{$depends{$i}};
-}
-
-# Validation of input.
-
-sub mfval($) {
- my ($type) = @_;
- # Returns true if the argument is a known makefile type. Otherwise,
- # prints a warning and returns false;
- if (grep { $type eq $_ }
- ("vc","vcproj","cygwin","borland","lcc","gtk","am","mpw","nestedvm","osx","wce","gnustep","emcc","clangcl")) {
- return 1;
- }
- warn "$.:unknown makefile type '$type'\n";
- return 0;
-}
-
-# Utility routines while writing out the Makefiles.
-
-sub dirpfx {
- my ($path) = shift @_;
- my ($sep) = shift @_;
- my $ret = "";
- my $i;
- while (($i = index $path, $sep) >= 0) {
- $path = substr $path, ($i + length $sep);
- $ret .= "..$sep";
- }
- return $ret;
-}
-
-sub findfile {
- my ($name) = @_;
- my $dir;
- my $i;
- my $outdir = undef;
- unless (defined $findfilecache{$name}) {
- $i = 0;
- foreach $dir (@srcdirs) {
- $outdir = $dir, $i++ if -f "$dir$name";
- }
- die "multiple instances of source file $name\n" if $i > 1;
- $findfilecache{$name} = (defined $outdir ? $outdir . $name : undef);
- }
- return $findfilecache{$name};
-}
-
-sub finddep {
- my $j = shift @_;
- my $file;
- # Find the first dependency of an object.
-
- # Dependencies for "x" start with "x.c" or "x.m" (depending on
- # which one exists).
- # Dependencies for "x.res" start with "x.rc".
- # Dependencies for "x.rsrc" start with "x.r".
- # Both types of file are pushed on the list of files to scan.
- # Libraries (.lib) don't have dependencies at all.
- if ($j =~ /^(.*)\.res$/) {
- $file = "$1.rc";
- } elsif ($j =~ /^(.*)\.rsrc$/) {
- $file = "$1.r";
- } elsif ($j !~ /\./) {
- $file = "$j.c";
- $file = "$j.m" unless &findfile($file);
- } else {
- # For everything else, we assume it's its own dependency.
- $file = $j;
- }
- $file = undef unless &findfile($file);
- return $file;
-}
-
-sub objects {
- my ($prog, $otmpl, $rtmpl, $ltmpl, $prefix, $dirsep) = @_;
- my @ret;
- my ($i, $x, $y);
- ($otmpl, $rtmpl, $ltmpl) = map { defined $_ ? $_ : "" } ($otmpl, $rtmpl, $ltmpl);
- @ret = ();
- foreach $ii (@{$programs{$prog}}) {
- $i = $objname{$ii};
- $x = "";
- if ($i =~ /^(.*)\.(res|rsrc)/) {
- $y = $1;
- ($x = $rtmpl) =~ s/X/$y/;
- } elsif ($i =~ /^(.*)\.lib/) {
- $y = $1;
- ($x = $ltmpl) =~ s/X/$y/;
- } elsif ($i !~ /\./) {
- ($x = $otmpl) =~ s/X/$i/;
- }
- push @ret, $x if $x ne "";
- }
- return join " ", @ret;
-}
-
-sub special {
- my ($prog, $suffix) = @_;
- my @ret;
- my ($i, $x, $y);
- @ret = ();
- foreach $ii (@{$programs{$prog}}) {
- $i = $objname{$ii};
- if (substr($i, (length $i) - (length $suffix)) eq $suffix) {
- push @ret, $i;
- }
- }
- return join " ", @ret;
-}
-
-sub splitline {
- my ($line, $width, $splitchar) = @_;
- my $result = "";
- my $len;
- $len = (defined $width ? $width : 76);
- $splitchar = (defined $splitchar ? $splitchar : '\\');
- while (length $line > $len) {
- $line =~ /^(.{0,$len})\s(.*)$/ or $line =~ /^(.{$len,}?\s(.*)$/;
- $result .= $1;
- $result .= " ${splitchar}\n\t\t" if $2 ne '';
- $line = $2;
- $len = 60;
- }
- return $result . $line;
-}
-
-sub deps {
- my ($otmpl, $rtmpl, $prefix, $dirsep, $depchar, $splitchar) = @_;
- my ($i, $x, $y);
- my @deps;
- my @ret;
- @ret = ();
- $depchar ||= ':';
- foreach $ii (sort keys %depends) {
- $i = $objname{$ii};
- next if $specialobj{$mftyp}->{$i};
- if ($i =~ /^(.*)\.(res|rsrc)/) {
- next if !defined $rtmpl;
- $y = $1;
- ($x = $rtmpl) =~ s/X/$y/;
- } else {
- ($x = $otmpl) =~ s/X/$i/;
- }
- @deps = @{$depends{$ii}};
- # Skip things which are their own dependency.
- next if grep { $_ eq $i } @deps;
- @deps = map {
- $_ = &findfile($_);
- s/\//$dirsep/g;
- $_ = $prefix . $_;
- } @deps;
- push @ret, {obj => $x, deps => [@deps], defs => $defs{$ii}};
- }
- return @ret;
-}
-
-sub prognames {
- my ($types) = @_;
- my ($n, $prog, $type);
- my @ret;
- @ret = ();
- foreach $n (@prognames) {
- ($prog, $type) = split ",", $n;
- push @ret, $n if index(":$types:", ":$type:") >= 0;
- }
- return @ret;
-}
-
-sub progrealnames {
- my ($types) = @_;
- my ($n, $prog, $type);
- my @ret;
- @ret = ();
- foreach $n (@prognames) {
- ($prog, $type) = split ",", $n;
- push @ret, $prog if index(":$types:", ":$type:") >= 0;
- }
- return @ret;
-}
-
-sub manpages {
- my ($types,$suffix) = @_;
-
- # assume that all UNIX programs have a man page
- if($suffix eq "1" && $types =~ /:X:/) {
- return map("$_.1", &progrealnames($types));
- }
- return ();
-}
-
-$orig_dir = cwd;
-
-# Now we're ready to output the actual Makefiles.
-
-if (defined $makefiles{'clangcl'}) {
- $mftyp = 'clangcl';
- $dirpfx = &dirpfx($makefiles{'clangcl'}, "/");
-
- ##-- Makefile for cross-compiling using clang-cl, lld-link, and
- ## MinGW's windres for resource compilation.
- #
- # This makefile allows a complete Linux-based cross-compile, but
- # using the real Visual Studio header files and libraries. In
- # order to run it, you will need:
- #
- # - MinGW windres on your PATH.
- # * On Ubuntu as of 16.04, you can apt-get install
- # binutils-mingw-w64-x86-64 and binutils-mingw-w64-i686
- # which will provide (respectively) 64- and 32-bit versions,
- # under the names to which RCCMD is defined below.
- # - clang-cl and lld-link on your PATH.
- # * I built these from the up-to-date LLVM project trunk git
- # repositories, as of 2017-02-05.
- # - case-mashed copies of the Visual Studio include directories.
- # * On a real VS installation, run vcvars32.bat and look at
- # the resulting value of %INCLUDE%. Take a full copy of each
- # of those directories, and inside the copy, for each
- # include file that has an uppercase letter in its name,
- # make a lowercased symlink to it. Additionally, one of the
- # directories will contain files called driverspecs.h and
- # specstrings.h, and those will need symlinks called
- # DriverSpecs.h and SpecStrings.h.
- # * Now, on Linux, define the environment variable INCLUDE to
- # be a list, separated by *semicolons* (in the Windows
- # style), of those directories, but before all of them you
- # must also include lib/clang/5.0.0/include from the clang
- # installation area (which contains in particular a
- # clang-compatible stdarg.h overriding the Visual Studio
- # one).
- # - similarly case-mashed copies of the library directories.
- # * Again, on a real VS installation, run vcvars32 or
- # vcvarsx86_amd64 (as appropriate), look at %LIB%, make a
- # copy of each directory, and provide symlinks within that
- # directory so that all the files can be opened as
- # lowercase.
- # * Then set LIB to be a semicolon-separated list of those
- # directories (but you'll need to change which set of
- # directories depending on whether you want to do a 32-bit
- # or 64-bit build).
- # - for a 64-bit build, set 'Platform=x64' in the environment as
- # well, or else on the make command line.
- # * This is a variable understood only by this makefile - none
- # of the tools we invoke will know it - but it's consistent
- # with the way the VS scripts like vcvarsx86_amd64.bat set
- # things up, and since the environment has to change
- # _anyway_ between 32- and 64-bit builds (different set of
- # paths in $LIB) it's reasonable to have the choice of
- # compilation target driven by another environment variable
- # set in parallel with that one.
- # - for older versions of the VS libraries you may also have to
- # set EXTRA_console and/or EXTRA_windows to the name of an
- # object file manually extracted from one of those libraries.
- # * This is because old VS seems to manage its startup code by
- # having libcmt.lib contain lots of *crt0.obj objects, one
- # for each possible user entry point (main, WinMain and the
- # wide-char versions of both), of which the linker arranges
- # to include the right one by special-case code. But lld
- # only seems to mimic half of that code - it does include
- # the right crt0 object, but it doesn't also deliberately
- # _avoid_ including the _wrong_ ones, and since all those
- # objects define a common set of global symbols for other
- # parts of the library to use, lld may well select an
- # arbitrary one of them the first time it sees a reference
- # to one of those global symbols, and then later also select
- # the _right_ one for the application's entry point, causing
- # a multiple-definitions crash.
- # * So the workaround is to explicitly include the right
- # *crt0.obj file on the linker command line before lld even
- # begins searching libraries. Hence, for a console
- # application, you might extract crt0.obj from the library
- # in question and set EXTRA_console=crt0.obj, and for a GUI
- # application, do the same with wincrt0.obj. Then this
- # makefile will include the right one of those objects
- # alongside the matching /subsystem linker option.
-
- open OUT, ">$makefiles{'clangcl'}"; select OUT;
- print
- "# Makefile for cross-compiling $project_name using clang-cl, lld-link,\n".
- "# and MinGW's windres, using GNU make on Linux.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- print $help;
- print
- "\n".
- "CCCMD = clang-cl\n".
- "ifeq (\$(Platform),x64)\n".
- "CCTARGET = x86_64-pc-windows-msvc18.0.0\n".
- "RCCMD = x86_64-w64-mingw32-windres\n".
- "else\n".
- "CCTARGET = i386-pc-windows-msvc18.0.0\n".
- "RCCMD = i686-w64-mingw32-windres\n".
- "endif\n".
- "CC = \$(CCCMD) --target=\$(CCTARGET)\n".
- &splitline("RC = \$(RCCMD) --preprocessor=\$(CCCMD) ".
- "--preprocessor-arg=/TC --preprocessor-arg=/E")."\n".
- "LD = lld-link\n".
- "\n".
- "# C compilation flags\n".
- &splitline("CFLAGS = /nologo /W3 /O1 " .
- (join " ", map {"-I$dirpfx$_"} @srcdirs) .
- " /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401 ".
- "/D_CRT_SECURE_NO_WARNINGS")."\n".
- "LFLAGS = /incremental:no /dynamicbase /nxcompat\n".
- &splitline("RCFLAGS = ".(join " ", map {"-I$dirpfx$_"} @srcdirs).
- " -DWIN32 -D_WIN32 -DWINVER=0x0400 --define MINGW32_FIX=1")."\n".
- "\n".
- "\n";
- print &splitline("all:" . join "", map { " \$(BUILDDIR)$_.exe" } &progrealnames("G:C"));
- print "\n\n";
- foreach $p (&prognames("G:C")) {
- ($prog, $type) = split ",", $p;
- $objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", undef);
- print &splitline("\$(BUILDDIR)$prog.exe: " . $objstr), "\n";
-
- $objstr = &objects($p, "\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", "X.lib");
- $subsys = ($type eq "G") ? "windows" : "console";
- print &splitline("\t\$(LD) \$(LFLAGS) \$(XLFLAGS) ".
- "/out:\$(BUILDDIR)$prog.exe ".
- "/lldmap:\$(BUILDDIR)$prog.map ".
- "/subsystem:$subsys\$(SUBSYSVER) ".
- "\$(EXTRA_$subsys) $objstr")."\n\n";
- }
- foreach $d (&deps("\$(BUILDDIR)X.obj", "\$(BUILDDIR)X.res", $dirpfx, "/", "vc")) {
- print &splitline(sprintf("%s: %s", $d->{obj},
- join " ", @{$d->{deps}})), "\n";
- if ($d->{obj} =~ /\.res$/) {
- print "\t\$(RC) \$(RCFLAGS) ".$d->{deps}->[0]." -o ".$d->{obj}."\n\n";
- } else {
- $deflist = join "", map { " /D$_" } @{$d->{defs}};
- print "\t\$(CC) /Fo".$d->{obj}." \$(COMPAT) \$(CFLAGS) \$(XFLAGS)$deflist /c \$<\n\n";
- }
- }
- print "\nclean:\n".
- &splitline("\trm -f \$(BUILDDIR)*.obj \$(BUILDDIR)*.exe ".
- "\$(BUILDDIR)*.res \$(BUILDDIR)*.map ".
- "\$(BUILDDIR)*.exe.manifest")."\n";
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'cygwin'}) {
- $mftyp = 'cygwin';
- $dirpfx = &dirpfx($makefiles{'cygwin'}, "/");
-
- ##-- CygWin makefile
- open OUT, ">$makefiles{'cygwin'}"; select OUT;
- print
- "# Makefile for $project_name under cygwin.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- # gcc command line option is -D not /D
- ($_ = $help) =~ s/=\/D/=-D/gs;
- print $_;
- print
- "\n".
- "# You can define this path to point at your tools if you need to\n".
- "# TOOLPATH = c:\\cygwin\\bin\\ # or similar, if you're running Windows\n".
- "# TOOLPATH = /pkg/mingw32msvc/i386-mingw32msvc/bin/\n".
- "CC = \$(TOOLPATH)gcc\n".
- "RC = \$(TOOLPATH)windres\n".
- "# Uncomment the following two lines to compile under Winelib\n".
- "# CC = winegcc\n".
- "# RC = wrc\n".
- "# You may also need to tell windres where to find include files:\n".
- "# RCINC = --include-dir c:\\cygwin\\include\\\n".
- "\n".
- &splitline("CFLAGS = -mno-cygwin -Wall -O2 -D_WINDOWS -DDEBUG -DWIN32S_COMPAT".
- " -D_NO_OLDNAMES -DNO_MULTIMON -DNO_HTMLHELP " .
- (join " ", map {"-I$dirpfx$_"} @srcdirs)) .
- "\n".
- "LDFLAGS = -mno-cygwin -s\n".
- &splitline("RCFLAGS = \$(RCINC) --define WIN32=1 --define _WIN32=1".
- " --define WINVER=0x0400 --define MINGW32_FIX=1 " .
- (join " ", map {"--include $dirpfx$_"} @srcdirs) )."\n".
- "\n";
- print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
- print "\n\n";
- foreach $p (&prognames("G:C")) {
- ($prog, $type) = split ",", $p;
- $objstr = &objects($p, "X.o", "X.res.o", undef);
- print &splitline($prog . ".exe: " . $objstr), "\n";
- my $mw = $type eq "G" ? " -mwindows" : "";
- $libstr = &objects($p, undef, undef, "-lX");
- print &splitline("\t\$(CC)" . $mw . " \$(LDFLAGS) -o \$@ " .
- "-Wl,-Map,$prog.map " .
- $objstr . " $libstr", 69), "\n\n";
- }
- foreach $d (&deps("X.o", "X.res.o", $dirpfx, "/")) {
- print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
- "\n";
- if ($d->{obj} =~ /\.res\.o$/) {
- print "\t\$(RC) \$(FWHACK) \$(RCFL) \$(RCFLAGS) \$< \$\@\n";
- } else {
- $deflist = join "", map { " -D$_" } @{$d->{defs}};
- print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS)" .
- " \$(XFLAGS)$deflist -c \$< -o \$\@\n";
- }
- }
- print "\n";
- print $makefile_extra{'cygwin'} || "";
- print "\nclean:\n".
- "\trm -f *.o *.exe *.res.o *.map\n".
- "\n";
- select STDOUT; close OUT;
-
-}
-
-##-- Borland makefile
-if (defined $makefiles{'borland'}) {
- $mftyp = 'borland';
- $dirpfx = &dirpfx($makefiles{'borland'}, "\\");
-
- %stdlibs = ( # Borland provides many Win32 API libraries intrinsically
- "advapi32" => 1,
- "comctl32" => 1,
- "comdlg32" => 1,
- "gdi32" => 1,
- "imm32" => 1,
- "shell32" => 1,
- "user32" => 1,
- "winmm" => 1,
- "winspool" => 1,
- "wsock32" => 1,
- );
- open OUT, ">$makefiles{'borland'}"; select OUT;
- print
- "# Makefile for $project_name under Borland C.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- # bcc32 command line option is -D not /D
- ($_ = $help) =~ s/=\/D/=-D/gs;
- print $_;
- print
- "\n".
- "# If you rename this file to `Makefile', you should change this line,\n".
- "# so that the .rsp files still depend on the correct makefile.\n".
- "MAKEFILE = Makefile.bor\n".
- "\n".
- "# C compilation flags\n".
- "CFLAGS = -D_WINDOWS -DWINVER=0x0401\n".
- "\n".
- "# Get include directory for resource compiler\n".
- "!if !\$d(BCB)\n".
- "BCB = \$(MAKEDIR)\\..\n".
- "!endif\n".
- "\n";
- print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
- print "\n\n";
- foreach $p (&prognames("G:C")) {
- ($prog, $type) = split ",", $p;
- $objstr = &objects($p, "X.obj", "X.res", undef);
- print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
- my $ap = ($type eq "G") ? "-aa" : "-ap";
- print "\tilink32 $ap -Gn -L\$(BCB)\\lib \@$prog.rsp\n\n";
- }
- foreach $p (&prognames("G:C")) {
- ($prog, $type) = split ",", $p;
- print $prog, ".rsp: \$(MAKEFILE)\n";
- $objstr = &objects($p, "X.obj", undef, undef);
- @objlist = split " ", $objstr;
- @objlines = ("");
- foreach $i (@objlist) {
- if (length($objlines[$#objlines] . " $i") > 50) {
- push @objlines, "";
- }
- $objlines[$#objlines] .= " $i";
- }
- $c0w = ($type eq "G") ? "c0w32" : "c0x32";
- print "\techo $c0w + > $prog.rsp\n";
- for ($i=0; $i<=$#objlines; $i++) {
- $plus = ($i < $#objlines ? " +" : "");
- print "\techo$objlines[$i]$plus >> $prog.rsp\n";
- }
- print "\techo $prog.exe >> $prog.rsp\n";
- $objstr = &objects($p, "X.obj", "X.res", undef);
- @libs = split " ", &objects($p, undef, undef, "X");
- @libs = grep { !$stdlibs{$_} } @libs;
- unshift @libs, "cw32", "import32";
- $libstr = join ' ', @libs;
- print "\techo nul,$libstr, >> $prog.rsp\n";
- print "\techo " . &objects($p, undef, "X.res", undef) . " >> $prog.rsp\n";
- print "\n";
- }
- foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
- print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
- "\n";
- if ($d->{obj} =~ /\.res$/) {
- print &splitline("\tbrcc32 \$(FWHACK) \$(RCFL) " .
- "-i \$(BCB)\\include -r -DNO_WINRESRC_H -DWIN32".
- " -D_WIN32 -DWINVER=0x0401 \$*.rc",69)."\n";
- } else {
- $deflist = join "", map { " -D$_" } @{$d->{defs}};
- print &splitline("\tbcc32 -w-aus -w-ccc -w-par -w-pia \$(COMPAT)" .
- " \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist ".
- (join " ", map {"-I$dirpfx$_"} @srcdirs) .
- " /o$d->{obj} /c ".$d->{deps}->[0],69)."\n";
- }
- }
- print "\n";
- print $makefile_extra{'borland'} || "";
- print "\nclean:\n".
- "\t-del *.obj\n".
- "\t-del *.exe\n".
- "\t-del *.res\n".
- "\t-del *.pch\n".
- "\t-del *.aps\n".
- "\t-del *.il*\n".
- "\t-del *.pdb\n".
- "\t-del *.rsp\n".
- "\t-del *.tds\n".
- "\t-del *.\$\$\$\$\$\$\n";
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'vc'}) {
- $mftyp = 'vc';
- $dirpfx = &dirpfx($makefiles{'vc'}, "\\");
-
- ##-- Visual C++ makefile
- open OUT, ">$makefiles{'vc'}"; select OUT;
- print
- "# Makefile for $project_name under Visual C.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- print $help;
- print
- "\n".
- "# If you rename this file to `Makefile', you should change this line,\n".
- "# so that the .rsp files still depend on the correct makefile.\n".
- "MAKEFILE = Makefile.vc\n".
- "\n".
- "# C compilation flags\n".
- "CFLAGS = /nologo /W3 /O1 /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401 /I.\n".
- "LFLAGS = /incremental:no /fixed\n".
- "\n";
- print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
- print "\n\n";
- foreach $p (&prognames("G:C")) {
- ($prog, $type) = split ",", $p;
- $objstr = &objects($p, "X.obj", "X.res", undef);
- print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
- print "\tlink \$(LFLAGS) -out:$prog.exe -map:$prog.map \@$prog.rsp\n\n";
- }
- foreach $p (&prognames("G:C")) {
- ($prog, $type) = split ",", $p;
- print $prog, ".rsp: \$(MAKEFILE)\n";
- $objstr = &objects($p, "X.obj", "X.res", "X.lib");
- @objlist = split " ", $objstr;
- @objlines = ("");
- foreach $i (@objlist) {
- if (length($objlines[$#objlines] . " $i") > 50) {
- push @objlines, "";
- }
- $objlines[$#objlines] .= " $i";
- }
- $subsys = ($type eq "G") ? "windows" : "console";
- print "\techo /nologo /subsystem:$subsys > $prog.rsp\n";
- for ($i=0; $i<=$#objlines; $i++) {
- print "\techo$objlines[$i] >> $prog.rsp\n";
- }
- print "\n";
- }
- foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
- print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
- "\n";
- if ($d->{obj} =~ /\.res$/) {
- print "\trc \$(FWHACK) \$(RCFL) -r -DWIN32 -D_WIN32 ".
- "-DWINVER=0x0400 -fo".$d->{obj}." ".$d->{deps}->[0]."\n";
- } else {
- $deflist = join "", map { " /D$_" } @{$d->{defs}};
- print "\tcl \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist".
- " /c ".$d->{deps}->[0]." /Fo$d->{obj}\n";
- }
- }
- print "\n";
- print $makefile_extra{'vc'} || "";
- print "\nclean: tidy\n".
- "\t-del *.exe\n\n".
- "tidy:\n".
- "\t-del *.obj\n".
- "\t-del *.res\n".
- "\t-del *.pch\n".
- "\t-del *.aps\n".
- "\t-del *.ilk\n".
- "\t-del *.pdb\n".
- "\t-del *.rsp\n".
- "\t-del *.dsp\n".
- "\t-del *.dsw\n".
- "\t-del *.ncb\n".
- "\t-del *.opt\n".
- "\t-del *.plg\n".
- "\t-del *.map\n".
- "\t-del *.idb\n".
- "\t-del debug.log\n";
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'wce'}) {
- $mftyp = 'wce';
- $dirpfx = &dirpfx($makefiles{'wce'}, "\\");
-
- ##-- eMbedded Visual C PocketPC makefile
- open OUT, ">$makefiles{'wce'}"; select OUT;
- print
- "# Makefile for $project_name on PocketPC using eMbedded Visual C.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- print $help;
- print
- "\n".
- "# If you rename this file to `Makefile', you should change this line,\n".
- "# so that the .rsp files still depend on the correct makefile.\n".
- "MAKEFILE = Makefile.wce\n".
- "\n".
- "# This makefile expects the environment to have been set up by one\n".
- "# of the PocketPC batch files wcearmv4.bat and wceemulator.bat. No\n".
- "# other build targets are currently supported, because they would\n".
- "# need a section in this if statement.\n".
- "!if \"\$(TARGETCPU)\" == \"emulator\"\n".
- "PLATFORM_DEFS=/D \"_i386_\" /D \"i_386_\" /D \"_X86_\" /D \"x86\"\n".
- "CC=cl\n".
- "BASELIBS=commctrl.lib coredll.lib corelibc.lib aygshell.lib\n".
- "MACHINE=IX86\n".
- "!else\n".
- "PLATFORM_DEFS=/D \"ARM\" /D \"_ARM_\" /D \"ARMV4\"\n".
- "CC=clarm\n".
- "BASELIBS=commctrl.lib coredll.lib aygshell.lib\n".
- "MACHINE=ARM\n".
- "!endif\n".
- "\n".
- "# C compilation flags\n".
- "CFLAGS = /nologo /W3 /O1 /MC /D _WIN32_WCE=420 /D \"WIN32_PLATFORM_PSPC=400\" /D UNDER_CE=420 \\\n".
- " \$(PLATFORM_DEFS) \\\n".
- " /D \"UNICODE\" /D \"_UNICODE\" /D \"NDEBUG\" /D \"NO_HTMLHELP\"\n".
- "\n".
- "LFLAGS = /nologo /incremental:no \\\n".
- " /base:0x00010000 /stack:0x10000,0x1000 /entry:WinMainCRTStartup \\\n".
- " /nodefaultlib:libc.lib /nodefaultlib:libcmt.lib /nodefaultlib:msvcrt.lib /nodefaultlib:OLDNAMES.lib \\\n".
- " /subsystem:windowsce,4.20 /align:4096 /MACHINE:\$(MACHINE)\n".
- "\n".
- "RCFL = /d UNDER_CE=420 /d _WIN32_WCE=420 /d \"WIN32_PLATFORM_PSPC=400\" \\\n".
- " \$(PLATFORM_DEFS) \\\n".
- " /d \"NDEBUG\" /d \"UNICODE\" /d \"_UNICODE\"\n".
- "\n";
- print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G"));
- print "\n\n";
- foreach $p (&prognames("G")) {
- ($prog, $type) = split ",", $p;
- $objstr = &objects($p, "X.obj", "X.res", undef);
- print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
- print "\tlink \$(LFLAGS) -out:$prog.exe -map:$prog.map \@$prog.rsp\n\n";
- }
- foreach $p (&prognames("G")) {
- ($prog, $type) = split ",", $p;
- print $prog, ".rsp: \$(MAKEFILE)\n";
- $objstr = &objects($p, "X.obj", "X.res", undef);
- @objlist = split " ", $objstr;
- @objlines = ("");
- foreach $i (@objlist) {
- if (length($objlines[$#objlines] . " $i") > 50) {
- push @objlines, "";
- }
- $objlines[$#objlines] .= " $i";
- }
- print "\techo \$(BASELIBS) > $prog.rsp\n";
- for ($i=0; $i<=$#objlines; $i++) {
- print "\techo$objlines[$i] >> $prog.rsp\n";
- }
- print "\n";
- }
- foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
- print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
- "\n";
- if ($d->{obj} =~ /\.res$/) {
- print "\trc \$(FWHACK) \$(RCFL) -r -fo".
- $d->{obj}." ".$d->{deps}->[0]."\n";
- } else {
- $deflist = join "", map { " /D$_" } @{$d->{defs}};
- print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist".
- " /c ".$d->{deps}->[0]." /Fo$d->{obj}\n";
- }
- }
- print "\n";
- print $makefile_extra{'wce'} || "";
- print "\nclean: tidy\n".
- "\t-del *.exe\n\n".
- "tidy:\n".
- "\t-del *.obj\n".
- "\t-del *.res\n".
- "\t-del *.pch\n".
- "\t-del *.aps\n".
- "\t-del *.ilk\n".
- "\t-del *.pdb\n".
- "\t-del *.rsp\n".
- "\t-del *.dsp\n".
- "\t-del *.dsw\n".
- "\t-del *.ncb\n".
- "\t-del *.opt\n".
- "\t-del *.plg\n".
- "\t-del *.map\n".
- "\t-del *.idb\n".
- "\t-del debug.log\n";
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'vcproj'}) {
- $mftyp = 'vcproj';
-
- ##-- MSVC 6 Workspace and projects
- #
- # Note: All files created in this section are written in binary
- # mode, because although MSVC's command-line make can deal with
- # LF-only line endings, MSVC project files really _need_ to be
- # CRLF. Hence, in order for mkfiles.pl to generate usable project
- # files even when run from Unix, I make sure all files are binary
- # and explicitly write the CRLFs.
- #
- # Create directories if necessary
- mkdir $makefiles{'vcproj'}
- if(! -d $makefiles{'vcproj'});
- chdir $makefiles{'vcproj'};
- @deps = &deps("X.obj", "X.res", "", "\\");
- %all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
- # Create the project files
- # Get names of all Windows projects (GUI and console)
- my @prognames = &prognames("G:C");
- foreach $progname (@prognames) {
- create_project(\%all_object_deps, $progname);
- }
- # Create the workspace file
- open OUT, ">$project_name.dsw"; binmode OUT; select OUT;
- print
- "Microsoft Developer Studio Workspace File, Format Version 6.00\r\n".
- "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r\n".
- "\r\n".
- "###############################################################################\r\n".
- "\r\n";
- # List projects
- foreach $progname (@prognames) {
- ($windows_project, $type) = split ",", $progname;
- print "Project: \"$windows_project\"=\".\\$windows_project\\$windows_project.dsp\" - Package Owner=<4>\r\n";
- }
- print
- "\r\n".
- "Package=<5>\r\n".
- "{{{\r\n".
- "}}}\r\n".
- "\r\n".
- "Package=<4>\r\n".
- "{{{\r\n".
- "}}}\r\n".
- "\r\n".
- "###############################################################################\r\n".
- "\r\n".
- "Global:\r\n".
- "\r\n".
- "Package=<5>\r\n".
- "{{{\r\n".
- "}}}\r\n".
- "\r\n".
- "Package=<3>\r\n".
- "{{{\r\n".
- "}}}\r\n".
- "\r\n".
- "###############################################################################\r\n".
- "\r\n";
- select STDOUT; close OUT;
- chdir $orig_dir;
-
- sub create_project {
- my ($all_object_deps, $progname) = @_;
- # Construct program's dependency info
- %seen_objects = ();
- %lib_files = ();
- %source_files = ();
- %header_files = ();
- %resource_files = ();
- @object_files = split " ", &objects($progname, "X.obj", "X.res", "X.lib");
- foreach $object_file (@object_files) {
- next if defined $seen_objects{$object_file};
- $seen_objects{$object_file} = 1;
- if($object_file =~ /\.lib$/io) {
- $lib_files{$object_file} = 1;
- next;
- }
- $object_deps = $all_object_deps{$object_file};
- foreach $object_dep (@$object_deps) {
- if($object_dep =~ /\.c$/io) {
- $source_files{$object_dep} = 1;
- next;
- }
- if($object_dep =~ /\.h$/io) {
- $header_files{$object_dep} = 1;
- next;
- }
- if($object_dep =~ /\.(rc|ico)$/io) {
- $resource_files{$object_dep} = 1;
- next;
- }
- }
- }
- $libs = join " ", sort keys %lib_files;
- @source_files = sort keys %source_files;
- @header_files = sort keys %header_files;
- @resources = sort keys %resource_files;
- ($windows_project, $type) = split ",", $progname;
- mkdir $windows_project
- if(! -d $windows_project);
- chdir $windows_project;
- $subsys = ($type eq "G") ? "windows" : "console";
- open OUT, ">$windows_project.dsp"; binmode OUT; select OUT;
- print
- "# Microsoft Developer Studio Project File - Name=\"$windows_project\" - Package Owner=<4>\r\n".
- "# Microsoft Developer Studio Generated Build File, Format Version 6.00\r\n".
- "# ** DO NOT EDIT **\r\n".
- "\r\n".
- "# TARGTYPE \"Win32 (x86) Application\" 0x0101\r\n".
- "\r\n".
- "CFG=$windows_project - Win32 Debug\r\n".
- "!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r\n".
- "!MESSAGE use the Export Makefile command and run\r\n".
- "!MESSAGE \r\n".
- "!MESSAGE NMAKE /f \"$windows_project.mak\".\r\n".
- "!MESSAGE \r\n".
- "!MESSAGE You can specify a configuration when running NMAKE\r\n".
- "!MESSAGE by defining the macro CFG on the command line. For example:\r\n".
- "!MESSAGE \r\n".
- "!MESSAGE NMAKE /f \"$windows_project.mak\" CFG=\"$windows_project - Win32 Debug\"\r\n".
- "!MESSAGE \r\n".
- "!MESSAGE Possible choices for configuration are:\r\n".
- "!MESSAGE \r\n".
- "!MESSAGE \"$windows_project - Win32 Release\" (based on \"Win32 (x86) Application\")\r\n".
- "!MESSAGE \"$windows_project - Win32 Debug\" (based on \"Win32 (x86) Application\")\r\n".
- "!MESSAGE \r\n".
- "\r\n".
- "# Begin Project\r\n".
- "# PROP AllowPerConfigDependencies 0\r\n".
- "# PROP Scc_ProjName \"\"\r\n".
- "# PROP Scc_LocalPath \"\"\r\n".
- "CPP=cl.exe\r\n".
- "MTL=midl.exe\r\n".
- "RSC=rc.exe\r\n".
- "\r\n".
- "!IF \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
- "\r\n".
- "# PROP BASE Use_MFC 0\r\n".
- "# PROP BASE Use_Debug_Libraries 0\r\n".
- "# PROP BASE Output_Dir \"Release\"\r\n".
- "# PROP BASE Intermediate_Dir \"Release\"\r\n".
- "# PROP BASE Target_Dir \"\"\r\n".
- "# PROP Use_MFC 0\r\n".
- "# PROP Use_Debug_Libraries 0\r\n".
- "# PROP Output_Dir \"Release\"\r\n".
- "# PROP Intermediate_Dir \"Release\"\r\n".
- "# PROP Ignore_Export_Lib 0\r\n".
- "# PROP Target_Dir \"\"\r\n".
- "# ADD BASE CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
- "# ADD CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
- "# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
- "# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
- "# ADD BASE RSC /l 0x809 /d \"NDEBUG\"\r\n".
- "# ADD RSC /l 0x809 /d \"NDEBUG\"\r\n".
- "BSC32=bscmake.exe\r\n".
- "# ADD BASE BSC32 /nologo\r\n".
- "# ADD BSC32 /nologo\r\n".
- "LINK32=link.exe\r\n".
- "# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:$subsys /machine:I386\r\n".
- "# ADD LINK32 $libs /nologo /subsystem:$subsys /machine:I386\r\n".
- "# SUBTRACT LINK32 /pdb:none\r\n".
- "\r\n".
- "!ELSEIF \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
- "\r\n".
- "# PROP BASE Use_MFC 0\r\n".
- "# PROP BASE Use_Debug_Libraries 1\r\n".
- "# PROP BASE Output_Dir \"Debug\"\r\n".
- "# PROP BASE Intermediate_Dir \"Debug\"\r\n".
- "# PROP BASE Target_Dir \"\"\r\n".
- "# PROP Use_MFC 0\r\n".
- "# PROP Use_Debug_Libraries 1\r\n".
- "# PROP Output_Dir \"Debug\"\r\n".
- "# PROP Intermediate_Dir \"Debug\"\r\n".
- "# PROP Ignore_Export_Lib 0\r\n".
- "# PROP Target_Dir \"\"\r\n".
- "# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
- "# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
- "# ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
- "# ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
- "# ADD BASE RSC /l 0x809 /d \"_DEBUG\"\r\n".
- "# ADD RSC /l 0x809 /d \"_DEBUG\"\r\n".
- "BSC32=bscmake.exe\r\n".
- "# ADD BASE BSC32 /nologo\r\n".
- "# ADD BSC32 /nologo\r\n".
- "LINK32=link.exe\r\n".
- "# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:$subsys /debug /machine:I386 /pdbtype:sept\r\n".
- "# ADD LINK32 $libs /nologo /subsystem:$subsys /debug /machine:I386 /pdbtype:sept\r\n".
- "# SUBTRACT LINK32 /pdb:none\r\n".
- "\r\n".
- "!ENDIF \r\n".
- "\r\n".
- "# Begin Target\r\n".
- "\r\n".
- "# Name \"$windows_project - Win32 Release\"\r\n".
- "# Name \"$windows_project - Win32 Debug\"\r\n".
- "# Begin Group \"Source Files\"\r\n".
- "\r\n".
- "# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\r\n";
- foreach $source_file (@source_files) {
- print
- "# Begin Source File\r\n".
- "\r\n".
- "SOURCE=..\\..\\$source_file\r\n";
- if($source_file =~ /ssh\.c/io) {
- # Disable 'Edit and continue' as Visual Studio can't handle the macros
- print
- "\r\n".
- "!IF \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
- "\r\n".
- "!ELSEIF \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
- "\r\n".
- "# ADD CPP /Zi\r\n".
- "\r\n".
- "!ENDIF \r\n".
- "\r\n";
- }
- print "# End Source File\r\n";
- }
- print
- "# End Group\r\n".
- "# Begin Group \"Header Files\"\r\n".
- "\r\n".
- "# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\r\n";
- foreach $header_file (@header_files) {
- print
- "# Begin Source File\r\n".
- "\r\n".
- "SOURCE=..\\..\\$header_file\r\n".
- "# End Source File\r\n";
- }
- print
- "# End Group\r\n".
- "# Begin Group \"Resource Files\"\r\n".
- "\r\n".
- "# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\r\n";
- foreach $resource_file (@resources) {
- print
- "# Begin Source File\r\n".
- "\r\n".
- "SOURCE=..\\..\\$resource_file\r\n".
- "# End Source File\r\n";
- }
- print
- "# End Group\r\n".
- "# End Target\r\n".
- "# End Project\r\n";
- select STDOUT; close OUT;
- chdir "..";
- }
-}
-
-if (defined $makefiles{'gtk'}) {
- $mftyp = 'gtk';
- $dirpfx = &dirpfx($makefiles{'gtk'}, "/");
-
- ##-- X/GTK/Unix makefile
- open OUT, ">$makefiles{'gtk'}"; select OUT;
- print
- "# Makefile for $project_name under X/GTK and Unix.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- # gcc command line option is -D not /D
- ($_ = $help) =~ s/=\/D/=-D/gs;
- print $_;
- print
- "\n".
- "# You can define this path to point at your tools if you need to\n".
- "# TOOLPATH = /opt/gcc/bin\n".
- "CC := \$(TOOLPATH)\$(CC)\n".
- "# You can manually set this to `gtk-config' or `pkg-config gtk+-1.2'\n".
- "# (depending on what works on your system) if you want to enforce\n".
- "# building with GTK 1.2, or you can set it to `pkg-config gtk+-2.0'\n".
- "# if you want to enforce 2.0. The default is to try 2.0 and fall back\n".
- "# to 1.2 if it isn't found.\n".
- "GTK_CONFIG = sh -c 'pkg-config gtk+-2.0 \$\$0 2>/dev/null || gtk-config \$\$0'\n".
- "\n".
- &splitline("CFLAGS := -O2 -Wall -Werror -ansi -pedantic -g " .
- (join " ", map {"-I$dirpfx$_"} @srcdirs) .
- " `\$(GTK_CONFIG) --cflags` \$(CFLAGS)")."\n".
- "XLIBS = `\$(GTK_CONFIG) --libs` -lm\n".
- "ULIBS = -lm#\n".
- "INSTALL=install\n",
- "INSTALL_PROGRAM=\$(INSTALL)\n",
- "INSTALL_DATA=\$(INSTALL)\n",
- "prefix=/usr/local\n",
- "exec_prefix=\$(prefix)\n",
- "bindir=\$(exec_prefix)/bin\n",
- "gamesdir=\$(exec_prefix)/games\n",
- "mandir=\$(prefix)/man\n",
- "man1dir=\$(mandir)/man1\n",
- "\n";
- print &splitline("all:" . join "", map { " \$(BINPREFIX)$_" }
- &progrealnames("X:U"));
- print "\n\n";
- foreach $p (&prognames("X:U")) {
- ($prog, $type) = split ",", $p;
- $objstr = &objects($p, "X.o", undef, undef);
- print &splitline("\$(BINPREFIX)" . $prog . ": " . $objstr), "\n";
- $libstr = &objects($p, undef, undef, "-lX");
- print &splitline("\t\$(CC) -o \$@ $objstr $libstr \$(XLFLAGS) \$(${type}LIBS)", 69),
- "\n\n";
- }
- foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
- print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
- "\n";
- $deflist = join "", map { " -D$_" } @{$d->{defs}};
- print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
- " -c \$< -o \$\@\n";
- }
- print "\n";
- print $makefile_extra{'gtk'} || "";
- print "\nclean:\n".
- "\trm -f *.o". (join "", map { " \$(BINPREFIX)$_" } &progrealnames("X:U")) . "\n";
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'am'}) {
- $mftyp = 'am';
- die "Makefile.am in a subdirectory is not supported\n"
- if &dirpfx($makefiles{'am'}, "/") ne "";
-
- ##-- Unix/autoconf Makefile.am
- open OUT, ">$makefiles{'am'}"; select OUT;
- print
- "# Makefile.am for $project_name under Unix with Autoconf/Automake.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n\n";
-
- print $makefile_extra{'am_begin'} || "";
-
- # All programs go in noinstprogs by default. If you want them
- # installed anywhere else, you have to also add them to
- # bin_PROGRAMS using '!begin am'. (Automake doesn't seem to mind
- # having a program name in _both_ of bin_PROGRAMS and
- # noinst_PROGRAMS.)
- @noinstprogs = ();
- foreach $p (&prognames("X:U")) {
- ($prog, $type) = split ",", $p;
- push @noinstprogs, $prog;
- }
- print &splitline(join " ", "noinst_PROGRAMS", "=", @noinstprogs), "\n";
-
- %objtosrc = ();
- %amspeciallibs = ();
- %amlibobjname = ();
- %allsources = ();
- foreach $d (&deps("X", undef, "", "/", "am")) {
- my $obj = $d->{obj};
- my $use_archive = 0;
-
- if (defined $d->{defs}) {
- # This file needs to go in an archive, so that we can
- # change the preprocess flags to include some -Ds
- $use_archive = 1;
- $archivecppflags{$obj} = [map { " -D$_" } @{$d->{defs}}];
- }
- if (defined $cflags{'am'} && $cflags{'am'}->{$obj}) {
- # This file needs to go in an archive, so that we can
- # change the compile flags as specified in Recipe
- $use_archive = 1;
- $archivecflags{$obj} = [$cflags{'am'}->{$obj}];
- }
- if ($use_archive) {
- $amspeciallibs{$obj} = "lib${obj}.a";
- $amlibobjname{$obj} = "lib${obj}_a-" .
- basename($d->{deps}->[0], ".c", ".m") .
- ".\$(OBJEXT)";
- }
- $objtosrc{$obj} = $d->{deps};
- map { $allsources{$_} = 1 } @{$d->{deps}};
- }
-
- # 2014-02-22: as of automake-1.14 we begin to get complained at if
- # we don't use this option
- print "AUTOMAKE_OPTIONS = subdir-objects\n\n";
-
- # Complete list of source and header files. Not used by the
- # auto-generated parts of this makefile, but Recipe might like to
- # have it available as a variable so that mandatory-rebuild things
- # (version.o) can conveniently be made to depend on it.
- print &splitline(join " ", "allsources", "=",
- sort {$a cmp $b} keys %allsources), "\n\n";
-
- @amcppflags = map {"-I\$(srcdir)/$_"} @srcdirs;
- print &splitline(join " ", "AM_CPPFLAGS", "=", @amcppflags, "\n");
-
- @amcflags = ("\$(GTK_CFLAGS)", "\$(WARNINGOPTS)");
- print &splitline(join " ", "AM_CFLAGS", "=", @amcflags), "\n";
-
- %amlibsused = ();
- foreach $p (&prognames("X:U")) {
- ($prog, $type) = split ",", $p;
- @progsources = ("${prog}_SOURCES", "=");
- %sourcefiles = ();
- @ldadd = ();
- $objstr = &objects($p, "X", undef, undef);
- foreach $obj (split / /,$objstr) {
- if ($amspeciallibs{$obj}) {
- $amlibsused{$obj} = 1;
- push @ldadd, $amlibobjname{$obj};
- } else {
- map { $sourcefiles{$_} = 1 } @{$objtosrc{$obj}};
- }
- }
- push @progsources, sort { $a cmp $b } keys %sourcefiles;
- print &splitline(join " ", @progsources), "\n";
- if ($type eq "X") {
- push @ldadd, "\$(GTK_LIBS)";
- }
- push @ldadd, "-lm";
- print &splitline(join " ", "${prog}_LDADD", "=", @ldadd), "\n";
- print "\n";
- }
-
- foreach $obj (sort { $a cmp $b } keys %amlibsused) {
- print &splitline(join " ", "lib${obj}_a_SOURCES", "=",
- @{$objtosrc{$obj}}), "\n";
- print &splitline(join " ", "lib${obj}_a_CPPFLAGS", "=",
- @amcflags, @{$archivecppflags{$obj}}), "\n"
- if $archivecppflags{$obj};
- print &splitline(join " ", "lib${obj}_a_CFLAGS", "=",
- @amcflags, @{$archivecflags{$obj}}), "\n"
- if $archivecflags{$obj};
- }
- print &splitline(join " ", "noinst_LIBRARIES", "=",
- sort { $a cmp $b }
- map { $amspeciallibs{$_} }
- keys %amlibsused),
- "\n\n";
-
- print $makefile_extra{'am'} || "";
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'mpw'}) {
- $mftyp = 'mpw';
- ##-- MPW Makefile
- open OUT, ">$makefiles{'mpw'}"; select OUT;
- print
- "# Makefile for $project_name under MPW.\n#\n".
- "# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- # MPW command line option is -d not /D
- ($_ = $help) =~ s/=\/D/=-d /gs;
- print $_;
- print "\n\n".
- "ROptions = `Echo \"{VER}\" | StreamEdit -e \"1,\$ replace /=(\xc5)\xa81\xb0/ 'STR=\xb6\xb6\xb6\xb6\xb6\"' \xa81 '\xb6\xb6\xb6\xb6\xb6\"'\"`".
- "\n".
- "C_68K = {C}\n".
- "C_CFM68K = {C}\n".
- "C_PPC = {PPCC}\n".
- "C_Carbon = {PPCC}\n".
- "\n".
- "# -w 35 disables \"unused parameter\" warnings\n".
- "COptions = -i : -i :: -i ::charset -w 35 -w err -proto strict -ansi on \xb6\n".
- " -notOnce\n".
- "COptions_68K = {COptions} -model far -opt time\n".
- "# Enabling \"-opt space\" for CFM-68K gives me undefined references to\n".
- "# _\$LDIVT and _\$LMODT.\n".
- "COptions_CFM68K = {COptions} -model cfmSeg -opt time\n".
- "COptions_PPC = {COptions} -opt size -traceback\n".
- "COptions_Carbon = {COptions} -opt size -traceback -d TARGET_API_MAC_CARBON\n".
- "\n".
- "Link_68K = ILink\n".
- "Link_CFM68K = ILink\n".
- "Link_PPC = PPCLink\n".
- "Link_Carbon = PPCLink\n".
- "\n".
- "LinkOptions = -c 'pTTY'\n".
- "LinkOptions_68K = {LinkOptions} -br 68k -model far -compact\n".
- "LinkOptions_CFM68K = {LinkOptions} -br 020 -model cfmseg -compact\n".
- "LinkOptions_PPC = {LinkOptions}\n".
- "LinkOptions_Carbon = -m __appstart -w {LinkOptions}\n".
- "\n".
- "Libs_68K = \"{CLibraries}StdCLib.far.o\" \xb6\n".
- " \"{Libraries}MacRuntime.o\" \xb6\n".
- " \"{Libraries}MathLib.far.o\" \xb6\n".
- " \"{Libraries}IntEnv.far.o\" \xb6\n".
- " \"{Libraries}Interface.o\" \xb6\n".
- " \"{Libraries}Navigation.far.o\" \xb6\n".
- " \"{Libraries}OpenTransport.o\" \xb6\n".
- " \"{Libraries}OpenTransportApp.o\" \xb6\n".
- " \"{Libraries}OpenTptInet.o\" \xb6\n".
- " \"{Libraries}UnicodeConverterLib.far.o\"\n".
- "\n".
- "Libs_CFM = \"{SharedLibraries}InterfaceLib\" \xb6\n".
- " \"{SharedLibraries}StdCLib\" \xb6\n".
- " \"{SharedLibraries}AppearanceLib\" \xb6\n".
- " -weaklib AppearanceLib \xb6\n".
- " \"{SharedLibraries}NavigationLib\" \xb6\n".
- " -weaklib NavigationLib \xb6\n".
- " \"{SharedLibraries}TextCommon\" \xb6\n".
- " -weaklib TextCommon \xb6\n".
- " \"{SharedLibraries}UnicodeConverter\" \xb6\n".
- " -weaklib UnicodeConverter\n".
- "\n".
- "Libs_CFM68K = {Libs_CFM} \xb6\n".
- " \"{CFM68KLibraries}NuMacRuntime.o\"\n".
- "\n".
- "Libs_PPC = {Libs_CFM} \xb6\n".
- " \"{SharedLibraries}ControlsLib\" \xb6\n".
- " -weaklib ControlsLib \xb6\n".
- " \"{SharedLibraries}WindowsLib\" \xb6\n".
- " -weaklib WindowsLib \xb6\n".
- " \"{SharedLibraries}OpenTransportLib\" \xb6\n".
- " -weaklib OTClientLib \xb6\n".
- " -weaklib OTClientUtilLib \xb6\n".
- " \"{SharedLibraries}OpenTptInternetLib\" \xb6\n".
- " -weaklib OTInetClientLib \xb6\n".
- " \"{PPCLibraries}StdCRuntime.o\" \xb6\n".
- " \"{PPCLibraries}PPCCRuntime.o\" \xb6\n".
- " \"{PPCLibraries}CarbonAccessors.o\" \xb6\n".
- " \"{PPCLibraries}OpenTransportAppPPC.o\" \xb6\n".
- " \"{PPCLibraries}OpenTptInetPPC.o\"\n".
- "\n".
- "Libs_Carbon = \"{PPCLibraries}CarbonStdCLib.o\" \xb6\n".
- " \"{PPCLibraries}StdCRuntime.o\" \xb6\n".
- " \"{PPCLibraries}PPCCRuntime.o\" \xb6\n".
- " \"{SharedLibraries}CarbonLib\" \xb6\n".
- " \"{SharedLibraries}StdCLib\"\n".
- "\n";
- print &splitline("all \xc4 " . join(" ", &progrealnames("M")), undef, "\xb6");
- print "\n\n";
- foreach $p (&prognames("M")) {
- ($prog, $type) = split ",", $p;
-
- print &splitline("$prog \xc4 $prog.68k $prog.ppc $prog.carbon",
- undef, "\xb6"), "\n\n";
-
- $rsrc = &objects($p, "", "X.rsrc", undef);
-
- foreach $arch (qw(68K CFM68K PPC Carbon)) {
- $objstr = &objects($p, "X.\L$arch\E.o", "", undef);
- print &splitline("$prog.\L$arch\E \xc4 $objstr $rsrc", undef, "\xb6");
- print "\n";
- print &splitline("\tDuplicate -y $rsrc {Targ}", 69, "\xb6"), "\n";
- print &splitline("\t{Link_$arch} -o {Targ} -fragname $prog " .
- "{LinkOptions_$arch} " .
- $objstr . " {Libs_$arch}", 69, "\xb6"), "\n";
- print &splitline("\tSetFile -a BMi {Targ}", 69, "\xb6"), "\n\n";
- }
-
- }
- foreach $d (&deps("", "X.rsrc", "::", ":")) {
- next unless $d->{obj};
- print &splitline(sprintf("%s \xc4 %s", $d->{obj}, join " ", @{$d->{deps}}),
- undef, "\xb6"), "\n";
- print "\tRez ", $d->{deps}->[0], " -o {Targ} {ROptions}\n\n";
- }
- foreach $arch (qw(68K CFM68K)) {
- foreach $d (&deps("X.\L$arch\E.o", "", "::", ":")) {
- next unless $d->{obj};
- print &splitline(sprintf("%s \xc4 %s", $d->{obj},
- join " ", @{$d->{deps}}),
- undef, "\xb6"), "\n";
- print "\t{C_$arch} ", $d->{deps}->[0],
- " -o {Targ} {COptions_$arch}\n\n";
- }
- }
- foreach $arch (qw(PPC Carbon)) {
- foreach $d (&deps("X.\L$arch\E.o", "", "::", ":")) {
- next unless $d->{obj};
- print &splitline(sprintf("%s \xc4 %s", $d->{obj},
- join " ", @{$d->{deps}}),
- undef, "\xb6"), "\n";
- # The odd stuff here seems to stop afpd getting confused.
- print "\techo -n > {Targ}\n";
- print "\tsetfile -t XCOF {Targ}\n";
- print "\t{C_$arch} ", $d->{deps}->[0],
- " -o {Targ} {COptions_$arch}\n\n";
- }
- }
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'lcc'}) {
- $mftyp = 'lcc';
- $dirpfx = &dirpfx($makefiles{'lcc'}, "\\");
-
- ##-- lcc makefile
- open OUT, ">$makefiles{'lcc'}"; select OUT;
- print
- "# Makefile for $project_name under lcc.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- # lcc command line option is -D not /D
- ($_ = $help) =~ s/=\/D/=-D/gs;
- print $_;
- print
- "\n".
- "# If you rename this file to `Makefile', you should change this line,\n".
- "# so that the .rsp files still depend on the correct makefile.\n".
- "MAKEFILE = Makefile.lcc\n".
- "\n".
- "# C compilation flags\n".
- "CFLAGS = -D_WINDOWS " .
- (join " ", map {"-I$dirpfx$_"} @srcdirs) .
- "\n".
- "\n".
- "# Get include directory for resource compiler\n".
- "\n";
- print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
- print "\n\n";
- foreach $p (&prognames("G:C")) {
- ($prog, $type) = split ",", $p;
- $objstr = &objects($p, "X.obj", "X.res", undef);
- print &splitline("$prog.exe: " . $objstr ), "\n";
- $subsystemtype = undef;
- if ($type eq "G") { $subsystemtype = "-subsystem windows"; }
- my $libss = "shell32.lib wsock32.lib ws2_32.lib winspool.lib winmm.lib imm32.lib";
- print &splitline("\tlcclnk $subsystemtype -o $prog.exe $objstr $libss");
- print "\n\n";
- }
-
- foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
- print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
- "\n";
- if ($d->{obj} =~ /\.res$/) {
- print &splitline("\tlrc \$(FWHACK) \$(RCFL) -r \$*.rc",69)."\n";
- } else {
- $deflist = join "", map { " -D$_" } @{$d->{defs}};
- print &splitline("\tlcc -O -p6 \$(COMPAT) \$(FWHACK) \$(CFLAGS)".
- " \$(XFLAGS)$deflist ".$d->{deps}->[0]." -o \$\@",69)."\n";
- }
- }
- print "\n";
- print $makefile_extra{'lcc'} || "";
- print "\nclean:\n".
- "\t-del *.obj\n".
- "\t-del *.exe\n".
- "\t-del *.res\n";
-
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'nestedvm'}) {
- $mftyp = 'nestedvm';
- $dirpfx = &dirpfx($makefiles{'nestedvm'}, "/");
-
- ##-- NestedVM makefile
- open OUT, ">$makefiles{'nestedvm'}"; select OUT;
- print
- "# Makefile for $project_name under NestedVM.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- # gcc command line option is -D not /D
- ($_ = $help) =~ s/=\/D/=-D/gs;
- print $_;
- print
- "\n".
- "# This path points at the nestedvm root directory\n".
- "NESTEDVM = /opt/nestedvm\n".
- "# You can define this path to point at your tools if you need to\n".
- "TOOLPATH = \$(NESTEDVM)/upstream/install/bin\n".
- "CC = \$(TOOLPATH)/mips-unknown-elf-gcc\n".
- "\n".
- &splitline("CFLAGS = -O2 -Wall -Werror -DSLOW_SYSTEM -g " .
- (join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
- "\n";
- print &splitline("all:" . join "", map { " $_.jar" } &progrealnames("X"));
- print "\n\n";
- foreach $p (&prognames("X")) {
- ($prog, $type) = split ",", $p;
- $objstr = &objects($p, "X.o", undef, undef);
- $objstr =~ s/gtk\.o/nestedvm\.o/g;
- print &splitline($prog . ".mips: " . $objstr), "\n";
- $libstr = &objects($p, undef, undef, "-lX");
- print &splitline("\t\$(CC) \$(${type}LDFLAGS) -o \$@ " .
- $objstr . " $libstr -lm", 69), "\n\n";
- }
- foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
- $oobjs = $d->{obj};
- $ddeps= join " ", @{$d->{deps}};
- $oobjs =~ s/gtk/nestedvm/g;
- $ddeps =~ s/gtk/nestedvm/g;
- print &splitline(sprintf("%s: %s", $oobjs, $ddeps)),
- "\n";
- $deflist = join "", map { " -D$_" } @{$d->{defs}};
- print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
- " -c \$< -o \$\@\n";
- }
- print "\n";
- print $makefile_extra{'nestedvm'} || "";
- print "\nclean:\n".
- "\trm -rf *.o *.mips *.class *.html *.jar org applet.manifest\n";
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'osx'}) {
- $mftyp = 'osx';
- $dirpfx = &dirpfx($makefiles{'osx'}, "/");
- @osxarchs = ('x86_64');
- my $osxminver = "10.6";
-
- ##-- Mac OS X makefile
- open OUT, ">$makefiles{'osx'}"; select OUT;
- print
- "# Makefile for $project_name under Mac OS X.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- # gcc command line option is -D not /D
- ($_ = $help) =~ s/=\/D/=-D/gs;
- print $_;
- print
- "CC = \$(TOOLPATH)gcc\n".
- "LIPO = \$(TOOLPATH)lipo\n".
- "\n".
- &splitline("CFLAGS = -O2 -Wall -Werror -g " .
- (join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
- "LDFLAGS = -framework Cocoa\n".
- &splitline("all:" . join "", map { " $_" } &progrealnames("MX:U")) .
- "\n";
- print $makefile_extra{'osx'} || "";
- print "\n".
- ".SUFFIXES: .o .c .m\n".
- "\n";
- print "\n\n";
- foreach $p (&prognames("MX")) {
- ($prog, $type) = split ",", $p;
- $icon = &special($p, ".icns");
- $infoplist = &special($p, "info.plist");
- print "${prog}.app:\n\tmkdir -p \$\@\n";
- print "${prog}.app/Contents: ${prog}.app\n\tmkdir -p \$\@\n";
- print "${prog}.app/Contents/MacOS: ${prog}.app/Contents\n\tmkdir -p \$\@\n";
- $targets = "${prog}.app/Contents/MacOS/$prog";
- if (defined $icon) {
- print "${prog}.app/Contents/Resources: ${prog}.app/Contents\n\tmkdir -p \$\@\n";
- print "${prog}.app/Contents/Resources/${prog}.icns: ${prog}.app/Contents/Resources $icon\n\tcp $icon \$\@\n";
- $targets .= " ${prog}.app/Contents/Resources/${prog}.icns";
- }
- if (defined $infoplist) {
- print "${prog}.app/Contents/Info.plist: ${prog}.app/Contents/Resources $infoplist\n\tcp $infoplist \$\@\n";
- $targets .= " ${prog}.app/Contents/Info.plist";
- }
- $targets .= " \$(${prog}_extra)";
- print &splitline("${prog}: $targets", 69) . "\n\n";
- $libstr = &objects($p, undef, undef, "-lX");
- $archbins = "";
- foreach $arch (@osxarchs) {
- $objstr = &objects($p, "X.${arch}.o", undef, undef);
- print &splitline("${prog}.${arch}.bin: " . $objstr), "\n";
- print &splitline("\t\$(CC) -arch ${arch} -mmacosx-version-min=${osxminver} \$(LDFLAGS) -o \$@ " .
- $objstr . " $libstr", 69), "\n\n";
- $archbins .= " ${prog}.${arch}.bin";
- }
- print &splitline("${prog}.app/Contents/MacOS/$prog: ".
- "${prog}.app/Contents/MacOS" . $archbins), "\n";
- print &splitline("\t\$(LIPO) -create $archbins -output \$@", 69), "\n\n";
- }
- foreach $p (&prognames("U")) {
- ($prog, $type) = split ",", $p;
- $libstr = &objects($p, undef, undef, "-lX");
- $archbins = "";
- foreach $arch (@osxarchs) {
- $objstr = &objects($p, "X.${arch}.o", undef, undef);
- print &splitline("${prog}.${arch}: " . $objstr), "\n";
- print &splitline("\t\$(CC) -arch ${arch} -mmacosx-version-min=${osxminver} \$(ULDFLAGS) -o \$@ " .
- $objstr . " $libstr", 69), "\n\n";
- $archbins .= " ${prog}.${arch}";
- }
- print &splitline("${prog}:" . $archbins), "\n";
- print &splitline("\t\$(LIPO) -create $archbins -output \$@", 69), "\n\n";
- }
- foreach $arch (@osxarchs) {
- foreach $d (&deps("X.${arch}.o", undef, $dirpfx, "/")) {
- print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
- "\n";
- $deflist = join "", map { " -D$_" } @{$d->{defs}};
- if ($d->{deps}->[0] =~ /\.m$/) {
- print "\t\$(CC) -arch $arch -mmacosx-version-min=${osxminver} -x objective-c \$(COMPAT) \$(FWHACK) \$(CFLAGS)".
- " \$(XFLAGS)$deflist -c \$< -o \$\@\n";
- } else {
- print "\t\$(CC) -arch $arch -mmacosx-version-min=${osxminver} \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
- " -c \$< -o \$\@\n";
- }
- }
- }
- print "\nclean:\n".
- "\trm -f *.o *.dmg". (join "", map { my $a=$_; (" $a", map { " ${a}.$_" } @osxarchs) } &progrealnames("U")) . "\n".
- "\trm -rf *.app\n";
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'gnustep'}) {
- $mftyp = 'gnustep';
- $dirpfx = &dirpfx($makefiles{'gnustep'}, "/");
-
- ##-- GNUstep makefile (use with 'gs_make -f Makefile.gnustep')
-
- # This is a pretty evil way to do things. In an ideal world, I'd
- # use the approved GNUstep makefile mechanism which just defines a
- # variable or two saying what source files go into what binary and
- # then includes application.make. Unfortunately, that has the
- # automake-ish limitation that it doesn't let you choose different
- # command lines for each object, so I can't arrange for all those
- # files with -DTHIS and -DTHAT to Just Work.
- #
- # A simple if ugly fix would be to have mkfiles.pl construct a
- # directory full of stub C files of the form '#define thing',
- # '#include "real_source_file"', and then reference those in this
- # makefile. That would also make it easy to build a proper
- # automake makefile.
- open OUT, ">$makefiles{'gnustep'}"; select OUT;
- print
- "# Makefile for $project_name under GNUstep.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- # gcc command line option is -D not /D
- ($_ = $help) =~ s/=\/D/=-D/gs;
- print $_;
- print
- "NEEDS_GUI=yes\n".
- "include \$(GNUSTEP_MAKEFILES)/common.make\n".
- "include \$(GNUSTEP_MAKEFILES)/rules.make\n".
- "include \$(GNUSTEP_MAKEFILES)/Instance/rules.make\n".
- "\n".
- &splitline("all::" . join "", map { " $_" } &progrealnames("MX:U")) .
- "\n";
- print $makefile_extra{'gnustep'} || "";
- print "\n".
- ".SUFFIXES: .o .c .m\n".
- "\n";
- print "\n\n";
- foreach $p (&prognames("MX")) {
- ($prog, $type) = split ",", $p;
- $icon = &special($p, ".icns");
- $infoplist = &special($p, "info.plist");
- print "${prog}.app:\n\tmkdir -p \$\@\n";
- $targets = "${prog}.app ${prog}.app/$prog";
- if (defined $icon) {
- print "${prog}.app/Resources: ${prog}.app\n\tmkdir -p \$\@\n";
- print "${prog}.app/Resources/${prog}.icns: ${prog}.app/Resources $icon\n\tcp $icon \$\@\n";
- $targets .= " ${prog}.app/Resources/${prog}.icns";
- }
- if (defined $infoplist) {
- print "${prog}.app/Info.plist: ${prog}.app $infoplist\n\tcp $infoplist \$\@\n";
- $targets .= " ${prog}.app/Info.plist";
- }
- $targets .= " \$(${prog}_extra)";
- print &splitline("${prog}: $targets", 69) . "\n\n";
- $libstr = &objects($p, undef, undef, "-lX");
- $objstr = &objects($p, "X.o", undef, undef);
- print &splitline("${prog}.app/$prog: " . $objstr), "\n";
- print &splitline("\t\$(CC) \$(ALL_LDFLAGS) -o \$@ " . $objstr . " \$(ALL_LIB_DIRS) $libstr \$(ALL_LIBS)", 69), "\n\n";
- }
- foreach $p (&prognames("U")) {
- ($prog, $type) = split ",", $p;
- $libstr = &objects($p, undef, undef, "-lX");
- $objstr = &objects($p, "X.o", undef, undef);
- print &splitline("${prog}: " . $objstr), "\n";
- print &splitline("\t\$(CC) \$(ULDFLAGS) -o \$@ " . $objstr . " $libstr", 69), "\n\n";
- }
- foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
- print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
- "\n";
- $deflist = join "", map { " -D$_" } @{$d->{defs}};
- if ($d->{deps}->[0] =~ /\.m$/) {
- print "\t\$(CC) -DGNUSTEP \$(ALL_OBJCFLAGS) \$(COMPAT) \$(FWHACK) \$(OBJCFLAGS)".
- " \$(XFLAGS)$deflist -c \$< -o \$\@\n";
- } else {
- print "\t\$(CC) \$(ALL_CFLAGS) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
- " -c \$< -o \$\@\n";
- }
- }
- print "\nclean::\n".
- "\trm -f *.o ". (join " ", &progrealnames("U")) . "\n".
- "\trm -rf *.app\n";
- select STDOUT; close OUT;
-}
-
-if (defined $makefiles{'emcc'}) {
- $mftyp = 'emcc';
- $dirpfx = &dirpfx($makefiles{'emcc'}, "/");
-
- ##-- Makefile for building Javascript puzzles via Emscripten
-
- open OUT, ">$makefiles{'emcc'}"; select OUT;
- print
- "# Makefile for $project_name using Emscripten. Requires GNU make.\n".
- "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
- "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
- # emcc command line option is -D not /D
- ($_ = $help) =~ s/=\/D/=-D/gs;
- print $_;
- print
- "\n".
- "# This can be set on the command line to point at the emcc command,\n".
- "# if it is not on your PATH.\n".
- "EMCC = emcc\n".
- "\n".
- &splitline("CFLAGS = -DSLOW_SYSTEM " .
- (join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
- "\n";
- $output_js_files = join "", map { " \$(OUTPREFIX)$_.js" } &progrealnames("X");
- print &splitline("all:" . $output_js_files);
- print "\n\n";
- foreach $p (&prognames("X")) {
- ($prog, $type) = split ",", $p;
- $objstr = &objects($p, "X.o", undef, undef);
- $objstr =~ s/gtk\.o/emcc\.o/g;
- print &splitline("\$(OUTPREFIX)" . $prog . ".js: " . $objstr . " emccpre.js emcclib.js emccx.json"), "\n";
- print "\t\$(EMCC) -o \$(OUTPREFIX)".$prog.".js ".
- "-O2 ".
- "-s ASM_JS=1 ".
- "--pre-js emccpre.js ".
- "--js-library emcclib.js ".
- "-s EXPORTED_FUNCTIONS=\"`sed 's://.*::' emccx.json | tr -d ' \\n'`\" " . $objstr . "\n\n";
- }
- foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
- $oobjs = $d->{obj};
- $ddeps= join " ", @{$d->{deps}};
- $oobjs =~ s/gtk/emcc/g;
- $ddeps =~ s/gtk/emcc/g;
- print &splitline(sprintf("%s: %s", $oobjs, $ddeps)),
- "\n";
- $deflist = join "", map { " -D$_" } @{$d->{defs}};
- print "\t\$(EMCC) \$(CFLAGS) \$(XFLAGS)$deflist" .
- " -c \$< -o \$\@\n";
- }
- print "\n";
- print $makefile_extra{'emcc'} || "";
- print "\nclean:\n".
- "\trm -rf *.o $output_js_files\n";
- select STDOUT; close OUT;
-}
-
-# All done, so do the Unix postprocessing if asked to.
-
-if ($do_unix) {
- chdir $orig_dir;
- system "./mkauto.sh";
- die "mkfiles.pl: mkauto.sh returned $?\n" if $? > 0;
- system "./configure", @confargs;
- die "mkfiles.pl: configure returned $?\n" if $? > 0;
-}
+++ /dev/null
-# -*- makefile -*-
-
-NET_EXTRA = tree234 dsf findloop
-
-net : [X] GTK COMMON net NET_EXTRA net-icon|no-icon
-
-# The Windows Net shouldn't be called `net.exe' since Windows
-# already has a reasonably important utility program by that name!
-netgame : [G] WINDOWS COMMON net NET_EXTRA net.res|noicon.res
-
-ALL += net[COMBINED] NET_EXTRA
-
-!begin am gtk
-GAMES += net
-!end
-
-!begin >list.c
- A(net) \
-!end
-
-!begin >gamedesc.txt
-net:netgame.exe:Net:Network jigsaw puzzle:Rotate each tile to reassemble the network.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-NETSLIDE_EXTRA = tree234
-
-netslide : [X] GTK COMMON netslide NETSLIDE_EXTRA netslide-icon|no-icon
-
-netslide : [G] WINDOWS COMMON netslide NETSLIDE_EXTRA netslide.res|noicon.res
-
-ALL += netslide[COMBINED] NETSLIDE_EXTRA
-
-!begin am gtk
-GAMES += netslide
-!end
-
-!begin >list.c
- A(netslide) \
-!end
-
-!begin >gamedesc.txt
-netslide:netslide.exe:Netslide:Toroidal sliding network puzzle:Slide a row at a time to reassemble the network.
-!end
+++ /dev/null
-/* Puzzle resource file without an icon, used in the absence of icons/foo.rc */
-
-#include "puzzles.rc2"
-
-/* XXX this probably isn't the right test, but it'll do. */
-#ifdef MINGW32_FIX
-/* XXX The MinGW toolchain (specifically, windres) doesn't like a resource
- * file with no resources. Give it a dummy one.
- * This can go if/when VERSIONINFO resources are added. */
-200 RCDATA { 0 }
-#endif
+++ /dev/null
-# -*- makefile -*-
-
-# The `nullgame' source file is a largely blank one, which contains
-# all the correct function definitions to compile and link, but
-# which defines the null game in which nothing is ever drawn and
-# there are no valid moves. Its main purpose is to act as a
-# template for writing new game definition source files. I include
-# it in the Makefile because it will be worse than useless if it
-# ever fails to compile, so it's important that it should actually
-# be built on a regular basis.
-nullgame : [X] GTK COMMON nullgame nullgame-icon|no-icon
-nullgame : [G] WINDOWS COMMON nullgame nullgame.res|noicon.res
* recreate it.
*/
-#define COMBINED /* we put all the puzzles in one binary in this port */
+#ifndef COMBINED
+#error Expected -DCOMBINED to come from the makefile
+#endif
#include <ctype.h>
#include <time.h>
+++ /dev/null
-# -*- makefile -*-
-
-PALISADE_EXTRA = divvy dsf
-
-palisade : [X] GTK COMMON palisade PALISADE_EXTRA palisade-icon|no-icon
-
-palisade : [G] WINDOWS COMMON palisade PALISADE_EXTRA palisade.res|noicon.res
-
-ALL += palisade[COMBINED] PALISADE_EXTRA
-
-!begin am gtk
-GAMES += palisade
-!end
-
-!begin >list.c
- A(palisade) \
-!end
-
-!begin >gamedesc.txt
-palisade:palisade.exe:Palisade:Grid-division puzzle:Divide the grid into equal-sized areas in accordance with the clues.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-pattern : [X] GTK COMMON pattern pattern-icon|no-icon
-
-pattern : [G] WINDOWS COMMON pattern pattern.res|noicon.res
-
-patternsolver : [U] pattern[STANDALONE_SOLVER] STANDALONE
-patternsolver : [C] pattern[STANDALONE_SOLVER] STANDALONE
-
-patternpicture : [U] pattern[STANDALONE_PICTURE_GENERATOR] STANDALONE
-patternpicture : [C] pattern[STANDALONE_PICTURE_GENERATOR] STANDALONE
-
-ALL += pattern[COMBINED]
-
-!begin am gtk
-GAMES += pattern
-!end
-
-!begin >list.c
- A(pattern) \
-!end
-
-!begin >gamedesc.txt
-pattern:pattern.exe:Pattern:Pattern puzzle:Fill in the pattern in the grid, given only the lengths of runs of black squares.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-PEARL_EXTRA = dsf tree234 grid penrose loopgen tdq
-
-pearl : [X] GTK COMMON pearl PEARL_EXTRA pearl-icon|no-icon
-pearl : [G] WINDOWS COMMON pearl PEARL_EXTRA pearl.res?
-
-pearlbench : [U] pearl[STANDALONE_SOLVER] PEARL_EXTRA STANDALONE m.lib
-pearlbench : [C] pearl[STANDALONE_SOLVER] PEARL_EXTRA STANDALONE
-
-ALL += pearl[COMBINED] PEARL_EXTRA
-
-!begin am gtk
-GAMES += pearl
-!end
-
-!begin >list.c
- A(pearl) \
-!end
-
-!begin >gamedesc.txt
-pearl:pearl.exe:Pearl:Loop-drawing puzzle:Draw a single closed loop, given clues about corner and straight squares.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-PEGS_EXTRA = tree234
-
-pegs : [X] GTK COMMON pegs PEGS_EXTRA pegs-icon|no-icon
-
-pegs : [G] WINDOWS COMMON pegs PEGS_EXTRA pegs.res|noicon.res
-
-ALL += pegs[COMBINED] PEGS_EXTRA
-
-!begin am gtk
-GAMES += pegs
-!end
-
-!begin >list.c
- A(pegs) \
-!end
-
-!begin >gamedesc.txt
-pegs:pegs.exe:Pegs:Peg solitaire puzzle:Jump pegs over each other to remove all but one.
-!end
-/* Standard stuff that goes into the Windows resources for all puzzles. */
+/* Windows resource file for all puzzles. */
+
+#if defined ICON_FILE
+200 ICON ICON_FILE
+#else
+#ifdef MINGW32_FIX
+/* XXX The MinGW toolchain (specifically, windres) doesn't like a resource
+ * file with no resources. Give it a dummy one.
+ * This can go if/when VERSIONINFO resources are added. */
+200 RCDATA { 0 }
+#endif
+#endif
#ifdef _WIN32_WCE
+++ /dev/null
-# -*- makefile -*-
-
-RANGE_EXTRA = dsf
-
-range : [X] GTK COMMON range RANGE_EXTRA range-icon|no-icon
-
-range : [G] WINDOWS COMMON range RANGE_EXTRA range.res|noicon.res
-
-ALL += range[COMBINED] RANGE_EXTRA
-
-!begin am gtk
-GAMES += range
-!end
-
-!begin >list.c
- A(range) \
-!end
-
-!begin >gamedesc.txt
-range:range.exe:Range:Visible-distance puzzle:Place black squares to limit the visible distance from each numbered cell.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-rect : [X] GTK COMMON rect rect-icon|no-icon
-
-rect : [G] WINDOWS COMMON rect rect.res|noicon.res
-
-ALL += rect[COMBINED]
-
-!begin am gtk
-GAMES += rect
-!end
-
-!begin >list.c
- A(rect) \
-!end
-
-!begin >gamedesc.txt
-rect:rect.exe:Rectangles:Rectangles puzzle:Divide the grid into rectangles with areas equal to the numbers.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-samegame : [X] GTK COMMON samegame samegame-icon|no-icon
-
-samegame : [G] WINDOWS COMMON samegame samegame.res|noicon.res
-
-ALL += samegame[COMBINED]
-
-!begin am gtk
-GAMES += samegame
-!end
-
-!begin >list.c
- A(samegame) \
-!end
-
-!begin >gamedesc.txt
-samegame:samegame.exe:Same Game:Block-clearing puzzle:Clear the grid by removing touching groups of the same colour squares.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-SIGNPOST_EXTRA = dsf
-
-signpost : [X] GTK COMMON signpost SIGNPOST_EXTRA signpost-icon|no-icon
-signpost : [G] WINDOWS COMMON signpost SIGNPOST_EXTRA signpost.res|noicon.res
-
-signpostsolver : [U] signpost[STANDALONE_SOLVER] SIGNPOST_EXTRA STANDALONE m.lib
-signpostsolver : [C] signpost[STANDALONE_SOLVER] SIGNPOST_EXTRA STANDALONE
-
-ALL += signpost[COMBINED] SIGNPOST_EXTRA
-
-!begin am gtk
-GAMES += signpost
-!end
-
-!begin >list.c
- A(signpost) \
-!end
-
-!begin >gamedesc.txt
-signpost:signpost.exe:Signpost:Square-connecting puzzle:Connect the squares into a path following the arrows.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-SINGLES_EXTRA = dsf LATIN
-
-singles : [X] GTK COMMON singles SINGLES_EXTRA singles-icon|no-icon
-singles : [G] WINDOWS COMMON singles SINGLES_EXTRA singles.res|noicon.res
-
-ALL += singles[COMBINED] SINGLES_EXTRA
-
-singlessolver : [U] singles[STANDALONE_SOLVER] SINGLES_EXTRA STANDALONE
-singlessolver : [C] singles[STANDALONE_SOLVER] SINGLES_EXTRA STANDALONE
-
-!begin am gtk
-GAMES += singles
-!end
-
-!begin >list.c
- A(singles) \
-!end
-
-!begin >gamedesc.txt
-singles:singles.exe:Singles:Number-removing puzzle:Black out the right set of duplicate numbers.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-sixteen : [X] GTK COMMON sixteen sixteen-icon|no-icon
-
-sixteen : [G] WINDOWS COMMON sixteen sixteen.res|noicon.res
-
-ALL += sixteen[COMBINED]
-
-!begin am gtk
-GAMES += sixteen
-!end
-
-!begin >list.c
- A(sixteen) \
-!end
-
-!begin >gamedesc.txt
-sixteen:sixteen.exe:Sixteen:Toroidal sliding block puzzle:Slide a row at a time to arrange the tiles into order.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-SLANT_EXTRA = dsf findloop
-
-slant : [X] GTK COMMON slant SLANT_EXTRA slant-icon|no-icon
-
-slant : [G] WINDOWS COMMON slant SLANT_EXTRA slant.res|noicon.res
-
-slantsolver : [U] slant[STANDALONE_SOLVER] SLANT_EXTRA STANDALONE
-slantsolver : [C] slant[STANDALONE_SOLVER] SLANT_EXTRA STANDALONE
-
-ALL += slant[COMBINED] SLANT_EXTRA
-
-!begin am gtk
-GAMES += slant
-!end
-
-!begin >list.c
- A(slant) \
-!end
-
-!begin >gamedesc.txt
-slant:slant.exe:Slant:Maze-drawing puzzle:Draw a maze of slanting lines that matches the clues.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-SOLO_EXTRA = divvy dsf
-
-solo : [X] GTK COMMON solo SOLO_EXTRA solo-icon|no-icon
-
-solo : [G] WINDOWS COMMON solo SOLO_EXTRA solo.res|noicon.res
-
-solosolver : [U] solo[STANDALONE_SOLVER] SOLO_EXTRA STANDALONE
-solosolver : [C] solo[STANDALONE_SOLVER] SOLO_EXTRA STANDALONE
-
-ALL += solo[COMBINED] SOLO_EXTRA
-
-!begin am gtk
-GAMES += solo
-!end
-
-!begin >list.c
- A(solo) \
-!end
-
-!begin >gamedesc.txt
-solo:solo.exe:Solo:Number placement puzzle:Fill in the grid so that each row, column and square block contains one of every digit.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-TENTS_EXTRA = matching dsf
-
-tents : [X] GTK COMMON tents TENTS_EXTRA tents-icon|no-icon
-
-tents : [G] WINDOWS COMMON tents TENTS_EXTRA tents.res|noicon.res
-
-ALL += tents[COMBINED] TENTS_EXTRA
-
-tentssolver : [U] tents[STANDALONE_SOLVER] TENTS_EXTRA STANDALONE
-tentssolver : [C] tents[STANDALONE_SOLVER] TENTS_EXTRA STANDALONE
-
-!begin am gtk
-GAMES += tents
-!end
-
-!begin >list.c
- A(tents) \
-!end
-
-!begin >gamedesc.txt
-tents:tents.exe:Tents:Tent-placing puzzle:Place a tent next to each tree.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-TOWERS_EXTRA = LATIN
-TOWERS_EXTRA_SOLVER = LATIN_SOLVER
-
-towers : [X] GTK COMMON towers TOWERS_EXTRA towers-icon|no-icon
-
-towers : [G] WINDOWS COMMON towers TOWERS_EXTRA towers.res|noicon.res
-
-towerssolver : [U] towers[STANDALONE_SOLVER] TOWERS_EXTRA_SOLVER STANDALONE
-towerssolver : [C] towers[STANDALONE_SOLVER] TOWERS_EXTRA_SOLVER STANDALONE
-
-ALL += towers[COMBINED] TOWERS_EXTRA
-
-!begin am gtk
-GAMES += towers
-!end
-
-!begin >list.c
- A(towers) \
-!end
-
-!begin >gamedesc.txt
-towers:towers.exe:Towers:Tower-placing Latin square puzzle:Complete the latin square of towers in accordance with the clues.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-TRACKS_EXTRA = dsf findloop
-
-tracks : [X] GTK COMMON tracks TRACKS_EXTRA tracks-icon|no-icon
-
-tracks : [G] WINDOWS COMMON tracks TRACKS_EXTRA tracks.res|noicon.res
-
-ALL += tracks[COMBINED] TRACKS_EXTRA
-
-trackssolver : [U] tracks[STANDALONE_SOLVER] TRACKS_EXTRA STANDALONE
-trackssolver : [C] tracks[STANDALONE_SOLVER] TRACKS_EXTRA STANDALONE
-
-!begin am gtk
-GAMES += tracks
-!end
-
-!begin >list.c
- A(tracks) \
-!end
-
-!begin >gamedesc.txt
-tracks:tracks.exe:Tracks:Path-finding railway track puzzle:Fill in the railway track according to the clues.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-twiddle : [X] GTK COMMON twiddle twiddle-icon|no-icon
-
-twiddle : [G] WINDOWS COMMON twiddle twiddle.res|noicon.res
-
-ALL += twiddle[COMBINED]
-
-!begin am gtk
-GAMES += twiddle
-!end
-
-!begin >list.c
- A(twiddle) \
-!end
-
-!begin >gamedesc.txt
-twiddle:twiddle.exe:Twiddle:Rotational sliding block puzzle:Rotate the tiles around themselves to arrange them into order.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-undead : [X] GTK COMMON undead undead-icon|no-icon
-undead : [G] WINDOWS COMMON undead undead.res|noicon.res
-
-ALL += undead[COMBINED]
-
-!begin am gtk
-GAMES += undead
-!end
-
-!begin >list.c
- A(undead) \
-!end
-
-!begin >gamedesc.txt
-undead:undead.exe:Undead:Monster-placing puzzle:Place ghosts, vampires and zombies so that the right numbers of them can be seen in mirrors.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-UNEQUAL_EXTRA = LATIN
-UNEQUAL_EXTRA_SOLVER = LATIN_SOLVER
-
-unequal : [X] GTK COMMON unequal UNEQUAL_EXTRA unequal-icon|no-icon
-
-unequal : [G] WINDOWS COMMON unequal UNEQUAL_EXTRA unequal.res|noicon.res
-
-unequalsolver : [U] unequal[STANDALONE_SOLVER] UNEQUAL_EXTRA_SOLVER STANDALONE
-unequalsolver : [C] unequal[STANDALONE_SOLVER] UNEQUAL_EXTRA_SOLVER STANDALONE
-
-ALL += unequal[COMBINED] UNEQUAL_EXTRA
-
-!begin am gtk
-GAMES += unequal
-!end
-
-!begin >list.c
- A(unequal) \
-!end
-
-!begin >gamedesc.txt
-unequal:unequal.exe:Unequal:Latin square puzzle:Complete the latin square in accordance with the > signs.
-!end
--- /dev/null
+puzzle(group
+ DISPLAYNAME "Group"
+ DESCRIPTION "Group theory puzzle"
+ OBJECTIVE "Complete the unfinished Cayley table of a group.")
+solver(group ${CMAKE_SOURCE_DIR}/latin.c)
+
+puzzle(separate
+ DISPLAYNAME "Separate"
+ DESCRIPTION "Rectangle-dividing puzzle"
+ OBJECTIVE "Partition the grid into regions containing one of each letter.")
+
+puzzle(slide
+ DISPLAYNAME "Slide"
+ DESCRIPTION "Sliding block puzzle"
+ OBJECTIVE "Slide the blocks to let the key block out.")
+solver(slide)
+
+puzzle(sokoban
+ DISPLAYNAME "Sokoban"
+ DESCRIPTION "Barrel-pushing puzzle"
+ OBJECTIVE "Push all the barrels into the target squares.")
+
+# These unfinished programs don't even have the structure of a puzzle
+# game yet; they're just command-line programs containing test
+# implementations of some of the needed functionality.
+
+cliprogram(numgame numgame.c)
+
+cliprogram(path path.c COMPILE_DEFINITIONS TEST_GEN)
+
+export_variables_to_parent_scope()
half-written, fundamentally flawed, or in other ways unready to be
shipped as part of the polished Puzzles collection.
-Those puzzles which have .R files can be built as part of the
-Puzzles collection by symlinking their source files into the parent
-directory and re-running mkfiles.pl. Anything without a .R file
-isn't even finished enough to do that, and you should read the
-source file itself to find out the status.
+The CMake build system will _build_ all of the source in this
+directory (to ensure it hasn't become unbuildable), but they won't be
+included in all-in-one puzzle binaries or installed by 'make install'
+targets. If you want to temporarily change that, you can reconfigure
+your build by defining the CMake variable PUZZLES_ENABLE_UNFINISHED.
+For example,
+
+ cmake . -DPUZZLES_ENABLE_UNFINISHED="group;slide"
+
+will build as if both Group and Slide were fully official puzzles.
+++ /dev/null
-# -*- makefile -*-
-
-GROUP_EXTRA = LATIN
-GROUP_EXTRA_SOLVER = LATIN_SOLVER
-
-group : [X] GTK COMMON group GROUP_EXTRA group-icon|no-icon
-
-group : [G] WINDOWS COMMON group GROUP_EXTRA group.res|noicon.res
-
-groupsolver : [U] group[STANDALONE_SOLVER] GROUP_EXTRA_SOLVER STANDALONE
-groupsolver : [C] group[STANDALONE_SOLVER] GROUP_EXTRA_SOLVER STANDALONE
-
-ALL += group[COMBINED] GROUP_EXTRA
-
-!begin am gtk
-GAMES += group
-!end
-
-!begin >list.c
- A(group) \
-!end
-
-!begin >gamedesc.txt
-group:group.exe:Group:Group theory puzzle:Complete the unfinished Cayley table of a group.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-SEPARATE_EXTRA = divvy dsf
-
-separate : [X] GTK COMMON separate SEPARATE_EXTRA separate-icon|no-icon
-
-separate : [G] WINDOWS COMMON separate SEPARATE_EXTRA separate.res|noicon.res
-
-ALL += separate[COMBINED] SEPARATE_EXTRA
-
-!begin am gtk
-GAMES += separate
-!end
-
-!begin >list.c
- A(separate) \
-!end
-
-!begin >gamedesc.txt
-separate:separate.exe:Separate:Rectangle-dividing puzzle:Partition the grid into regions containing one of each letter.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-SLIDE_EXTRA = dsf tree234
-
-slide : [X] GTK COMMON slide SLIDE_EXTRA slide-icon|no-icon
-
-slide : [G] WINDOWS COMMON slide SLIDE_EXTRA slide.res|noicon.res
-
-slidesolver : [U] slide[STANDALONE_SOLVER] SLIDE_EXTRA STANDALONE
-slidesolver : [C] slide[STANDALONE_SOLVER] SLIDE_EXTRA STANDALONE
-
-ALL += slide[COMBINED] SLIDE_EXTRA
-
-!begin am gtk
-GAMES += slide
-!end
-
-!begin >list.c
- A(slide) \
-!end
-
-!begin >gamedesc.txt
-slide:slide.exe:Slide:Sliding block puzzle:Slide the blocks to let the key block out.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-sokoban : [X] GTK COMMON sokoban sokoban-icon|no-icon
-
-sokoban : [G] WINDOWS COMMON sokoban sokoban.res?
-
-ALL += sokoban[COMBINED]
-
-!begin am gtk
-GAMES += sokoban
-!end
-
-!begin >list.c
- A(sokoban) \
-!end
-
-!begin >gamedesc.txt
-sokoban:sokoban.exe:Sokoban:Barrel-pushing puzzle:Push all the barrels into the target squares.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-unruly : [X] GTK COMMON unruly unruly-icon|no-icon
-unruly : [G] WINDOWS COMMON unruly unruly.res|noicon.res
-
-unrulysolver : [U] unruly[STANDALONE_SOLVER] STANDALONE
-unrulysolver : [C] unruly[STANDALONE_SOLVER] STANDALONE
-
-ALL += unruly[COMBINED]
-
-!begin am gtk
-GAMES += unruly
-!end
-
-!begin >list.c
- A(unruly) \
-!end
-
-!begin >gamedesc.txt
-unruly:unruly.exe:Unruly:Black and white grid puzzle:Fill in the black and white grid to avoid runs of three.
-!end
+++ /dev/null
-# -*- makefile -*-
-
-UNTANGLE_EXTRA = tree234
-
-untangle : [X] GTK COMMON untangle UNTANGLE_EXTRA untangle-icon|no-icon
-
-untangle : [G] WINDOWS COMMON untangle UNTANGLE_EXTRA untangle.res|noicon.res
-
-ALL += untangle[COMBINED] UNTANGLE_EXTRA
-
-!begin am gtk
-GAMES += untangle
-!end
-
-!begin >list.c
- A(untangle) \
-!end
-
-!begin >gamedesc.txt
-untangle:untangle.exe:Untangle:Planar graph layout puzzle:Reposition the points so that the lines do not cross.
-!end
use warnings;
use HTML::Entities;
-open my $desc, "<", "gamedesc.txt"
- or die "gamedesc.txt: open: $!\n";
+my $gamedesc = shift @ARGV;
+
+open my $desc, "<", $gamedesc
+ or die "$gamedesc: open: $!\n";
open my $spans, ">", "wwwspans.html"
or die "wwwspans.html: open: $!\n";