英文:
Trouble compiling Linux functions on Windows Dev Machine
问题
我的应用程序在Linux服务器上运行,但我在Windows机器上进行开发。
我在编译来自"golang.org/x/sys/unix"包的函数和类型时遇到问题。以下是我代码的一部分无法编译的部分:
if runtime.GOOS == "linux" {
var stat unix.Statfs_t
err := unix.Statfs(mount, &stat)
if err != nil {
fmt.Printf("Error: %v\n", err)
continue
}
totalSpace = uint64(stat.Blocks) * uint64(stat.Bsize)
freeSpace = uint64(stat.Bfree) * uint64(stat.Bsize)
}
我使用JetBrains的Goland进行编译。我得到了这些错误:"undefined: unix.Statfs_t"和"undefined: unix.Statfs","编译完成,退出代码为2"。
我使用go get -u "golang.org/x/sys/unix"
导入了该包,但仍然出现此错误。有人知道如何解决吗?
英文:
My app runs on a linux server, but I develop on a Windows machine.
I'm having problems compiling functions and types from the "golang.org/x/sys/unix" package. Here is a portion of my code not compiling well:
if runtime.GOOS == "linux" {
var stat unix.Statfs_t
err := unix.Statfs(mount, &stat)
if err != nil {
fmt.Printf("Error: %v\n", err)
continue
}
totalSpace = uint64(stat.Blocks) * uint64(stat.Bsize)
freeSpace = uint64(stat.Bfree) * uint64(stat.Bsize)
}
I'm compiling using Goland from JetBrains. I get these errors: "undefined: unix.Statfs_t" and "undefined: unix.Statfs", "Compilation finished with exit code 2".
I imported the package with go get -u "golang.org/x/sys/unix"
, but I still get this error. Anyone know how to fix this?
答案1
得分: 3
Go源文件包的导入由编译器处理。运行时检查runtime.GOOS == "linux"
不起作用,因为太晚了。可以使用Go编译器的构建约束。
对于Linux和Windows,可以同时使用显式和文件名隐式的构建约束。
disk/disk.go
:
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
mount := string(filepath.Separator)
total, free, err := DiskSpace(mount)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Println(total, free)
}
disk/disk_linux.go
:
package main
import (
"golang.org/x/sys/unix"
)
func DiskSpace(mount string) (total, free uint64, err error) {
var stat unix.Statfs_t
err = unix.Statfs(mount, &stat)
if err != nil {
return 0, 0, err
}
total = uint64(stat.Blocks) * uint64(stat.Bsize)
free = uint64(stat.Bfree) * uint64(stat.Bsize)
return total, free, nil
}
disk/disk_windows.go
:
package main
import (
"golang.org/x/sys/windows"
)
func DiskSpace(dir string) (total, free uint64, err error) {
var (
directoryName = windows.StringToUTF16Ptr(dir)
freeBytesAvailableToCaller uint64
totalNumberOfBytes uint64
totalNumberOfFreeBytes uint64
)
err = windows.GetDiskFreeSpaceEx(
directoryName,
&freeBytesAvailableToCaller,
&totalNumberOfBytes,
&totalNumberOfFreeBytes,
)
if err != nil {
return 0, 0, err
}
return totalNumberOfBytes, totalNumberOfFreeBytes, nil
}
disk/disk_other.go
:
//go:build !(linux || windows)
package main
import (
"fmt"
)
func DiskSpace(mount string) (total, free uint64, err error) {
err = fmt.Errorf("DiskSpace not implemented for this OS")
return 0, 0, err
}
在Linux上:
disk$ go build && ./disk
64183046144 37856325632
$
在Windows上:
disk>go build && disk.exe
205507317760 59385081856
>
你可能想考虑在开发中使用WSL。
Windows Subsystem for Linux (WSL)允许开发人员在Windows上直接运行GNU/Linux环境,无需传统虚拟机或双启动设置的开销。
英文:
Go source file package imports are processed by the compiler. A runtime check, runtime.GOOS == "linux"
, is not going to work; it's too late. Use Go compiler build constraints.
For both Linux and Windows, using both explicit and file name implicit build constraints,
disk/disk.go
:
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
mount := string(filepath.Separator)
total, free, err := DiskSpace(mount)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Println(total, free)
}
disk/disk_linux.go
:
package main
import (
"golang.org/x/sys/unix"
)
func DiskSpace(mount string) (total, free uint64, err error) {
var stat unix.Statfs_t
err = unix.Statfs(mount, &stat)
if err != nil {
return 0, 0, err
}
total = uint64(stat.Blocks) * uint64(stat.Bsize)
free = uint64(stat.Bfree) * uint64(stat.Bsize)
return total, free, nil
}
disk/disk_windows.go
:
package main
import (
"golang.org/x/sys/windows"
)
func DiskSpace(dir string) (total, free uint64, err error) {
var (
directoryName = windows.StringToUTF16Ptr(dir)
freeBytesAvailableToCaller uint64
totalNumberOfBytes uint64
totalNumberOfFreeBytes uint64
)
err = windows.GetDiskFreeSpaceEx(
directoryName,
&freeBytesAvailableToCaller,
&totalNumberOfBytes,
&totalNumberOfFreeBytes,
)
if err != nil {
return 0, 0, err
}
return totalNumberOfBytes, totalNumberOfFreeBytes, nil
}
disk/disk_other.go
:
//go:build !(linux || windows)
package main
import (
"fmt"
)
func DiskSpace(mount string) (total, free uint64, err error) {
err = fmt.Errorf("DiskSpace not implemented for this OS")
return 0, 0, err
}
On Linux:
disk$ go build && ./disk
64183046144 37856325632
$
On Windows:
disk>go build && disk.exe
205507317760 59385081856
>
You may want to consider using WSL for development.
> Windows Subsystem for Linux (WSL) lets developers run a GNU/Linux environment directly on Windows, unmodified, without the overhead of a traditional virtual machine or dual-boot setup.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论