【小沐学C++】C++ 基于Premake构建工程项目(Windows)

16 篇文章 4 订阅

1、简介

Premake是一个命令行实用程序,它读取软件项目的脚本定义,最常见的是使用它为Visual Studio,Xcode或GNU Make等工具集生成项目文件。

在这里插入图片描述

在这里插入图片描述

  • 什么是构建系统
    构建系统(BuildSystem)是用来从源码生成用户可以使用的目标(Targets)的自动化工具。目标可以包括库,可执行文件,或者生成的脚本等等。
    • 项目模块依赖关系维护 ;
    • 目标的可配置化(不同系统:Windows,Mac…;不同平台:Win32,Win64,Amd64…)
    • 目标生成的自动化

在这里插入图片描述

  • 常见的构建系统
    主流的可以跨平台,支持C++的构建系统
    • CMake
    • Scons
    • Premake
    • GNU Make
    • GNU autotools
    • Apache Ant(主要用于Java)
    • Gradle(主要用于Java)

在这里插入图片描述

  • Premake生成的目标工程
    Premake 5.0 的当前开发版本可以生成针对以下目标的 C、C++ 或 C# 项目:
    • Microsoft Visual Studio 2005-2019
    • GNU Make, including Cygwin and MinGW
    • Xcode
    • Codelite

在这里插入图片描述

2、下载和安装

2.1 下载

https://premake.github.io/download
在这里插入图片描述
这里我们下载编译好的sdk开发包,解压如下:
在这里插入图片描述

2.3 快速入门

  • 1、新建测试文件夹test
mkdir test
cd test
  • 2、新建构建脚本premake5.lua
    在这里插入图片描述
    premake5.lua的内容如下:
workspace "XiaomuWorkspace"
   configurations { "Debug", "Release" }

project "XiaomuProject"
   kind "ConsoleApp"
   language "C++"
   files { "**.h", "**.cpp" }

   filter { "configurations:Debug" }
      defines { "DEBUG" }
      symbols "On"

   filter { "configurations:Release" }
      defines { "NDEBUG" }
      optimize "On"
  • 3、执行构建命令,生成指定工程
Premake5 vs2017

在这里插入图片描述
生成文件如下:
在这里插入图片描述

3、使用

3.1 支持的工程文件Project Files

ActionDescription
vs2022Generate Visual Studio 2022 project files
vs2019Generate Visual Studio 2019 project files
vs2017Generate Visual Studio 2017 project files
vs2015Generate Visual Studio 2015 project files
vs2013Generate Visual Studio 2013 project files
vs2012Generate Visual Studio 2012 project files
vs2010Generate Visual Studio 2010 project files
vs2008Generate Visual Studio 2008 project files
vs2005Generate Visual Studio 2005 project files
gmakeGenerate GNU Makefiles (This generator is deprecated by gmake2)
gmake2Generate GNU Makefiles (including Cygwin and MinGW)
xcode4XCode projects
codeliteCodeLite projects

若要生成 Visual Studio 2013 项目文件,请使用以下命令:

premake5 vs2013

3.2 构建设置Build Settings

设置名称设置标志
指定二进制类型(可执行文件、库)kind
指定源代码文件files, removefiles
定义编译器或预处理器符号defines
找到包含文件includedirs
设置预编译标头pchheader, pchsource
链接库、框架或其他项目links, libdirs
启用调试信息symbols
针对尺寸或速度进行优化optimize
添加任意构建标志buildoptions, linkoptions
设置已编译目标的名称或位置targetname, targetdir
defines { "DEBUG", "TRACE" }
defines { "CALLSPEC=__dllexport" }
includedirs { "../lua/include", "../zlib" }
includedirs { "../includes/**" }
pchheader "myproject.h"
optimize "Speed"
filter { "system:linux", "action:gmake" }
  buildoptions { "`wx-config --cxxflags`", "-ansi", "-pedantic" }
targetname "mytarget"

3.3 链接Linking

(1)链接到外部库是通过links 功能完成的。

links { "png", "zlib" }

(2)links 指令的位置在project 下面设置。

workspace "MyWorkspace"

   project "MyLibraryProject"
      -- ...project settings here...

   project "MyExecutableProject"
      -- ...project settings here...
      links { "MyLibraryProject" }

(3)而查找库,则使用如下指令。

libdirs { "libs", "../mylibs" }
# or
libdirs { os.findlib("X11") }

3.4 配置Configurations

配置是要应用于构建的设置集合,包括标志和开关、头文件和库搜索目录等。每个工作区定义自己的配置名称列表;大多数 IDE 提供的默认值是“调试”和“发布”。

workspace "MyWorkspace"
   configurations { "Debug", "Release" }
workspace "MyWorkspace"
   configurations { "Debug", "DebugDLL", "Release", "ReleaseDLL" }
workspace "MyWorkspace"
   configurations { "Froobniz", "Fozbat", "Cthulhu" }
workspace "HelloWorld"
   configurations { "Debug", "Release" }

   filter "configurations:Debug"
      defines { "DEBUG" }
      flags { "Symbols" }

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

