When I joined Team Fizz over last summer, I was introduced to the awesomeness that is Premake. Shortly after that, this post on Bobby Anguelov’s blog introduced me to FXC and everything awesome that it could bring to the table. I instantly wanted to use it. The problem then became, how I can get Premake to generate projects and include the necessary custom build steps for my shader files to be able to utilize FXC? I figured this would be a pretty common issue for people and it would either be intuitive to setup or there would be a lot of information online on how to make it happen. I was completely wrong on both counts and I wasn’t able to make this work until just last night.
Semi-recently, Premake added support for two features that I felt could potentially solve my issue. The buildrule function was supposed to allow me to set a custom build rule to files based on a configuration declaration, and this sounded like it would directly be the solution I was looking for. I could just have the shader files in my project, the configuration declaration could look for files based on extension to apply the build rule to, and everything would work. I’m not sure if we just didn’t set it up properly (the documentation for this feature isn’t great) or it just doesn’t work right, but it didn’t do what I needed it to.
The second option was project reference through the external function. While less optimal, the plan was to manually create a project for my shaders, set the custom build tool on each shader file to use FXC, and then have Premake just add this project into the sln when it creates and links in all other projects. This is what ended up working for me, so I thought I would document what I did in case anyone else runs into this issue. I know I would have appreciated it about 6 months ago.
In your build script, assuming a current enough version of Premake, you can use the external command to reference a pre-existing project into the sln being made. Just slide the command in anywhere that you would add “project” for a project that you wanted Premake to autogenerate, and make sure that you add the name to the startup project’s links so that the proper build dependency is made. Here is what mine looks like:
Shader is the name of my vcxproj, which is what comes after external. It’s also in a folder named Shader at the root of my sln directory, which is what goes in location. Setting the kind to StaticLib (and making sure you actually set the project to match) might not be necessary, but it fit the rest of the architecture of our engine. Uuid can be found by opening your vcxproj in notepad and looking for this:
Once you have the project made, setup, and your buildscript ready, you just need to setup your shader files’ properties to use FXC. The link to Bobby’s blog from earlier in this post completely details the process so I won’t repeat it here.
So, there you have it. I won’t say this is the best way to accomplish what I wanted, or even necessarily a good way, but it’s a way and it works for me. Hopefully if anyone finds themselves in the situation I was in, it will be helpful. And if anyone has a better way to solve this, please let me know; I would love to get that kind of feedback and improve things.