Can I pass commandline arguments when invoking "zig build run"? - command-line-arguments

I'm just starting with the new programming language Zig and finding documentation pretty sparse.
I can build and run the current project by invoking zig build run.
I can also do zig run src/main.zig assuming standard project layout.
But in neither case can I find a way to pass along commandline arguments to my project.
I know that after building I can invoke my project as a binary as zig-out/bin/<my project's name> foo bar but is there a way to do it straight from build run?
Just trying the obvious zig build run foo bar tells me Cannot run step 'foo' because it does not exist.
None of the commandline switches for zig itself seem to do what I want and I can't find anyone discussing this by Googling for it.

just pass your arguments after -- (zig build run -- <args>)
e.g:
zig build run -- foo bar

Related

How can I prepare a Linux source tree so an external module can be compiled against it?

I am keeping a WIFI driver alive by patching compilation errors for new Kernel versions. I can build it against a source tree, so I do not have to boot the kernel for which I want to fix it.
Unfortunately for this I have to fully compile the entire kernel. I know how to build a small version by using make localmodconfig, but that still takes very long.
Recently, I learned about the prepare target. This allows me to "compile" the module, so I learn about compilation problems. However, it fails in the linking phase, which prevents using make prepare in a Git bisect run. I also had the impression that it requires to clean the source tree from time to time due to spurious problems.
The question is: What is the fastest way to prepare a source tree so I can compile a Wifi module against it?
The target you are looking for is modules_prepare. From the doc:
An alternative is to use the "make" target "modules_prepare." This will make sure the kernel contains the information required. The target exists solely as a simple way to prepare a kernel source tree for building external modules.
NOTE: "modules_prepare" will not build Module.symvers even if CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be executed to make module versioning work.
If you run make -j modules_prepare (-j is important to execute everything in parallel) it should run pretty fast.
So what you need is basically something like this:
# Prepare kernel source
cd '/path/to/kernel/source'
make localmodconfig
make -j modules_prepare
# Build your module against it
cd '/path/to/your/module/source'
make -j -C '/path/to/kernel/source' M="$(pwd)" modules
# Clean things up
make -j -C '/path/to/kernel/source' M="$(pwd)" clean
cd '/path/to/kernel/source'
make distclean
The last cleaning up step is needed if you are in a bisect run before proceeding to the next bisection step, otherwise you may leave behind unwanted object files that might make other builds fail.

How to build `cmd/compile` itself

Goal
I want to build cmd/compile, which is the compile command of go.
Problem
First, I cloned https://github.com/golang/go to ~/src/github.com/golang/go and modify codes in src/cmd/compile.
Second, I moved to ~/src/github.com/golang/go/src, and typed go build -o aaa -i cmd/compile.
Finally, aaa works, but it does not contain anything I modified.
As you know, in anywhere (even if ~/ or /tmp or the others), once you type go build -o aaa -i cmd/compile, you can get aaa.
But, I want make it modify, and build it.
How can I do that?
When you build the package cmd/compile, it builds the stdlib package for the current compiler, not the package in the source tree you're in.
If you're planning to work on the compiler itself, you need to bootstrap your own compiler:
Clone the go source code
Go to /src
Run ./all.bash
That will build the whole source tree, and create a new compiler for you. Once that's done, you have to use the compiler built by this process, which is under ~/src/github.com/golang/go/bin.

Cross compile from Windows to Linux using os/exec Command

The title mostly says it. I know that I can do
set GOOS=linux
set GOARCH=amd64
in cmd before I go build, but I'm trying to write a build script and do it all with exec.Command.
My go build -o etc works with exec.Command (it builds), but when printing out GOOS in a test script after either of this commands:
cmd := exec.Command("set", "GOOS=linux")
// OR
cmd := exec.Command("set GOOS=linux")
I get windows.
Any ideas? Thanks!
I strongly suggest you just use a tool like Gox instead. It cross-compiles into every supported build target by just executing gox. It also has options if you only want to build for certain targets.
As for the code you're asking about, exec.Command doesn't create a new process, or really do anything other than create a Cmd struct. The os/exec documentation (specifically the docs for the Command function) has an example of what you seem to be trying to do- execute another program with custom environment variable assignments... see the Example (Environment) section of the linked documentation and try to follow that structure if you still want to cross-compile your way.

Consistent builds / remove personal information from binaries

I've now realized that Go saves absolute paths to source code in binaries for the purpose of printing stack-traces and the likes. I don't want to completely remove this information, however, this also means that every developer building the same program will produce an executable with a different checksum. Before I try to reimplement the build using chroot or something like that: isn't there any way to tell Go not to use absolute paths for this purpose?
I know it doesn't directly address what you asked, but #JimB's suggestion does indicate a class of solutions to the problem you seem to be having.
One of the easier ones (I think) would be to have your developers install Docker and create an alias so that the go command runs:
docker run --rm --tty --volume $GOPATH:/go golang:1.7.1(-$YOUR_PLATFORM) go
Then, every build (and test and run) thinks it's using a GOPATH of /go and your developers' checksums won't disagree based on that.
See here for more info.
isn't there any way to tell Go not to use absolute paths for this purpose?
Nowadays there is: -trimpath.
https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies explains:
-trimpath
remove all file system paths from the resulting executable.
Instead of absolute file system paths, the recorded file names
will begin either a module path#version (when using modules),
or a plain import path (when using the standard library, or GOPATH).

Change Gnu Make -j Behavior to personally ignore, but pass on?

I have a makefile that is a 3rdParty dependency builder, so it's actually just going to various other directories and running cmake/make with various flags to ensure all 15-20 dependencies of my project compile the way I need.
Building parallel would really help here, (the build takes about 2 hours serially), but I need a 'make -jN' to not run the toplevel makefile parallel, instead run it serially (the various 3rdParty libs have internal dependencies to meet) and pass the arg to the inside makefiles.
Is there a way to get this behavior?
Use the .NOTPARALLEL pseudo target; from the docs:
`.NOTPARALLEL'
If `.NOTPARALLEL' is mentioned as a target, then this invocation of
`make' will be run serially, even if the `-j' option is given.
Any recursively invoked `make' command will still be run in
parallel (unless its makefile contains this target). Any
prerequisites on this target are ignored.

Resources