How to add custom option to target in makefile? - makefile

I am working at a make file with a target that allows me to run System Component Tests(SCTs). The target is called sct which after some pre-work calls the command python -m pytest -n auto. I need to add a optional flag to the target to switch between the mentioned command line and python -m pytest -n0.
If nothing is set (make sct) pytest should be started with the option -n auto. If the flag is added (name should be "non-dist" -> sth. like make sct --non-dist) pytest should be started with the -n0 option.
Is there a way to add an flag to my sct target? If you don't have a solution some keywords to find a solution myself would help a lot.

A common arrangement is to define a variable, which can easily be overridden on the command line.
# default flags
SCTFLAGS := -n auto
sct:
python -m pytest $(SCTFLAGS)
You can add some embellishments to make it easier for the person running make to pick a valid value, but this should at least get you started. Just make will run with the default value, and
make SCTFLAGS=-n0
will run with the non-prod flags.

Related

How to get GNU Make to tell me why it is rebuilding a target

Is there a way to tell make to show me a list of inputs to a target and which ones are triggering a rebuild because they have been modified?
Yes, you can use the -d option in make to show detailed information about the dependencies and the commands being executed. For example, if you run make -d , make will show a list of the dependencies of the target, as well as the commands being executed and their output.
Additionally, you can use the -n option to show what make would do, without actually executing any commands. This is useful to see which targets would be rebuilt because their dependencies have been modified. For example, if you run make -n , make will show the dependencies of the target and the commands that would be executed, without actually executing them.

Set Info.plist Value from Build Phase

I have an iOS for which I want to run a build phase that reads a value from a JSON file, export that as an environment variable and then read that in my Info.plist.
I currently have:
# Build Scripts/SetAPIVersion
set -e
if ! which jq > /dev/null; then
echo "error: jq is missing. Be sure to git pull `dev-box` and run apply.sh"
exit 1
fi
export API_VERSION =$(cat ../src/version.json | jq .api)
echo "Set API Version to $(API_VERSION)!"
My application will build however the value does not appear to be set. What am I doing wrong here?
You can use this:
plutil -replace APIVersion -string <VERSION> <PATH TO INFO>.plist
Also you can use PlistBuddy:
/usr/libexec/PlistBuddy -c "Set :APIVersion string <VERSION>" <PATH TO INFO>.plist
If versions are static numbers depending on environment, you can use project build settings user defined variable to:
The shell interpreter is run as a subprocess. When it exports an environment variable, that only affects that shell interpreter process and its subprocesses, but doesn't affect the parent process (i.e. Xcode) nor its sibling processes (other build phases).
You can make the shell script build phase take an input file, say Info.plist.in, and produce Info.plist from that. It would transform the input to the output however you like. For example, it could use sed to replace a special string with the value it should have. Be sure to configure the inputs and outputs of the run-script build phase as appropriate.
Alternatively, you could have the run-script build phase produce a header file that defines a macro, say api_version.h which #defines API_VERSION, #include that header file in your Info.plist, and enable preprocessing of Info.plist in the build settings. Again, make sure the inputs and outputs of the run-script phase are correct.

Rerun execute_process on file change

I am looking for a way to get CMake to re-run a shell command every time it detects that the dependencies for a specific target/executable has changed. I tried adding a custom command the has a dependency on a target, but this does not seem to be doing the trick.
Example of what I thought might work:
ADD_CUSTOM_COMMAND(
OUTPUT temp
DEPENDS my_Target
COMMAND ./some_command.sh)
Any suggestions of a command that may be able to run a command when a dependency change has been detected for a target. Or even better if we can check for a change in specific files.
From your description, it sounds like you might want this:
cmake_minimum_required(VERSION 2.8)
project(cmaketest)
add_custom_command(OUTPUT some_file.cpp
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.cpp
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/bar.cpp
${CMAKE_CURRENT_BINARY_DIR}/some_file.cpp
VERBATIM
)
add_executable(mn main.cpp some_file.cpp)
Put the output file in the source list of the target which depends on it.
add_custom_command() uses simple check for OUTPUT file existence to determine if the command should be run. If it doesn't exist, then CMake do make my_Target and only then run your command. At the same time, if OUTPUT exist, CMake doesn't run anything at all.
To achieve what you want you need to add_custom_target() (probably with ALL keyword to run it with make) and implement checking for changes inside your some_command.sh.

Two lines of shell script

I know nothing about shell scripting but something has come up and I need to be able to understand what two lines of code do so that I can modify a project I am working on
SDKROOT= make -C $TEMP_DIR -f $PROJECT_DIR/greg/Makefile VPATH=$PROJECT_DIR/greg || exit $?
$TEMP_DIR/greg -o $DERIVED_FILES_DIR/${INPUT_FILE_BASE}.m $INPUT_FILE_PATH
will you please explain what these two lines of code do... I know what the variables are and the path names but the rest of the syntax is confusing and foreign. Please help.
The first line:
SDKROOT= make -C $TEMP_DIR -f $PROJECT_DIR/greg/Makefile VPATH=$PROJECT_DIR/greg || exit $?
SDKROOT= sets the environment variable SDKROOT to nothing for the execution of the make command.
make is the build tool, and it's being run with the following options:
-C $TEMP_DIR: means run make in the directory $TEMP_DIR
-f $PROJECT_DIR/greg/Makefile specifies to make to use the Makefile in $PROJECT_DIR/greg
VPATH=$PROJECT_DIR/greg sets another variable, VPATH to $PROJECT_DIR/greg. VPATH specifies to make a search path for prerequisits.
|| exit $? means that if the make command fails the script should exit with the same error code as make, as $? means the return code of the last run program/command.
The second line:
$TEMP_DIR/greg -o $DERIVED_FILES_DIR/${INPUT_FILE_BASE}.m $INPUT_FILE_PATH
appears to be running the command $TEMP_DIR/greg with the option -o $DERIVED_FILES_DIR/${INPUT_FILE_BASE}.m and with some input from $INPUT_FILE_PATH. This looks like the program which may have been built from the previous line's make command, so it's hard to know exactly what it does.
EDIT
The SDKROOT is an environment variable used by XCode to say where the SDK it's using is installed. It will be a path like /Developer/SDKs/MacOSX"${HOST_VERSION}".sdk/ for instance. The value should be setup somewhere in XCode I imagine (I don't used xcode so can't be more helpful than that.). By doing SDKROOT= at the beginning of the command the value of SDKROOT will be nothing/blank. The reason for this is that the code being compiled will use resources which exist in the SDKROOT, rather than local ones; such resources may be classes, config or libraries for example.

Can I refer to the default target on the "make" command line?

If I type just
$ make
it will invoke the make command with the default target (typically the first target specified in the Makefile, but the rules are a bit more complicated than that).
Is there a way to specify the default target on the command line without knowing what it is, other than by simply omitting the target name?
What I'd like to be able to do is combine these two commands:
$ make clean
$ make
into a single invocation of make. If I happen to know that the default target is all, I can type:
$ make clean all
but that doesn't work if I don't know what the default target is.
Ideally, I'd like some syntax that refers to the default target (the GNU make manual calls it the "default goal"). This:
$ make clean .DEFAULT_GOAL
shows the general idea, but it doesn't work.
Second best would be a simple and reliable way to determine, from the command line, what the default target is:
$ make clean $(get-default-target)
A GNU-specific solution would be ok.
I suspect, from a quick look into the manual, that there's no good way to do this.
For a shot at the second-best solution, you can parse the default goal from the output of make -pq:
make -pq | sed -ne 's/^.DEFAULT_GOAL := //p'

Resources