premake5脚本介绍(lua)

1、premake5介绍
Premake :https://github.com/premake/premake-core
使用 Premake,开发者可以通过编写简单的 Lua 脚本来描述项目的结构和构建选项。Premake 会根据这些脚本生成特定平台(如 Windows、Linux、Mac 等)的项目文件和构建脚本,例如 Visual Studio 的 .sln 文件、Makefile 或 Xcode 的 .xcodeproj 文件等。

下载最新的windows release版本,不需要自己编译

解压后,只需要其中的premake.exe文件,放在项目路径中

完整的使用教学可以参考wiki

tokens,列出了所有预定义的变量,供我们使用,用法类似于vs中项目设置里的宏(ProjectDir 、SolutionDir、ProjecName等等),不同的地方是vs中取值用$(),premake中用%{}

postbuildcommants,可以使用编译后命令来复制文件(如.dll)到.exe文件目录下

这是wiki的第一个premake使用示例

/* hello.c */
#include <stdio.h>

int main(void) {
   puts("Hello, world!");
   return 0;
}
在项目中创建一个文件 premake5.lua

workspace "HelloWorld"   -- 解决方案名称
   configurations { "Debug", "Release" }

project "HelloWorld"
   kind "ConsoleApp"    -- 项目类型为可执行程序
   language "C"
   targetdir "bin/%{cfg.buildcfg}" -- 编译输出路径

   files { "**.h", "**.c" }        -- 所有子文件夹中的所有.h .c文件,递归抓取

   filter "configurations:Debug" -- 针对debug和release配置下的一些特定的设置
      defines { "DEBUG" }        -- 预定义的宏
      symbols "On"

   filter "configurations:Release"
      defines { "NDEBUG" }
      optimize "On"

2、案例1
所有项目用一个位于解决方案目录的premake5.lua脚本进行维护

假设解决方案名称为MySolution,其中有两个项目,第一个MyProject1 是生成动态链接库供第二个项目MyApp使用

workspace "MySolution"            -- 解决方案名称
    architecture "x64"   
    
    configurations
    {
        "Debug",
        "Release",    
        "Dist"
    }
-- 输出路径变量:结构类似于 debug-windows-x64    
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.arcchitecture}"   

project "MyProject1"         -- 项目名称
    location "MyProject1"
    kind "SharedLib"         -- DLL
    language "C++"

    targetdir ("bin/" .. outputdir .. "/%{prj.name}") -- lua的字符串拼接方式 ..
    objdir ("bin-int/" .. outputdir .. "/%{prj.name}") -- 编译中间产物存放路径
    
    files                                   -- 包含项目下所有的.h .cpp文件
    {
        "%{prj.name}/src/**.h",    
        "%{prj.name}/src/**.cpp"
    }

    include
    {
        "%{prj.name}/3rd/glfw/include"
    }

    filter "system:windows" --对特定的系统(windows、OS..)、配置(Debug/Release)、平台(x64、x86)的项目属性
        cppdialect "C++17"  --C++特性版本
        staticruntime "On"  
        systemversion "10.0.22000.0"    -- windows SKD版本

        defines
        {
            "PLATFORM_WINDOWS",
            "BUILD_DLL"
        }

        postbuildcommands    -- 后构建命令,构建完毕后执行的操作
        {
            -- 拷贝本项目输出文件中的dll到指定文件夹中
            ("{COPY} %{cfg.buildtarget.relpath} ../bin/" .. outputdir .. "/MyApp")
        }

    filter "configurations:Debug"
        defines "_DEBUG"
        symbols "On"

    filter "configurations:Release"
        defines "_RELEASE"
        optimize "On" 

    filter "configurations:Dist"
        defines "_DIST"
        optimize "On"
    -- 可以过滤多个选项,一起配置
    -- filter {"system:windows", "configurations:Release"}
    --     buildoptions "/MT"

project "MyApp"
    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"
    }

    include
    {
        "%{prj.name}/vendor/spdlog/include",
        "MyProject1/src"
    }

    links        --链接库
    {
        "MyProject1"
    }

    filter "system:windows" 
        cppdialect "C++17" 
        staticruntime "On"  
        systemversion "10.0.22000.0" 

        defines
        {
            "PLATFORM_WINDOWS"
        }

    filter "configurations:Debug"
        defines "_DEBUG"
        symbols "On"

    filter "configurations:Release"
        defines "_RELEASE"
        optimize "On" 

    filter "configurations:Dist"
        defines "_DIST"
        optimize "On"

之后在解决方案路径下打开CMD,输入 call premake5.exe vs2022 即可。

premake5.exe如果不在同一路径下,则在前面加上它的相对路径如:call premake/premake.exe vs2022;
目标vs版本可以自己选择
说明:

