libgit2使用教程(一)实现 git init

主要内容:
1. 使用 libgit2 的准备工作
2. 构建和运行
3. 初始化一个 git 仓库

示例代码:https://github.com/XiaochenFTX/libgit2_samples

进入正题

开始直接到 libgit2 的 readme 我们首先需要从那里获取一些有用的信息。
官网:https://libgit2.github.com/
API:http://libgit2.github.com/libgit2/
虽然官方文档写的挺水的,不过毕竟可以获得信息的途径就这么少,所以凑合着也还能用。

接下来提到了两个非常重要的函数, init 和 shutdown ,必须保证在任何操作之前调用初始化:

git_libgit2_init();

释放 init 申请的资源,使用:

git_libgit2_shutdown();

这样就可以开始第一个程序了

#include <git2.h> 

int main() 
{ 
    git_libgit2_init(); 
    
    git_libgit2_shutdown();

     return 0; 
}

ok 打完收工。

先把它跑一下看看,如果可以正常跑完,就说明所有的构建基本上都没啥问题了。

当然,这并没有什么卵用。接下来来搞个有意义的代码来结束这篇。
第一个例子就实现一下 git init

const char* path = "/Users/XiaochenFTX/Documents/data";
git_repository *rep = nullptr;
git_repository_init(&rep, path, 0);

打完收工。

当然,良好的编程习惯,在最后不要忘了释放资源。

git_repository_free(rep); 
git_libgit2_shutdown();

接口的详细说明可以去查官方的 API 我会在必要的地方对一些我觉得比较重要的东西进行说明。

git_repository_init 的第一个参数是将初始化好的 git_repository 指针返回,这个库的接口基本上都是这个风格的,以后就不再提这个事了。
这个函数会返回一个错误码,返回值为 0 表示执行成功,小于 0 表示有错误。所以可以通过判断返回值得方式来确定函数调用是否成功。
想知道具体报错信息,可以调用 giterr_last() 这个函数返回一个 git_error 结构体指针。

/**
* Structure to store extra details of the last error that occurred.
*
* This is kept on a per-thread basis if GIT_THREADS was defined when the
* library was build, otherwise one is kept globally for the library
*/
typedef struct {
    char *message;
    int klass;
} git_error;

klass 对应 git_error_t 的枚举值,用于说明是哪部分出的问题。message 是一个人类可以看懂的的说明信息。开发中遇到问题可以把这个信息打印出来,对找问题有很大帮助。

最终完成 sample1 的代码就是这个样子

#include <git2.h>
#include <iostream>

int main()
{
    git_libgit2_init();
    const char *path = "/Users/XiaochenFTX/Documents/data";
    git_repository *rep = nullptr;
    
    // git init
    int error = git_repository_init(&rep, path, 0);
    if (error < 0) {
        const git_error *e = giterr_last();
        std::cout << "Error: " << error << " / " << e->klass << " : " << e->message << std::endl;
        
        goto SHUTDOWN;
    }
SHUTDOWN:
    git_repository_free(rep);
    git_libgit2_shutdown();
    
    return 0;
}

最后解释一下为什么要用 goto
很多同学在学习 C 语言的时候,如果遇到不负责任的老师,都会强调不要用 goto 这个东西,更有甚者干脆讲都不讲。而具体原因不外乎:会让代码逻辑混乱,可读性差,不好调试
当然,造成这些后果,都是在“如果用不好”的前提下的。然而,我认为这个语言特性真的不是不值一提的垃圾,把 goto 用好在一定程度上是可以让代码更美观、更简洁、更易读。
随便举个例子,比如跳出多层循环,难道还要引入一个外层变量再逐层判断吗?在这种情况下那种方式可读性更高?
还有就是在错误发生的情况下,直接跳到函数结尾进行清理。如果不使用 goto ,我见过几种奇葩方案,最突出的应该是用 do{}while(0); 吧,这样强行为了不用 goto 而产生的奇葩行为,我只能呵呵了。
所以,我推荐在必要的时候使用 goto 来使代码更清晰、简洁。当然,也不是随便瞎用,任何工具都有其最佳适用范围,不能矫枉过正。

