File exists but shell can't launch the process [duplicate] - process

i am trying to run an executable in linux shell ( OpenELEC on raspberry pi )
OpenELEC:~ # /storage/fingi/usr/lib/autossh/autossh
-sh: /storage/fingi/usr/lib/autossh/autossh: not found
What does the "not found" in this case mean ?
If i try to do ldd:
OpenELEC:~ # ldd /storage/fingi/usr/lib/autossh/autossh
/usr/bin/ldd: eval: line 1: /storage/fingi/usr/lib/autossh/autossh: not found
And if i do file:
OpenELEC:~ # file /storage/fingi/usr/lib/autossh/autossh
/storage/fingi/usr/lib/autossh/autossh: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=599207c47d75b62ede5f214f9322ae2a18643eb7, stripped
The file type is in correct format . But it wont work adn wont give more descriptive error msg either.
Since openELEC is very restrictive, i had copied the autossh executable from a raspbmc installation . I have done it for several other executables as well ( screen , boost libraries etc ) and they work fine .
Can anyone suggest what might be the issue?
Edit 1:
as was suggested, this is the output of file command on an executable ( also copied from raspbmc ) that is working:
OpenELEC:~ # file /storage/fingi/usr/bin/screen
/storage/fingi/usr/bin/screen: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=5c58f047a25caa2c51a81d8285b4f314abc690e7, stripped

What does the "not found" in this case mean ?
This usually means that the executable cannot find one or more (shared) libraries to satisfy its external symbols.
This usually happens when no libraries are stored in the initramfs, or there is a shared library missing that the executable needs.
This can also happen if the executable is built with a C library that is incompatible with the runtime library, e.g. uClibc versus glibc/eglibc.
strings executable | less is the quickest way to see the required libraries and external symbols that the executable requires.
Or
Recompile your program and use static linking by specifying the -static option.

Check that the file has been set to executable permissions with ls -l if it hasn't change with chmod +x /storage/fingi/usr/lib/autossh/autossh

Related

Modern CMake Cross Compiling to AArch64 with Sysroots

