Add SCons files to ack searches - scons

I love the code search utility ack. It is smart enough to look through Makefiles, but doesn't know about the SConstruct and SConscript files that scons uses. How do I add those to the files that ack will look in?

Here is a patch that treats SCons files like make files:
--- ~/bin/ack-old 2011-06-01 15:43:51.000000000 -0600
+++ ~/bin/ack 2011-06-01 15:42:09.000000000 -0600
## -1583,6 +1583,8 ##
return 'skipped' unless is_searchable( $basename );
+ return ('python',TEXT) if $basename eq 'SConstruct' || $basename eq 'SConscript';
+
my $lc_basename = lc $basename;
return ('make',TEXT) if $lc_basename eq 'makefile' || $lc_basename eq 'gnumakefile';
return ('rake','ruby',TEXT) if $lc_basename eq 'rakefile';

This can't be done using ack's type sets. Makefiles and Rakefiles are hard-coded in the source. I thought you could add a scons type by modifying $HOME/.ackrc and adding --type-set=scons=SConstruct,SConscript, but that will search for a file that ends in ".SConstruct" or ".SConscript".
The easiest workaround is to add the -a (all file types) flag to ack.
If you just want ack to search and be able to filter the SConstruct somehow, then you could add #!/usr/bin/python as the first line of the SConstruct file. Ack will then treat the file as python source code, and you can filter with --python.

A new ack2 is in development which will allow exact file matching in the .ackrc file. That will enable easier support for Scons and Jam.

Related

CMake recursively add all source files inside all subdirectories of a directory to the executable?

I have a pretty big file structure of a project which I need to convert into a multiplatform cmake project. Now it seams that cmake requires ever single cpp file be added individually to the executable. But is there a script that automates this? That snoopes through the file structure and just adds every source file automatically? Since the project will probably get a lot more source files and I probably wont be able to manually add every single one.
You could use execute_process() with a cmake -P script that uses globbing to recursively scan for source files which writes to an included file in your CMakeLists.txt i.e. something like:
"CMakeLists.txt":
execute_process(COMMAND ${CMAKE_COMMAND}
-D "RDIR=${CMAKE_CURRENT_SOURCE_DIR}"
-P "scansources.cmake"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
include("sources.cmake")
add_executable(myexe ${sources})
"scansources.cmake" (generates "sources.cmake"):
file(GLOB_RECURSE sourcelist
*.c
*.cc
*.cpp
*.cxx)
string(REGEX REPLACE "${RDIR}/" "" relative_sources "${sourcelist}")
string(REPLACE ";" "\n" sources_string "${relative_sources}")
set(sources_string "set(sources\n${sources_string})")
file(WRITE sources.cmake "${sources_string}")
The reason why this works is because execute_process() occurs at configure time.
You could, of course, generate sources.cmake via some other tool or IDE then you wouldn't need scansources.cmake or execute_process().

How can I add per-file defines to a scons project

I'm in the process of porting a makefile project to scons and I can't figure out how to create a unique #define for each file. I would like to have the base filename for each file defined in order to support some custom debug macros. In the makefile, I'm able to do this with the following definition.
-DBASE_FILE_NAME=\"$(<F)\"
I'm not sure how to do this or if it is even possible in scons and would appreciate any feedback.
After some experimentation, the following seems to work.
import os
from glob import glob
# use Python glob, not scons Glob!
CPP_FILES = glob('./src/*.cpp')
env = Environment(CPPPATH='./include', etc...)
for f in CPP_FILES:
env.Object(f, CPPDEFINES={'BASE_FILENAME' : "\\\"" + os.path.basename(f) + "\\\""})
O_FILES = [os.path.splitext(f)[0] + '.o' for f in CPP_FILES]
env.Program('myprogram', O_FILES)
This lets me define things on a per-file basis without listing the files out individually.
Perhaps the following? (Haven't tried it, but something along those lines should work)
env.Program('filename.c',CPPDEFINES='-DBASE_FILE_NAME=\"$SOURCE\"')

Including header files in cygwin

As you know the getch() and getche() functions don't work with the cygwin, a linux oriented one.
But can I include the conio.h header file of borland c and call the functions getch in my makefiles?
Will it work and can anyone tell me how to include the header files from different directories in cywgin.
I have a header file strcal.h in directory c:/makk/string/.
How do I include that header file in my makefile?
gcc -I/string small.c
It is not working and my current directory is makk.
In stdio.h, there is a getchar() function which is what you need. You can't just bring across the Borland header file since that just declares the function, it doesn't define it. Standard C has no need for getch().
To include header files in different areas, you use the -I directives of gcc to set up search paths.
So, if you have a /xyz/myheader.h file, you can do something like:
gcc -I /xyz myprogram.c
To get at c:/makk/string/strcal.h, you may have to use gcc -I /cygdrive/c/makk/string or, if you know you're actually in that makk directory, you can use -I string (note the lack of leading / since you want a relative path, not an absolute one).

Is there a script that would allow me to edit multiple files as if they are one file in VIM?

I prefer to edit in one large file rather than many independent files, but due to limitations in languages, source control, and the preference of team mates I need to output to many files.
What I'm looking for would recurse through all the files in a source directory and generate a single file to edit in VIM, with special file seperator markers. On save it would save the the changes to the correct file(s) ideally in a smart manner, based only on changes made.
Does something like this exist?
shar
Well, you could use shar(1), but it puts an X in front of each line that you will probably find annoying. (Shar came with my Mac but on my Linux systems you need to add a package.)
Shar is just, itself, a short shell script, so you could modify it easily enough to work without the X.
You might try copying /usr/bin/shar to /tmp and applying this diff with patch(1).
--- /usr/bin/shar 2009-07-13 22:26:18.000000000 -0700
+++ /tmp/shar2 2010-12-24 19:05:34.000000000 -0800
## -65,8 +65,8 ##
echo "mkdir -p $i > /dev/null 2>&1"
else
echo "echo x - $i"
- echo "sed 's/^X//' >$i << 'END-of-$i'"
- sed 's/^/X/' $i
+ echo "cat >$i << 'END-of-$i'"
+ cat $i
echo "END-of-$i"
fi
done
It reminds me of vimballs format. However, it's meant to expand files into the user runtimepath directory.
In other words, you can list all the files you want join and apply :MkVimBall (here is an example).
Then, for the extraction, you will have to momentarily (i.e. save and restore its value after the extraction) set &runtimepath to the root directory of your project before extracting with :so %.
You'll also have to play with various options like the &filetype, etc.
It's a dirty hack, but well ... it shall do the job.
Instead of dumping several files into one, processing this one and then separating stuff apart again, you could use bufdo or windo to repeat a command on all opened buffers: open the buffers to be processed, then cast the bufdo command and it will work on every opened file: http://vimdoc.sourceforge.net/htmldoc/windows.html#list-repeat

what triggers scons to build files when I have a custom builder?

I'm going nuts trying to control when files are built in scons. I have a very simple example build tree (see below), with a Poem builder that just takes a .txt file and converts it to lower case in a corresponding .eectxt file.
In my SConstruct and SConscript files, I declare dependencies of 3 .txt files.
But I can't figure out what's putting these into the default build!
sconstest/
SConstruct
tiger.txt
src/
SConscript
hope.txt
jabberwocky.txt
where the *.txt files are poems and my SConstruct and SConscript look like this:
SConstruct:
env = Environment();
def eecummings(target, source, env):
if (len(target) == 1 and len(source) == 1):
with open(str(source[0]), 'r') as fin:
with open(str(target[0]), 'w') as fout:
for line in fin:
fout.write(line.lower());
return None
env['BUILDERS']['Poem'] = Builder(action=eecummings, suffix='.eectxt', src_suffix='.txt');
Export('env');
poems = SConscript('src/SConscript');
tigerPoem = env.Poem('tiger.txt');
src/SConscript:
Import('env');
input = ['jabberwocky.txt', 'hope.txt'];
output = [env.Poem(x) for x in input];
Return('output');
What I want to do is to declare the dependency of the .eectxt files from the corresponding .txt files, but not cause them to be built unless I explicitly put them into the Default() build in the SConstruct file, or I request them explicitly at the command line.
How can I do this?
By default, a directory depends on all files and/or targets which reside in it.
So running:
scons
Will then build all targets under the current directory.
I figured out how to do what I want, but I still don't understand why I need to do it this way. Acceptance to the first decent answer that explains it.
Here's what works, if I add the following to the root SConstruct file:
env.Ignore('.', tigerPoem);
env.Ignore('src', poems);
env.Alias('poems', [tigerPoem]+poems);
This ignores the 3 poems from the default target, and then adds them as targets aliased to "poems", so if I run scons it builds nothing, but if I run scons poems it builds the files.
Why does this work? Why does calling env.Poem(...) add something to the default targets?

Resources