标签 Buildc 下的文章

godep的一个“坑”

很多人学习和使用Golang一段时间后,都会被golang的第三方包依赖版本搞得有些烦躁,golang设计者最初过于乐观的设计使得今天大 家不得不各自想办法解决这个问题。godep就是综合了多年第三方包依赖问题的解决方案后的一个趋向统一的方案,至少是在go get的设计没有进化前的一个比较不错的方案。

今天试用了一把godep,不过“体验”并不理想,这缘于我遇到了godep的一个“坑”,不过是那种你在正式项目中不一定遇到的“坑”,这里来说到说到。

按照godep官方使用说明的第一步,先下载godep:

$ go get github.com/tools/godep
$godep
Godep is a tool for managing Go package dependencies.

Usage:

    godep command [arguments]

The commands are:

    save     list and copy dependencies into Godeps
    go       run the go tool in a sandbox
    get      download and install packages with specified dependencies
    path     print sandbox path for use in a GOPATH
    restore  check out listed dependency versions in GOPATH
    update   use different revision of selected packages

Use "godep help [command]" for more information about a command.

确认正确下载后,我们来准备一个测试例子,目录如下:

$GOPATH/
    src/
        tonybai.com/
                foolib/
                   foo.go
                fooapp/
                   main.go
       
   
//foo.go
package foo

func Add(a, b int) int {
        return a + b
}

//main.go
package main

import (
        "fmt"
        foo "tonybai.com/foolib"
)

func main() {
        fmt.Println(foo.Add(1, 3))
}

fooapp下,编译执行程序:

$go run main.go
4

接下来godep登场,根据godep文档中得步骤,接下来我们应该在一个构建依赖关系完整的项目中执行godep save以保存依赖关系以及依赖的当前版本第三方包:

$godep save
godep: directory "/Users/tony/Test/GoToolsProjects/src" is not using a known version control system
godep: error loading dependencies

出错了!godep提示$GOPATH/src目录没有使用任何版本控制系统(not using a known version control system)。 奇怪啊!这个错误什么意思呢?难道使用godep还需要将$GOPATH/src整体作为一个Project纳入git or subversion repository中?无奈之下,我只能先这么做,再作观察。我在$GOPATH下执行git init,建立一个local git repository,然后将src add到这个repository中。

回到fooapp下,再次执行godep save,居然依旧是同样地错误结果。于是到godep的issues中去查,看看是否有人和我遇到了同样地问题!godep的#116 issue中提到的问题恰恰和我的一致,不过这个issue一 直是open状态,也没有人comments。接着翻看一下godep的源码,godep依赖一些第三方包,save这个命令在分析版本控制工具库时也是 调用了多层外部包实现的,短时间内无法定位问题。

静想一下,godep是管理第三方包依赖关系的,而第三方包多是go get下载的,是不是foolib要放到repository中才行呢?于是尝试在foolib中建立git repository并做一次commit。第三次在fooapp下执行godep save,错误依旧!

难道fooapp也必须放在repository中?试试吧。在fooapp下init一个git repository,将fooapp下的main.go提交到repository中。再执行godep save:

$godep save
$ls -l
total 8
drwxr-xr-x  5 tony  staff  170 10 30 22:01 Godeps/
-rw-r–r–  1 tony  staff  103 10 30 21:44 main.go

这回成功了!godep save在fooapp下建立了Godeps目录,其结构如下:

$ls -R
Godeps.json    Readme        _workspace/

./_workspace:
src/

./_workspace/src:
tonybai.com/

./_workspace/src/tonybai.com:
foolib/

./_workspace/src/tonybai.com/foolib:
foolib.go

godep将当前版本的foolib copy到Godeps/_workspace下了。

Godeps.json记录了fooapp对foolib的依赖关系:

{
        "ImportPath": "fooapp",
        "GoVersion": "go1.3",
        "Deps": [
                {
                        "ImportPath": "tonybai.com/foolib",
                        "Rev": "20a9c2a682537813d37847f2f270bf929672cc84"
                }
        ]
}

godep记录了foolib的当前revision number,这个number恰是我最新一次commit的hash code:

~/Test/GoToolsProjects/src/tonybai.com/foolib]$git log
commit 20a9c2a682537813d37847f2f270bf929672cc84
Author: Tony Bai <bigwhite.cn@gmail.com>
Date:   Thu Oct 30 22:00:25 2014 +0800

    init

到这里让我觉得godep的设计思路有些与我的buildcC程序辅助构建工具)的思路有些类似,只是godep做得更彻底:

    1、godep将项目依赖统统放到项目的私有_workspace下,而buildc是共享的,通过project下的版本号配置区分依赖
    2、godep将依赖管理到revision(修订号)级别,buildc只是根据version来区分依赖。

