编写大项目的时候,大部分文件可以复用,但构建项目的软件,使用的平台,可使用的外部资源因各种各不相同,所以大部分时候最好编写一些预编译规则来方便其它平台、软件的人构建项目。
常见的是CMake,不过编写的规则感觉有些复杂,这里推荐一个开源库Premake,规则使用lua脚本编写,使用规则构建项目时也很简单。
直接去github下载发行版就行,将premake5.exe
程序放在自定义的一个文件夹里,之后在自己的项目根目录建立一个名为premake5.lua
的文件。具体编写方法在github主页可以看到,这里给出我目前的lua脚本:
workspace "Dragon"
architecture "x64"
startproject "Sandbox"
configurations
{
"Debug",
"Release",
"Dist"
}
workdspace
是当前项目根目录名,architecture
指定系统架构,因为我们设置的两个项目,Sandbox
为启动项目。configurations
指定各种调试版本。
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
IncludeDir = {}
IncludeDir["GLFW"] = "Dragon/vendor/GLFW/include"
IncludeDir["GLAD"] = "Dragon/vendor/GLAD/include"
IncludeDir["ImGui"] = "Dragon/vendor/ImGui"
IncludeDir["glm"] = "Dragon/vendor/glm"
IncludeDir["stb_image"] = "Dragon/vendor/stb_image"
IncludeDir["Assimp"] = "Dragon/vendor/Assimp/include"
include "Dragon/vendor/GLFW"
include "Dragon/vendor/GLAD"
include "Dragon/vendor/ImGui"
outputdir
是输出目录,它的格式为:
InCludeDir
可以类比于python中的字典,这里用于创建一些外置库的路径。
include
设置默认包含的外接库。
project "Dragon"
location "Dragon"
kind "StaticLib"
language "C++"
cppdialect "C++17"
staticruntime "on"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
pchheader "dgpch.h"
pchsource "Dragon/src/dgpch.cpp"
files
{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp",
"%{prj.name}/vendor/stb_image/**.h",
"%{prj.name}/vendor/stb_image/**.cpp",
"%{prj.name}/vendor/glm/glm/**.hpp",
"%{prj.name}/vendor/glm/glm/**.inl",
"%{prj.name}/vendor/Assimp/include/assimp/**.hpp",
"%{prj.name}/vendor/Assimp/include/assimp/**.h",
"%{prj.name}/vendor/Assimp/include/assimp/**.inl"
}
defines
{
"_CRT_SECURE_NO_WARNINGS"
}
includedirs
{
"%{prj.name}/src",
"%{prj.name}/vendor/spdlog/include",
"%{IncludeDir.GLFW}",
"%{IncludeDir.GLAD}",
"%{IncludeDir.ImGui}",
"%{IncludeDir.glm}",
"%{IncludeDir.stb_image}",
"%{IncludeDir.Assimp}"
}
links
{
"GLFW",
"GLAD",
"ImGui",
"opengl32.lib"
}
filter "system:windows"
systemversion "latest"
defines
{
"DG_PLATFORM_WINDOWS",
"DG_BUILD_DLL",
"GLFW_INCLUDE_NONE"
}
filter "configurations:Debug"
defines "DG_DEBUG"
runtime "Debug"
symbols "on"
filter "configurations:Release"
defines "DG_RELEASE"
runtime "Release"
optimize "on"
filter "configurations:Dist"
defines "DG_DIST"
runtime "Release"
optimize "on"
Dragon项目,project
指定项目名称,location
是项目的文件夹位置,kind
是要指定的库的类型,有动态库和静态库,这里使用静态库,也就是StaticLib
,对应staticruntime
开启,language
指定开发使用的语言,cppdialect
指定要使用的C++标准。targetdir
是输出的文件夹,里面包含lib文件,objdir
是中间文件输出的文件夹。pchheader
是预编译头文件,pchsource
是预编译文件源。files
中指定要包含进项目的文件,defines
是一些预处理命令,这里是为了防止老一点的库警告。includedirs
指定包含文件目录,links
指定要链接的库文件和项目。filter
可以用于修饰不同系统,这里暂时只考虑windows,也可用于不同的项目生成版本,debug、release、dist等。
project "Sandbox"
location "Sandbox"
kind "ConsoleApp"
language "C++"
cppdialect "C++17"
staticruntime "on"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
files
{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp"
}
includedirs
{
"Dragon/vendor/spdlog/include",
"Dragon/src",
"Dragon/vendor",
"%{IncludeDir.glm}",
"%{IncludeDir.GLAD}",
}
links
{
"Dragon",
"GLAD",
"opengl32.lib"
}
filter "system:windows"
systemversion "latest"
defines
{
"DG_PLATFORM_WINDOWS"
}
filter "configurations:Debug"
defines "DG_DEBUG"
runtime "Debug"
symbols "on"
filter "configurations:Release"
defines "DG_RELEASE"
runtime "Release"
optimize "on"
filter "configurations:Dist"
defines "DG_DIST"
runtime "Release"
optimize "on"
Sandbox项目类似,只不过它生成的是exe文件,是控制台程序,其它大部分类似。
同时,如果我们包含了其它的外接项目,如GLFW,GLAD:
我们可以对这些外接项目文件设置
premake5.lua
文件,来方便在主premake5.lua
中调用这些外接项目。
GLFW:
project "GLFW"
kind "StaticLib"
language "C"
staticruntime "on"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
files
{
"include/GLFW/glfw3.h",
"include/GLFW/glfw3native.h",
"src/glfw_config.h",
"src/context.c",
"src/init.c",
"src/input.c",
"src/monitor.c",
"src/vulkan.c",
"src/window.c"
}
defines
{
"_CRT_SECURE_NO_WARNINGS"
}
filter "system:windows"
systemversion "latest"
files
{
"src/win32_init.c",
"src/win32_joystick.c",
"src/win32_monitor.c",
"src/win32_time.c",
"src/win32_thread.c",
"src/win32_window.c",
"src/wgl_context.c",
"src/egl_context.c",
"src/osmesa_context.c"
}
defines
{
"_GLFW_WIN32"
}
filter "configurations:Debug"
runtime "Debug"
symbols "on"
filter "configurations:Release"
runtime "Release"
optimize "on"
这样我们可以在构建项目时自动编译GLFW项目。
GLAD:
project "GLAD"
kind "StaticLib"
language "C"
staticruntime "on"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
files
{
"include/glad/glad.h",
"include/KHR/khrplatform.h",
"src/glad.c"
}
includedirs
{
"include"
}
filter "system:windows"
systemversion "latest"
filter "configurations:Debug"
runtime "Debug"
symbols "on"
filter "configurations:Release"
runtime "Release"
optimize "on"
ImGui:
project "ImGui"
kind "StaticLib"
language "C++"
cppdialect "C++17"
staticruntime "on"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
files
{
"imconfig.h",
"imgui.h",
"imgui.cpp",
"imgui_draw.cpp",
"imgui_internal.h",
"imgui_widgets.cpp",
"imstb_rectpack.h",
"imstb_textedit.h",
"imstb_truetype.h",
"imgui_demo.cpp"
}
filter "system:windows"
systemversion "latest"
filter "configurations:Debug"
runtime "Debug"
symbols "on"
filter "configurations:Release"
runtime "Release"
optimize "on"
为方便编译整个项目,我们编写一个批处理文件GenerateProjects.bat
:
call vendor\bin\premake\premake5.exe vs2019
PAUSE
call
后的路径为premake5.exe
程序路径,然后最后为IDE的类型,PAUSE
方便我们在终端查看项目编译是否成功以及查看错误信息。
使用这种编译方式的好处是,我们上传文件到github等平台时,我们可以删除所有和VS或其它IDE使用的特殊文件,删除所有中间文件,只留下所有编译项目使用的源文件即可,比如我的项目根目录:
下一节进入重头戏,渲染模块。
项目github地址:https://github.com/Dragon-Baby/Dragon
网友评论