How to create debug and release versions of libraries - cmake

I'm releasing a library which will be able to install headers and .a libraries for reuse. I would like users to be able to link either to release or debug builds of the lib if they so desire. I know that I can use DEBUG_POSTFIX like in Create a directory based on Release/Debug build type in CMake. My question is how do the users differentiate between the two? They would still put target_link_libraries(mylib), so I don't understand how a debug build would be chosen.

If MyLibTargets.cmake is correctly made they don't specify between the two. MyLibTargets.cmake should properly set IMPORTED_CONFIGURATIONS and IMPORTED_LOCATION_<CONFIG> for the target mylib. Then Debug maps to the Debug location and Release maps to the Release location. This is done automatically using the export command for multi-configuration generator. It's not really any different how a multi-configuration generator chooses Debug / Release libraries for any regular library target.

Related

Is it possible to generate a Kotlin .def file from a CMake library?

I have an existing CMake project which is used to build a native library (supporting a few Linux platforms as well as Windows). This library will soon be integrated into a Kotlin app, for which I need to create a .def file, as stated here
Conceptually, I could create this using FILE and other native CMake tools, but if there's a "proper" way to do this, I'd prefer to use that!
Is that file something you have to write yourself? I can't tell just from reading the docs, but that's the impression I'm getting. If each .def corresponds to a CMake target, you could create a build event custom command by using the build events signature of add_custom_command to run the cinterop command.
If you want to script the process of writing the .def file so it's more automatically-robust to you renaming things in the future,
As for putting things like target compile options in a file, you could use the $<TARGET_GENEX_EVAL:> and $<TARGET_PROPERTY:> generator expressions and the COMPILE_OPTIONS target property and the CMAKE_CXX_FLAGS (and similar) variables in a file(GENERATE) command call.
Simliar for compile definitions (see the COMPILE_DEFINITIONS target property).
For a list of all properties supported on targets, see https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#properties-on-targets

How to only build libraries that are actual dependencies in CMake

I have a library that is brought in as an external to several applications and included using add_subdirectory. It has four build flavours due to the flexibility of its use: GUI/CLI and shared/static. GUI apps tend to build the GUI flavour as then the user warnings it produces appear as pop-up dialogs. However it is also used by some command line apps which use the CLI version that produces user warnings on the terminal. Some applications use the shared version because they use other libraries that use this same library, and need shared resources such as output logfile handles. Some applications use the static version because they are small utilities that we want to distribute as standalone binaries without dependencies.
If I am building a CMake project that only uses one of these four flavours, I really only want to build that one single flavour of the library. Yet despite this CMake insists on building all four, which is a total waste of time.
How can I flag to CMake that the library should only be built if it is explicitly listed as a dependency of something else that is being built?
For each target, set the EXCLUDE_FROM_ALL property to TRUE in the library's CMakeLists.txt. It will then only be built if actually required.
set_target_properties(MyLib PROPERTIES
EXCLUDE_FROM_ALL TRUE
)

CMake link to only release config of target in both debug and release

Is there another a way to link only the release lib of a target when including the target with target_link_libraries for both release and debug configs.
I know target_link_libraries has the options optimize and debug and that it can be done like this
target_link_libraries(current_target
optimized $<TARGET_PROPERTY:lib_target,IMPORTED_IMPLIB_RELEASE>
debug $<TARGET_PROPERTY:lib_target,IMPORTED_IMPLIB_RELEASE>
)
However I generally keep the targets in a list
set(target_list
lib_target1
lib_target2
...
)
and I perform other things on the same list, like getting the binary directory of the target to include in the search path for debugging. Using the optimized and debug options also do not allow the lib_target... properties to be passed along through the current_target. I can work around it just curious if there is another way?
If you link with IMPORTED target, then its configuration-dependent properties refer to "imported configuration". You may always adjust mapping between configurations of your project and imported ones:
Global configuration mapping is adjusted by CMAKE_MAP_IMPORTED_CONFIG_<CONFIG> variables.
The setting below will use Release configuration of every IMPORTED target for any of Release, Debug or RelWithDebugInfo configurations of your project:
set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE Release)
set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG Release)
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBUGINFO Release)
Note, that these settings should be issued before creating of IMPORTED targets. That is, if such targets are created with find_package() calls, the settings should precede these calls.
Per-target configuration mapping is adjusted by MAP_IMPORTED_CONFIG_<CONFIG> properties.
Settings below do the same as global settings above but only for lib_target1 IMPORTED target:
set_target_properties(lib_target1 PROPERTIES
MAP_IMPORTED_CONFIG_RELEASE Release
MAP_IMPORTED_CONFIG_DEBUG Release
MAP_IMPORTED_CONFIG_RELWITHDEBUGINFO Release)
These settings can be applied only after given IMPORTED target is created, e.g. after find_package() call.
It is worth to mention, that you may also specify fallback imported configurations:
set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG Release Debug)
With such setting, if your project is built in Debug configuration, and some IMPORTED target doesn't have Release configuration, then its Debug configuration will be used. (But if that target has neither Release nor Debug configuration, CMake will emit an error).

cmake: how to define target without linking (compilation only)

Is there any simple way to create a target where object files aren't linked?
I need additional target only for tests if everything compiles for ARM.
I don't want to create any executable (it would not link anyway), because my project will be finally a part of something much bigger, which has its own old stable make-based build system.
So I just need to compile sources. All tests are done with other, PC target compiled with gcc.
You can use an object library:
add_library(dummy OBJECT <source files>)
See also:
add_library => object-libraries
Official tutorial.

linking failed when building my own project using LLVM

I'm learning to build a llvm project, this is the reference: http://llvm.org/docs/Projects.html. I use the "llvm/projects/sample" directory as the primary project skeleton, and it works. Then I want to build tools from "llvm/examples" to my project, such as Fibonacci, it can't work. I do it this way: first copy the "llvm/examples/Fabonacci" directory to "MyProj/tools" ("MyProj" is top level of my project) and change Makefile to contain Fabonacci target, then configure & make. but the Fabonacci tool seems can't be built. It depends on some libs when linking. So what can I do if I want to build the source code from "llvm/projects/example" in my project?
You need to provide LLVM libraries to linker when building your own project. This means adding some flags, library directories and libraries themselves to link command. Build script probably needs some editing.
llvm-config tool can be used for providing necessary options to compiler/linker. Check documentation and examples.