godep的辅助构建原理(godep go build main.go)通过一条命令即可看出来:

$godep go env
GOARCH="amd64"
GOBIN="/usr/local/go/bin"
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/tony/Test/GoToolsProjects/src/fooapp/Godeps/_workspace:/Users/tony/Test/GoToolsProjects"

godep临时将_workspace放在GOPATH列表的前面,这样gc在编译时就会按顺序先在_workspace下面找依赖包,这样fooapp的私有依赖就会理所当然的被gc用到,即便在其他GOPATH路径下有同名包(可能是不同版本的)。

显然这也算是godep的一个小bug吧(或者是godep依赖的包的bug,目前不确认),毕竟提示的路径是不正确的,不应该提示"/Users/tony/Test/GoToolsProjects/src" is not using a known version control system,而应该是"/Users/tony/Test/GoToolsProjects/src/tonybai.com/foolib或"/Users/tony/Test/GoToolsProjects/src/fooapp没有版本控制系统的repository留存。

另外觉得godep的author应该把这个“坑”作为一个使用godep的前提进行说明,并在github主页给出明确展示,即便这个“坑”多数人可能不会遇到。

buildc 0.3.1版本发布

随着buildc在内部应用的深入,buildc逐渐进入了以内部需求和问题为主要驱动力的演化模式。我们内部的C应用多是后端服务类应用,个人 觉得具有一定代表性。buildc最初就是为了针对这类C应用而设计的。因此我们内部的需求和问题应该也同样具有一定代表性,而这种演化模式在一 段时间范围内还是有意义的。

buildc 0.3.1版本修正了上一版本的若干bug,并增加了两个新功能。

* 提高容错能力

buildc对第三方库的组织结构有着严格的要求,一般是:

package_name/
      version/
         CPU_MODE_OS/
            include/
            lib/

一般来说,第三方库会由组织内特定人员进行管理和维护,第三方库服务器上的目录结构不会出现组织错误的情况。但buildc 0.3.0还是遇到特例了:当某个package的第三级目录为空时,buildc 0.3.0版本会抛出异常。为此,buildc 0.3.1增加了对这块逻辑的容错处理:
     1. 如果目录是空目录,直接略过。
     2. 如果目录存在合法的目录,cpu_mode_os,加入.buildc.repository中
     3. 如果目录中存在合法的目录和不合法的目录,略过不合法的目录。

* 支持命令行变量

有些项目针对不同客户有不同的功能版本,但代码是一份,针对不同客户的Release版本用一些特定的宏开关控制,而这些功能开关需要在编译构建 期指定。比如最初版本的buildc.cfg中的片段如下:

custom_defs = ['-std=gnu99', '-DLOGLEVEL=1', '-DUSE_NM']

后A省的客户希望LOGLEVEL用2级,不需要NM(网管)功能,而B省的客户希望LOGLEVEL用2级同时也使用NM功能,那我们的 custom_defs就需要有多种配置了,例如:

if province == "A":
    custom_defs = ['-std=gnu99', '-DLOGLEVEL=2']
elif provice == "B"
    custom_defs = ['-std=gnu99', '-DLOGLEVEL=2', '-DUSE_NM']
else:
    custom_defs = ['-std=gnu99', '-DLOGLEVEL=1', '-DUSE_NM']

province这个变量可以定义在buildc.cfg中,但每次针对不同省份Release时,需要手工修改province变量的值,这样 十分麻烦。因此我们想到是否可以让buildc像Make那样支持命令行变量呢,就像这样:

buildc config make province="B"

于是乎buildc 0.3.1版本就实现了这个功能,你可以在buildc config make或buildc pack中使用buildc的命令行变量,命令行变量支持var=value形式,其中value支持如下几种值:

var=1
var=on
var="on"

对于var=on,在buildc内部会将var=on转化为var="on",否则python会提示找不到on的定义。

* 支持指定项目配置文件(buildc.cfg)

当功能开关变得很多时,我们往往很难记住那么多命令行变量,我们可能就会为每个项目保存多个项目构建的配置文件,比如 buildc_for_liaoning.cfg、buildc_for_beijing.cfg等。而以前的buildc只默认支持 buildc.cfg这样一种配置文件,无法支持这类需求,因此buildc 0.3.1增加了指定项目配置文件功能。

如果你要为A省客户发布,你可以敲入buildc config make –config=PATH_OF_CONFIG_FILE,buildc就会加载你指定的配置文件了,而不是默认的buildc.cfg。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats