How to load user-specific configuration for CMake project - configuration

I like to use a configuration file that sets several cached variables. The purpose is to reuse it for every projects running on a machine or to select different library versions for testing or special purpose.
I can achieve it with a CMake file like this one:
set(path_to_lib_one path/to/lib/one)
set(option1 dont_want_to_bother_setting_this_option)
set(option2 that_option_have_to_be_set_again)
And call include(myConfigfile).
But I would like to know if their is a cache-like way of doing it and what are the best practices to manage user/setup specific configurations.

Use the initial cache option offered by CMake. You store your options in the right format (set withCACHE`) and call
cmake -C <cacheFile> <pathToSourceDir>
Self-contained example
The CMakeLists.txt looks like
project(blabla)
cmake_minimum_required(VERSION 3.2)
message("${path_to_lib_one} / ${option1} / ${option2}")
and you want to pre-set the three variables. The cacheFile.txt looks like
set(path_to_lib_one path/to/lib/one CACHE FILEPATH "some path")
set(option1 "dont_want_to_bother_setting_this_option" CACHE STRING "some option 1")
set(option2 42 CACHE INT "and an integer")
and your CMake call (from a directory build below the source directory)
cmake -C cacheFile.txt ..
The output is
loading initial cache file ../cacheFile.txt
[..]
path/to/lib/one / dont_want_to_bother_setting_this_option / 42
Documentation:
https://cmake.org/cmake/help/latest/manual/cmake.1.html#options
Load external cache files
Additionally, CMake offer a way to read in a cache file, that was created by another project. The command is load_cache. You can use it to just load the variables from the external cache or to copy them to the cache of the current project.
Documentation: https://cmake.org/cmake/help/latest/command/load_cache.html

Related

Bitbake append file to reconfigure kernel

I'm trying to reconfigure some .config variables to generate a modified kernel with wifi support enabled. The native layer/recipe for the kernel is located in this directory:
meta-layer/recipes-kernel/linux/linux-yocto_3.19.bb
First I reconfigure the native kernel to add wifi support (for example, adding CONFIG_WLAN=y):
$ bitbake linux-yocto -c menuconfig
After that, I generate a "fragment.cfg" file:
$ bitbake linux-yocto -c diffconfig
I have created this directory into my custom-layer:
custom-layer/recipes-kernel/linux/linux-yocto/
I have copied the "fragment.cfg file into this directory:
$ cp fragment.cfg custom-layer/recipes-kernel/linux/linux-yocto/
I have created an append file to customize the native kernel recipe:
custom-layer/recipes-kernel/linux/linux-yocto_3.19.bbappend
This is the content of this append file:
FILESEXTRAPATHS_prepend:="${THISDIR}/${PN}:"
SRC_URI += "file://fragment.cfg"
After that I execute the kernel compilation:
$ bitbake linux-yocto -c compile -f
After this command, "fragment.cfg" file can be found into this working directory:
tmp/work/platform/linux-yocto/3.19-r0
However none of the expected variables is active on the .config file (for example, CONFIG_WLAN is not set).
How can I debug this issue? What is supposed I'm doing wrong?
When adding this configuration you want to use append in your statement such as:
SRC_URI_append = "file://fragment.cfg"
After analyzing different links and solutions proposed on different resources, I finally found the link https://community.freescale.com/thread/376369 pointing to a nasty but working patch, consisting in adding this function at the end of append file:
do_configure_append() {
cat ${WORKDIR}/*.cfg >> ${B}/.config
}
It works, but I expected Yocto managing all this stuff. It would be nice to know what is wrong with the proposed solution. Thank you in advance!
If your recipe is based on kernel.bbclass then fragments will not work. You need to inherit kernel-yocto.bbclass
You can also use merge_config.sh scripts which is present in kernel sources. I did something like this:
do_configure_append () {
${S}/scripts/kconfig/merge_config.sh -m -O ${WORKDIR}/build ${WORKDIR}/build/.config ${WORKDIR}/*.cfg
}
Well, unfortunately, not a real answer... As I haven't been digging deep enough.
This was working alright for me on a Daisy-based build, however, when updating the build system to Jethro or Krogoth, I get the same issue as you.
Issue:
When adding a fragment like
custom-layer/recipes-kernel/linux/linux-yocto/cdc-ether.cfg
The configure step of the linux-yocto build won't find it. However, if you move it to:
custom-layer/recipes-kernel/linux/linux-yocto/${MACHINE}/cdc-ether.cfg
it'll work as expected. And it's a sligthly less hackish way of getting it to work.
If anyone comes by, this is working on jethro and sumo:
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
SRC_URI_append = " \
file://fragment.cfg \
"
FILESEXTRAPATHS documentation says:
Extends the search path the OpenEmbedded build system uses when looking for files and patches as it processes recipes and append files. The directories BitBake uses when it processes recipes are defined by the FILESPATH variable, and can be extended using FILESEXTRAPATHS.

Different user settings for synced sublime

I've synced my User folder with sublime settings.
But what if I want to use different settings for different machines? For example, in settings of terminal package I define path to Git Bash, and it's
"terminal": "C:/Program Files (x86)/Git/bin/sh.exe"
on one machine, and
"terminal": "C:/Program Files/Git/bin/sh.exe"
on another.
I've tried to use default settings, but they refresh all the time.
Maybe look into this package: https://packagecontrol.io/packages/PackageSync
I've never used it, but according to the README,
PackageSync provides the following user configurable settings:
...
ignore_files [array]
The list of files to ignore when backing up.
So you would want to create a PackageSync.sublime_settings file that has this in it:
{
"ignore_files": "Terminal.sublime_settings"
}
This isn't ideal since it prevents the enitre file from syncing, not just that one entry (the "terminal": "C:/Program Files (x86)/Git/bin/sh.exe" entry), but it should work. (Disclaimer: I have not tried this myself)
Alternative: Possible workaround:
You could also just use the line "terminal" : "~/my_custom_terminal_shortcut" in your settings and then create a ~/my_custom_terminal_shortcut file on each computer that links to the appropriate location

How to download HTTP directory with all files and sub-directories as they appear on the online files/folders list?

There is an online HTTP directory that I have access to. I have tried to download all sub-directories and files via wget. But, the problem is that when wget downloads sub-directories it downloads the index.html file which contains the list of files in that directory without downloading the files themselves.
Is there a way to download the sub-directories and files without depth limit (as if the directory I want to download is just a folder which I want to copy to my computer).
Solution:
wget -r -np -nH --cut-dirs=3 -R index.html http://hostname/aaa/bbb/ccc/ddd/
Explanation:
It will download all files and subfolders in ddd directory
-r : recursively
-np : not going to upper directories, like ccc/…
-nH : not saving files to hostname folder
--cut-dirs=3 : but saving it to ddd by omitting
first 3 folders aaa, bbb, ccc
-R index.html : excluding index.html
files
Reference: http://bmwieczorek.wordpress.com/2008/10/01/wget-recursively-download-all-files-from-certain-directory-listed-by-apache/
I was able to get this to work thanks to this post utilizing VisualWGet. It worked great for me. The important part seems to be to check the -recursive flag (see image).
Also found that the -no-parent flag is important, othewise it will try to download everything.
you can use lftp, the swish army knife of downloading if you have bigger files you can add --use-pget-n=10 to command
lftp -c 'mirror --parallel=100 https://example.com/files/ ;exit'
wget -r -np -nH --cut-dirs=3 -R index.html http://hostname/aaa/bbb/ccc/ddd/
From man wget
‘-r’
‘--recursive’
Turn on recursive retrieving. See Recursive Download, for more details. The default maximum depth is 5.
‘-np’
‘--no-parent’
Do not ever ascend to the parent directory when retrieving recursively. This is a useful option, since it guarantees that only the files below a certain hierarchy will be downloaded. See Directory-Based Limits, for more details.
‘-nH’
‘--no-host-directories’
Disable generation of host-prefixed directories. By default, invoking Wget with ‘-r http://fly.srk.fer.hr/’ will create a structure of directories beginning with fly.srk.fer.hr/. This option disables such behavior.
‘--cut-dirs=number’
Ignore number directory components. This is useful for getting a fine-grained control over the directory where recursive retrieval will be saved.
Take, for example, the directory at ‘ftp://ftp.xemacs.org/pub/xemacs/’. If you retrieve it with ‘-r’, it will be saved locally under ftp.xemacs.org/pub/xemacs/. While the ‘-nH’ option can remove the ftp.xemacs.org/ part, you are still stuck with pub/xemacs. This is where ‘--cut-dirs’ comes in handy; it makes Wget not “see” number remote directory components. Here are several examples of how ‘--cut-dirs’ option works.
No options -> ftp.xemacs.org/pub/xemacs/
-nH -> pub/xemacs/
-nH --cut-dirs=1 -> xemacs/
-nH --cut-dirs=2 -> .
--cut-dirs=1 -> ftp.xemacs.org/xemacs/
...
If you just want to get rid of the directory structure, this option is similar to a combination of ‘-nd’ and ‘-P’. However, unlike ‘-nd’, ‘--cut-dirs’ does not lose with subdirectories—for instance, with ‘-nH --cut-dirs=1’, a beta/ subdirectory will be placed to xemacs/beta, as one would expect.
No Software or Plugin required!
(only usable if you don't need recursive deptch)
Use bookmarklet. Drag this link in bookmarks, then edit and paste this code:
javascript:(function(){ var arr=[], l=document.links; var ext=prompt("select extension for download (all links containing that, will be downloaded.", ".mp3"); for(var i=0; i<l.length; i++) { if(l[i].href.indexOf(ext) !== false){ l[i].setAttribute("download",l[i].text); l[i].click(); } } })();
and go on page (from where you want to download files), and click that bookmarklet.
wget is an invaluable resource and something I use myself. However sometimes there are characters in the address that wget identifies as syntax errors. I'm sure there is a fix for that, but as this question did not ask specifically about wget I thought I would offer an alternative for those people who will undoubtedly stumble upon this page looking for a quick fix with no learning curve required.
There are a few browser extensions that can do this, but most require installing download managers, which aren't always free, tend to be an eyesore, and use a lot of resources. Heres one that has none of these drawbacks:
"Download Master" is an extension for Google Chrome that works great for downloading from directories. You can choose to filter which file-types to download, or download the entire directory.
https://chrome.google.com/webstore/detail/download-master/dljdacfojgikogldjffnkdcielnklkce
For an up-to-date feature list and other information, visit the project page on the developer's blog:
http://monadownloadmaster.blogspot.com/
You can use this Firefox addon to download all files in HTTP Directory.
https://addons.mozilla.org/en-US/firefox/addon/http-directory-downloader/
wget generally works in this way, but some sites may have problems and it may create too many unnecessary html files. In order to make this work easier and to prevent unnecessary file creation, I am sharing my getwebfolder script, which is the first linux script I wrote for myself. This script downloads all content of a web folder entered as parameter.
When you try to download an open web folder by wget which contains more then one file, wget downloads a file named index.html. This file contains a file list of the web folder. My script converts file names written in index.html file to web addresses and downloads them clearly with wget.
Tested at Ubuntu 18.04 and Kali Linux, It may work at other distros as well.
Usage :
extract getwebfolder file from zip file provided below
chmod +x getwebfolder (only for first time)
./getwebfolder webfolder_URL
such as ./getwebfolder http://example.com/example_folder/
Download Link
Details on blog

How can I use ediff (emacs diff) as a diff/merge tool in Windows ClearCase?

I'm forced to use ClearCase (Windows version) at work, and I want to use emacs ediff as a diff and merge tool. The problem with the ClearCase map file is that it requires .exe files - I've tried to specify a batch file calling ediff and it didn't work.
I don't want to write a C/C++ program (it's been more than 10 years since I've coded anything in C for Win32) that will call ediff with the proper arguments. Is there a simpler way?
See also:
Any way to use a custom diff tool with cleartool/clearcase?
As mentioned in this SO question, the map file allows you to call an external diff tool.
For Windows, you should try first to call emacs in ediff mode:
emacs --eval "(ediff-files \"file_1\" \"file_2\")"
or
xemacs -eval "(ediff-files \"file_1\" \"file_2\")"
(should invoke a new instance of XEmacs ediff)
If this works, you may write a .bat file called by the map file, and building the appropriate "emacs ediff" command line.
Something along the lines of:
#echo off
set local
if !%XEMACS_PATH%!==!! SET
XEMACS_PATH=C:\<XEmacs-Path>\i586-pc-win32
set FILE1=%~1
set FILE2=%~2
REM * Bad habit - working on administrative shares.. Why is $->$$ not needed?
REM SET FILE1=%FILE1:$=$$%
REM SET FILE2=%FILE2:$=$$%
REM * Escaping backslash..
SET FILE1=%FILE1:\=\\%
SET FILE2=%FILE2:\=\\%
"%XEMACS_PATH:"=%\gnudoit.exe" "(ediff \"%FILE1%\" \"%FILE2%\")"
If map file is not at ease with calling a .bat file, simply generate an .exe from your .bat.
I have done some tests and it turns out:
"compare with previous version" actually calls:
cleartool diff -graphical -pred myFile
calling the .bat through a cmd.exe call does not work
c:\Program Files\Rational\ClearCase\lib\mgrs\map
text_file_delta xcompare "c:\WINDOWS\system32\cmd.exe /c c:\cc\test.bat"
cleartool: Error: Operation "xcompare" unavailable for manager "text_file_delta"
(Operation pathname was: "C:\Program Files\Rational\ClearCase\lib\mgrs\"c:\WINDOWS\system32\cmd.exe /c c:\cc\test.bat"")
transforming the .bat in .exe does work
arg2 (%2) and arg4 (%4) are what you are looking for, with arg5 (%5) the name of the temporary file created for the content of the previous version (for snapshot view which can not access extended path name)
So the following bat (transformed in exe) works from the command-line only (not from the ClearCase Explorer: DrWatson):
"C:\Program Files\WinMerge\WinMergeU.exe" %4 %5
You should be able to adapt it to Xemacs, but Alex's suggestion (working with Clearcase from Emacs) might be another more practical solution.
you can use clearcase package as described here

Get the application's path

I've recently searched how I could get the application's directory in Java. I've finally found the answer but I've needed surprisingly long because searching for such a generic term isn't easy. I think it would be a good idea to compile a list of how to achieve this in multiple languages.
Feel free to up/downvote if you (don't) like the idea and please contribute if you like it.
Clarification:
There's a fine distinction between the directory that contains the executable file and the current working directory (given by pwd under Unix). I was originally interested in the former but feel free to post methods for determining the latter as well (clarifying which one you mean).
In Java the calls
System.getProperty("user.dir")
and
new java.io.File(".").getAbsolutePath();
return the current working directory.
The call to
getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
returns the path to the JAR file containing the current class, or the CLASSPATH element (path) that yielded the current class if you're running directly from the filesystem.
Example:
Your application is located at
C:\MyJar.jar
Open the shell (cmd.exe) and cd to C:\test\subdirectory.
Start the application using the command java -jar C:\MyJar.jar.
The first two calls return 'C:\test\subdirectory'; the third call returns 'C:\MyJar.jar'.
When running from a filesystem rather than a JAR file, the result will be the path to the root of the generated class files, for instance
c:\eclipse\workspaces\YourProject\bin\
The path does not include the package directories for the generated class files.
A complete example to get the application directory without .jar file name, or the corresponding path to the class files if running directly from the filesystem (e.g. when debugging):
String applicationDir = getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
if (applicationDir.endsWith(".jar"))
{
applicationDir = new File(applicationDir).getParent();
}
// else we already have the correct answer
In .NET (C#, VB, …), you can query the current Assembly instance for its Location. However, this has the executable's file name appended. The following code sanitizes the path (using System.IO and using System.Reflection):
Directory.GetParent(Assembly.GetExecutingAssembly().Location)
Alternatively, you can use the information provided by AppDomain to search for referenced assemblies:
System.AppDomain.CurrentDomain.BaseDirectory
VB allows another shortcut via the My namespace:
My.Application.Info.DirectoryPath
In Windows, use the WinAPI function GetModuleFileName(). Pass in NULL for the module handle to get the path for the current module.
Python
path = os.path.dirname(__file__)
That gets the path of the current module.
Objective-C Cocoa (Mac OS X, I don't know for iPhone specificities):
NSString * applicationPath = [[NSBundle mainBundle] bundlePath];
In Java, there are two ways to find the application's path. One is to employ System.getProperty:
System.getProperty("user.dir");
Another possibility is the use of java.io.File:
new java.io.File("").getAbsolutePath();
Yet another possibilty uses reflection:
getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
In VB6, you can get the application path using the App.Path property.
Note that this will not have a trailing \ EXCEPT when the application is in the root of the drive.
In the IDE:
?App.Path
C:\Program Files\Microsoft Visual Studio\VB98
In .Net you can use
System.IO.Directory.GetCurrentDirectory
to get the current working directory of the application, and in VB.NET specifically you can use
My.Application.Info.DirectoryPath
to get the directory of the exe.
Delphi
In Windows applications:
Unit Forms;
path := ExtractFilePath(Application.ExeName);
In console applications:
Independent of language, the first command line parameter is the fully qualified executable name:
Unit System;
path := ExtractFilePath(ParamStr(0));
Libc
In *nix type environment (also Cygwin in Windows):
#include <unistd.h>
char *getcwd(char *buf, size_t size);
char *getwd(char *buf); //deprecated
char *get_current_dir_name(void);
See man page
Unix
In unix one can find the path to the executable that was started using the environment variables. It is not necessarily an absolute path, so you would need to combine the current working directory (in the shell: pwd) and/or PATH variable with the value of the 0'th element of the environment.
The value is limited in unix though, as the executable can for example be called through a symbolic link, and only the initial link is used for the environment variable. In general applications on unix are not very robust if they use this for any interesting thing (such as loading resources). On unix, it is common to use hard-coded locations for things, for example a configuration file in /etc where the resource locations are specified.
In bash, the 'pwd' command returns the current working directory.
In PHP :
<?php
echo __DIR__; //same as dirname(__FILE__). will return the directory of the running script
echo $_SERVER["DOCUMENT_ROOT"]; // will return the document root directory under which the current script is executing, as defined in the server's configuration file.
echo getcwd(); //will return the current working directory (it may differ from the current script location).
?>
in Android its
getApplicationInfo().dataDir;
to get SD card, I use
Environment.getExternalStorageDirectory();
Environment.getExternalStoragePublicDirectory(String type);
where the latter is used to store a specific type of file (Audio / Movies etc). You have constants for these strings in Environment class.
Basically, for anything to with app use ApplicationInfo class and for anything to do with data in SD card / External Directory using Environment class.
Docs :
ApplicationInfo ,
Environment
In Tcl
Path of current script:
set path [info script]
Tcl shell path:
set path [info nameofexecutable]
If you need the directory of any of these, do:
set dir [file dirname $path]
Get current (working) directory:
set dir [pwd]
Java:
On all systems (Windows, Linux, Mac OS X) works for me only this:
public static File getApplicationDir()
{
URL url = ClassLoader.getSystemClassLoader().getResource(".");
File applicationDir = null;
try {
applicationDir = new File(url.toURI());
} catch(URISyntaxException e) {
applicationDir = new File(url.getPath());
}
return applicationDir;
}
in Ruby, the following snippet returns the path of the current source file:
path = File.dirname(__FILE__)
In CFML there are two functions for accessing the path of a script:
getBaseTemplatePath()
getCurrentTemplatePath()
Calling getBaseTemplatePath returns the path of the 'base' script - i.e. the one that was requested by the web server.
Calling getCurrentTemplatePath returns the path of the current script - i.e. the one that is currently executing.
Both paths are absolute and contain the full directory+filename of the script.
To determine just the directory, use the function getDirectoryFromPath( ... ) on the results.
So, to determine the directory location of an application, you could do:
<cfset Application.Paths.Root = getDirectoryFromPath( getCurrentTemplatePath() ) />
Inside of the onApplicationStart event for your Application.cfc
To determine the path where the app server running your CFML engine is at, you can access shell commands with cfexecute, so (bearing in mind above discussions on pwd/etc) you can do:
Unix:
<cfexecute name="pwd"/>
for Windows, create a pwd.bat containing text #cd, then:
<cfexecute name="C:\docume~1\myuser\pwd.bat"/>
(Use the variable attribute of cfexecute to store the value instead of outputting to screen.)
In cmd (the Microsoft command line shell)
You can get the name of the script with %* (may be relative to pwd)
This gets directory of script:
set oldpwd=%cd%
cd %0\..
set app_dir=%pwd%
cd %oldpwd%
If you find any bugs, which you will. Then please fix or comment.
I released https://github.com/gpakosz/whereami which solves the problem in C and gives you:
the path to the current executable
the path to the current module (differs from path to executable when calling from a shared library).
It uses GetModuleFileNameW on Windows, parses /proc/self/maps on Linux and Android and uses _NSGetExecutablePath or dladdr on Mac and iOS.
Note to answer "20 above regarding Mac OSX only: If a JAR executable is transformed to an "app" via the OSX JAR BUNDLER, then the getClass().getProtectionDomain().getCodeSource().getLocation(); will NOT return the current directory of the app, but will add the internal directory structure of the app to the response. This internal structure of an app is /theCurrentFolderWhereTheAppReside/Contents/Resources/Java/yourfile
Perhaps this is a little bug in Java. Anyway, one must use method one or two to get the correct answer, and both will deliver the correct answer even if the app is started e.g. via a shortcut located in a different folder or on the desktop.
carl
SoundPimp.com