Take a very close look at LsCs. It is a fork of CopperSpice which is a fork of Qt 4.8-ish. It dynamically configures what it builds based on what the system has. Lots of plugins. You probably also want to take a close look at the cmake directory. Probably this file in particular.
All of your “repetitive code” can go into “functions”, or at least most of it can. That which cannot can just be in a .cmake stub file that the other cmake files includes.
Every tragedy in IT will be repeated at least 3 different times on at least 3 different platforms if you live long enough.
During the days interpreted BASIC on PDP-11 and MAI BASIC/4 machines we were notorious for %INCLUDE of entire programs or just a range of line numbers from them. (God forbid somebody renumber the source!) Even more notorious, because it was billed as a safety feature, was writing programs that immediately exited. To get them to actually do anything you had to CHAIN to a specific line number.
Enter interpreted languages on PCs. Once again, it is the Wild Wild West!
If only the scripted languages had line numbers so we could play our cruelest games!
If you refactor your entire project around the concept of
“Write it once”
cutting anything replicated out into a common includable .cmake file, things should get cleaner for you.