Consider the following example project_(CMakeLists.txt):
cmake_minimum_required(VERSION 3.1)
project(CCL LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
find_package(PkgConfig REQUIRED)
find_package(ZLIB)
find_package(PNG)
find_library(MATH_LIBRARY m)
pkg_search_module(OpenEXR OpenEXR)
add_executable(main main.cpp)
if (MATH_LIBRARY)
target_link_libraries(main PUBLIC ${MATH_LIBRARIES})
endif()
Main.cpp:
#include <iostream>
#include <cmath>
int main(void)
{
std::cout << "Hello, sin()" << std::sin(30) << std::endl;
return 0;
}
I want to compile this project with the following CMake toolchain
(aarch64-toolchain.cmake):
# Cross-compilation system information.
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
# The sysroot contains all the libraries we might need to link against and
# possibly headers we need for compilation.
set(CMAKE_SYSROOT /var/lib/schroot/chroots/ubuntu-focal-arm64)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu)
# Install path when SYSROOT is read-only.
# set(CMAKE_STAGING_PREFIX aarch64-staging)
# Set the compilers for C, C++ and Fortran.
set(GCC_TRIPLE "aarch64-linux-gnu")
set(CMAKE_C_COMPILER ${GCC_TRIPLE}-gcc-10 CACHE FILEPATH "C compiler")
set(CMAKE_CXX_COMPILER ${GCC_TRIPLE}-g++-10 CACHE FILEPATH "C++ compiler")
set(CMAKE_Fortran_COMPILER ${GCC_TRIPLE}-gfortran CACHE FILEPATH "Fortran compiler")
# Automatically use the cross-wrapper for pkg-config when available.
set(PKG_CONFIG_EXECUTABLE aarch64-linux-gnu-pkg-config CACHE FILEPATH "pkg-config executable")
# Set the architecture-specific compiler flags.
set(ARCH_FLAGS "-mcpu=cortex-a53+crc+simd")
set(CMAKE_C_FLAGS_INIT ${ARCH_FLAGS})
set(CMAKE_CXX_FLAGS_INIT ${ARCH_FLAGS})
set(CMAKE_Fortran_FLAGS_INIT ${ARCH_FLAGS})
# Don't look for programs in the sysroot (these are ARM programs, they won't run
# on the build machine).
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Only look for libraries, headers and packages in the sysroot, don't look on
# the build machine.
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE arm64)
Where the sysroot (/var/lib/schroot/chroots/ubuntu-focal-arm64) was setup using:
name=ubuntu-focal
mk-sbuild --arch=arm64 --skip-proposed --skip-updates --skip-security --name=${name} focal
su - $USER
mk-sbuild --arch=arm64 --skip-proposed --skip-updates --skip-security --name=${name} focal
Configuration-wise, this works fine, however when I try to build this project
find_library 'correctly' finds the wrong libm.so library:
$ cmake -DCMAKE_TOOLCHAIN_FILE=../aarch-toolchain.cmake ..
$ make
Scanning dependencies of target main
[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
make[2]: *** No rule to make target '/var/lib/schroot/chroots/ubuntu-focal-arm64/usr/lib/aarch64-linux-gnu/libm.so', needed by 'main'. Stop.
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
Looking into the sysroot itself, the library is correctly found, but obviously,
it is a symlink to a file local to the sysroot, not the host:
$ ls -hal /var/lib/schroot/chroots/ubuntu-focal-arm64/usr/lib/aarch64-linux-gnu/
lrwxrwxrwx 1 root root 32 Apr 14 2020 libm.so -> /lib/aarch64-linux-gnu/libm.so.6
It seems to me that CMake is picking up the wrong library (find_library should
really be using the compiler libraries first), so I guess that my toolchain-file
is written incorrectly somehow. How should it be changed to correctly find the
math library, without changing the sysroot or project itself?
(Also, please note that this is an example project to illustrate the problem. I still need to be able to search the sysroot for packages.)
Edits
As requested in the comments, the end state should be a proper aarch64 binary
("main"). Essentially, the build commands below should succeed both with and
without the toolchain, and should yield a functional binary (although, the
aarch64 one naturally only work inside the sysroot).
$ mkdir -p host-build && cd host-build && cmake .. && make
$ mkdir -p device-build && cd device-build && cmake -DCMAKE_TOOLCHAIN_FILE=../aarch64-toolchain.cmake .. && make
TLDR: There is no easy way, as far as I know.
Your toolchain file is fine, it's the symlinks that are bad and they should ideally be relative and not absolute if you wish to use it for building. Below I mention a few options and explain the issue. This is all based on my experience with cross-compiling. Perhaps someone knows more.
There isn't anything wrong with your toolchainfile. From my perspective it is configured correctly. This is an issue as you pointed out with the symlinks being relative to your created rootfs and not absolute to the host machine but they are presented as absolute.
IIRC there is not much you can do here.
I'll give you a few options that I know of from personal experience:
Forget cross-compiling and using QEMU chroot into the environment and build there. This is the easiest option.
Get all the required libraries on your host machine (outside of the sysroot) and compile using them - You just have to make sure that you have the exact same libraries as the target machine. Your toolchain file would be then reconfigured to look for libraries among the ones here.
EDIT: As #josch pointed out in the comments under his answer I should expand on this point to make it more clear to users. However because he already mentioned the most important steps to take when applying this, I will refer the reader to his answer. I will however provide a link to debians official HowTo regarding Multi-arch
The other option would mean fixing your projects CMakeLists to more adapt to the cross-compiling. This would require you to specify the absolute paths to the correct libraries. There is a drawback as you need to always point to the newest library. You could for example create another .cmake file that helps you configure the correct paths and because target_link_libraries() allows you to specify absolute paths, you could use the newly created custom targets.
The last option would be to fix the symlinks (ideally by making them relative). This is in my opinion the preferred way. In the end the rootfs that you will be using for building will be just that, i.e. used for building.
As far as I know (I might be wrong here) but the mks-build is just a debian tool that is originally used for packaging .deb files and as such wasn't made to be complimentary to CMake. And if it was then the debian team probably has the toolchain files you are looking for (i.e. I would look for cross-compiling and package guides regarding .deb packages - if they exist they will be included).
CMAKE_SYSROOT, CMAKE_FIND_ROOT_PATH only add a prefix to specific find_ commands/functions. They pretty much can't change anything about the target system or the linker behavior (which is the issue here). Which means they are correctly configured. It's the fake system that is wrongly configured.
You wrote to the debian-cross mailing list so I assume that your question is Debian specific? If so, maybe tag your question as such. Here is how you cross compile any Debian package for amd64 (aarch64) using sbuild:
sbuild --host=arm64 your_package.dsc
sbuild will take care of setting up your chroot as required and call the build tools with the correct arguments. You do not even need to create a special build chroot for that and can just re-use your existing chroots (sbuild will know what to do with them).
If instead, you just want to cross-compile some software using CMake on Debian, the process is as simple as installing a cross-compiler and pointing CMake to it:
$ sudo apt install g++-aarch64-linux-gnu
$ cmake -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ .
$ make VERBOSE=1
...
/usr/bin/aarch64-linux-gnu-g++ -rdynamic CMakeFiles/main.dir/main.cpp.o -o main
...
$ file main
main: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1 ...
That's it. No need for a sysroot.
If you haven't set up arm64 as a foreign architecture on your system, you need to run this once:
dpkg --add-architecture arm64
apt-get update

How to run a dynamically linked executable syscall emulation mode se.py in gem5?

After How to solve "FATAL: kernel too old" when running gem5 in syscall emulation SE mode? I managed to run a statically linked hello world under certain conditions.
But if I try to run an ARM dynamically linked one against the stdlib with:
./out/common/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./a.out
it fails with:
fatal: Unable to open dynamic executable's interpreter.
How to make it find the interpreter? Hopefully without copying my cross' toolchain's interpreter on my host's root.
For x86_64 it works if I use my native compiler, and as expected strace says that it is using the native interpreter, but it does not work if I use a cross compiler.
The current FAQ says it is not possible to use dynamic executables: http://gem5.org/Frequently_Asked_Questions but I don't trust it, and then these presentations mention it:
http://www.gem5.org/wiki/images/0/0c/2015_ws_08_dynamic-linker.pdf
http://research.cs.wisc.edu/multifacet/papers/learning_gem5_tutorial.pdf
but not how to actually use it.
QEMU user mode has the -L option for that.
Tested in gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e
https://www.mail-archive.com/gem5-users#gem5.org/msg15582.html
Support for dynamic linking has been added in November 2019
At: https://gem5-review.googlesource.com/c/public/gem5/+/23066
It was working for sure at that point, but then it broke at some point and needs fixing.....
arm 32-bit https://gem5.atlassian.net/browse/GEM5-461
arm 64-bit https://gem5.atlassian.net/browse/GEM5-828
If you have a root filesystem to use, for example one generated by Buildroot you can do:
./build/ARM/gem5.opt configs/example/se.py \
--redirects /lib=/path/to/build/target/lib \
--redirects /lib64=/path/to/build/target/lib64 \
--redirects /usr/lib=/path/to/build/target/usr/lib \
--redirects /usr/lib64=/path/to/build/target/usr/lib64 \
--interp-dir /path/to/build/target \
--cmd /path/to/build/target/bin/hello
Or if you are using an Ubuntu cross compiler toolchain for example in Ubuntu 18.04:
sudo apt install gcc-aarch64-linux-gnu
aarch64-linux-gnu-gcc -o hello.out hello.c
./build/ARM/gem5.opt configs/example/se.py \
--interp-dir /usr/aarch64-linux-gnu \
--redirects /lib=/usr/aarch64-linux-gnu/lib \
--cmd hello.out
You have to add any paths that might contain dynamic libraries as a separate --redirect as well. Those are enough for C executables.
--interp-dir sets the root directory where the dynamic loader will be searched for, based on ELF metadata which says the path of the loader. For example, buildroot ELF files set that path to /lib/ld-linux-aarch64.so.1, and the loader is a file present at /path/to/build/target/lib/ld-linux-aarch64.so.1. As mentioned by Brandon, this path can be found with:
readelf -a $bin_name | grep interp
The main difficulty with syscall emulation dynamic linking, is that we want somehow:
linker file accesses to go to a magic directory to find libraries there
other file accesses from the main application to go to normal paths, e.g. to read an input file in the current working directory
and it is hard to detect if we are in the loader or not, especially because this can happen via dlopen in the middle of a program.
The --redirects option is a simple solution for that.
For example /lib=/path/to/build/target/lib makes it so that if the guest would access the C standard library /lib/libc.so.6, then gem5 sees that this is inside /lib and redirects the path to /path/to/build/target/lib/libc.so.6 instead.
The slight downside is that it becomes impossible to actually access files in the /lib directory of the host, but this is not common, so it works in most cases.
If you miss any --redirect, the dynamic linker will likely complain that the library was not found with a message of type:
hello.out: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
If that happens, you have to find the libstdc++.so.6 library in the target filesystem / toolchain and add the missing --redirect.
It later broke at https://gem5.atlassian.net/browse/GEM5-430 but was fixed again.
Downsides of dynamic linking
Once I got dynamic linking to work, I noticed that it actually has the following downsides, which might or not be considerable depending on the application:
the dynamic linker has to run some instructions, and if you have a very minimal userland test executable, and are running on a low CPU like O3, then this startup can dominate runtime, so watch out for that
ExecAll does not show symbol names for stdlib functions, you just get offsets from some random nearest symbol e.g. #__end__+274873692728. Maybe something along these lines would work: Debugging shared libraries with gdbserver but not sure
dynamically jumping to a stdlib function for the first time requires going through the dynamic linking machinery, which can create problems if you are trying to control a microbench.
I actually already hit this once: the dynamic version of a program was doing something extra that and that compounded with a gem5 bug broke my experiment, and cost me a few hours of debugging.
Interpreters like Python and Java
Python and Java are just executables, and the script to execute an argument to the executable.
So in theory, you can run them in syscall emulation mode e.g. with:
build/ARM/gem5.opt configs/example/se.py --cmd /usr/bin/python --options='hello.py arg1 arg2'
In practice however hugely complex executable like interpreters are likely to have syscalls that not yet implemented given the current state of gem5 as of November 2019, see also: When to use full system FS vs syscall emulation SE with userland programs in gem5?
Generally it is not hard to implement / ignore uneeded calls though, so give it a shot. Related threads:
Java: Running Java programs in gem5(or any language which is not C)
Python: 3.6.8 aarch64 fails with "fatal: syscall unused#278 (#278) unimplemented.", test setup
Old answer
I have been told that as of 49f96e7b77925837aa5bc84d4c3453ab5f07408e (May 2018) there is no convenient / well tested way for running dynamically linked cross arch executables in syscall emulation: https://www.mail-archive.com/gem5-users#gem5.org/msg15585.html
I suspect however that it wouldn't be very hard to patch gem5 to support it. QEMU user mode already supports that, you just have to point to the root filesystem with -L.
The cross-compiled binary should have an .interp entry if it's a dynamic executable.
Verify it with readelf:
readelf -a $bin_name | grep interp
The simulator is setup to find this section in main executable when it loads the executable into the simulated address space. If this sections exists, a c-string is set to point to that text (normally something like /lib64/ld-linux-x86-64.so.2). The simulator then calls glibc's open function with that c-string as the parameter. Effectively, this opens the dynamic linker-loader for the simulator as a normal file. The simulator then maps the file into the simulated address space in phases with mmap and mmap_fixed.
For cross compilation, this code must fail. The error message follows it directly if the simulator cannot open the file. To make this work, you need to debug the opening process and possibly the subsequent pasting of the loader into the address space. There is mechanism to set the program's entry point into the loader rather than directly into the code section of the main binary. (It's done through the auxiliary vector on the stack.) You may need to play around with that as well.
The interesting code is (as of 05/29/19) in src/base/loader/elf_object.cc.
I encountered this problem after I just cross compiled the code. You can try to add "--static" after the command.

