I need to link the library. The name of the lib is LibName.VERSION.lib. VERSION can be different. How do I tell cmake that?
I use target_link_libraries. If I specify precisely the "LibName.VERSION" as a name it works, but the VERSION can differ. If I specify only the "LibName" it does not work. Is there any way without specifying the VERSION (without env var, cmake args, etc.)?
I solved this by using:
target_link_libraries(
${PROJECT_NAME} PRIVATE
"${SOME_PATH}/lib/LibName.*.lib"
)
Related
I have a dependency as source in my project that I have no control over.
I'm using cmake's clang-tidy integration to analyze my code, and this dependency is firing A LOT of warnings. Is there a way to tell cmake not to run clang-tidy on specific files ?
I tried to add the files to the -line-filter option of clang-tidy, but this doesn't work:
set_target_properties(target PROPERTIES
CXX_CLANG_TIDY "${clang_tidy_loc};\
${TIDY_CONFIG} \
-line-filter=\"[\
{\"name\":\"path/to/file.cpp\"},\
{\"name\":\"path/to/file.h\"}\
]\"")
If the solution could work with other static analyzers like cppcheck it would be really nice.
Thanks.
If some property - like CXX_CLANG_TIDY - is only available on target level, you have to move the files you want to have different settings for into a separate new target itself.
This can be done by using OBJECT libraries.
In your case something like:
add_library(
target_no_static_code_analysis
OBJECT
path/to/file.cpp
path/to/file.h
)
# NOTE: Resetting only needed if you have a global CMAKE_CXX_CLANG_TIDY
set_target_properties(
target_no_static_code_analysis
PROPERTIES
CXX_CLANG_TIDY ""
)
...
add_library(target ${other_srcs} $<TARGET_OBJECTS:target_no_static_code_analysis>)
References
CMake/Tutorials/Object Library
In case you have a header only library I use SYSTEM (should also be possible for OBJECT libraries)
add_library(
header_only_library_no_static_code_analysis
INTERFACE
)
target_include_directories(
header_only_library_no_static_code_analysis
SYSTEM # Adds -isystem instead of -I and this tells clang-tidy not to analyze these includes
INTERFACE
path/to
)
I couldn't use this approach for a long time due to following bug
https://bugs.launchpad.net/gcc-arm-embedded/+bug/1698539
But with GNU Arm Embedded Toolchain Version 9-2020-q2-update it seems resolved :)
Id like to use GLib in my C application which uses CMake as the build system.
Now, I'm somehow confused how I should enable GLib in my CMakeLists.txt. Basically, you add libraries in cmake using the find_package command, so I tried, according to this bugreport
find_package(GLib2)
But nothing is found. In the GLib documentation it is suggested to use pkg-config, on the other hand.
What is the recommended way of enabling glib in a cmake-based project?
Since CMake 3.6 (released in July 2016), pkg_check_modules supports IMPORTED_TARGET argument, reducing the dependency configuration to a single target_link_libraries statement, which will take care of all required compiler and linker options:
find_package(PkgConfig REQUIRED)
pkg_check_modules(deps REQUIRED IMPORTED_TARGET glib-2.0)
target_link_libraries(target PkgConfig::deps)
(above I used the name deps because one can list multiple dependencies with a single pkg_check_modules statement)
In your CMakeLists.txt:
find_package(PkgConfig REQUIRED)
pkg_search_module(GLIB REQUIRED glib-2.0)
target_include_directories(mytarget PRIVATE ${GLIB_INCLUDE_DIRS})
target_link_libraries(mytarget INTERFACE ${GLIB_LDFLAGS})
Give a look at my answer on using CMake with GTK
It's pretty much the same with GLib.
GLib (and various other C libraries using autotools) provide a pkg-config file for declaring:
compiler flags
linker flags
build-time variables
dependencies
The appropriate way to discover where these libraries are with CMake is to use the FindPkgConfig CMake module:
https://cmake.org/cmake/help/v3.0/module/FindPkgConfig.html
yet another version, combination of multiple answers and what actually worked for me (on Linux)!
cmake_minimum_required(VERSION 2.6.4)
project(my_proj)
find_package(PkgConfig REQUIRED)
pkg_search_module(GLIB REQUIRED glib-2.0)
include_directories(${GLIB_INCLUDE_DIRS})
link_directories(${GLIB_LIBRARY_DIRS})
add_executable(my_proj main.c)
add_definitions(${GLIB_CFLAGS_OTHER})
target_link_libraries(my_proj ${GLIB_LIBRARIES})
I've been working on some CMake modules for GNOME (including one for GLib) which you might want to try. Basically, just find_package(GLib), then you can use the glib-2.0 imported target to link to it.
I have a huge project managed with CMake and this project has hundreds of components each of them having own source files and each of them linking to a list of libraries, specified with target_link_libraries(${project} some_libraries, some_other_libraries)
Now, what I am aiming for is that:
Without actually modifying any of the CMakeLists.txt I want ALL the projects's target executable to link to some specific libraries.
Is there a way of achieving this? Since this is a one time trial, I don't want to manually hunt down all the CMakeLists.txt files and modify them (yes, this is the other alternative). Just a note, I compile the entire project from command line, using cmake (no cmake gui).
This is kind of a hack, but for a C++ project, you can use CMAKE_CXX_STANDARD_LIBRARIES. For a C project, I think you would use CMAKE_C_STANDARD_LIRBARIES.
Example for C++ that links to libbar and libfoo:
cmake ... -DCMAKE_CXX_STANDARD_LIBRARIES="-lbar -lfoo"
See the documentation here:
https://cmake.org/cmake/help/v3.6/variable/CMAKE_LANG_STANDARD_LIBRARIES.html
This won't be available for older versions of CMake; it was added some time after version 3.0.
This is a dirty, dirty hack, so please only use it for testing.
You can actually overload the add_executable command by defining a function of the same name. Do this close to the top of the top-level CMakeLists.txt:
function (add_executable name)
message("Added executable: " ${name})
_add_executable(${name} ${ARGN})
target_link_libraries(${name$} your_additional_lib)
endfunction()
Note that _add_executable is an internal CMake name that may break in future CMake versions. As of now (version 3.0) it seems to work with all versions though.
You can overload add_library the same way if required.
For more fine-grained control over what is linked, instead of calling target_link_libraries you can also mess with the LINK_LIBRARIES and INTERFACE_LINK_LIBRARIES target properties directly.
I'm using CMake 2.8 in order to build an application based on MQX OS (using CodeWarrior).
The CMake project basically builds a set of static libraries (let's say LIB1 and LIB2).
I then reference these libraries in the final executable cmake rule:
target_add_executable(X ${some_sources})
target_link_libraries(X LIB1 LIB2)
My problem is that some symbols are defined in more that one library.
Thus, a link command like:
mwldarm <args> -o <output> <objects> /path/to1/libLIB1.a /path/to2/libLIB2.a
would lead to multiple definition of symbols error.
Instead, I would like CMake to generate a link command like:
mwldarm <args> -o <output> <objects> -L/path/to1 -L/path/to2 -lLIB -lLIB2
Question: How to get the following variables from CMAKE?
Libraries directories flags (ex: -L/path/to1 -L/path/to2)
Libraries link flags (ex: -lLIB -lLIB2)
I've read stuff concerning RPATH but it seems to concern shared libraries only. Am I right?
Thanks for advance.
I do appreciate.
It seems that policy CMP0003 may be what you need.
To use it add the following line near the beginning of your CMakeLists.txt:
CMAKE_POLICY( SET CMP0003 OLD )
Another possibility is to directly set the dependencies and search path, however it's not the cleanest way. Assuming you libraries are called liba.a and libb.a, then:
LINK_DIRECTORIES( ${paths_to_search_for} )
TARGET_ADD_EXECUTABLE(X ${some_sources} )
ADD_DEPENDENCIES(X LIB1 LIB2)
TARGET_LINK_LIBRARIES(X a b )
Note that in this case a and b are not cmake targets, therefore a little machinery is needed to correctly set the dependencies.
Part of the design of CMake is that it links with full paths. Why is that a problem?
Toggling the behavior with the policy is not the correct approach.
http://www.cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cd4fa896b
I think CMP0003 is used to switch on/off the function of adding searching path automatically as described in the official document
Libraries linked via full path no longer produce linker search paths.
rather than about replacing the path name with -l.
When linking a library, if the library is a target CMake known, CMake always replaces related -L and -l options with the library's path name. This may not be a problem for linking static libraries. But for a executable to link a shared library, it's may be a problem. Then I found a hacking method, code like below, to solve the problem linking a shread library using -L and `-l' rather than absolute path.
# Find out the link.txt
set(LINK_TXT "${CMAKE_BINARY_DIR}/${ToLinkLib}/CMakeFiles/${ToLinkLIb}.dir/link.txt")
# Add the searching path into link command
add_custom_command(TARGET ${YourTarget} PRE_BUILD
COMMAND sed ARGS -ie "\"s;[[:blank:]]-l; -L${LIBRARY_OUTPUT_PATH} -l;\"" ${LINK_TXT}
DEPENDS ${LINK_TXT}
COMMENT "Hacking CMake: edit __link.txt__ to use -l instead of path to link internal library ...")
# NOTE: Dont't missing the `-l'.
target_link_libraries(${YourTarget} -l${ToLinkLib})
Of course, this is just a hacking so may not be working well with all versions of CMake.
UPDATED: why linking a shared library may be a problem?
When I run a executable cross compiled for android, which linking a shared library built by the same CMake scripts, I've encounter a problem of linking failed. After I used the above hacking method to get a new version, I can run my executable with a command like below
$ LD_LIBRARY_PATH=. ./the_exe opts
My project depends on GLEW and is built with CMake, so i took the FindGLEW.cmake from here http://code.google.com/p/nvidia-texture-tools/source/browse/trunk/cmake/FindGLEW.cmake?r=96 and wrote find_package(GLEW REQUIRED) in my CMakeLists.txt. Problem is that i am working on a cluster PC were several versions of GLEW are available. One version is stored in /usr/lib which is not the latest. the latest version is stored in /opt/local/lib64. this is the version i want to link against. so i added the path to the FindGLEW.cmake under the GLEW_LIBRARY paths. the problem is that the makefile always links against the older version, but i need the newest version (1.7) for using stuff like GL_PATCHES, GL_PATCH_PARAMETERS and so on. can i some how force CMake to use the newer version like it is the case with FindBoost.cmake. one solution is to erase the older one's but this is not an option. i also changed the order of the paths in the GLEW_LIBRARY list, but without success.
in my old Makefile i just wrote LDDFLAGS = -L/opt/local/lib64 -lGLEW so the path is absolutely clear, but now with CMake i want to use the find feature, but want to prefer a specific version.
I use this to link statically to a custom compiled GLEW lib at a specific location:
#GLEW libraries
add_library(glew_static STATIC IMPORTED)
set_target_properties(glew_static PROPERTIES
IMPORTED_LOCATION /home/ryan/DevLibrary/glew-1.9.0/lib/libGLEW.a)
target_link_libraries(smolder glew_static)
With this in place you can remove
find_package(GLEW REQUIRED)
You can use this with shared libraries as well, simply remove the STATIC keyword from add_library.