scons - How to add search directories to an existing scanner - c++

My main goal is to add support of -isystem include paths in scons, like this is proposed here : https://stackoverflow.com/a/2547261/4042960
The solution of creating new variables works fine: I do that:
#### Add support for system headers
env['SYSTEMINCPREFIX'] = '-isystem '
env['SYSTEMINCSUFFIX'] = ''
env['_CPPSYSTEMINCFLAGS'] = '$( ${_concat(SYSTEMINCPREFIX, CPPSYSTEMPATH, SYSTEMINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
env['_CCCOMCOM'] += ' $_CPPSYSTEMINCFLAGS'
I use it by adding for instance:
env.Append(CPPSYSTEMPATH = ['/my/include/path'])
My problem is that now, the path /my/include/path is not scanned by the C (or C++) dependency scanner. After many search, I failed to find how to add my variable "CPPSYSTEMPATH" to be treated like "CPPPATH" by the dependency scanner.
Does anyone know how I could add the search path contained in "CPPSYSTEMPATH" to the existing C scanner ?
I hope that my problem is clear enough, else do not hesitate to tell me.

Here's a basic recipe for replacing the FindPath method of the default C scanner, but be warned it's an ugly hack:
# Create environment
env = Environment()
# Define your new env variable as combination of both paths
env['MYCPPPATHS'] = ['$CPPPATH','$CPPSYSTEMPATH']
# Replace the path_function of the standard C scanner by:
import SCons.Tool
import SCons.Scanner
setattr(SCons.Tool.CScanner,'path_function',SCons.Scanner.FindPathDirs('MYCPPPATHS'))
# Do your build stuff...
env['CPPSYSTEMPATH'] = 'myinclude'
env.Program('main','main.cpp')
By the way, why not ask these kind of questions on our user mailing list scons-users#scons.org? ;)

Related

how to find if prefix is a match to some string in a set in Ruby?

I am trying to go through a predefined dir path set but I only have the prefix of the path
I have tried use include? or find a method that does that.
I can only think about the trivial solution of define a regexp and go for each in the set, but that seems to be not so ruby-like style
require 'set'
legal_paths = Set['A/B/C', 'A/D/E', 'A/F/G']
Dir.glob('**/system.log').each do |fd|
if failed_tests_path.include?(fd) #fd for example = A/F/G/E/system.log, A/B/C/K/system.log etc...
puts fd
end
end
I want fd to be only system.log files that the paths are including inside the set (the set holds the prefix to the path)
If these are only the prefix, try String#start_with?:
require 'set'
legal_paths = Set['A/B/C', 'A/D/E', 'A/F/G']
files = Dir.glob('**/system.log').select do |fd|
fd.start_with?(*legal_paths)
end
Why not make use of the fact that you can specify these prefixes in the glob?
legal_paths = ['A/B/C', 'A/D/E', 'A/F/G']
files = Dir.glob("{#{legal_paths.join(',')}}/**/system.log")
Note though that if the legal_paths are input by the user, the above might not be secure as the user could traverse to parent directories using ...

How to check if a joint path exists before creating it using a for statement