( 和 ):这是Lua编程语言中用于创建一个包含多个元素的表(table)的语法。在这里,括号内的内容表示一个表,里面包含了一个要执行的命令。
".....": 这是Lua中的字符串,如"… outputdir …" 表示把引号之间的内容变成字符串,并与两边的字符串相连
{COPY}: 这是一个占位符,通常在构建系统中用于表示某种特定的操作。在这里,它表示复制操作。
%{cfg.buildtarget.relpath}: 这是一个用于获取构建目标的相对路径的变量。cfg 是一个表示当前配置的变量,buildtarget 表示构建目标(编译生成的文件),relpath 表示相对路径。所以这个表达式会被替换为构建目标的相对路径。
../bin/ … outputdir … “/MyApp”: 这是构建目标的输出路径。../bin/ 表示输出目录的上一级目录,outputdir 是一个变量,表示构建时指定的输出目录(可能是Debug或Release等),"/MyApp" 则是输出文件的名称和路径。
3、案例2
如果还需要链接其他库,可以在解决方案目录的premake脚本里继续添加库项目,但是更好的处理大型项目(包含多个子项目)的方式是采用一定的组织和规划。当项目结构变得更复杂时,你可以考虑将每个子项目都单独创建一个premake脚本来维护,然后在顶级解决方案的premake脚本中引用它们。这种方法可以帮助你更好地组织和管理项目。

项目结构如下:

mySolution/
    myApp/
        src/
        include/
        premake5.lua  -- myApp 的 Premake 脚本
    mylib1/
        src/
        include/
        premake5.lua  -- mylib1 的 Premake 脚本
    mylib2/
        src/
        include/
        premake5.lua  -- mylib2 的 Premake 脚本

在顶级解决方案的premake脚本(例如,MySolution/premake5.lua)中,你可以引用每个子项目的premake脚本,如下所示:

-- 配置解决方案名称
solution "MySolution"    -- 在visual studio中solution和workspace是一个意思

-- 配置全局设置,如构建类型、目标目录等
configurations { "Debug", "Release" }
targetdir ("bin/%{cfg.buildcfg}")

-- 包括 myApp 项目的配置
dofile("myApp/premake5.lua")

-- 包括 mylib1 项目的配置
dofile("mylib1/premake5.lua")

-- 包括 mylib2 项目的配置
dofile("mylib2/premake5.lua")

-- 可以在解决方案级别添加全局配置

接下来,你可以为每个子项目创建单独的Premake脚本,以定义项目的构建配置。例如,myApp/premake5.lua 可能如下所示:

-- 定义 myApp 项目
project "myApp"
    location "myApp"
    kind "ConsoleApp"
    language "C++"

    -- myApp 项目的源文件和头文件
    files
    {
        "src/**.cpp",
        "include/**.h"
    }

    -- 包括子项目的头文件目录
    includedirs
    {
        "../mylib1/include",
        "../mylib2/include"
    }

    -- 链接子项目(mylib1 和 mylib2)
    links
    {
         "mylib1",
         "mylib2" 
    }

    -- 配置编译选项、链接选项等

类似地,你可以在每个子项目的premake脚本中定义项目的构建配置。

通过将每个子项目都单独维护其自己的premake脚本,然后在顶级解决方案的premake脚本中引用它们,你可以更好地组织和管理项目的配置,特别是在项目结构变得更加复杂时。这种方法允许你将每个项目的配置独立管理,从而提高了可维护性。

/

一、脚本例子

1、如下脚本,保存为premake5.lua

-- premake5.lua
    workspace "HelloWorld" --解决方案名称
       configurations { "Debug", "Release" } --解决方案配置项
     
    project "HelloWorld" --项目名称
       kind "ConsoleApp" --项目类型
       language "C"      --使用语言
       targetdir "bin/%{cfg.buildcfg}" --目标文件
     
       files { "**.h", "**.c" }        --指定加载哪些类型文件
     
       filter "configurations:Debug"   --Debug配置项属性
          defines { "DEBUG" }          --定义Debug宏
          symbols "On"                 --开启调试符号
     
       filter "configurations:Release"  --Release配置项属性
          defines { "NDEBUG" }
          optimize "On"                --开启优化参数
2、通过下面命令运行项目文件

$ premake5 vs2013
    这个特别的命令将为Visual Studio 2013生成HelloWorld.sln和HelloWorld.vcxproj文件

3、不是默认名称的加载,靠file参数指定

$ premake5 --file=MyProjectScript.lua vs2013
**:lua语法学习网址Lua: about

5、脚本中的每一行都是一个函数的调用,通常可以省略括号,在需要参数时括号必须要加,如下

 -- 可以省略括号
    workspace("HelloWorld")
    configurations({ "Debug", "Release" })
     
    --不可以省略括号
    local lang = "C++"
    language (lang)  -- using a variable, needs parenthesis
     
    workspace("HelloWorld" .. _ACTION) -- using string concatenation, needs parenthesis
6、如果有相同变量有多个值,后面的值会覆盖前面的值,如

language "C++"   -- the value is now "C++"
    language "C"     -- the value is now "C"
7、对于参数列表可以使用大括号。如

  defines { "DEBUG", "TRACE" }  -- defines multiple values using list syntax
    defines { "NDEBUG" }           -- defines a single value using list syntax
    defines "NDEBUG"              -- defines a single value as a simple string
8、删除定义的值

