Cross-platform paths in CMake - linux

I have a project I can build on both Linux and Windows using CMake. The only issue is that Unix-style paths, in CMakeLists.txt, can't work on Windows (which uses backslashes instead of slashes, also requiring the drive letter).
Is there any way I can write a cross-platform CMakeLists.txt?

You question affects different details:
Just don't use backslashes. Windows will also process slashes.
Don't use drive letters. Use relative paths everywhere.
GET_FILENAME_COMPONENT(X "${CMAKE_CURRENT_SOURCE_DIR}" REALPATH) can solve the whole path without writing any absolute paths.
Add the tool binary paths into your PATH environment variable. So you do not need to search them by yourself (with absolute paths) or
Use FIND_PROGRAM() to get the tools absolute path without guessing around. You could add hints in which registry entries and paths cmake will search for the tool or
Consider to write your own module for every tool. You can copy the skeleton from any module of the modules folder (have a lock at FindJava.cmake; a very good and portable example on how to search a program).
If all those does not help, you can detect the platform by IF(WIN32) or IF(UNIX).
Hope, this helps...

Related

Changing ncurses 6 "terminfo-dirs" after compilation/installation

There is a ncurses6 originally installed in a user home dir, let's say "/home/test", so a test environment was built over this ncurses path, a lot of (in development) apps were compiled and is working now, depending only of the current HOME env variable.
But, because of a purpose beyond our control, we have to change the user home dir. And now it's anything different from "/home/test".
The external apps and ncurses tools still working, we need just point the libraries with LD_LIBRARY_PATH and use a more specific path like we used before for ncurses tools:
LD_LIBRARY_PATH=~/bin/ncurses-6.0/lib ~/bin/ncurses-6.0/bin/tic
But now, after changing the user home dir, we need to point also the terminfo database:
TERMINFO=~/bin/ncurses-6.0/share/terminfo LD_LIBRARY_PATH=~/bin/ncurses-6.0/lib ~/bin/ncurses-6.0/bin/tic
But, is there any way to make the TERMINFO database path permanent without recompiling and reinstalling the ncurses ? Is it hard code in ncurses during compilation ?
The default values are compiled-in. You can override those with environment variables (TERMINFO is standard, TERMINFO_DIRS is an extension). That's not new with ncurses6 (it predates ncurses4, twenty years ago).
The most practical "permanent" change would be to put the overrides in your shell initialization.
It's possible to modify an ELF binary (there's no checksums), but the resulting path couldn't be longer. It could be shorter, since the strings are null-terminated. Since your example adds to the path, that wouldn't work for you, anyway.

How to discover the Paths to Loading Binaries

I have a problem where I need to know the filesystem path of the current binary, as well as those of any loading (as opposed to loaded) binaries. Here is an example (for Windows): Say we have an executable A.exe, which dynamically binds to B.dll, which in turn binds to C.dll. How could code executing in C.dll get the file paths of C.dll, B.dll, and A.exe?
Oh, and I need to be able to do it on Linux, Mac, and Windows.
On Linux, the closest thing I've found is dl_iterate_phdr, but the who-loaded-who info is missing.
On Windows, The Dynamic-Link functions don't have quite the right functionality.
On Mac, all I can find is what's in dlfcn.h, which is rather pithy for this purpose.
Thanks.

How to get gdb on Linux to find source file for binary cross compiled on windows