3.5 平台Platforms

“平台”在这里有点用词不当;我再次遵循Visual Studio命名法。实际上,平台只是另一组构建配置名称,提供了另一个方向用于配置项目。

configurations { "Debug", "Release" }
platforms { "Win32", "Win64", "Xbox360" }
configurations { "Debug", "Release" }
platforms { "Win32", "Win64", "Xbox360" }

filter { "platforms:Win32" }
    system "Windows"
    architecture "x86"

filter { "platforms:Win64" }
    system "Windows"
    architecture "x86_64"

filter { "platforms:Xbox360" }
    system "Xbox360"
configurations { "Debug", "Release" }
platforms { "Static", "DLL" }

filter { "platforms:Static" }
    kind "StaticLib"

filter { "platforms:DLL" }
    kind "SharedLib"
    defines { "DLL_EXPORTS" }

3.6 过滤Filters

project "MyProject"

  filter { "configurations:Debug" }
    targetdir "bin/debug"

  filter { "configurations:Release" }
    targetdir "bin/release"

3.7 预设值Tokens

wks.name
wks.location -- (location where the workspace/solution is written, not the premake-wks.lua file)

prj.name
prj.location -- (location where the project is written, not the premake-prj.lua file)
prj.language
prj.group

cfg.longname
cfg.shortname
cfg.kind
cfg.architecture
cfg.platform
cfg.system
cfg.buildcfg
cfg.buildtarget -- (see [target], below)
cfg.linktarget -- (see [target], below)
cfg.objdir

file.path
file.abspath
file.relpath
file.directory
file.reldirectory
file.name
file.basename -- (file part without extension)
file.extension -- (including '.'; eg ".cpp")

-- These values are available on build and link targets
-- Replace [target] with one of "cfg.buildtarget" or "cfg.linktarget"
--   Eg: %{cfg.buildtarget.abspath}
[target].abspath
[target].relpath
[target].directory
[target].name
[target].basename -- (file part without extension)
[target].extension -- (including '.'; eg ".cpp")
[target].bundlename
[target].bundlepath
[target].prefix
[target].suffix

4、测试

4.1 测试1:入门例子

  • 新建文件夹test001:
mkdir test001
cd test001
  • 新建代码文件hello.c:
/* hello.c */
#include <stdio.h>

int main(void) {
   puts("Hello, world! 爱看书的小沐!");
   return 0;
}
  • 新建构建脚本文件premake5.lua:
-- premake5.lua
workspace "XiaoMuProject"
   configurations { "Debug", "Release" }

project "XiaoMu001"
   kind "ConsoleApp"
   language "C"
   targetdir "bin/%{cfg.buildcfg}"

   files { "**.h", "**.c" }

   filter "configurations:Debug"
      defines { "DEBUG" }
      symbols "On"

   filter "configurations:Release"
      defines { "NDEBUG" }
      optimize "On"
  • 执行构建命令如下:
# premake5 --file=MyProjectScript.lua vs2013
premake5 vs2017

结果如下:
在这里插入图片描述
用vs2017打开上面生成的工程文件:
在这里插入图片描述
在这里插入图片描述

4.2 测试2:入门例子2

  • premake5.lua
workspace "XiaMuTest002" -- 解决方案
    startproject "Test" -- 开始项目

    configurations
    {
        "Debug",
        "Release"
    }

    platforms
    {
        "Win32",
        "Win64"
    }

    filter "platforms:Win32"
        system "Windows"
        architecture "x32"

    filter "platforms:Win64"
        system "Windows"
        architecture "x86_64"

outputdir = "%{cfg.platform}/%{cfg.buildcfg}/%{prj.name}"
project "XiaMuTest002"
    kind "ConsoleApp"
    language "C++"
	
    files
    {
        "./**.cpp",
        "*.c"
    }
	
	targetdir("../bin/" .. outputdir)
	objdir("../obj/" .. outputdir)

在这里插入图片描述

4.3 测试3:glfw例子

4.3.1 准备第三方库glfw

https://github.com/glfw/glfw/releases
在这里插入图片描述
下载完毕之后,解压到文件夹如下:
在这里插入图片描述
在这里插入图片描述

4.3.2 新建封装库项目ExampleDll

  • ExampleDll.h
#ifndef EXAMPLE_DLL_HPP
#define EXAMPLE_DLL_HPP 1

#include <string>
#include <memory>
struct GLFWwindow;

namespace ExDLL
{	
	class _declspec(dllexport) Window
	{
	public:
		Window(int width, int  height, const std::string& title);
		~Window();
		bool shouldClose() const noexcept;
		void pollEvents() const noexcept;
		void swapBuffers() const noexcept;
		std::pair<int, int> getWindowSize() const noexcept;	
	private:
		GLFWwindow* wnd;
	};
}
#endif
  • ExampleDll.cpp
#include "ExampleDll.h"
#include <GLFW/glfw3.h>
	
namespace ExDLL
{
	Window::Window(int width, int height, const std::string& title)
	{
		glfwInit();
		wnd = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
		glfwMakeContextCurrent(wnd);
	}
	
