[Xiao Mu learns C++] C++ builds engineering projects based on Premake (Windows)

1 Introduction

Premake is a command line utility that reads the script definitions of a software project and is most commonly used to generate project files for toolsets such as Visual Studio, Xcode, or GNU Make.

Insert image description here

Insert image description here

  • What is a build system?
    A build system (BuildSystem) is an automated tool used to generate targets (Targets) that users can use from source code. Targets can include libraries, executables, or generated scripts, etc.
    • Project module dependency maintenance;
    • Target configurability (different systems: Windows, Mac...; different platforms: Win32, Win64, Amd64...)
    • Automation of target generation

Insert image description here

  • Common build systems:
    Mainstream build systems that can be cross-platform and support C++
    • CMake
    • Scons
    • Premake
    • GNU Make
    • GNU autotools
    • Apache Ant (mainly for Java)
    • Gradle (mainly for Java)

Insert image description here

  • Target projects generated by Premake
    The current development version of Premake 5.0 can generate C, C++ or C# projects targeting the following targets:
    • Microsoft Visual Studio 2005-2019
    • GNU Make, including Cygwin and MinGW
    • Xcode
    • Codelite

Insert image description here

2. Download and install

2.1 Download

https://premake.github.io/download
Insert image description here
Here we download the compiled SDK development package and unzip it as follows:
Insert image description here

2.3 Quick Start

  • 1. Create a new test folder test
mkdir test
cd test
  • 2. Create a new build script premake5.lua.
    Insert image description here
    The content of premake5.lua is as follows:
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. Execute the build command to generate the specified project
Premake5 vs2017

Insert image description here
The generated files are as follows:
Insert image description here

3. Use

3.1 Supported project files Project Files

Action Description
vs2022 Generate Visual Studio 2022 project files
vs2019 Generate Visual Studio 2019 project files
vs2017 Generate Visual Studio 2017 project files
vs2015 Generate Visual Studio 2015 project files
vs2013 Generate Visual Studio 2013 project files
vs2012 Generate Visual Studio 2012 project files
vs2010 Generate Visual Studio 2010 project files
vs2008 Generate Visual Studio 2008 project files
vs2005 Generate Visual Studio 2005 project files
gmake Generate GNU Makefiles (This generator is deprecated by gmake2)
gmake2 Generate GNU Makefiles (including Cygwin and MinGW)
xcode4 XCode projects
codelite CodeLite projects

To generate Visual Studio 2013 project files, use the following command:

premake5 vs2013

3.2 Build Settings

Set name set flag
Specify binary type (executable, library) kind
Specify source code file files, removefiles
Define compiler or preprocessor symbols defines
find include file includedirs
Set precompiled headers pchheader, pchsource
Link libraries, frameworks or other projects links, libdirs
Enable debugging information symbols
Optimize for size or speed optimize
Add any build flags buildoptions, linkoptions
Set the name or location of the compiled target 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) Linking to external libraries is completed through the links function.

links {
    
     "png", "zlib" }

(2) The location of the links directive is set under the project.

workspace "MyWorkspace"

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

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

(3) To search for a library, use the following command.

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

3.4 Configurations

A configuration is a collection of settings to be applied to a build, including flags and switches, header files and library search directories, etc. Each workspace defines its own list of configuration names; the defaults provided by most IDEs are "Debug" and "Release".

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

"Platform" is a bit of a misnomer here; again I'm following Visual Studio nomenclature. In reality, a platform is just another set of build configuration names that provide another direction for configuring your project.

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 Default 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. Test

4.1 Test 1: Getting Started Example

  • Create a new folder test001:
mkdir test001
cd test001
  • Create a new code file hello.c:
/* hello.c */
#include <stdio.h>

int main(void) {
    
    
   puts("Hello, world! 爱看书的小沐!");
   return 0;
}
  • Create a new build script file 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"
  • Execute the build command as follows:
# premake5 --file=MyProjectScript.lua vs2013
premake5 vs2017

The results are as follows:
Insert image description here
Open the project file generated above with vs2017:
Insert image description here
Insert image description here

4.2 Test 2: Getting Started Example 2

  • premake5.two
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)

Insert image description here

4.3 Test 3: glfw example

4.3.1 Prepare the third-party library glfw


Insert image description here
After downloading https://github.com/glfw/glfw/releases , extract it to the folder as follows:
Insert image description here
Insert image description here

4.3.2 Create a new package library project 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 Create a new test project 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 Create a new build script

  • premake5.two
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 Execute build command

The final folder built and the files stored in it are organized as follows:
Insert image description here

premake5 vs2017

Insert image description here
The generated project file opened by vs2017 is as follows: Insert image description here
after compiling and running:

Insert image description here

Conclusion

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

Guess you like

Origin blog.csdn.net/hhy321/article/details/129135067