I am trying to debug an application that is cross-compiled on a Windows host for a Linux target.
The problem:
Because the initial compilation is in windows the stored source file paths in the binary is of the form C:\Users\foo\project\.... On the Linux target I have put the source files under \home\foo\project\.... By default gdb does not find the source file because of the different path.
What I have tried so far:
Use "directory" command in gdb to give an exact path for the .c source file in the target Linux system where the app is being debugged. This works but unfortunately there are literally hundreds of files so this solution is unrealistic.
Use the set substitute-path C:\\Users\\foo\\project /home/foo/project command to have gdb substitute all prefixes. Note that the \\ seems necessary such that show substitute-path registers the right string. This unfortunately does not work. My guess is that the substitute-path command does not handle ms-dos style paths.
Tried separating the debug info out into a separate .debug file (see How to generate gcc debug symbol outside the build target?) and then using debugedit to change the paths with the command debugedit --base-dir=C:\Users\foo --dest-dir=/home/foo project.debug. Unfortunately this does not work either. debugedit seems to work fine if the existing path is all UNIX/Linux like but doesn't seem to work with ms-dos style paths.
I have looked around stackoverflow and while there are similar topics I can't find anything that will help me. Would really appreciate any suggestions/help. I realize that cross compiling from Windows is a very roundabout way but can't avoid that for the moment.
Thanks
Although it's rather old question, I did encountered the same problem. I managed to resolve it but using sed on binary executable... (yeah, a 'bit' hack-ish, but did not found another way). With sed I've managed to replace symbols paths right inside the executable, the trick is that new path's length should be the same as the old one.
sed -i "s#C:/srcpath#/srcpath/.#g" ./executable
Be sure to make new path the same length, otherwise the executable will brake.
I also have this same problem. Your option 1 isn't as bad as you think because you can script creating all the 'directory' commands with something like this python code:
def get_directory_paths():
return_array = list()
unix_path = os.path.join('my','unix','path')
for root, dirs, files in os.walk(unix_path):
for dir in dirs:
full_unix_path = os.path.join(root,dir)
escaped_unix_path = re.sub("\s", "\\\\ ", full_unix_path)
return_array.insert(0, "directory " + escaped_unix_path)
return '\n'.join(return_array)
The downside is that if you have two source files with the same name in different directories, I don't think gcc can pick the right one. That worries me, but in my particular situation, I think I'm safe.
For option 2 (which I suspect would fix the aliasing condition from #1), I think the problem is that the substitutions are not ending with a "file separator" according to the linux so they aren't applied:
To avoid unexpected substitution results, a rule is applied only if the from part of the directory name ends at a directory separator. For instance, a rule substituting /usr/source into /mnt/cross will be applied to /usr/source/foo-1.0 but not to /usr/sourceware/foo-2.0. And because the substitution is applied only at the beginning of the directory name, this rule will not be applied to /root/usr/source/baz.c either." (from https://sourceware.org/gdb/current/onlinedocs/gdb/Source-Path.html#index-set-substitute_002dpath )
I haven't tried anything like your #3 and I also considered something like #dragn suggestion, but in my situation the paths are not even close to the same length, so that will be an issue.
I think I'm stuck with #1 and a script, but if anyone has other suggestions, I'm interested options :-)

Android.mk : How to add backslashes automatically

In Android.mk, I read the context of system environment variable like $(MY_ENV_VARIABLE). The env variable contains following string inside "Program(x86) Files".
But the build fails, claiming that the specified library cannot be found. The failure takes place of windows style weird space in "Program(x86) Files".
So my question is, is there any mechanism to automatically escape the special symbols like space (i.e "Program(x86)\ Files", for my case).
You might be able to try using the windows pathing conventions of using the tilde character so instead of C:\Program(x86) Files\mydir it would be C:\PROGRA~2\mydir (PROGRA~1 is for the 64 bit program files).
Like eldar said in the comments it is better to not use spaces in path names because most of make's functions use spaces as delimiters. Another option you could try is to take a look at my suggestion here: WINAVR not finding file in include path with whitespace
Since Android is a pretty complicated build environment it might be hard to see where to place the final substitution unless you know what you're doing and hopefully won't break anything else in the makefile.

Cygwin Access Windows UNC Mapped Drive

I often need to do some text processing for windows network drive. Since there are so many of them I have almost all my drive letters are used (I think T is still available).
I something need to do:
cd "\lonshr-cad\cad\Feeds\BondPricesNYClose\" or
less "\lonshr-cad\cad\Feeds\BondPricesNYClose\BondPrices_display_16112011.txt"
but my Cygwin shows that the MS-DOS sytle path detected.
Is there a quick way to access these file?
Try with the normal slash "/" or with single quotes instead of double quotes. If you want to use an absolute path then use /cygdrive/t for the T drive
Just use forward slashes:
cd //lonshr-cad/cad/Feeds/BondPricesNYClose
and
less //lonshr-cad/cad/Feeds/BondPricesNYClose/BondPrices_display_16112011.txt
You can also create aliases that can cd to these directories or less specific files. That way you don't have to type the entire UNC path (or copy/paste/change slashes).

Resources