Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMAKE How to get Target File Location

Tags:

cmake

I'm trying to get the location of a static library of another project. I tried

get_property(target_name TARGET Test PROPERTY LOCATION) but CMAKE gives the following error

CMake Error at project.cmake:6 (get_property):
The LOCATION property may not be read from target "A".
Use the target name directly with add_custom_command, or use the generator
expression $<TARGET_FILE>, as appropriate.

I tried to use the generator expression mentioned in the error message with no success.

MESSAGE($<TARGET_FILE:A>)

just outputs the exact same string, so the generator expression doesn't seem to be evaluated at all:

$<TARGET_FILE:A>

I read the Documentation. In the first lines it mentions:

Generator expressions are evaluated during build system generation to produce information specific to each build configuration.

If I'm understanding this correctly then at the time the message function is evaluated the generator expressions are not evaluated anymore? So what am I supposed to be doing in this case?

I committed a minimal example of this problem on GitHub

EDIT:

I'm sorry to have asked the question in such a roundabout way without a clear explanation of my intentions:

My Aim is to get CMake to build a single (!) static library for my project, which someone else (who doesn't use CMake) can use. I would still use the "normal" resolution of dependencies for my project, but the other person - who doesn't use CMake - would have to manualy link multiple libraries to his project, which is somewhat inconvenient. A single library would solve this.

On my way of trying to get CMake to staticly link two static libraries, I read somewhere (sorry, I haven't saved a link) that at least when using Visual Studio as a compiler you can get the result I want if I append the full path of the static library to be linked to the static linker flags like that:

set_target_properties(B PROPERTIES STATIC_LIBRARY_FLAGS >>>INSERT_PATH_HERE<<<)

which does in fact work. But now I'd have to manualy insert the fully qualified path to the variable there

set_target_properties(B PROPERTIES STATIC_LIBRARY_FLAGS "/path/to/library.lib")

which doesn't seem to be a "good" way to do it to me. So I experimented with generator expressions and came up with the following one:

set_target_properties(B PROPERTIES STATIC_LIBRARY_FLAGS $<TARGET_FILE:A>)

which doesn't work, for reasons I don't fully understand. I guess set_target_properties just doesn't support generator expressions. While trying to get my project to work I tried

MESSAGE($<TARGET_FILE:A>)

(as stated above this explenation) and thought that if I'd get that statement to work I could solve my real problem. So thats what I asked the question posted above. I didn't realise that this would lead to confusion for the people trying to answer me.

like image 224
Dirk Avatar asked Nov 18 '14 10:11

Dirk


People also ask

What is CMakelist file?

CMakeLists. txt file contains a set of directives and instructions describing the project's source files and targets (executable, library, or both). When you create a new project, CLion generates CMakeLists. txt file automatically and places it in the project root directory.

How do I specify a path in CMake?

CMake will use whatever path the running CMake executable is in. Furthermore, it may get confused if you switch paths between runs without clearing the cache. So what you have to do is simply instead of running cmake <path_to_src> from the command line, run ~/usr/cmake-path/bin/cmake <path_to_src> .

What is a CMake target?

A CMake-based buildsystem is organized as a set of high-level logical targets. Each target corresponds to an executable or library, or is a custom target containing custom commands.


1 Answers

If you want to use a library in another one you should use target_link_libraries function:

target_link_libraries(B A) 

The signature of target_link_libraries automatically propagates A into all non-static libraries and executables which use B (both directly and indirectly).

Static libraries which use B are aware of their dependency on A but they aren't going to have a copy of the objects files from A within them. The dependency information is carried in INTERFACE_LINK_LIBRARIES and LINK_LIBRARIES target properties of the libraries.

By design, a static library is just an archive of object files. There's no need in mixing object files from different libraries together manually if you only want to use the libraries within your CMake project. CMake will instruct your linker with the list of libraries which needs to be linked into and proper order of the libraries (which indeed is produced out of the dependency graph). The linker, in turn, will resolve all symbols from the object files which are carried in the supplied static libraries.

If you still need to have precise control of the blending objects files, you might consider to use OBJECT library type:

# Create plain objects library which essentially is a set of object files
add_library(zipobj OBJECT zip.cpp)
# Archive all objects from zipobj. Recompilation of zip.cpp won't take place.
add_library(zip STATIC $<TARGET_OBJECTS:zipobj>)

add_library(lzmaobj OBJECT lzma.zpp)
add_library(lzma STATIC $<TARGET_OBJECTS:lzmaobj>)

# Create a library which contains object files from both zipobj and lzmaobj
add_library(archive STATIC $<TARGET_OBJECTS:zipobj> $<TARGET_OBJECTS:lzmaobj>)

EDIT: Also you might try merge_libraries function: http://www.mail-archive.com/[email protected]/msg28670.html

like image 192
roolebo Avatar answered Sep 19 '22 14:09

roolebo