Can the object file name be changed from .obj during cmake compiler testing?

Ultimately, I'm trying to build Apache QPID to run in the HPE NonStop OSS environment (a Posix-like environment on the NonStop system). The latest version of QPID uses cmake to build so I first need to get cmake to work for that environment. My earlier attempts tried to build in OSS directly (I needed to build cmake first before trying to build QPID), but I ran into many problems there. So lately I'm trying to build in Windows using a set of cross-development tools (compilers etc.) for NonStop. I've downloaded a Windows version of cmake 2.8 (suggested by the QPID build instructions) and am trying to use that with the X-dev tools to build QPID for OSS.
One big issue I've run into has to do with how cmake does things to test compilers and so forth early on. It will invoke the compiler to create an intermediate object file from C (and/or C++) source file and after that it will invoke the compiler to link an object file from the intermediate file. It seems that cmake prefers to add .obj to file names to create the intermediate object file name. This will work OK with my cross-compiler when creating the file (the name passed with -o to the compiler) but it will not work when passing this name for link purposes. Here is a short bit of the output per the CMakeError.log file (from trying build an OSS version of cmake 2.8 itself):
Determining if the C compiler works failed with the following output:
Change Dir: C:/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp
Run Build Command:C:/cygwin/bin/make.exe "cmTryCompileExec/fast"
/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build
make[1]: Entering directory '/cygdrive/c/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp'
"C:/Program Files (x86)/CMake 2.8/bin/cmake.exe" -E cmake_progress_report C:/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp/CMakeFiles 1
Building C object CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj
/cygdrive/c/NonStop/tndm_cmplrs-j20/usr/bin/c89.exe -o CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj -c C:/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTryCompileExec
/cygdrive/c/NonStop/tndm_cmplrs-j20/usr/bin/c89.exe "CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj" -o cmTryCompileExec
c89.exe: error: Invalid input file extension"CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj".
The cross-compiler fails because it requires intermediate object files to use .o for the extension, in order to determine they are intermediate object files. There is no way to get the c89 compiler to recognize testCCompiler.c.obj as a file type it knows what to do with.
So I've been searching (trying to find a local expert, but no one in my organization knows cmake; also numerous Google searches but could not find an answer) to see if there is any way to get cmake to change the name of the output file it uses for these type of compiles and tests. I've found info and then set CMAKE_C_OUTPUT_EXTENSION in a toolchain file:
SET(CMAKE_C_OUTPUT_EXTENSION ".o")
but that has made no difference.
If I can find a way to get cmake to create object files with names like testCCompiler.c.o instead of testCCompiler.c.obj, then the c89 cross-compiler would work.
Is it possible to do this?
UPDATE: I've managed to figure out that setting CMAKE_C_OUTPUT_EXTENSION in the toolchain file doesn't help. This gets overwritten in the CMakeCInformation.cmake (depending on whether UNIX is set or not). I also tracked down that UNIX gets set to true in Platform/UnixPaths.cmake, which gets INCLUDEd by various Platform files. So I've created a Modules/Platform/OSS.cmake file which includes it to takes care of that. I'll probably need/want to add other settings there later as I determine more flags for compilers etc that should be set to specific values for the OSS environment.