	Window::~Window()
	{
		glfwDestroyWindow(wnd);
		glfwTerminate();
	}

	bool Window::shouldClose() const noexcept
	{
		return glfwWindowShouldClose(wnd) != 0;
	}

	void Window::pollEvents() const noexcept
	{
		glfwPollEvents();
	}

	void Window::swapBuffers() const noexcept
	{
		glfwSwapBuffers(wnd);
	}

	std::pair<int, int> Window::getWindowSize() const noexcept
	{
		std::pair<int, int> sz{};
		glfwGetWindowSize(wnd, &sz.first, &sz.second);
		return sz;
	}
}

4.3.3 新建测试项目ExampleTest

  • main.cpp
#include <ExampleDll.h>

#if defined _WIN32
	#include <Windows.h>
	#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#endif
#include <gl/GL.h>

//导入ExampleDll中的Window类
class _declspec(dllimport) ExDLL::Window;

int main()
{
	ExDLL::Window window{ 1000, 600, "Hello World! 爱看书的小沐,2023" };
	while (!window.shouldClose())
	{
		// 事件更新
		window.pollEvents();
		
		// 绘图
		glBegin(GL_TRIANGLES);
			glColor3f(1.0, 0.0, 0.0);
			glVertex2f(-0.5f, -0.5f);

			glColor3f(1.0, 1.0, 0.0);
			glVertex2f(0.5f, -0.5f);

			glColor3f(1.0, 0.0, 1.0);
			glVertex2f(0, 0.5f);
		glEnd();

		// 渲染更新
		window.swapBuffers();
	}
	return 0;
}

4.3.4 新建构建脚本

  • premake5.lua
workspace "XiaoMuTest003"
	startproject "ExampleTest" -- 开始项目
	location "vs"
	language "C++"
	architecture "x64"
	configurations {"Debug","Release"}
	
	filter {"configurations:Debug"}
		symbols "On"
	filter {"configurations:Release"}
		optimize "On"
	-- 重置过滤器的其他设定
	filter {}
	
	targetdir ("build/target/%{prj.name}/%{cfg.longname}")
	objdir ("build/obj/%{prj.name}/%{cfg.longname}")
	postbuildcommands{
		("{COPY} %{cfg.buildtarget.relpath} \"../bin/\"")
	}
	
-- 定义函数,包含glfw三方库头文件,可被其他工程调用
function includeGLFW()
	includedirs "../3rd/glfw-3.3.8.bin.WIN64/include"
end

-- 定义函数,链接glfw三方库
function linkGLFW()
	libdirs "../3rd/glfw-3.3.8.bin.WIN64/lib-vc2017"
	links "glfw3dll"
end

-- ExampleDll项目
project "ExampleDll"
	kind "SharedLib"
	files "src/ExampleDll/**"
	includeGLFW()
	linkGLFW()

-- 定义函数,链接ExampleDll动态库
function useExampleDLL()
	includedirs "src/ExampleDll"
	links "ExampleDll"
end

-- App应用程序
project "ExampleTest"
	kind "ConsoleApp"
	files "src/ExampleTest/**"
	useExampleDLL()
	filter "system:windows"
		links {"OpenGL32"}

4.3.5 执行构建命令

最后构建的文件夹和里面存放的文件组织如下:
在这里插入图片描述

premake5 vs2017

在这里插入图片描述
vs2017打开生成的工程文件如下:在这里插入图片描述
编译和运行后:

在这里插入图片描述

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于C/C++的人工智能小项目: 项目名称:井字棋人工智能 项目描述:实现一个简单的井字棋游戏,其中包括一个基于MiniMax算法的人工智能玩家。 项目实现: 1. 实现井字棋游戏的基本逻辑,包括棋盘的初始化、落子、判断胜负等功能。 2. 设计MiniMax算法的估值函数,用于评估当前棋盘状态的好坏程度。 3. 实现MiniMax算法的搜索过程,以找到当前最优的落子位置。 4. 设计一个简单的人机交互界面,包括显示当前棋盘状态、提示玩家进行落子、显示游戏结果等功能。 5. 实现一个基于命令行的控制台界面,以方便用户进行操作。 项目难点: 1. 实现MiniMax算法的估值函数,需要考虑到多种棋局特征,如连子数、空位数量、棋子分布等。 2. 实现MiniMax算法的搜索过程,需要考虑到搜索深度、剪枝等问题,以保证算法的效率和准确性。 3. 设计人机交互界面,需要考虑到用户体验和界面美观性等问题。 项目拓展: 1. 实现Alpha-Beta剪枝算法,以提高MiniMax算法的效率。 2. 设计一个基于图形界面的井字棋游戏,以提高用户体验。 3. 实现一个基于神经网络的井字棋人工智能,以提高算法的智能化程度。 总结: 该项目涉及到了人工智能算法、游戏开发、界面设计等多个方面,是一个相对较为综合的小项目。通过实现该项目,可以加深对人工智能算法的理解,提高对C/C++语言的掌握程度,并且可以锻炼自己的编程能力和思维能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值