Is there a way to use environment variables with Ninja? - build

I have the following ninja file because I could not find a way to pass environment variables to ninja steps:
rule init
command = sh init.sh
rule plan
command = sh plan.sh
rule apply
command = sh apply.sh
build plan: plan
build init: init
build apply: apply
default plan
I would like to skip using shell scripts and capture all the steps in Ninja. I am not sure if this is supported at all.

It is a design decision of Ninja not to do that. If you need to pass in any parameter to Ninja the supported way to generate the build file with a build generator.

Related

Run ninja without rules

I have a build where it would be easiest for now to just have unique build rules for each build target (eg object file and library). Is it possible to specify in the build.ninja-file what to do without first specifying a rule for it.
For example (toy syntax)
build this_file: depends_on_this.o depends_on_that.o - gcc argumentss_to_use files.o etc
As usual I found out a way to do this a minute after asking.
We could just forward the whole command as a variable
rule run
command = $cmd
build log.txt: run
cmd = echo $hello >> log.txt

How can I run multiple builds in parallel in Travis CI, each with a separate script, for a C++ project?

I have a C++ project for which I would like to automate builds using Travis CI.
The project uses GNU make to build. There are multiple build targets, which are independent of each other, and I would like to automate the check that the build succeeds for each target using Travis CI. So, I would like multiple Travis builds to run for each commit, one for each target.
One way I could do this is:
script:
- make target1
- make target2
- make target3
However, this could potentially hide problems, such as the case where the build of target2 succeeds only when target1 has already been built.
An alternative could then be:
script:
- make target1
- make clean
- make target2
- make clean
- make target3
This looks a bit ugly, and also could take more time than needed. Errors in the build of target3 cannot be found till target1 and target2 are successfully built.
A better way might be to use the build matrix feature of Travis, which is what I have been unable to do. I tried the following:
matrix:
- script: make target1
- script: make target2
- script: make target3
But this doesn't work. The Travis documentation for C++ suggests that a matrix can interleave different environments and compilers, and I am not able to find any way to run different scripts separately. Can this be specified with the environment in some way?
Is this possible? If so, what is the correct way to do this?
Thank you.
I have found the solution. Information on this is given in the Travis Docs here, and information specific to Makefiles is given here.
The solution that worked for me is:
env:
matrix:
- TARGET="target1"
- TARGET="target2"
- TARGET="target3"
script:
- make $TARGET
This creates three jobs that run in parallel.

How can NPM scripts use my current working directory (when in nested subfolder)

It's good that I can run NPM scripts not only from the project root but also from the subfolders. However, with constraint that it can't tell my current working path ($PWD).
Let's say there's a command like this:
"scripts": {
...
"pwd": "echo $PWD"
}
If I run npm run pwd within a subfolder of the project root (e.g, $PROJECT_ROOT/src/nested/dir), instead of printing out my current path $PROJECT_ROOT/src/nested/dir, it always gives $PROJECT_ROOT back. Are there any way to tell NPM scripts to use my current working directory instead of resolving to where package.json resides?
Basically I want to pull a Yeoman generator into an existing project and use it through NPM scripts so that everyone can use the shared knowledge (e.g, npm run generator) instead of learning anything Yeoman specific (e.g npm i yo -g; yo generator). As the generator generates files based on current working path, while NPM scripts always resolves to the project root, I can't use the generator where it intend to be used.
If you want your script to use different behavior based on what subdirectory you’re in, you can use the INIT_CWD environment variable, which holds the full path you were in when you ran npm run.
Source: https://docs.npmjs.com/cli/run-script
Use it like so:
"scripts": {
"start": "live-server $INIT_CWD/somedir --port=8080 --no-browser"
}
Update 2019-11-19
$INIT_CWD only works on *nix-like platforms. Windows would need %INIT_CWD%. Kind of disappointing that Node.js doesn't abstract this for us. Solution: use cross-env-shell live-server $INIT_CWD/somedir.... -> https://www.npmjs.com/package/cross-env
One known solution is through ENV variable injection.
For example:
Define scripts in package.json:
"pwd": "cd $VAR && echo $PWD"
Call it from anywhere sub directories:
VAR=$(pwd) npm run pwd
However, this looks really ugly, are there any cleaner/better solutions?
With node 8+ you can automate the ENV variable injection.
1.- In $HOME/.node_modules/ (a default node search path) create a file mystart with
process.env.ORIGPWD = process.env.PWD
2.- Then in your $HOME/.bashrc tell node to load mystart every time
export NODE_OPTIONS="-r mystart"
3.- Use $ORIGPWD in your scripts. That works for npm, yarn and others.

How to use multiple build.gradle files?

My project structure is:
I want user additionally to configure the build using some of the build scripts from specifications dir but the main build script to be used to configure the project as well. Using -b option give the ability to specify another build scrpt different from the default one, but I want this default one to be executed as well. I don't want to use apply from: and to add all scripts because user have to decide what he wants.
So is there a way to tell Gradle to add additional build script - command line with which to configure extra the Project?
If you need this this, you could do something like this:
apply from: "config/specifications/${project.spec}.gradle"
which would then allow users to do e.g.
./gradlew -P spec=example
See https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_properties_and_system_properties for more details on setting project properties from the command line.

How can I persist an environment variable to the visual studio build helper?

I've got an NMake project in Visual Studio 2008 that has the Build command set to a custom tool that performs a long build task.
Build = "#call MyTool -config $(ConfigurationName)"
I want a way to to pass a special flag ("-quickbuild") to my tool to tell it to do a quick subset of the overall build.
Build = "#call MyTool -config $(ConfigurationName) -quickbuild"
However I want it to be easy to switch between them so I don't actually want to change the build command.
My thought was to change the build command to this:
Build = "#call MyTool -config $(ConfigurationName) $(ShouldQuickbuild)"
and create a visual studio macro that will set the "ShouldQuickbuild" environment variable to "-quickbuild" then call DTE.Solution.SolutionBuild.BuildProject(...) on the project. The problem is it doesn't see the "ShouldQuickbuild" environment variable.
Any ideas on how I can get this working. Is there a better approach for doing what I want?
Use a batch file and check, If the environment is passed on to the batch file, then you can get that in the batch file and call the actual tool that you want.
The batch file would look like this :
#echo off
MyTool -config %1 %ShouldQuickbuild%
IF the environment is not passed to the batch file, you have to somehow get the info across, globally. Is it possible to create a file from a VS macro? Or call an EXE? Then it's quite simple..
Try putting your variable inside of % delimiters, as in %ShouldQuickBuild%.
You can you control this with the "Solution Configureation". Create two new configureations "Debug Quick" and "Release Quick". These would be copies of the originals. Then change the build command for each configuration.