I'm trying to use makedirs to create subfolders in an existing folder since I will have to create the same folders at least 40 more times based on projects but I want to check if the folders exist first in case I accidentally run the script twice on the same project.
I thought that maybe os.path.join.exists would work but I don't think this is real.
import os
mypath = r'path'
subfolder_names = [
'01_subfolder',
'02_subfolder',
'03_subfolder',
'04_subfolder',
'06_subfolder',
'07_subfolder',
'08_subfolder',
'09_subfolder',
'10_subfolder'
]
for subfolder_name in subfolder_names:
# doesn't work but I need something to check first
if not os.path.join.exists(mypath,subfolder_name)
os.makedirs(os.path.join(mypath,subfolder_name))
output it should put the folders or say "these ones already exist" it would be nice if it would spit out which folders already exist and which ones don't.
You are pretty close. You need to join first and then check for existence:
subfolder_names = ['01_subfolder', '02_subfolder', '03_subfolder', '04_subfolder', '06_subfolder', '07_subfolder', '08_subfolder', '09_subfolder', '10_subfolder']
for subfolder_name in subfolder_names:
p = os.path.join(mypath, subfolder_name
if not os.path.join.exists(p):
os.makedirs(p)
join and exists are separate functions.
You can also choose to do this functionally:
from itertools import filterfalse, repeat
subfolder_names = ['01_subfolder', '02_subfolder', '03_subfolder', '04_subfolder', '06_subfolder', '07_subfolder', '08_subfolder', '09_subfolder', '10_subfolder']
paths = map(os.path.join, repeat(mypath), subfolder_names)
missing_paths = filterfalse(os.path.exists, paths)
for missing_path in missing_paths:
os.makedirs(missing_path)

In Buck, how do I expand a genrule output directory?

I have a genrule that outputs a directory containing C++ headers. I also have a cxx_library which uses the output of the genrule. The headers field of the cxx_library looks like this:
...
headers = [
':my-headers',
],
...
The problem is that my C++ source files include the headers like this:
#include "my_header.h"
But Buck prepares the staging area like this:
my-cxx-library#default,private-headers/out
Where out is an alias to the folder containing my generated headers.
So in order to use the headers, I would have to include them like this:
#include "out/my_header.h"
The library is not my own, so I would not like to change the source-code. Instead, I would like to use something like a subdir_glob to include everything inside :my-headers/out.
I tried this:
...
headers = subdir_glob([
(':my-headers/out', '**/*.h'),
]),
...
However, it seems that when done this way, the string :my-headers does not get resolved to the output path of :my-headers.
Is there a function in buck that can expand a rule to its output path?
This isn't trivially possible today, but there is a workaround you can use:
genrule(
name = 'headers',
cmd = 'generate_headers.py --outdir=$OUT'
out = 'headers-dir',
)
genrule(
name = 'generated_header_A.h',
cmd = 'cp $(location :headers)/genereated_header_A.h $OUT',
out = 'generated_header_A.h',
)
Then, in your cxx_library, you just need to declare your headers by referencing the location:
headers = {
'some_namespace/header_A.h': ':generated_header_A.h',
},
The above code assumes all of this is in the same build file, but if it isn't, you just need to use a fully-qualified build target instead.

SugarCRM customization of Basic template

I need to add a field in basic template. Can anyone help me how can i add another field in include/SugarObjects/templates/basic/vardefs.php in upgrade safe manner.
In VardefManager's function addTemplate not like general standards of Sugar it is not requiring the custom paths
include/SugarObjects/VardefManager.php near line 107 SugarCE6.5.5:
if(empty($templates[$template])){
$path = 'include/SugarObjects/templates/' . $template . '/vardefs.php';
if(file_exists($path)){
require($path);
$templates[$template] = $vardefs;
}else{
$path = 'include/SugarObjects/implements/' . $template . '/vardefs.php';
if(file_exists($path)){
require($path);
$templates[$template] = $vardefs;
}
}
}
Really waiting for awesome responses.
Create a file at the path custom/include/SugarObjects/VardefManager.php with the name VardefManager.php and in that file include your mail file it is include/SugarObjects/VardefManager.php.
Here you will create a class with same and and create a function with the name
static function addTemplate
with same the arguments pass in the main file. and override the method here with your custom code (as you want to add some lines of code in that).
This will be upgrade safe and will be workable to you.

Go for Zend framework or Django for a modular web application?

I am using both Zend framework and Django, and they both have they strengths and weakness, but they are both good framworks in their own way.
I do want to create a highly modular web application, like this example:
modules:
Admin
cms
articles
sections
...
...
...
I also want all modules to be self contained with all confid and template files.
I have been looking into a way to solve this is zend the last days, but adding one omer level to the module setup doesn't feel right. I am sure this could be done, but should I? I have also included Doctrine to my zend application that could give me even more problems in my module setup!
When we are talking about Django this is easy to implement (Easy as in concept, not in implementation time or whatever) and a great way to create web apps. But one of the downsides of Django is the web hosing part. There are some web hosts offering Django support, but not that many..
So then I guess the question is what have the most value; rapid modular development versus hosting options!
Well, comments are welcome!
Thanks
You can implement sub-modules with relatively little effort in ZF. Let's say you have directory structure such as:
application/
modules/
admin/
cms/
controllers/
views/
controllers/
views/
You'd register the modules like this in your bootstrap (sub-modules use _ to separate the sub-module from the main module):
$frontController->setControllerDirectory(array(
'default' => APPLICATION_PATH . '/modules/default/controllers',
'admin' => APPLICATION_PATH . '/modules/admin/controllers',
'admin_cms' => APPLICATION_PATH . '/modules/admin/cms/controllers'
));
The issue with this is that it would actually use an underline in the URL instead of a slash, so eg: "admin_cms/conteroller/action" instead of "admin/cms/controller/action". While this "works", it's not pretty. One way to solve the issue is to provide your own route for the default route. Since the default Zend_Controller_Router_Route_Module does it almost right, you can simply extend from it and add the wanted behavior:
<?php
class App_Router_Route_Module extends Zend_Controller_Router_Route_Module
{
public function __construct()
{
$frontController = Zend_Controller_Front::getInstance();
$dispatcher = $frontController->getDispatcher();
$request = $frontController->getRequest();
parent::__construct(array(), $dispatcher, $request);
}
public function match($path)
{
// Get front controller instance
$frontController = Zend_Controller_Front::getInstance();
// Parse path parts
$parts = explode('/', $path);
// Get all registered modules
$modules = $frontController->getControllerDirectory();
// Check if we're in default module
if (count($parts) == 0 || !isset($modules[$parts[0]]))
array_unshift($parts, $frontController->getDefaultModule());
// Module name
$module = $parts[0];
// While there are more parts to parse
while (isset($parts[1])) {
// Construct new module name
$module .= '_' . $parts[1];
// If module doesn't exist, stop processing
if (!isset($modules[$module]))
break;
// Replace the parts with the new module name
array_splice($parts, 0, 2, $module);
}
// Put path back together
$path = implode('/', $parts);
// Let Zend's module router deal with the rest
return parent::match($path);
}
}
And in your bootstrap:
$router = Zend_Controller_Front::getInstance()->getRouter();
$router->addRoute('default', new App_Router_Route_Module);
What this does is traverse the path as long as it finds a module, and transparently rewrites the path so that the default Zend_Controller_Router_Route_Module can do the real work. For example the following path: "/admin/cms/article/edit" will be transformed into "/admin_cms/article/edit", which allows the standard convention of the ZF's ":module/:controller/:action" do the magic.
This allows you to have nice modular structure with self-contained modules, while still use pretty, logical URLs. One thing you want to make note of is that if you use Zend_Navigation and specify the navigation items using module/controller/action parameters, you need to tell ZF how to correctly build the URL using "/" instead of "_" in module names (by default ZF uses the :module/:controller/:action spec when it builds the URLs). You can do this by implementing your own Zend_Controller_Action_Helper_Url, like this:
<?php
class App_Router_Helper_Url extends Zend_Controller_Action_Helper_Url
{
public function url($urlOptions = array(), $name = null, $reset = false, $encode = false)
{
// Replace the _ with / in the module name
$urlOptions['module'] = str_replace('_', '/', $urlOptions['module']);
// Let the router do rest of the work
return $this->getFrontController()->getRouter()->assemble($urlOptions, $name, $reset, $encode);
}
}
And in your bootstrap:
Zend_Controller_Action_HelperBroker::addHelper(new App_Router_Helper_Url);
Now Zend_Navigation works nicely with your sub-module support as well.
I (despite of being happy ZF user) would go for Django. In ZF the "fully-modular" application is kind of holly grail. It's nearly impossible (or at least without extreme effort) to create selfcontained modules, instalable like "copy this folder into your modules directory" :) Not sure about Django, but from what I head it's simplier there...