I am referring the official doc to use find_library() and my cmake version is 3.9.1.
In short, my find_library() only deals with the first library name and ignore the rest.
For example, when I do something like,
find_library (var NAMES libname1 libname2 PATHS libpath)
var will only get the full path-name of library libname1 not the counterpart of libname2. Both the libraries are placed correctly in libpath. In fact, if I reverse the order as NAMES libname2 libname1, var will only get the full path-name of library libname2
Any suggestion?
The find_librarycommand finds a library by trying the NAMES one after another. So the NAMES are synonyms for the library (e.g. libjpg libjpeg). After the first match it saves the path to the library in the variable var. You need to use two find_library calls to accomplish what you are after.
Related
In my project, the CMakeLists includes other cmake files from a library and those dependencies need some cache variables to be configured by user values.
It is all working well if I define those values from the command line with the cmake command:
-DTHIRDPARTY_FRAMEWORK_ROOT="$thirdpartyFrameworkPath"
But can I define (= hardcode) such values in my own CMakeLists file?
To avoid my own users to do it when they configure my project (some values of the 3d party configuration are constant in my project), and make my own cmake interface simpler.
I tried to simply set the variable with a value, but it is both defined and used in the included cmake so it gets overwritten with their default value just before being used.
Using set(... FORCE) seems to work but it does not look clean to me, and might lead to confusing errors if they rename or change the type of the variables on their side. It also forces me to add a type and a doc string because of the set(... CACHE ...) syntax.
Is there a better way to do this?
Setting CACHE INTERNAL variable is a proper way for hardcode a parameter of the inner project in the outer one:
set(THIRDPARTY_FRAMEWORK_ROOT CACHE INTERNAL "Hardcoded root for 'thirdparty'" <value>)
INTERNAL type makes sure that this setting will overwrite the option (FORCE doesn't need) and makes sure that the option won't be shown for a "normal" user.
Since the parameter is not intended to be changed by a user, its real type is meaningless, so there is no needs for it to coincide with the one set in the inner project.
As for description, you could set it to be empty (the parameter is not shown to the normal user, remember?). Alternatively, in the description you could explain why do you set the variable in the outer project. So an "advanced" user will see your description.
If I create an alias target in CMake like
add_library(my::foo ALIAS my_foo)
is there any way to query the name of the underlying target name from the alias target?
My use case:
A shared C++ codebase with several independent modules. The root folder of this codebase contains a CMakeList.txt to be added via add_subdirectory to the project using it. According to our convention e.g. my_foo will always be located in a subfolder named my_foo. Furthermore, my_foo will be exported as alias target my::foo and used as such in the project. Note that my_foo is always an INTERFACE target, so I cannot set any custom properties on it.
We use conan to manage third party library dependencies. All modules that have such dependencies contain a conanfile.txt
For convenience I want to write a function (located in the shared codebase's root CMakeList) that takes a list of module targets the project wants to use and scans all of them for conanfiles and sets up the dependencies for those used. I want to be able to pass my::foo as argument to that function but derive my_foo from that argument inside the function to get the corresponding folder name to scan for the conanfile
Any other suggestions that solve the problem according to my use case are welcome as well!
An alias target has a special property, where it store name of the original target: ALIASED_TARGET.
get_target_property(my_foo_original my::foo ALIASED_TARGET)
message(STATUS "Alias my::foo refers to the target ${my_foo_original}")
I want to use multiple external CMake files in my project. Unfortunately two different files use the same CMake function name foo. I don't want to modify these external files.
Is there a way to call one specific function or will CMake error out? Would it help if one of the functions has a named parameter, i.e., foo(a b c …) and foo(DESTINATION a b c …)?
New function's definition replaces the previous one with the same name. So access to the previous function is lost.
If different functions (but with the same name) are used in different subprojects, you may try to build one subproject as ExternalProject, so function's collision wouldn't occure.
In CMake any function definitions contains the only piece of information for the caller - minimal number of parameters which should be passed to the function. By using this information it is impossible to resolve function's overloading, if it would be implemented.
I'm writing a tool to add variables to a2l file, the input is elf file.
For searching which compile unit (CU) has the variable, I have to search through all CUs (till meet the variable).
Because the SW is very big, it takes time to find a variable.
I would like to know if there's any faster way to know which CU the variable is defined ?
The DWARF standard includes an optional section, .debug_pubnames, that provides name-to-offset translation for global objects and functions.
Another approach is to use the symbol table. If it has an entry for the variable then you can use its address with the optional .debug_aranges section or, failing that, read every DW_TAG_compile_unit looking for the one with the enclosing address range.
For example, I have a variable that holds a list of dependencies
BOARDS:=lance.mcm light.mcm sac.mcm
I need another variable named NET such that
NET:=lance.net light.net sac.net
It should be set such that when I change the BOARDS variable, NET should change as well.
For example, if I add a new zor.mcm into the BOARDS variable, it should automatically add zor.net into the NET variable.
The best solution I have found is to use this syntax:
NET:=$(BOARDS:.mcm=.net)
This will look at BOARDS and change the .mcm into .net
As an alternative:
BOARDS:=lance.mcm light.mcm sac.mcm
NET:= $(addsuffix .net, $(basename $(BOARDS)))
This will preserve contents inside the file pathnames should they match pattern