How can I find a file inside a directory based on the file extension?
I want to create a function that finds a linker script. The function will be defined in the toolchain file, because each compiler has a different type of linker script.
I want to pass to the function a path to a directory with linker files for all type of supported compilers.
The function implemented for the specific compiler will find the right linker file (for example, armcc compiler will find the file with the extension .sct)
Thanks for the help.
Related
TL;DR
How do I configure CMake and Emscripten to build my static library to produce a WASM and JS bootstrap file?
I have a static library being built with CMake that I want to build as a WASM library (and JS bootstrap) using Emscripten. Simply using the Emscripten CMake toolchain and adding the appropriate compiler/linker flags result in only a .a file being built - even if -o <project name>.js is added to the compiler and/or linker flags.
The reason is that because I've told CMake I want a static library, it uses CMAKE_AR to build. CMAKE_AR (if undefined) is defined as emar in the Emscripten toolchain file, and emar cannot produce .wasm and .js output.
I have tried creating a new executable target that has a dependency on the library, and otherwise just sets up the compiler/linker settings. However this causes a CMake error, because I've defined an executable target that has no source files (they're associated with the library target). If I add a stub main file, I get an Emscripten warning:
system_libs:WARNING: main() is in the input files, but "_main" is not in EXPORTED_FUNCTIONS, which means it may be eliminated as dead code. Export it if you want main() to run.
I could get round by adding an empty file to exe source file list (probably, I haven't tried), but this feels very much like a hack.
You are correct in that you need to create an executable target in order to produce a .wasm file.
If cmake insists on you creating a dummy source file because it doesn't understand that all the code for your program can come from libraries then I guess you that is your best option.
See CMake: Is it possible to build an executable from only static libraries and no source? for how to work around this limitation of cmake.
I have the following code:
project(test)
cmake_minimum_required(VERSION 3.17)
set(PNG_DIR C:/Users/Kagami/.emscripten_cache/wasm/ports-builds/libpng)
find_library(PNG_STATIC_LIBRARY
NAMES libpng.a
HINTS ${PNG_DIR}
)
message(${PNG_DIR})
message(${PNG_STATIC_LIBRARY})
I have a file named libpng.a in that PNG_DIR directory but find_library still returns -NOTFOUND. What would be the possible reasons?
find_library will find a library that he can be used with the arch you use. So on your Windows it will not look for .a but for .lib.
But find_path just search a file doesn't matter if it's a real library or not.
From the documentation :
Each library name given to the NAMES option is first considered as a library file name and then considered with platform-specific prefixes (e.g. lib) and suffixes (e.g. .so). Therefore one may specify library file names such as libfoo.a directly. This can be used to locate static libraries on UNIX-like systems.
The NAMES parameter to find_library specifies the library name, not the file name.
So in your case the correct command would be
find_library(PNG_STATIC_LIBRARY
NAMES png
HINTS ${PNG_DIR}
)
Note that you can give more than one name as arguments to the NAMES, in case the library ships under different names on the different platforms.
An additional complication here comes from the fact that on Windows we have two incompatible toolchains, MinGW and MSVC. If your library has a .a file ending, it was almost certainly compiled for the MinGW toolchain, so you will not be able to use it from a Visual Studio build. Here you would first need to recompile the library with the correct toolchain.
I am running Linux Redhat, I have Anaconda installed and I am trying to install a program (libspimage) using CMAKE amd I get the following warning/error:
CMake Warning at src/CMakeLists.txt:74 (ADD_LIBRARY):
Cannot generate a safe runtime search path for target _spimage_pybackend
because files in some directories may conflict with libraries in implicit
directories:
runtime library [libtiff.so.5] in /usr/lib64 may be hidden by files in:
/home/michantia/anaconda2/lib
Some of these libraries may not be found correctly.
When I do:
echo $PATH
I get:
/home/mi_a/anaconda2/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/michantia/.local/bin:/home/michantia/bin
I tried:
export PATH=/usr/lib64:$PATH
hoping cmake would find the libraries in this directory before finding them in anancoda's, but that did not work. I also tried two other similar suggestions for a similar problem that I saw in stackoverflow, but that did not work.
Any other ideas are highly welcomed.
Warning message
Cannot generate a safe runtime search path for target
is related neither with CMake ability to find a library (libtiff.so.5 in your case) nor with a linker ability to link the library.
The warning message means that when a target (_spimage_pybackend) will be loaded, the loader will be unable to choose the correct library: according to the loader's algorithm and the target's setting, file /home/michantia/anaconda2/lib/libtiff.so.5 will be choosen instead of proper one /usr/lib64/libtiff.so.5.
The error is usually resulted in linking into the single target two libraries from different directories, when the directory with a second library also contains a file with the name of the first library:
Directory /usr/lib64 contains a library libtiff.so.5, which is linked into the target.
Directory /home/michantia/anaconda2/lib contains a library <A> which is also linked into the target; but this directory also contains a file libtiff.so.5.
According to CMake algorithm, runpath for the binary file of such target will include both directories, so both libraries could be found. But such runpath confuses the loader to find the first library properly.
Except from avoiding such situation (when a library is contained in two directories), one hardly is able to handle this warning.
I have such C:/project/test.ts file:
import $ = require('jquery');
console.log($);
And I have placed jquery.d.ts file in: C:/jquery.d.ts
Using file watcher (with additional compiler arguments: --module amd C:/jquery.d.ts) file test.ts compiles successfully.
Using built-in compiler (with the same arguments: --module amd C:/jquery.d.ts) file test.ts doesn't compile. Error:
Error:(1, 20) TS2307: Cannot find external module 'jquery'.
Of course, I could define reference path test.ts file like this:
/// <reference path="C:/jquery.d.ts" />
After that - it compiles fine using both compilers. But its not convenient in big project. Would be better to define reference path just in one place (compiler arguments).
So how to define reference path using built-in TypeScript compiler command line options?
Would be better to define reference path just in one place (compiler arguments).
So how to define reference path using built-in TypeScript compiler command line options
You would include these with your project. Download directly from github or use tsd.
I have large project with more than 100 .ts files, so defining reference path directly in each of files - bad solutio
Basically create a globals.d.ts file and ///<reference these files once. Then you can just reference globals.d.ts and these get referenced implicitly.
In the main folder of my project, I have a CMakeLists.txt file. Inside this file, I include (using add_subdirectory) another CMakeLists.txt file located in my header file directory. The responsibility of this second file is to add all of my header files to the project:
file(GLOB gl_nbody_HEADERS "*.h")
add_executable(gl_nbody ${gl_nbody_HEADERS})
However, this files causes an error:
CMake Error: CMake can not determine linker language for target:gl_nbody
CMake Error: Cannot determine link language for target "gl_nbody".
What is strange is that when I include the two lines causing this error in my main CMakeLists.txt file (modified to work correctly for the change in directory), it works fine.
What is going wrong here?
add_executable causes the creation of an executable target, meaning the compilation of a list of source code files into an executable binary.
In order for this to work, and have CMake select a suitable compiler, the list of source files must contain at least one file with a "compilable" extension, ie. .c, or .cpp, or .cxx....
I don't see why you are trying to compile an executable here, since you only seem to try to list header files for inclusion into a project (which only makes sense for IDE-based generators, such as Visual Studio).
Also, it is not recommended to use globbing of files in CMake, because if you add more files to your project, CMake cannot detect them automatically, and will not regenerate build files. Please list all files explicitely.
The proper solution here is to list the header files in the proper add_executable command call where you list the actual source files that you want to compile.
You might also want to use the source_group() command, that allows you to group files into folders in the generated Visual Studio solution, for example:
source_group(header_files ${gl_nbody_HEADERS})