Linking with ffmpeg shared build

I am trying to work with the ffmpeg library on a cygwin development environment. I downloaded the shared build from here (64-bit). The bin folders contain dlls but no .a or .dll.a files. Linking, which is done like so:
$ gcc encoding_mp3.o -L/cygdrive/c/Users/Desktop/webserver/cygnus/lib/w32api -L/cygdrive/c/Users/Desktop/webserver/cygnus/ffmpeg/ffmpeg_shared/bin -lavcodec-54 -lm -luser32 -lpthread -o encoding_mp3
results in the following error:
/cygdrive/c/Users/Desktop/webserver/cygnus/ffmpeg/ffmpeg_shared/bin/avcodec-54.dll: file not recognized: File format not recognized collect2: ld returned 1 exit status
My question(s):
1. The bin/ folder in the shared build contains only avcodec-54.dll. Is there a way to convert the dll to a dll.a or .a?
2. Where am I going wrong?
If source code is required, please let me know.
You need to download the "dev" versions, or the "static linking" ones (a little down, on the page).
dlls cannot be converted to libs, nor can they be used (usually) to generate they own little import stubs (the .dll.a)
From the page you linked "Dev packages provide the headers and .lib/.dll.a files required to use the .dll files in other programs."
.a / .lib usually are located in "lib" folders.

