V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
icoming
V2EX  ›  Go 编程语言

Golang 交叉编译的问题

  •  
  •   icoming · 2023-04-18 15:33:16 +08:00 · 1983 次点击
    这是一个创建于 576 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Windows下编写的,Linux相关的那段代码无法通过编译,提示"Unresolved type 'Statvfs_t'"

    加了判断根据系统调用不同的函数,也不行吗?

    那要怎么解决?


    //go:build windows || linux
    
    package main
    
    import (
    	"fmt"
    	"golang.org/x/sys/windows"
    	"os"
    	"runtime"
    	"syscall"
    )
    
    // 获取磁盘的可用空间。依次为 可用空间、总空间、剩余空间(包含系统保留)
    //
    // 参考 https://stackoverflow.com/a/60724929
    func get() (free uint64, total uint64, avail uint64, err error) {
    	wd, err := os.Getwd()
    	if err != nil {
    		return
    	}
    
    	switch runtime.GOOS {
    	case "windows":
    		pathPtr, err := windows.UTF16PtrFromString(wd)
    		if err != nil {
    			return
    		}
    		err = windows.GetDiskFreeSpaceEx(pathPtr, &free, &total, &avail)
    		if err != nil {
    			return
    		}
    
    	case "linux":
    		var stat syscall.Statvfs_t
    		if err := syscall.Statvfs(wd, &stat); err != nil {
    			fmt.Println(err)
    			return
    		}
    
    		// 块大小 = fragment 大小 * fragment 个数(单位为字节)
    		blockSize := uint64(stat.Frsize)
    		// 可用空间 = 块大小 * 可用块数(单位为字节)
    		free = stat.F_bfree * blockSize
    		// 总空间 = 块大小 * 总块数(单位为字节)
    		total = stat.F_blocks * blockSize
    		// 剩余空间 = 块大小 * 剩余块数(单位为字节)
    		avail = stat.F_bavail * blockSize
    
    	default:
    		return 0, 0, 0, fmt.Errorf("未适配的平台'%s'", runtime.GOOS)
    	}
    
    	return
    }
    
    第 1 条附言  ·  2023-04-18 16:41:38 +08:00
    谢谢,明白怎么处理不同系统的 API 不一致的问题了。
    11 条回复    2023-04-19 00:32:51 +08:00
    fzdwx
        1
    fzdwx  
       2023-04-18 15:47:14 +08:00 via Android
    分文件,同名函数以及 go build 指定平台
    likeunix
        2
    likeunix  
       2023-04-18 15:50:32 +08:00
    不是在运行时判断,而是在编译时判断
    lincanbin
        3
    lincanbin  
       2023-04-18 15:54:34 +08:00
    不同平台的代码放在不同 package 里,编译脚本去检测环境,根据环境去全仓库替换包名。
    NessajCN
        4
    NessajCN  
       2023-04-18 15:55:51 +08:00
    不是都告诉你"Unresolved type 'Statvfs_t'"了吗...
    你类型名字打错了,是 syscall.Statfs_t
    qxooqx
        5
    qxooqx  
       2023-04-18 16:08:25 +08:00
    关键字 构建约束
    添加注释,或者指定文件名就可以了
    cyp0633
        6
    cyp0633  
       2023-04-18 16:26:53 +08:00
    要分 // +build windows 和 // +build linux 俩文件吧
    Trim21
        7
    Trim21  
       2023-04-18 16:32:58 +08:00 via Android
    要分文件加构建约束,而且你打错字了
    icoming
        8
    icoming  
    OP
       2023-04-18 17:09:16 +08:00
    @fzdwx
    @likeunix
    @lincanbin
    @NessajCN
    @qxooqx
    @cyp0633
    @Trim21

    谢谢,明白怎么处理分开构建了。
    另外,确实打错字了。

    又有个问题,Goland 不提示另一系统的代码文件中的错误,这又该怎么办?
    flyqie
        9
    flyqie  
       2023-04-18 18:36:38 +08:00
    @icoming #8

    1 随便打开一个不是当前平台的文件,最上面会弹出一个提示条,点编辑设置。
    icoming
        10
    icoming  
    OP
       2023-04-18 19:20:53 +08:00
    @flyqie 谢谢,可以了
    hugo54
        11
    hugo54  
       2023-04-19 00:32:51 +08:00
    二楼很一针见血了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4863 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 01:10 · PVG 09:10 · LAX 17:10 · JFK 20:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.