[IDE]VSCode+Premake5打造(c++)跨平台开发调试工具(5): SFML测试

不想看废话的话,直接上github:https://github.com/zhangping312/VSCode-Premake5-Example

    说实话,上一篇VSCode配置编译和调试C++程序已经全部结束了,引用第3方库的功能其实是通过premake5中配置的,这篇是讲述在premake5在XCode上的踩的坑, Windows上没有任何问题。先描述一下自己遇到的问题:Mac上我不想安装SFML库,或者将SFML库拷贝到Library/Framework目录中,因为这些库我不常用。
    先去SFML官网下载,需要下载3个文件,VS2017 32位和64位的,和Mac的。在Game同级目录中创建Third文件夹,把下载好的SFML-2.5.1-windows-vc15-32-bit.zip,SFML-2.5.1-windows-vc15-64-bit.zip和SFML-2.5.1-macOS-clang.tar.gz解压到Third文件夹中。
    在Third文件夹中创建SFML-2.5.1文件夹,从之前解压好的3个文件夹中随便选一个include文件夹,拷贝至Third/SFML-2.5.1/中,并新建一个lib文件夹,在Third/SFML-2.5.1/lib文件夹中创建Macosx和Windows文件夹,在Third/SFML-2.5.1/lib/Windows文件夹中创建x86和x86_64文件夹,并将相对应的lib库中的内容全部拷贝过来, 与lib文件夹一样继续对bin文件夹进行处理,bin文件夹中都是运行需要的dll文件。前期工作先做Windows上的,Mac等会再说。
    开始写SFML的代码,代码可以从SFML官网上拷贝一份,但是发现#include好像出错,这里也需要配置,就是之前一直没说的c_cpp_properties.json,Ctrl + Shift + P后输入C/C++: Edit Configuration(Json),会自动创建c_cpp_properties.json文件,修改成如下:

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "${workspaceFolder}\\..\\Third\\SFML-2.5.1\\include"
            ],
            "defines": [],
            "windowsSdkVersion": "10.0.18362.0",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "${default}"
        }
    ],
    "version": 4
}  

    主要就关心inincludePath,其他的先不管,现在就有代码提示了,开始敲代码,对之前的Application.h和Application.cpp进行修改:
    Application.h:

#include <iostream>
#include <exception>
#include <SFML/Graphics.hpp>

class Application
{
public:
    Application(const std::string& title, unsigned int width, unsigned int height);
    Application(const Application& other) = delete;
    Application& operator=(const Application& other) = delete;
    virtual ~Application();

    void Run();

private:
    sf::RenderWindow* m_WindowHandle = nullptr;
};

    Application.cpp:

#include "Application.h"

Application::Application(const std::string& title, unsigned int width, unsigned int height)
{
    m_WindowHandle = new sf::RenderWindow(sf::VideoMode(width, height), title.c_str());
    if (!m_WindowHandle) throw std::runtime_error("Failed to create SFML window!");
}

Application::~Application()
{
    if (m_WindowHandle) delete m_WindowHandle;
    m_WindowHandle = nullptr;
}

void Application::Run()
{
    sf::CircleShape shape(100.f);
    shape.setFillColor(sf::Color::Green);

    while (m_WindowHandle->isOpen())
    {
        sf::Event event;
        while (m_WindowHandle->pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                m_WindowHandle->close();
        }

        m_WindowHandle->clear();
        m_WindowHandle->draw(shape);
        m_WindowHandle->display();
    }
}

    好了,代码就就到这。如果你现在编译肯定失败的,还需要修改premake5.lua配置。找到SFML/premake5.lua文件,对此修改如下:

IncludeDirs = {}
IncludeDirs["SFML"] = g_WorkspaceFolder .. "/../Third/SFML-2.5.1/include"

project "SFML"
    kind "ConsoleApp"
    language "C++"
    cppdialect "C++17"
    
    -- Place where build files will be generated
    location (g_BuildFolder .. "/%{prj.name}")
    -- Place where compiled binary target
    targetdir (g_WorkspaceFolder .. "/../bin/%{prj.name}")
    -- Place where object and other intermediate files
    objdir (g_WorkspaceFolder .. "/../bin-int/%{prj.name}")

    -- Specify script files for the project
    files
    {
        g_WorkspaceFolder .. "/%{prj.name}/Source/**.h",
        g_WorkspaceFolder .. "/%{prj.name}/Source/**.cpp",
    }

    -- Window configuration
    filter "system:windows"
        -- Specify the include file search path
        includedirs
        { 
            g_WorkspaceFolder .. "/%{prj.name}/Source/",
            "%{IncludeDirs.SFML}"
        }
        -- Specify the library file search path
        libdirs { g_WorkspaceFolder .. "/../Third/SFML-2.5.1/lib/%{cfg.system}/%{cfg.architecture}" }
    
        -- Copy dlls
        prebuildcommands 
        {
            ("{COPY} \"%{wks.location}../Third/SFML-2.5.1/bin/%{cfg.system}/%{cfg.architecture}/*.dll\" \"%{cfg.buildtarget.directory}\""),
        }

    filter { "system:windows", "configurations:Debug" }
        links   { "sfml-system-d.lib", "sfml-window-d.lib", "sfml-graphics-d.lib" }

    filter { "system:windows", "configurations:Release" }
        links   { "sfml-system.lib","sfml-window.lib", "sfml-graphics.lib" }

    -- Mac configuration
    filter "system:macosx"
    systemversion "10.14"   -- 我的Mac版本是10.14.5,低于development target的10.15, 为了避免手动修改,改成10.14
        includedirs     { g_WorkspaceFolder .. "/%{prj.name}/Source/" }-- Xcode: User Header Search Paths

    这次修改的内容主要有设置SFML头文件和库文件路径,并拷贝dll到可执行文件处。现在可以通过VSCode进行调试代码,也可以通过bat文件生成或者VSCode执行任务生成VS2019工程,在VS2019上进行编译和调试。
    现在开始配置XCode的设置了。先贴出修改后的SFML/premake5.lua文件:

IncludeDirs = {}
IncludeDirs["SFML"] = g_WorkspaceFolder .. "/../Third/SFML-2.5.1/include"

project "SFML"
    kind "ConsoleApp"
	language "C++"
	cppdialect "C++17"
    
    -- Place where build files will be generated
    location (g_BuildFolder .. "/%{prj.name}")
    -- Place where compiled binary target
    targetdir (g_WorkspaceFolder .. "/../bin/%{prj.name}")
    -- Place where object and other intermediate files
    objdir (g_WorkspaceFolder .. "/../bin-int/%{prj.name}")

    -- Specify script files for the project
    files
    {
        g_WorkspaceFolder .. "/%{prj.name}/Source/**.h",
        g_WorkspaceFolder .. "/%{prj.name}/Source/**.cpp",
    }

    -- Window configuration
    filter "system:windows"
        -- Specify the include file search path
        includedirs
        { 
            g_WorkspaceFolder .. "/%{prj.name}/Source/",
            "%{IncludeDirs.SFML}"
        }
        -- Specify the library file search path
        libdirs { g_WorkspaceFolder .. "/../Third/SFML-2.5.1/lib/%{cfg.system}/%{cfg.architecture}" }
    
        -- Copy dlls
        prebuildcommands 
        {
            ("{COPY} \"%{wks.location}../Third/SFML-2.5.1/bin/%{cfg.system}/%{cfg.architecture}/*.dll\" \"%{cfg.buildtarget.directory}\"")
        }

    filter { "system:windows", "configurations:Debug" }
        links   { "sfml-system-d.lib", "sfml-window-d.lib", "sfml-graphics-d.lib" }

    filter { "system:windows", "configurations:Release" }
        links   { "sfml-system.lib","sfml-window.lib", "sfml-graphics.lib" }

    -- Mac configuration
    filter "system:macosx"
        systemversion "10.14"   -- 我的Mac版本是10.14.5,低于development target的10.15, 为了避免手动修改,改成10.14
        includedirs     { g_WorkspaceFolder .. "/%{prj.name}/Source/" }-- Xcode: User Header Search Paths
        sysincludedirs  { "%{IncludeDirs.SFML}" }--Xcode: Header Search Paths
        links           { "sfml-system.framework", "sfml-window.framework", "sfml-graphics.framework", "freetype.framework" }
        linkoptions 
        { 
            "-F" .. g_WorkspaceFolder .. "/../Third/SFML-2.5.1/lib/%{cfg.system}/Frameworks",
            "-Xlinker -rpath -Xlinker " .. g_WorkspaceFolder .. "/../Third/SFML-2.5.1/lib/%{cfg.system}/Frameworks"
        }

        --syslibdirs      { g_WorkspaceFolder .. "/../Third/SFML-2.5.1/lib/%{cfg.system}/Frameworks" }
        --libdirs      { g_WorkspaceFolder .. "/../Third/SFML-2.5.1/lib/%{cfg.system}/Frameworks" }
        -- runpathdirs     
        -- { 
        --     g_WorkspaceFolder .. "/../bin/%{prj.name}",
        --     g_WorkspaceFolder .. "/../Third/SFML-2.5.1/lib/%{cfg.system}/Frameworks",
        --     g_WorkspaceFolder .. "/../Third/SFML-2.5.1/lib/%{cfg.system}/extlibs"
        -- }
        -- prebuildcommands
        -- {
        --     ("{COPY} \"%{wks.location}/../Third/SFML-2.5.1/lib/%{cfg.system}/Frameworks/sfml-system.framework\" \"%{cfg.buildtarget.directory}\""),
        --     ("{COPY} \"%{wks.location}/../Third/SFML-2.5.1/lib/%{cfg.system}/Frameworks/sfml-window.framework\" \"%{cfg.buildtarget.directory}\""),
        --     ("{COPY} \"%{wks.location}/../Third/SFML-2.5.1/lib/%{cfg.system}/Frameworks/sfml-graphics.framework\" \"%{cfg.buildtarget.directory}\""),
        --     ("{COPY} \"%{wks.location}/../Third/SFML-2.5.1/lib/%{cfg.system}/Frameworks/freetype.framework\" \"%{cfg.buildtarget.directory}\"")
        -- }

    这里坑超级多,premake5的wiki上好多设置感觉在XCode上都是无效的。一个个来说,首先是sysincludedirs值是Header Search Paths表示可以#include <>,不然使用#include <SFML/Graphics.hpp>会报错,includedirs指的是User Header Search Paths,用的是#include "", 这些可以通过google查找学习。
    linkoptions这个参数是后面经过多个坑踩出来的最后结果,下面所有的注释都是自己踩过留下来的。先来说下情况,因为SFML库不常用,不想安装也不想拷贝Framework到/Library/Framework目录中,其实更加重要的原因是我自己编译出来的库,我难道还得放到/Library/Framework目录中吗。我先测试了prebuildcommands拷贝到可执行程序目录中,可以编译,XCode也可编译执行,但可执行文件会报错,Library not loaded,然后这个方法弃之。第2个方法指定frameworkpath,但premake5没有提供这个功能,测试了libdirs和syslibdirs,发现没有用。第3个方法,回到拷贝framework,运行的时候指定runpath,但发现runpathdirs这个值无效,看链接的输出时候没有。本来打算放弃了,不死心,对着build出来的xcode工程修改,自己添加framework和设置runpath,直接执行可执行程序,可以,就说明之前想的方法可行。疯狂google如何通过xcodebuild设置runpath和frameworkpath。没有找到,只好通过XCode拷贝链接指令,一个个看过来,发现通过xcodebuild的有漏了2个参数。
    查看链接指令的方式:

    发现自己漏了这2条:
//用于编译
-Xlinker -no_deduplicate -F/Users/zhangping/Documents/ZP/VSCode-Premake5-Example/Game/../Third/SFML-2.5.1/lib/macosx/Frameworks 
//用于运行
-Xlinker -rpath -Xlinker /Users/zhangping/Documents/ZP/VSCode-Premake5-Example/Game/../Third/SFML-2.5.1/lib/macosx/Frameworks
    然后通过linkoptions补上了这2个参数,编译运行OK,VSCode也可以编译和调试了。这边得吐槽SFML的framework,好逗比,freetype.framework必须在../Frameworks中,不就是表示将freetype.framework放在Frameworks目录中和sfml-system.framework等同级吗?
    代码和SFML库都已经上传到github上的,Mac和Windows目录下的库文件都删除了一部分,不然太大,而且还用不上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值