使用Go动态创建编译二进制文件。

huangapple go评论77阅读模式
英文:

Dynamically create compiled binary with go

问题

首先,对于标题可能不太好的问题我表示抱歉 - 我想我遇到的困难很大程度上与我不知道如何正确表达我想要实现的内容有关。

在Go语言中,我希望有一个程序,当运行时可以动态地创建一个二进制子程序。为了用一个基本的Hello World示例来说明,以下是伪代码,因为我不知道如何实现它。

generator.go
-> 从statement.txt中读取语句(例如"Hello World")
-> 将这个语句插入到以下程序中...

package main

import (
    "fmt"
)

func main(){
    fmt.Println([在此处插入动态语句])
}

-> 将此代码编译为子程序

每当执行go run generator.go时,都会创建一个subprogram二进制文件。运行该文件将输出Hello World。将statement.txt更改为其他内容,再次执行go run generator.go将再次创建subprogram,运行该文件将执行新的语句。

总结一下:

  • 使用Go语言,我如何创建一个程序,可以动态地创建一个编译后的子程序作为输出。

谢谢。

英文:

First sorry for perhaps a bad title - I imagine a lot of the difficulty I'm experiencing relates to not knowing the correct terminology for what I'm trying to achieve.

In Go, I wish to have a program which when run can dynamically create a secondary binary. To illustrate with a basic hello world example - in pseudo code since I don't know how to achieve it.

generator.go
-> Read in statement from statement.txt (i.e. "Hello World")
-> Insert this statement into the following program...

package main

import (
    "fmt"
)

func main(){
    fmt.Println([dynamic statement inserted here])
}

-> compile this code into subprogram

Whenever go run generator.go is executed a subprogram binary is created. Running this would output Hello World. Changing statement.txt to something else and executing go run generator.go again would once more create subprogram which when run would execute the new statement.

In summary

With Go, how can I create a program which can dynamically create a compiled child program as output.

Thanks.

答案1

得分: 6

所以你有两个子任务,它们一起完成你想要的功能:

  1. 执行文本替换以获取最终的源代码。
  2. 将最终的源代码编译成可执行二进制文件。

1. 文本替换

第一个任务可以使用text/template包轻松完成。你可以将源模板作为单独的文件,或者嵌入到主Go源代码中(例如作为const)。

你可以使用template.ParseFiles()template.New().Parse()来构建/解析源代码模板,并获得一个Template。一旦你有了模板,可以组装(例如从文件加载)要包含在源模板中的值,并使用Template.Execute()来执行它。这样你就得到了最终的源代码。

text/template包提供了一个强大的模板引擎,不仅仅可以进行文本替换。

**注意:**在go的子包中,还有一个Go解析器的实现可供你使用,它已经在标准库中可用。但是,对于你的情况来说,使用text/template包更简单,而且看起来足够好。

2. 编译

要将最终的源代码编译成可执行二进制文件,你需要编译器的帮助。你可以使用os/exec包来调用编译器,它将生成二进制文件。可以使用exec.Command()函数获取一个Cmd,然后使用Cmd.Run()Cmd.Start()来执行它。

英文:

So you have 2 sub-tasks which together do what you want:

  1. Perform a text substitution to acquire the final source code.
  2. Compile the final source code into executable binary.

1. Text substitution

The first can be easily done using the text/template package. You can either have the source templates as separate, individual files, or embedded in the main Go source (e.g. as consts).

You can build / parse the source code templates and get a Template with e.g. template.ParseFiles() or using template.New().Parse(). Once you have your template, assemble (e.g. load from file) the values you want to include in the source template and execute it e.g. with Template.Execute(). You have the final source now.

The text/template package gives you a powerful template engine which is capable to a lot more than just text substitution.

Note: There is also a Go parser implemented and available in the standard library at your disposal in the subpackages of go, but using the text/template package is much simpler and looks it's enough and perfectly fine for your case.

2. Compile

To compile the final source into an executable binary, you need the help of the compiler. You can use the os/exec package to invoke the compiler which will produce the binary. See the exec.Command() function to acquire a Cmd, and Cmd.Run() and Cmd.Start() to execute it.

huangapple
  • 本文由 发表于 2015年5月15日 19:54:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/30258900.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定