附一、代码中引用 libgit2:
在根目录的 CMakeLists.txt 中把相关工程文件夹都用 add_subdirectory 加进来,并且指定 libgit2 的 include 为引用目录

include_directories(extras/libgit2/include)
add_subdirectory(extras/libgit2)
add_subdirectory(sample1)

在需要链接这个库的工程中使用 target_link_libraries 链接上 libgit2
就像我们的 sample1 中这样

target_link_libraries(sample1 git2)

有些环境下会报找不到 -lssh2 的错误:
ld: library not found for -lssh2
只要在根目录的 CMakeLists.txt 中加上一句:

LINK_DIRECTORIES(${LIBSSH2_LIBRARY_DIRS})

这样简单的构建系统就搭建好了,可以开始写代码了
使用其他 IDE 的话,直接用 cmake 导出对应的工程,在自己创建的工程中引入就可以了。
不太推荐直接编译好库放到工程里使用,我自己试了之后发现它用到的几个第三方库还需要自己手动构建再引用。

附二、示例代码的使用:

1. 从 github 上拉代码

git clone git@github.com:XiaochenFTX/libgit2_samples.git
cd libgit2_samples
git submodule update –init –recursive

2. 使用 cmake 导出熟悉的 IDE 工程,或者直接构建运行

mkdir build 
cd build/

Xcode:

cmake .. -G “Xcode”

Visual Studio:

cmake .. -G "Visual Studio"

直接构建:

cmake .. 
make

我使用的 IDE 是 Clion ,使用 Clion 导入工程也可以直接使用

MacOS OpenGL窗口程序的正确打开方式

当小白挖开gl渲染这个坑的时候,最先遇到的问题一定是窗口。然后就是虐死强迫症系列的剧情。
教程最多的一定是glut系列,然而,放到Xcode里一片黄,原因是苹果在未来要不支持这玩意了。再之后就是glew、glfw等一堆库,到这个时候一个没什么基础的小白玩家应该已经有流失的想法了。
这篇博客主要介绍怎么直接搞出一个干净的glview窗口程序,简简单单的开始OpenGL的新手引导。

然后也可以解决一些问题:
1. 如何创建一个OpenGL窗口
2. glut的警告问题
3. 可以使用4.0以上版本的OpenGL
4. 对于非小白玩家而言可能第3条是最重要的

废话少说,书归正传:
第一步、创建工程
1. 新建一个Cocoa Application工程
130298
2. 拖一个OpenGL View 替换掉原来的默认View
582077
这样这个窗口就可以启动运行了。

第二步、写代码
1. 新建一个Cocoa Class,选择继承自 NSOpenGLView
306506
2. 把上边建好的GLView关联上我们自己的类
742882
这样就可以在我们自己类中调用渲染代码了。

第三步、支持GL4.1
需要实现的函数:
initWithCoder
defaultPixelFormat
prepareOpenGL
drawRect

重点就是在初始化部分,需要设置一下属性才能真正的支持4.1

- (nullable instancetype)initWithCoder:(NSCoder *)coder { 

   [[self openGLContext] makeCurrentContext]; 

   self = [super initWithCoder:coder]; 

   return self; 
} 

+ (NSOpenGLPixelFormat*)defaultPixelFormat { 
   NSOpenGLPixelFormatAttribute attrs[] = 
   { 
      NSOpenGLPFADoubleBuffer, // 可选地,可以使用双缓冲 
      NSOpenGLPFAOpenGLProfile, // Must specify the 3.2 Core Profile to use OpenGL 3.2 
      NSOpenGLProfileVersion4_1Core, 
      0 
   }; 

   return [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; 
}

这样就是一个可以正常撸的GL窗口程序了。非常适合强迫症玩家入门使用,编译器完全没有警告。

在这就不贴完整代码了。有一个可运行的程序,在github上。
https://github.com/XiaochenFTX/glFirst

RSS
Follow by Email
YouTube
YouTube
Pinterest
fb-share-icon
LinkedIn
Share
VK
Weibo
WeChat
WhatsApp
Reddit
FbMessenger
Copy link
URL has been copied successfully!