Closed DanRStevens closed 1 year ago
Was thinking it might be interesting to define a list of projects, with some config data, and then include a generic makefile that would setup dependency and build rules for them. The included makefile could automatically create target and dependency information based on variables, rather than only providing methods to be called to setup the projects.
One thought for that was to scan for variables with a given name pattern, which might be used to configure project settings. It seems GNU make allows for that possibility using the built-in .VARIABLES
variable:
6.14 Other Special Variables
Unfortunately, .VARIABLES
is GNU make only, with no support for it from Posix make.
It would still be possible to use a fixed variable name to define a list of projects, and then project specific variables for any needed config. Example:
ProjectNames := nas2d test testGraphics
ProjectConfig_test_dependsOn := nas2d
ProjectConfig_testGraphics_dependsOn := nas2d
include makefile-generic.mk
Once the project names are known, config could be accessed using 6.3.2 Computed Variable Names, such as $(ProjectConfig_$(ProjectName)_dependsOn)
.
Will probably want to use simpler names for project specific config than in the above example.
Hopefully defaults can be set such that explicit config isn't generally required. Perhaps the type of output could be assumed based on the project name. For instance, if a project name starts or ends with "lib", then the output may default to a static library. If the project name starts or ends with "dll", then the output may default to a DLL (Windows) or Shared Object (Linux). Otherwise the project could default to output an executable file.
A slight complication is that some projects can be compiled as either a static library or a DLL. That would be a configuration issue though, and not something I've really addressed yet in the context of a makefile.
Compiler flags, such as CXXFLAGS
should probably be used as a global default, with the ability to override if there is a project specific version of the flags defined.
So the portability situation is perhaps a little worse than I initially expected. It seems Posix make doesn't support the foreach
syntax offered by GNU make, and GNU Make doesn't support the .for
syntax offered by bmake
/pmake
(BSD make).
There is a possible workaround using the shell, as illustrated on StackOverflow: Designing a portable makefile loop
run: $(PROGS) for p in $(PROGS); do ./$$p; done
Edit:
Looks like other functions, such as call
and eval
are also not available with other variants of make.
Given the different implementations of make
, and the limitations of many of them, it doesn't look to be reasonable to dynamically generate full project config from minmal metadata while also maintaining portability across different platforms and the implementations of make
that they provide. Given that, I think the recent improvements are about as good as can be expected for the moment, this this Issue is probably worth closing now.
The current
makefile
doesn't really clearly define projects. It has targets for the different projects, though each project is mostly a duplicate block of similar code. It may make sense to extract out the common aspects of a project to help de-duplicate themakefile
, and to make it easier to add new projects.In particular, if the
makefile
could be made more generic, it can be re-used to simplify downstream projects such as OPHD, which may be split into multiple projects (https://github.com/OutpostUniverse/OPHD/issues/1191, https://github.com/OutpostUniverse/OPHD/issues/903), and so could make use of a high level concept of a project.There is an existing
makefile
in the op2ext project which may be of use:The problem with
makefile-generic.mk
is that it's reliant of GNU make, as opposed to Posix make, and our current MacOS build relies on the nativemake
found on MacOS, which is Posix make.The specific error seems to be with the use of
define
, for creating multiline variables, which doesn't seem to be supported with Posix make:It may be possible to do something similar to the above
makefile-generic.mk
, but avoiding the use ofdefine
. Perhaps using more individual variables andforeach
to iterate over them could be an alternate solution.Some possibly relevant sections of the GNU make manual may provide some inspiration:
The section on the
eval
function is particularly interesting. It gives an example using all of the above, includingdefine
, and ties it all together with: