SCons: Get abspath of original file (as though I hadn't set variant_dir) - scons

I can use File('foo.bar').abspath to get the location of a file, but if I've got variant_dir set then the returned path will be in variant_dir rather than it's original location. If I have duplicate=0 set, then the file returned won't actually exist.
Obviously SCons knows where the original file is, as it's passed as an argument when the file's actually built (eg gcc -c -o variant/foo.o orig/foo.c).
Is there some sort of File('foo.bar').origpath that I can use?
If it came to it I could use os.path.join(Dir('#').abspath, 'orig') but that requires the SConscript to know which directory it's in, which is messy.

You can use srcnode(). To quote the man page:
The srcnode() method returns another
File or Dir object representing the
source path of the given File or Dir.
This will give you the absolute path in the source directory:
File('foo.bar').srcnode().abspath

Related

Can not find object file with cmake link_directories

I want to add several .o files to the link process. If I do it like this:
TARGET_LINK_LIBRARIES(FFMPEGTest stdc++fs -pthread /home/stiv2/jsoft/nv-ffmpeg/ffmpeg/libswresample/audioconvert.o ...some more stuff... )
then it finds the file. All of these files are in the same directory, so I want to add them semultaneously:
link_directories(/home/stiv2/jsoft/nv-ffmpeg/ffmpeg/libswresample/)
TARGET_LINK_LIBRARIES(FFMPEGTest stdc++fs -pthread audioconvert.o ...some more stuff... )
but this doesn't work:
/usr/bin/ld: cannot find -laudioconvert.o
how do I fix this?
Documentation for target_link_libraries doesn't allow a relative path (audioconvert.o) to be a parameter to that command. It should be either absolute path (/home/stiv2/jsoft/nv-ffmpeg/ffmpeg/libswresample/audioconvert.o) or a plain library name (like z for libz.a library).
Because the object file audioconvert.o is not a library, it cannot be specified with a plain library name. You have no other choice than specify an absolute path for the object files.
For specify several object files in some directory you may use foreach loop:
foreach(obj audioconvert.o foo.o bar.o)
target_link_libraries(FFMPEGTest /home/stiv2/jsoft/nv-ffmpeg/ffmpeg/libswresample/${obj})
endforeach()
Actually, every parameter <param> to target_link_libraries, which doesn't look like an absolute path (and doesn't corresponds to a library target), is transformed into -l<param> option for the linker.
The linker interprets this parameter as a plain library name, and searches for a file named lib<param>.a or lib<param>.so in the link directories.
So, with parameter -laudioconvert.o the linker searches a file with a name libaudioconvert.o.a - obviously, this is not what do you want.

Linux Kbuild: what is the difference between $(src) and $(obj)

In Documentation/kbuild/makefiles.txt chapter 3.10 it is mentioned that $(src) refers to the location of the source code while $(obj) refers to the location of the generated output files. I am confused about this when using a different output directory.
In Makefile.build the very first thing that is done is src := $(obj). How does that make any sense? If I print $(src) and $(obj) they always have the same value.
However, what is even more confusing to me, is that if this was the case, make should issue an error.
If the working directory is outside the kernel source (O=path/to/out/dir) when the rule $(obj)/%.o: $(src)/%.c is evaluated it should search for the source file relative to the output directory. And since the source file is not there it should fail saying it cannot find a rule for $(src)/%.c target.
Can someone please explain what I'm getting wrong here?
Answering my own question in case others wondered about this...
The main Makefile uses vpath to add the src location, so when kbuild does not find the source file in the output tree it will find it in the source tree.

The system cannot find the file specified - WinError 2

Upon looping a directory to delete txt files ONLY - a message is returned indicating The System cannot find the file specified: 'File.txt'.
I've made sure the txt files that I'm attempting to delete exist in the directory I'm looping. I've also checked my code and to make sure it can see my files by printing them in a list with the print command.
import os
fileLoc = 'c:\\temp\\files'
for files in os.listdir(fileLoc):
if files.endswith('.txt'):
os.unlink(files)
Upon initial execution, I expected to see all txt files deleted except for other non-txt files. The actual result was an error message "FileNotFoundError: [WinError 2] The system cannot find the file specified: 'File.txt'.
Not sure what I'm doing wrong, any help would be appreciated.
It isn't found because the the path you intended to unlink is relative to fileLoc. In fact with your code, the effect is to unlink the file relative to the current working directory. If there were *.txt files
in the cwd then the code would have unfortunate side-effects.
Another way to look at it:
Essentially, by analogy, in the shell what you're trying to do is equivalent to this:
# first the setup
$ mkdir foo
$ touch foo/a.txt
# now your code is equvalent to:
$ rm *.txt
# won't work as intended because it removes the *.txt files in the
# current directory. In fact the bug is also that your code would unlink
# any *.txt files in the current working directory unintentionally.
# what you intended was:
$ rm foo/*.txt
The missing piece was the path to the file in question.
I'll add some editorial: The Old Bard taught us to "when in doubt, print variables". In other words, debug it. I don't see from the OP an attempt to do that. Just a thing to keep in mind.
Anyway the new code:
Revised:
import os
fileLoc = 'c:\\temp\\files'
for file in os.listdir(fileLoc):
if file.endswith('.txt'):
os.unlink(os.path.join(fileLoc,file))
The fix: os.path.join() builds a path for you from parts. One part is the directory (path) where the file exists, aka: fileLoc. The other part is the filename, aka file.
os.path.join() makes a whole valid path from them using whatever OS directory separator is appropriate for your platform.
Also, might want to glance through:
https://docs.python.org/2/library/os.path.html

zip command not working

I am trying to zip a file using shell script command. I am using following command:
zip ./test/step1.zip $FILES
where $FILES contain all the input files. But I am getting a warning as follows
zip warning: name not matched: myfile.dat
and one more thing I observed that the file which is at last in the list of files in a folder has the above warning and that file is not getting zipped.
Can anyone explain me why this is happening? I am new to shell script world.
zip warning: name not matched: myfile.dat
This means the file myfile.dat does not exist.
You will get the same error if the file is a symlink pointing to a non-existent file.
As you say, whatever is the last file at the of $FILES, it will not be added to the zip along with the warning. So I think something's wrong with the way you create $FILES. Chances are there is a newline, carriage return, space, tab, or other invisible character at the end of the last filename, resulting in something that doesn't exist. Try this for example:
for f in $FILES; do echo :$f:; done
I bet the last line will be incorrect, for example:
:myfile.dat :
...or something like that instead of :myfile.dat: with no characters before the last :
UPDATE
If you say the script started working after running dos2unix on it, that confirms what everybody suspected already, that somehow there was a carriage-return at the end of your $FILES list.
od -c shows the \r carriage-return. Try echo $FILES | od -c
Another possible cause that can generate a zip warning: name not matched: error is having any of zip's environment variables set incorrectly.
From the man page:
ENVIRONMENT
The following environment variables are read and used by zip as described.
ZIPOPT
contains default options that will be used when running zip. The contents of this environment variable will get added to the command line just after the zip command.
ZIP
[Not on RISC OS and VMS] see ZIPOPT
Zip$Options
[RISC OS] see ZIPOPT
Zip$Exts
[RISC OS] contains extensions separated by a : that will cause native filenames with one of the specified extensions to be added to the zip file with basename and extension swapped.
ZIP_OPTS
[VMS] see ZIPOPT
In my case, I was using zip in a script and had the binary location in an environment variable ZIP so that we could change to a different zip binary easily without making tonnes of changes in the script.
Example:
ZIP=/usr/bin/zip
...
${ZIP} -r folder.zip folder
This is then processed as:
/usr/bin/zip /usr/bin/zip -r folder.zip folder
And generates the errors:
zip warning: name not matched: folder.zip
zip I/O error: Operation not permitted
zip error: Could not create output file (/usr/bin/zip.zip)
The first because it's now trying to add folder.zip to the archive instead of using it as the archive. The second and third because it's trying to use the file /usr/bin/zip.zip as the archive which is (fortunately) not writable by a normal user.
Note: This is a really old question, but I didn't find this answer anywhere, so I'm posting it to help future searchers (my future self included).
eebbesen hit the nail in his comment for my case (but i cannot vote for comment).
Another possible reason missed in the other comments is file exceeding the file size limit (4GB).
I converted my script for unix environment using dos2unix command and executed my script as ./myscript.sh instead bash myscript.sh.
I just discovered another potential cause for this. If the permissions of the directory/subdirectory don't allow the zip to find the file, it will report this error. Actually, if you run a chmod -R 444 on the directory, and then try to zip it, you will reproduce this error, and also have a "stored 0%" report, like this:
zip warning: name not matched: borrar/enviar
adding: borrar/ (stored 0%)
Hence, try changing the permissions of the file. If you are trying to send them through email, and those email filters (like Gmail's) invent silly filters of not sending executables, don't forget that making permissions very strict when making zip compression can be the cause of the error you are reporting, of "name not matched".
spaces are not allowed:
it would fail if there are more than one files(s) in $FILES unless you put them in loop
I also encountered this issue. In my case, the line separate is CRLF in my zip shell script which causes the problem. Using LF fixed it.

Function works properly with relative path input but NOT with absolute path input

There exists a function that is part of a software package (MRICro), and it is called 'dcm2nii.'
When a relative path is used as the output directory, the function works perfectly well.
But, when the absolute path to the exact same folder is used, the function breaks down.
Example (absolute path):
dcm2nii -o /net/user1/project_name/Data/2011_01_10_SVD1/Processed/3_fMRI_rest E2538S3I00*
Example (relative path):
dcm2nii -o ../Processed/3_fMRI_rest E2538S3I00*
Sample error message that occurs when using the absolute path for the output folder (the last line suggests that the output file can not be created):
Validating 52 potential DICOM images.
Found 52 DICOM images.
Converting 52/52 2
E2538S3I0001.MR.dcm->20110110_112950E2538S3I0001MRFPSD1F29OCT2010RCs003a1001.nii
GZip 20110110_112950E2538S3I0001MRFPSD1F29OCT2010RCs003a1001.nii
unable to create /net/user1/project_name/Data/2011_01_10_SVD1/Processed/3_fMRI_rest/20110110_112950E2538S3I0001MRFPSD1F29OCT2010RCs003a1001.nii.gz
I do not know if this problem is due to me doing something wrong in Linux/bash or due to the function actually having a mistake.
But, any input is appreciated.
On a more general level, I am looking for any foreseeable reason for why a function would be able to use a relative folder path and not an absolute one (provided that they resolve to the same location).
EDIT: pwd gives:
/net/user1/project_name/Data/2011_01_10_SVD1/3_fMRI_rest
you would really have to show us the code before we can tell you what the cause of the problem is, however the behaviour you described is possible
This is an example of poor practice but consider the following
#!/bin/bash
....
current_dir = $(pwd)
out_dir = $1
cd ${somewhere}
..... do stuff
#no we want to come back to create the output dir
mkdir ${current_dir}/$out_dir
This appears to be a bug of some kind.. I am experiencing the same issue. If I try to execute this command on data in my home folder, I get the same error.
However, if I move my data to a path that doesn't involve any expansion, i.e. ''/tmp/data'', the program executes fine.

Resources