scons: how to define command/target that only takes place during 'scons -c'? - command

Before building the targets I wish to create some directory structures, I know I can use:
env = Environment()
env.Execute('mkdir -p xxx')
But this will cause "mkdir -p' to be executed even when I do clean up:
scons -c
And the "env.Execute" will gets called.
I wish there's some command or target that's only taking place when I execute 'scons -c'
How to achieve that?
Thanks.

The -c option is a built in scons option and you can check if it was set with GetOption('clean').
You could then call the commands conditionally based off the value of the 'clean' option. Here is an example:
env = Environment()
if not GetOption('clean'):
env.Execute('mkdir -p xxx')
else:
env.Execute('echo "Cleaning up..."')
More info on the other built in options can be found here:
https://scons.org/doc/production/HTML/scons-user.html#sect-command-line-option-strings
https://scons.org/doc/production/HTML/scons-man.html#options

Related

Is there a way to configure pytest_plugins from a pytest.ini file?

I may have missed this detail but I'm trying to see if I can control the set of plugins made available through the ini configuration itself.
I did not find that item enumerated in any of the configurable command-line options nor in any of the documentation around the pytest_plugins global.
The goal is to reuse a given test module with different fixture implementations.
#hoefling is absolutely right, there is actually a pytest command line argument that can specify plugins to be used, which along with the addopts ini configuration can be used to select a set of plugin files, one per -p command.
As an example the following ini file selects three separate plugins, the plugins specified later in the list take precedence over those that came earlier.
projX.ini
addopts =
-p projX.plugins.plugin_1
-p projX.plugins.plugin_2
-p projY.plugins.plugin_1
We can then invoke this combination on a test module with a command like
python -m pytest projX -c projX.ini
A full experiment is detailed here in this repository
https://github.com/jxramos/pytest_behavior/tree/main/ini_plugin_selection

How can I make a function run every time cd successfully changes to another directory within sh on FreeBSD?

I'm using sh as my shell on FreeBSD but I want to be able to have a pretty prompt like the one bash gives me on Ubuntu. There are two things that the FreeBSD implementation of sh seems to lack as far as PS1 escape characters go:
The \w works but does not expand $HOME to ~, so this is something I have already hacked up myself
I can use PS1 to update the prompt on the terminal, but as far as I can tell it is not possible to use the PS1 variable to update the title bar as well. ESC and BEL fail to set the title as one would expect if they were using bash or ksh
Here is my .shrc file
update_prompt() {
case "$PWD" in
"$HOME"*)
pretty_pwd="~${PWD#*"${HOME}"}"
;;
"/usr$HOME"*)
pretty_pwd="~${PWD#*"/usr${HOME}"}"
;;
*)
pretty_pwd="$PWD"
;;
esac
case "$TERM" in
xterm*|rxvt*)
PS1="[$USER#\\h $pretty_pwd]\\$ "
;;
*)
;;
esac
printf "\\033]0;[%s#$(hostname -s): %s]\\007" "$USER" "$pretty_pwd"
}
update_prompt
So when I fire up a terminal or log in via ssh, it gives the pretty prompt that I like. But now I need this function to run every time that cd is executed and returns an exit status of 0.
I was going to use an alias that was something like:
alias cd="cd $1 && update_prompt"
but that was before I realized that aliases do not except arguments. How might I go about doing something like this?
You can use a function instead of an alias:
cd() {
command cd "$#" && update_prompt
}
Just put it into ~/.shrc. You have to use command here to let sh know that you are referring to the actual cd builtin command instead of the function you've just defined.
Refer to the sh(1) manual page for the details on how to make sh(1) source the ~/.shrc file when it starts:
Therefore, a user should place commands that are to be executed only at login
time in the .profile file, and commands that are executed for every shell
inside the ENV file. The user can set the ENV variable to some file by placing
the following line in the file .profile in the home directory, substituting for
.shrc the filename desired:
ENV=$HOME/.shrc; export ENV
I use this trick in my cd alias manager. Here's a link to the source code of the function: https://github.com/0mp/goat/blob/v2.5.0/libgoat.sh#L31-L57
You can do it with alias+arguments if you swap the commands:
$ alias cd="echo change; cd"
$ pwd
/nas
$ cd /
change
$ pwd
/
$ cd /etc
change
$ pwd
/etc
$

Avoid executing custom commands in cmake when unnecessary

I have this custom build which invokes matlab to compile a .slx file into a .dll file.
function(BUILD_SIMULINK model)
set(EXECUTE_COMMAND matlab -r "rtwbuild( ${model} )" )
add_custom_target(
${model} ALL
COMMAND ${EXECUTE_COMMAND}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${model}.slx
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${model}.dll
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Building: ${model}"
)
endfunction(BUILD_SIMULINK)
However my problem is that whenever I use cmake --build ., this command will always be executed.
How can I prevent this command from executing when the DEPENDS hasn't changed and the OUTPUT exists? What I'm looking for is similar to how cmake avoids re-compiling c/cpp files when the source hasn't changed and the appropriate object file exists.
See add_custom_target() command documentation:
The target has no output file and is always considered out of date even if the commands try to create a file with the name of the target. Use the add_custom_command() command to generate a file with dependencies.
There is not OUTPUT keyword. I think its only accepted because CMake sees OUTPUT as a dependency. Actually I get an CMake warning when I run your code:
...
This project specifies custom command DEPENDS on files in the build tree
that are not specified as the OUTPUT or BYPRODUCTS of any
add_custom_command or add_custom_target:
test_model.dll
You need to use add_custom_command():
cmake_minimum_required(VERSION 2.6)
project(TestCustomTargetWithDependency NONE)
function(BUILD_SIMULINK model)
#set(EXECUTE_COMMAND matlab -r "rtwbuild( ${model} )" )
set(EXECUTE_COMMAND "${CMAKE_COMMAND}" -E touch "${model}.dll")
add_custom_command(
OUTPUT "${model}.dll"
COMMAND ${EXECUTE_COMMAND}
DEPENDS "${model}.slx"
COMMENT "Building: ${model}"
)
add_custom_target(
${model} ALL
DEPENDS "${model}.dll"
)
endfunction(BUILD_SIMULINK)
file(WRITE "test_model.slx" "")
BUILD_SIMULINK(test_model)
๐“๐“ธ๐“ฝ๐“ฎ: Sources/Dependencies default is CMAKE_CURRENT_SOURCE_DIR and outputs default is CMAKE_CURRENT_BINARY_DIR. No need to explicitly prefix those.

Error Packaging a Shell script with Autotools

I'm trying to write a simple Autotool package that just packages a single script. This might seem like overkill, but the script is to be added into the build-system for an embedded system and the build-system is designed to play nicely with Autotools.
I have a shell-script called wifi_query.sh. To package this I've followed the following steps:
Created Makefile.am which contains the following -
bin_SCRIPTS = wifi_query.sh
CLEANFILES = $(bin_SCRIPTS)
I also created wifi_query.sh.in which contains the line exec wifi_query.sh. I'm not sure I understand the purpose of the .in file.
I then run autoscan.
Then I run:
sed -e 's/FULL-PACKAGE-NAME/wifi_query/' \
-e 's/VERSION/1/' \
-e 's|BUG-REPORT-ADDRESS|/dev/null|' \
-e '10i\
AM_INIT_AUTOMAKE' \
< configure.scan > configure.ac
Run touch NEWS README AUTHORS ChangeLog.
Run autoreconf -iv
./configure
make distcheck
When I run make distcheck I get an error saying: "* No rule to make target 'wifi_query.sh', needed by 'all-am'. Stop.".
I don't understand this error, if anyone could give me any pointers that would be good. My suspicion is that the error may be due to wifi_query.sh.in, but I have very limited autotools experience.
It seems I needed to replace the line bin_SCRIPTS = wifi_query.sh with dist_bin_SCRIPTS = wifi_query.sh in Makefile.am. Having done that everything seems to work.

How to use Devel::Cover with prove?

I see there are some similar questions here and on http://www.perlmonks.org but I still do not get it.
Imagine I have a project with a 'lib/' and a 't' directories. I run my tests with 'prove':
$ cd $PROJECT_ROOT
$ prove ./*.t
I want to get a report in html for one or more files in the 'lib/' directory. I do not want reports for the files in the 't' directory.
A simple example should be enough. Thanks
perl Makefile.PL or perl Build.PL
cover -test
The proper way is to always start out with Makefile.PL/Build.PL, just as selected answer suggests. However, sometimes you are not the one who started out, so...
I used to make a fake makefile:
% cat Makefile
test:
prove -Ilib -r t
The following also seems to work (w/o touching ANY files on disk):
cover -t -make 'prove -Ilib -r t; exit $?'
This only works because of how perl's system/exec handle an argument with shell metacharacters in it (; in this case) and may break in the future if cover decides to quote it more rigirously. Also it shouldn't work under windows. I wish cover had a -prove option instead.
This one still generates coverage for *.t as well as CPAN modules at nonstandard locations. This behaviour can be fixed using +select/+ignore options (see the Devel::Cover's manpage):
cover -t +select ^lib +ignore ^
So the tl;dr "magic" command is
cover -t +select ^lib +ignore ^ -make 'prove -Ilib -r t; exit $?'
EDIT The following didn't work for me - it only prints short summary:
PERL5OPT="$PERL5OPT -MDevel::Cover" prove -Ilib -r t
cover -t +select ^lib +ignore ^
Note that prove -MSomething applies Something to prove itself and doesn't pass it on (unlike with -I).
Make prove run every test file with Devel::Cover activated:
$ prove --exec 'perl -MDevel::Cover=-silent,1 -Ilib' t/*.t
By default this will print the statistics after each test file. Thatโ€™s why I added -silent => 1.
To print the complete statistics at the end add:
$ cover -summary