Set workdir/pwd of go build - go

Is it possible to set the workdir to a different path?
For example, I want to run go build from the root path, but my source code is under a different directory, and I do not want to cd to it.
npm, for example, has the --prefix, which serves for this purpose.

Yes, its possible.
go build -o [output file path/name] [source code file path/name]
For example, if your source code file is located in projectdir/code/src/ and want to build and save output to projectdir/code/out, do following:
$ go build -o projectdir/code/out/main projectdir/code/src/main.go
As per go build documentation:
If the named output is an existing directory or ends with a slash or
backslash, then any resulting executables will be written to that
directory.
So our above build command can be rewritten like this:
go build -o projectdir/code/out/ projectdir/code/src/main.go
and it will generate executable named main in projectdir/code/out/ directory.
For more details, run go help build

No, this is not possible with 1.19. Just cd into it.
Go 1.20 (yet unreleased) brings the -C flag which might be what you want.

Related

Git Pre-Commit Hook: Unable to Run `dartfmt` (command not found) (Windows)

Ideally, I would like to have dartfmt to format my code on every commit, and I think that git hooks are ideal for this. So far, I've tried the code found in this link, but with no success, despite it appearing on multiple other websites — maybe it's outdated.
In the end, I think nothing much more complicated than this should work in most cases (inside the .git/hooks/pre-commit file):
#!/bin/bash
dartfmt -w . # or maybe `flutter format .` for Flutter
The errors I get are:
For dartfmt -w .: dartfmt: command not found
For flutter format .: find: ‘> bin [’: No such file or directory
Both of those commands do work if placed directly in the terminal.
to make dartfmt work, try running which dartfmt manually to get the path to the executable, and then use the absolute path when calling it in the script.
If which isn't able to find it, and assuming you know the complete path to the directory where dartfmt is located, try adding that directory to PATH in the script:
#!/bin/bash
PATH="/path/to/dart-sdk/bin:$PATH"
export PATH
Also, I'd suggest taking a moment double check what git will use for the working directory when it calls those hook scripts. There might be some undesired behavior by using . if the CWD isn't what is expected. See this post.
To format your dart code regularly, you can follow one of the two ways mentioned below:
Preferred way:
In IntelliJ Idea go to Settings -> Language & Frameworks -> Flutter -> Select Format Code on save option.
This will format your code every few seconds. This is preferred because you can customize your personal formatting settings such as max words in a line etc.
Alternatively
From Official website run dartfmt -w bin lib to format your code from the command line.
Add dartfmt reference in PATH, like this:
export PATH="/xxx/flutter/bin/cache/dart-sdk/bin:$PATH"

Make goimports NOT scan files within vendor

I want to setup a CI system that it fails when code is not properly formatted according to goimports.
How I list my dirs:
go list -f {{.Dir}} ./...
/Users/felix/gocode/src/github.com/XXXX/YYY
/Users/felix/gocode/src/github.com/XXXX/YYY/cmd/foo
/Users/felix/gocode/src/github.com/XXXX/YYY/cmd/dev
/Users/felix/gocode/src/github.com/XXXX/YYY/pkg/monitoring/top
How I run goimports in the end:
goimports -l $(go list -f {{.Dir}} ./...)
/Users/felix/gocode/src/github.com/XXX/YYY/config.go
/Users/felix/gocode/src/github.com/XXX/YYY/raid_test.go
/Users/felix/gocode/src/github.com/XXX/YYY/vendor/github.com/shirou/gopsutil/disk/disk_freebsd.go
/Users/felix/gocode/src/github.com/XXX/YYY/vendor/github.com/shirou/gopsutil/disk/disk_linux.go
/Users/felix/gocode/src/github.com/XXX/YYY/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
As you can see it also lists files within vendor. The execution also takes quite some time so I guess it's really checking all the files.
I really just care about the files outside vendor.
I think you use <1.9 Go version. Since 1.9 ./... shouldn't match vendor directory. See https://golang.org/doc/go1.9#vendor-dotdotdot.

Modify source files during cmake build

I need to modify some of my project's sources during compilation. It'd be better if I get to modify them between preprocessing and compilation, but I know it's harder to achieve (The solution proposed here is not optimal for me) so I can settle with a pre-preprocessing step.
Since the source files are to be modified, I need to create a copy of them, modify that copy then run the build on this copy. My current solution is:
Prior to cmake invocation, I copy most of the project root contents' to a separate directory. This is required because there are many script invocations during the build so I need to keep most of the project hierarchy intact. Since there are many files and many of them will not be modified, I first copy all files as symbolic links (cp -sR), then hard copy all .c and .h files. Then I just cd to that directory and invoke cmake and make as usual.
The problem here is that since cmake is not aware that it's working on copies of the actual source, the generated Makefile doesn't check whether the actual source was updated. So I need a full rebuild (Full project tree copy and cmake invocation) whenever I modify a single source file.
This can probably be solved by adding a custom command for each hard copied source file that depends on the actual source file, and recopies it after being modified. I guess it's okay, but it really is... ugly, and requires lots of cmake additions. I don't think what I'm trying to do is so exotic, so I believe there is a better option that could work with little changes to my cmake. I'd also like to hear ideas regarding post preprocessor step invocation.
EDIT: A simplified example case.
This is the project tree:
CMakeLists.txt
src/
CMakeLists.txt
file1.c
file1.c
python/
script.py
The root CMakeLists.txt is add_subdirectory(src/). The src/CMakeLists.txt is add_executable(myexe file1.c file2.c).
I need to execute python python/script.py for each source file, so it should be called on src/file1.c and src/file2.c.
My current solution is a build script as follows:
rm -r build_dir
mkdir build_dir
cp -rt build_dir CMakeLists.txt src/ python/
cd build_dir
cmake .
make # ...
Plus an invocation of python/script.py (prebuild add_custom_command) which globs for the relevant files itself, then processes them.

Running a bash command via CMake

I'm trying to have CMake either run three bash commands or a bash script. However, I can't seem to get it to work.
The bash commands are:
cd ${CMAKE_SOURCE_DIR}/dependencies/library
make
cd ${CMAKE_BINARY_DIR}
Essentially, I would like CMake to build the library in that directory if it does not already exist.
Here's the CMake code I tried:
if(NOT "${CMAKE_SOURCE_DIR}/dependencies/library/lib.o")
execute_process(COMMAND cd ${CMAKE_SOURCE_DIR}/dependencies/library)
execute_process(COMMAND make)
execute_process(COMMAND cd ${CMAKE_BINARY_DIR})
endif(NOT "${CMAKE_SOURCE_DIR}/dependencies/library/lib.o")
However, it's not building anything. What am I doing wrong?
Also, while I'm here asking this: should the third command, to move to the binary folder, be included?
Thanks!
execute_process() is executed during configure time. But you want this to run at build time, thus add_custom_command() and add_custom_target() is what you're looking for.
In this special case you want to generate an output file, so you should go for add_custom_command() (both are essentially the same, but command produces one or multiple output files, while target does not.
The cmake snippet for this should look something like the following:
add_custom_command(
OUTPUT ${CMAKE_SOURCE_DIR}/dependencies/library/lib.o
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/dependencies/library
COMMAND make
)
You then have to add the output file in another target as dependency, and everything should (hopefully) work as expected.
You can also add DEPENDS statements to the add_custom_command() call to rebuild the object file in case some input sources have changed.

Avoid typing out all go files in the main package when "Go run"-ng

When you have multiple .go files in a main package, i need to list them all out when doing a go run.
So when i have main.go, a.go, b.go and they all belong to the main package, i need to type go run main.go a.go b.go in order to use functions and structs inside the other 2 go files. The go build command however, is smart enough to link all files together automatically.
Have i misunderstood something about Go, or is this normal (listing out all the files in the main package when doing a go run)?
The short answer is: you need to list them all out. You can do this with shell tricks, if you're desperate. I usually just write a shell script to go build and then run the resulting executable, after it gets too annoying.
# this works unless you have _test.go files
go run *.go
# if you really want to... enable extended glob
shopt -s extglob
# so you can do something like this (matches all .go except *_test.go files)
go run !(*_test).go
Check out this thread: https://groups.google.com/forum/#!topic/golang-nuts/EOi0VAQNA4c
If your source is in $GOPATH/src
as in
$GOPATH/src/somedir/main.go
$GOPATH/src/somedir/a.go
$GOPATH/src/somedir/b.go
doing "go install somedir" will compile and install the somedir binary in to $GOPATH/bin
no need to list out the files individually
"go install" finds all the files on it's own.
My common work cycle with go is (from my bash prompt):
$ clear; go install myproj && $GOPATH/bin/myproj
which, clears the screen, builds and installs "myproj" and then runs it
so, after I change code, I just hit Ctrl-C, Up arrow, and enter.
Entire cycle time is ~1 second (for small to start stuff)

Resources