Change Extension of Library? - cmake

Is there a way to change a shared library's extension, only on windows from ".dll" to something else?
add_library(mylib SHARED <src>)
So instead of creating a mylib.dll file i need it to be something else like mylib.dla.

Set the target's SUFFIX property, i.e.:
add_library(mylib SHARED <src>)
set_target_properties(mylib PROPERTIES SUFFIX ".dla")

set(CMAKE_STATIC_LIBRARY_SUFFIX ".dla")
will change all suffixes but will work for you as well

Related

How do I include MTL_HEADER_SEARCH_PATHS in Swift Package Manager Package.swift?

In a internal .metal file in the ShaderPackage defined in Package.swift, I want to include an internal header. That header is nested deeply inside the include folder and I don't want to have to use the relative path. In a non Swift Package Manager (SPM) project, I can just set MTL_HEADER_SEARCH_PATHS to recursively include all subfolders, then include Header.h anywhere in the project without needing to know exactly where it is. (This isn't about exposing either file beyond the package bounds - just an internal-to-package question).
First question: Is there a way to set MTL_HEADER_SEARCH_PATHS from a Package.swift (manifest file for SPM)? Doesn't look like there's any build settings for Metal, only C, CXX, and Swift. Whatever settings I add to cSettings in the form of .headerSearchPath("include/subfolder") doesn't get picked up by Metal, nor .cXXSettings or .swiftSettings. Can I define a custom setting somehow?
Second: If there's a way to set MTL_HEADER_SEARCH_PATHS, can I do it recursively? Or do I have to add each subfolder within include? Thanks!

Get source files from an interface library

I have a header only library I want to write a CMake file for, to be used in other projects. To do this I need to declare the library an interface target. The header files are then added by CMakeList.txt files in subfolders.
Now I want to get the list of source files to run clang-format on them. But get_target_property does not work on interface targets. Is there any way to extract the sources (or headers) from an interface target?
This is the code I have at the moment (not working)
make_minimum_required(VERSION 3.12)
project(foo
LANGUAGES CXX
VERSION 1.0.0)
add_library(bar INTERFACE)
# add header files in sub folders with
target_sources(bar INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/header.h"
)
# this gives the error
get_target_property(MY_SOURCES bar SOURCES)
The error message
INTERFACE_LIBRARY targets may only have whitelisted properties. The
property "SOURCES" is not allowed.
I tried to link the interface target into a real target and get the sources that way, but I only got the sources added directly to the second target, not the sources from the interface target
Because your target is declared as INTERFACE, the target_sources() command populates the INTERFACE_SOURCES property of the target, not SOURCES. From the docs:
The INTERFACE, PUBLIC and PRIVATE keywords are required to specify the scope of the following arguments. PRIVATE and PUBLIC items will populate the SOURCES property of <target>. PUBLIC and INTERFACE items will populate the INTERFACE_SOURCES property of <target>.
Try grabbing the INTERFACE_SOURCES property instead:
add_library(bar INTERFACE)
# add header files in sub folders with
target_sources(bar INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/header.h"
)
# this gives the error
get_target_property(MY_SOURCES bar INTERFACE_SOURCES)

What is the default privacy/scope setting for include_directories?

I understand that target_include_directories() can be used in conjunction with PUBLIC, INTERFACE, or PRIVATE to specify the scope or privacy of the directories. But a lot of antiquated code still uses include_directories(), and I'm not sure how these directories are treated by the targets that use them.
Is using include_directories() essentially the same as using target_include_directories(MyTarget PRIVATE ...)? I have seen this similar question, but is there no default scoping behavior with include_directories() either?
Is using include_directories() essentially the same as using target_include_directories(MyTarget PRIVATE ...)?
Yes, for every target, affected by include_directories (that is, in the current CMakeLists.txt and below), it has the same effect as PRIVATE keyword in target-specific version of the command.
Documentation for include_directories says, that the command assigns INCLUDE_DIRECTORIES property of the targets and directories:
The include directories are added to the INCLUDE_DIRECTORIES directory property for the current CMakeLists file. They are also added to the INCLUDE_DIRECTORIES target property for each target in the current CMakeLists file.
and the directory property affects on further target's ones:
This property is used to populate the INCLUDE_DIRECTORIES target property.
Exactly INCLUDE_DIRECTORIES target property is affected by the PRIVATE keyword of target_include_directories command:
PRIVATE and PUBLIC items will populate the INCLUDE_DIRECTORIES property of <target>. PUBLIC and INTERFACE items will populate the INTERFACE_INCLUDE_DIRECTORIES property of <target>.

CMake can't find IMPORTED library

In foo/CMakeLists.txt, based on this and this, I have the following
SET (EXTERNAL_LIB_ROOT "../../external_libs/")
ADD_LIBRARY (avcodec-debug STATIC IMPORTED)
SET_PROPERTY (
TARGET avcodec-debug PROPERTY IMPORTED_LOCATION
${EXTERNAL_LIB_ROOT}/libavcodec-0.8.10.a)
In bar/CMakeLists.txt I have this:
# old way uses system libraries
#TARGET_LINK_LIBRARIES (bar avformat avcodec avutil)
# new way uses local debug builds
TARGET_LINK_LIBRARIES (bar avformat avcodec-debug avutil)
When I run make I get
/usr/bin/ld: cannot find -lavcodec-debug
If I revert to the old way, build, touch foo/CMakeLists.txt and rebuild, CMake's configuration output indicates that avcodec-debug is being found by the build system.
So why can't I add it as a dependency?
As it mentioned above by Angew the visibility for imported library differs, though you can extend it using GLOBAL modifier. It might be enough for you to modify add_library call next way:
ADD_LIBRARY(avcodec-debug STATIC IMPORTED GLOBAL)
Imported targets do not follow the same visibility rules as non-imported targets. While non-imported targets are global (visible and accessible from anywhere after they're defined), imported targets are only visible in the CMakeLists.txt where they are defined and below (in directories added by add_subdirectory() in this defining CMakeList).
Since foo is a sibling of bar in your case, the target name avcodec-debug is not visible inside bar/CMakeLists.txt, so it's treated as a normal library name.
It's generally preferred to define imported targets in files you include rather than in their own projects. So change (or extract the relevant parts of) foo/CMakeLists.txt into foo/avcodec.cmake and then in the top-level CMakeList, replace
add_subdirectory(foo)
with
include(foo/avcodec.cmake)

Force doxygen to ignore class extensions in Objective-C

Is there a way to force doxygen to ignore all class extensions in an Objective-C project without using preprocessor directives?
I use class extensions extensively in my Class.m files for my private attributes. When I use doxygen to generate documentation for my application, the generated class list includes all of my "secret" class extensions. I would like to hide these extensions from the generated documentation.
I can get doxygen to ignore a particular class extension by using the doxygen preprocessor and surrounding the extension in the Class.m with a #ifndef/#endif. I really don't like adding this to all of my Class.m files that have the internal extensions, because I feel that I am adding more clutter to my files.
If you want exclude all the class continuation add this row to the Doxy file
EXCLUDE_SYMBOLS = *()
The class extensions can be excluded without changing the source code. This can be done by listing the class extensions in the exclude_symbols setting. See the sample screenshot: