Premake自动项目生成
项目生成到底有什么意义呢?为什么不直接使用Visual Studio来做项目?
当我们不得不处理不同的平台的时候,就会出现弊端了。此时我们只能够处理windows上的Visual Studio文件,我们还有解决方案文件,有VcXproj文件,那些是C++项目文件,但这些都是Hazel引擎在windows上的。一旦我们涉及到linux环境,Mac环境,或者其他的就会出问题。
下载Premake和基本配置
确切的说,我们需要为我们的引擎生成项目文件,这些文件可以与工具集配合使用编译这些应用程序。
https://github.com/premake/premake-core/

选择下载:premake-5.0.0-alpha13-windows.zip
首先我们在项目首页创建一个vendor文件夹,这个vendor文件夹和Hazel里面的vendor不一样,里面的vendor文件夹仅是她所需的东西,这些和我们的资料无关,而是在整个解决方案中所需要的。


在vendor里面创建一个bin文件夹,再创建一个premake文件夹,并把我们刚下载的premeke5.exe扔进去:

【记得下载许可证,LICENSE.txt文件和premake.exe放在同级目录即可!】
在Premake的Github的Wiki部分有相关的介绍,如何使用Premake。


在Hazel里面创建好一个premake5.lua,我们开始编写代码:
premake.lua
workspace "Hazel"
architecture "x64"
configurations
{
"Debug",
"Release",
"Dist"
}
写到这里,我们可以发现被设置为Hazel,然后需要配置64位操作系统,并且会有三个分别为”Debug”,”Release”,”Dist”,分别是调试,比调试更快的一个版本,完整的发行版。
具体项目Hazel的配置

在Project下面,我们需要放入一些属性中的内容,比如我们的预处理器等。但是此时我们要注意到,Project “Hazel”这个实际上是我们在解决方案Hazel目录下的一个Hazel,所以我们需要确定路径,使用location "Hazel"。
确定文件类型,使用kind "SharedLib",用于指明它是一个动态链接库文件。
指定语言类型,使用language "C++",表示是C++编写的。

可以在仓库中找到一个Tokens的地方,找到可以用的宏
通过代码outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"我们可以实现做一个类似-Debug-Windows-X64的东西。
同时确定我们要输出的目录,也就是targetdir,还有中间目录objdir
files文件则是
includedirs取决于附加包含目录

filter是条件过滤,这里是让其只对windows有效。
cppdialect则是选择对应的C++版本,避免默认编译器使用C++14的标准。
staticruntime “On”(暂时不明,学习的知识不够我了解)
systemversion需要定义为Windows SDK版本,如果不输入的话就会默认是8.1的版本,本机需要有这个版本才可以,不然会找不到。

defines则会开始使用我们预处理器,这里不清楚是否使用了_WINDLL,所以先不用。
下面再写一个postbuildcommands,用来做“每次我们启动的时候将Hazel.dll复制进Sandbox文件夹”的操作。
下面这一个filter则是我们要做的调试的条件过滤,注意这里并不是windows+Debug,这里只是单纯的Debug而已,如果两项操作要一起进行那么必须指定两种过滤选项。
premake.lua
workspace "Hazel"
architecture "x64"
configurations
{
"Debug",
"Release",
"Dist"
}
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
project "Hazel"
location "Hazel"
kind "SharedLib"
language "C++"
targetdir ("bin/".. outputdir .. "/%prj.name")
objdir ("bin-int/".. outputdir .. "/%prj.name")
files
{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp"
}
includedirs
{
"%{prj.name}/vendor/spdlog/include"
}
filter "system:windows"
cppdialect "c++17"
staticruntime "On"
systemversion "10.0.22621.0"
defines
{
"HZ_PLATFORM_WINDOWS",
"HZ_BUILD_DLL"
}
postbuildcommands
{
("{COPY} %{cfg.buildtarget.relpath} ../bin/" .. outputdir .. "/Sandbox")
}
filter "configurations:Debug"
defines "HZ_DEBUG"
symbols "On"
filter "configurations:Release"
defines "HZ_RELEASE"
symbols "On"
filter "configurations:Dist"
defines "HZ_DIST"
symbols "On"
这就是Hazel项目的配置,可以用相同的方式去配置Sandbox
Sandbox的配置和最终测试
依旧是继续写下来,需要注意的是location有所更改,includedirs多了一个Hazel/src,并且预处理器少了一个。由于Sandbox需要连接Hazel,所以需要写有关于链接的命令。
project "Sandbox"
location "Sandbox"
kind "ConsoleApp"
language "C++"
targetdir ("bin/".. outputdir .. "/%prj.name")
objdir ("bin-int/".. outputdir .. "/%prj.name")
files
{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp"
}
includedirs
{
"%{prj.name}/vendor/spdlog/include",
"Hazel/src"
}
links
{
"Hazel"
}
filter "system:windows"
cppdialect "c++17"
staticruntime "On"
systemversion "10.0.22621.0"
defines
{
"HZ_PLATFORM_WINDOWS"
}
filter "configurations:Debug"
defines "HZ_DEBUG"
symbols "On"
filter "configurations:Release"
defines "HZ_RELEASE"
symbols "On"
filter "configurations:Dist"
defines "HZ_DIST"
symbols "On"
接下来我们可以删除掉主页的bin和bin-int文件,将Hazel和Sandbox里面除了src和vendor文件夹之外的都删掉,包括Hazel.sln也删掉。
在Hazel工程中船创建一个GenerateProjects.bat批处理文件,内容为:
call vendor\bin\premake\premake5.exe vs2017
PAUSE
此时,直接执行该批处理文件!

会帮我们重新创建好工程!
构建的时候遇见的BUG和解决方案
问题一:因为我直接运行的时候使用的VisualStdio跑的,默认是运行的Hazel这个dll文件。
出现此问题是因为直接运行了dll,这是一个动态运行库,方案一是直接构建,然后打开文件夹去运行Sandbox.exe。方案二应该就是修改设为启动项目就好了。
问题二:经典的utf-8报SPDLOG的错,之前已经解决过一次了不说了。
问题三:超级难绷的构建问题,因为本文是跟着教程走的,貌似可能是因为Premake选择的版本比较低,无法构建vs2022版本的,所以是构建2017然后升级为2022,会报错工具v141的bug,这个时候打开属性,点击平台工具集就行

问题四:找不到SPDLOG的头文件
我很奇怪,但是估计是可能视频里面看错了,我把Premake.lua里面改了一下就行,就是改Sandbox的内容(后面果然作者也改了)
includedirs
{
"Hazel/vendor/spdlog/include",
"Hazel/src"
}
神秘BUG:
构建的时候是以VS2017来构建的,我目前的电脑是VS2022,进入sln项目后,然后我要先把VS2017的平台工具集v141改成v143,然后因为用到一个日志文件库spdlog,要手动加一个/utf-8。然后这俩一起加上去就直接卡死主线程,无法编译bin。
我现在不输入/utf-8,编译一半就会帮我把这个卡死的主线程因为检测到utf-8报错,直接帮我把主线程退出来,然后我再输入/utf-8,就能成功编译了。