How to add header file path in CMake file

I am new to OpenCL. I have written a vector addition code in OpenCL with help from Internet. I have included one header file i.e. CL/cl.h using #include.
I am using NVIDIA graphic card and the OpenCL implementation is NVIDIA_GPU_Computing_SDK. My OpenCL header files are residing at this path /opt/NVIDIA_GPU_Computing_SDK/OpenCL/common/inc. I can run OpenCL programs through linux terminal by adding this path when compiling my code. But now I want to write CMake file for this code. CMake files are working fine for C programs, but not OpenCL programs because of this Path problem. In terminal, I used to enter $cmake ., after this $make, it will search for a Makefile which is created by cmake, now my error is after entering command make
fatal error: CL/cl.h: No such file or directory!
Now tell me how can I include this header file into CMake file?
You will need to put these lines into CMakeLists.txt:
include_directories(/opt/NVIDIA_GPU_Computing_SDK/OpenCL/common/inc)
link_directories(/opt/NVIDIA_GPU_Computing_SDK/OpenCL/common/<lib or something similar>)
add_executable(yourexe src1.c ...)
target_link_libraries(yourexe OpenCL)
But beware that this is not portable, because OpenCL SDK can be somewhere else on another machine. The proper way to do this is to use FindOpenCL.cmake module.
Maybe you can use a CMake "find" script like:
http://gitorious.org/findopencl/findopencl/blobs/master/FindOpenCL.cmake
http://code.google.com/p/opencl-book-samples/source/browse/trunk/cmake/FindOpenCL.cmake?r=14
CMake file example from OpenCL Programming Guide Book: http://code.google.com/p/opencl-book-samples/source/browse/trunk/CMakeLists.txt?r=14
I was looking for FindOpenCL.cmake macro which would work well on Windows, OSX and Linux... I couldn't find any which did work well on every platform, so I wrote new one which I use in couple of projects (webcl-validator and opencl-testsuite).
https://github.com/elhigu/cmake-findopencl
Especially Windows support is improved in this one.
In Windows it checks if 64bit or 32bit lib should be used and it also tries to find libraries from according to environment variables set by Nvidia, Intel and AMD OpenCL SDKs.
It also tries to find .lib in Cygwin, which didn't work with other scripts I tried.