build-cpp / cmkr

Modern build system based on CMake and TOML.
https://cmkr.build
MIT License
439 stars 27 forks source link

Add support for target templates #47

Closed cursey closed 2 years ago

cursey commented 2 years ago

Hi again! I work on a project called REFramework and my colleague expressed interest in converting it's build files over to cmkr after seeing me use it on a few of my personal projects.

While going through the process of converting the build files over to cmake.toml I realized I was duplicating a lot of stuff for each target. The way the project is structured generates individual builds for each game the project supports with only minor differences between each target. Having a "template" of what each target looks like would decrease the amount of duplicated toml, and so I added it.

Here's what it looks like (example):

# A project using templates.

[project]
name = "templates"
description = "Template example"

[template.app]
type = "executable"
sources = ["src/templates.cpp"]
compile-definitions = ["IS_APP=true"]

[target.app-a]
template = "app"
compile-definitions = ["APP_A"]

[target.app-b]
template = "app"
compile-definitions = ["APP_B"]

For a more complex example check out cmake.toml from REFramework (WIP).

mrexodia commented 2 years ago

Hi,

Thanks for your contribution! This actually has been something I’ve been wanting to implement for a while so thanks!

I’ll review the code a bit better tomorrow, but from your example it looks like you may actually want to use an interface target and link to that, it wouldn’t require a template.

mrexodia commented 2 years ago

Could you push your cmake.toml files for your project so I can take a look?

cursey commented 2 years ago

Could you push your cmake.toml files for your project so I can take a look?

The link @ the bottom of my post should have gone to it (I did it on a personal fork since it's very a very work-in-progress change). Here it is again just in case: https://github.com/cursey/REFramework/blob/cmkr/cmake.toml

cursey commented 2 years ago

but from your example it looks like you may actually want to use an interface target and link to that, it wouldn’t require a template.

I think you're right about this 🤦‍♀️ (not very familiar with interface targets outside of header-only libraries). I'm not sure there is much need for this PR in that case unless there is some other use case I'm missing.

mrexodia commented 2 years ago

My bad, I didn’t see your link 🤦‍♂️ With regards to the interface, I think this is a documentation issue. I’ll keep this in mind when writing the missing page about the terms used in cmake/cmkr.

I will take a look at all my cmkr projects again, I’m pretty sure there is a use but it involves cmake-after. From what I remember I wanted to do this to declare a “pintool” or “driver” or “qt” target type because those all use some custom cmake scripts that do magic things to the target.

cursey commented 2 years ago

I think I've found another use for templates. Target properties do not seem to apply through INTERFACE targets, but they do with templates. You can also do some interesting things with cmake-before and templates:

[template.game]
# ...
compile-definitions = [ "${GAME_NAME}" ]

[target.re2]
template = "game"
cmake-before = "SET(GAME_NAME RE2)"

Check https://github.com/cursey/REFramework/blob/cmkr/cmake.toml for full example. After using them more I'm convinced this template PR provides some value over INTERFACE targets.

mrexodia commented 2 years ago

I fixed the CI in the main branch, if you rebase on that we can see if the checks pass.

cursey commented 2 years ago

I've tried to implement the changes you requested. I've also included a test that builds a driver using FindWdk.cmake and templates. Let me know what you think.

mrexodia commented 2 years ago

Thanks! I will review it properly when I have some more time 🙂

mrexodia commented 2 years ago

Thanks a lot for your contribution!

Locally I created a bit more exhaustive test (cmkr_template_test.zip if you're interested), added error handling and fixed some minor bugs. I also removed the driver example for now because there isn't a way to integrate it nicely and I added the templates test so that the documentation is generated. Probably I will do a full-fledged driver example in the build-cpp organization later.

mrexodia commented 2 years ago

I released v0.2.6