defines { "DEBUG", "TRACE" }  -- value is now { "DEBUG", "TRACE" }
    removedefines { "TRACE" }     -- value is now { "DEBUG" }
二、配置

    workspace工作空间:每个项目的顶层都是工作空间,如vs中间叫做解决方案,工作空间定义了一套通用的构建配置和平台,用于所有包含的项目。你也可以在这一层指定额外的构建设置(定义、包含路径等),这些设置将同样被项目所继承。
1、一般是一个工作区,如果需要多个工作区,用configurations指定,如

workspace "HelloWorld"
       configurations { "Debug", "Release" }
2、为工作区指定不同名称

 workspace "Hello World"
       filename "Hello"
       configurations { "Debug", "Release" }
    项目:一个工作空间可以存放多个项目, 可以把项目看成一个库或者可执行文件

1、指定项目名称

workspace "MyWorkspace"
      configurations { "Debug", "Release" }
     
    project "MyProject"
2、指定项目种类

project "MyProject"
      kind "ConsoleApp"
      language "C++"
3、项目文件和脚本文件在相同的目录中

workspace "MyWorkspace"
      configurations { "Debug", "Release" }
      location "build"
     
    project "MyProject"
      location "build/MyProject"
    defines:用来给一个project添加预处理或者编译符号

1、作用域定义

 -- global scope, all workspaces will receive these values
    defines { "GLOBAL" }
     
    workspace "MyWorkspaces"
      -- workspace scope inherits the global scope; the list value
      -- will now be { "GLOBAL", "WORKSPACE" }
      defines { "WORKSPACE" }
     
    project "MyProject"
      -- project scope inherits from its workspace; the list value
      -- will now be { "GLOBAL", "WORKSPACE", "PROJECT" }
      defines { "PROJECT" }
2、你也可以通过使用特殊的 "*"名称来选择当前作用域的父级或容器,而不必知道其名称

 -- declare my workspace
    workspace "MyWorkspace"
      defines { "WORKSPACE1" }
     
    -- declare a project or two
    project "MyProject"
      defines { "PROJECT" }
     
    -- re-select my workspace to add more settings
    project "*"
      defines { "WORKSPACE2" }  -- value is now { "WORKSPACE1", "WORKSPACE2" }
     
    -- re-select the global scope
    workspace "*"
    添加文件:使用files函数向你的项目添加文件--源代码、资源等等。

1、可以在文件模式中使用通配符来匹配一组文件。通配符*将匹配一个目录中的文件

 files {
       "hello.h",  -- you can specify exact names
       "*.c",      -- or use a wildcard...
       "**.cpp"    -- ...and recurse into subdirectories
    }
2、位于其他目录下的文件应该相对于脚本文件来指定。例如,如果脚本位于MyProject/build,而源文件位于MyProject/src,那么这些文件应该被指定为

files { "../src/*.cpp" }
3、排除文件

files { "**.c" }
    removefiles { "tests/*.c" }
 
    linking链接,链接库
链接器:指定一个要链接的库和项目的列表

1、链接到一个同级项目(同一工作区的项目),请使用项目名称

workspace "MyWorkspace"
     
       project "MyLibraryProject"
          -- ...project settings here...
     
       project "MyExecutableProject"
          -- ...project settings here...
          links { "MyLibraryProject" }
2、指定链接库位置

libdirs { "libs", "../mylibs" }
3、查找链接库

libdirs { os.findlib("X11") }
    配置:配置是应用于构建的设置的集合,包括标志和开关、头文件和库搜索目录等等

1、使用静态库或共享库时名字可以取个有意义的即可

  workspace "MyWorkspace"
       configurations { "Debug", "DebugDLL", "Release", "ReleaseDLL" }
2、在某个平台上构建项目

  configurations { "Debug", "Release" }
    platforms { "Win32", "Win64", "Xbox360" }
3、配置和平台列表现在可以按项目指定

workspace "MyWorkspace"
        configurations { "Debug", "Release" }
        platforms { "Windows", "PS3" }
     
    project "MyProject"
        removeplatforms { "PS3" }
4、工作区级的配置转化为项目及的配置并被项目引用

project "UnitTest"
        configurations { "Debug", "Release" }
    过滤器:过滤器总是由两部分组成:一个指定被过滤的字段的前缀,和一个指定该字段的哪些值应该被接受的模式

1、过滤器的使用

 -- All of these settings will appear in the Debug configuration
    filter "configurations:Debug"
      defines { "DEBUG" }
      flags { "Symbols" }
     
    -- All of these settings will appear in the Release configuration
    filter "configurations:Release"
      defines { "NDEBUG" }
      optimize "On"
     
    -- This is a sneaky bug (assuming you always want to link against these lib files).
    -- Because the last filter set was Release. These libraries will only be linked for release.
    -- To fix this place this after the "Deactivate" filter call below. Or before any filter calls.
    links { "png", "zlib" }
     
    -- "Deactivate" the current filter; these settings will apply
    -- to the entire workspace or project (whichever is active)
    filter {}
      files { "**.cpp" }

  • 19
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值