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

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

Related

Create dynamic library that implements multiple LLVM passes

I have a static library, which consists of several passes and is a part of opt. I want to make it dynamic and create one dylib file, so I could call opt, loading created .dylib and passing the desired LLVM pass. I'm using LLVM 7.0.
I created such dylib file with the help of Xcode (by adding to already existing dynamic library target additional passes), but I can't find any information, how to make it with the help of CMake.
At the moment, CMake file of the library looks like this:
add_llvm_library(MyLibrary
Pass1.cpp
Pass2.cpp
Pass3.cpp
...
PassN.cpp
DEPENDS
intrinsics_gen
)
What is expected is performing such command:
path/to/opt -load /path/to/MyLibrary.dylib -Pass3 ...
It isn't clear to me, whether it is possible to leave the structure of the library as is or if I have to modify it, by giving each pass a CMakeLists.txt file.
Tried this, faced up to the problem of multiple dependencies, which required to include several libraries. Linked libraries required required another libraries being linked. After a while, took a Hello CMakeLists.txt, which was provided in LLVM, as an example. Instead of add_llvm_library, wrote add_llvm_loadablemodule, making such CMakeLists.txt
if (WIN32 OR CYGWIN)
set(LLVM_LINK_COMPONENTS ...)
endif()
add_llvm_loadable_module(Mylib_Dylib
Pass1.cpp
Pass2.cpp
...
PassN.cpp
PLUGIN_TOOL
opt
)
It build Mylib.dylib, and it was possible to call a pass from it.
Since LLVM 8.0 the add_llvm_loadable_module CMake directive has been removed from LLVM. It has been replaced with using add_llvm_library with the MODULE argument.
if (WIN32 OR CYGWIN)
set(LLVM_LINK_COMPONENTS ...)
endif()
add_llvm_library(Mylib_Dylib MODULE
Pass1.cpp
Pass2.cpp
...
PassN.cpp
PLUGIN_TOOL
opt
)

Creating a library in CMake depending on source files not available when generating build files

I have a CMake configuration file building two libraries:
a third-party library (here called ThirdPartyLib) containing a real-time OS / board support package from a supplier. It is built outside CMake using the autotools toolchain.
an extended version of the former library (here called ExtendedThirdPartyLib)
Unfortunately, some source code that I need (various tools) are not built in the ordinary build script for (1). Since I don't want to mess with the suppliers build script I want to add another library (2), building the missing files and thus extending the library from the supplier.
I want to able to do something like this in CMakeFiles.txt:
cmake_minimum_required(VERSION 3.2)
project(bsp)
include(ExternalProject)
ExternalProject_Add(
ThirdPartyLib
URL <http://some.url/bsp.tar.bz2
BUILD_COMMAND make -C ../external/ThirdPartyLib/src
)
set_target_properties(ThirdPartyLib PROPERTIES EXCLUDE_FROM_ALL TRUE)
add_library(ExtendedThirdPartyLib
${CMAKE_CURRENT_BINARY_DIR}/some/path/missing_file1.c
${CMAKE_CURRENT_BINARY_DIR}/some/path/missing_file2.c
)
add_dependencies(ExtendedThirdPartyLib ThirdPartyLib)
target_include_directories(ExtendedThirdPartyLib PUBLIC
${CMAKE_CURRENT_BINARY_DIR}/some/path/include
)
target_link_libraries(ExtendedThirdPartyLib ThirdPartyLib)
The problem here is that the path to missing_file1.c and missing_file2.c are not valid when CMake is generating the build files (they are extracted from the tarball from the supplier). CMake exits with an error output saying: "Cannot find source file".
Is there a neat way to make this work? I.e. is it possible to convince CMake that certain non-existant input files will exist when building of the library begins? Or is there any other recommended way to solve this issue?
(I have temporary made local copies of the files I need to build from the suppliers tarball, but that is of course not a good solution. If those files are changed in future versions of the suppliers package and I forget to overwrite my local copies it could be a horrible mess...
Another "solution" would be to create a small makefile outside CMake and use another ExternalProject_Add in the CMakeFiles.txt somehow. But that's not a good solution either, e.g. if compile and linker flags are modified I need to remember to change the makefile too.)
Personally, I dislike the ExternalProject_Add command, because it does way too many things for my taste, but I've digressed.
What if you do something like this, where bar is simulating your ExtendedThirdPartyLib target, since it depends on generated files
cmake_minimum_required(VERSION 3.11)
project(lol C)
set(SOURCES lol.c) # only this file exists
add_library(lol ${SOURCES})
set(FOO_FILES "foo1.c" "foo2.c")
add_custom_command(OUTPUT ${FOO_FILES}
COMMAND ${CMAKE_COMMAND} -E touch ${FOO_FILES}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Creating ${FOO_FILES}"
VERBATIM)
add_custom_target(foo DEPENDS ${FOO_FILES})
add_library(bar ${FOO_FILES})
add_dependencies(bar foo)
target_link_libraries(lol bar)
The whole approach hinges on the fact that the method, where produced/generated files are procured, is explicitly defined via the custom command and associated custom target.
You should modify the custom command to extract the required files (e.g. could even call some external script) from the tarball (which might require downloading with curl or something similar).

CLion and CMake: only building a library without an executable?

How to only build a static library with clion without having an executable?
How does the CMakeLists.txt look like? (without add_executable)
Update: If I don't add executable to Clion, I have an
error, that an executable is required.
Here my CMakeLists.txt.
This is an old question. But I'll add the answer to your question as a help for other people. You need to replace your add_executable with add_library
add_library(target_name source_files)
Short answer: compile the library target and run any custom command as a placeholder to avoid the warning.
Long answer:
CLion lets you either build the whole project and run executables/configurations.
When running executables, you can choose a target to compile and the executable to run after compiling the target. For executable targets, they are usually the same thing. You compile the executable target and then run it.
It seems like this is not really designed for libraries, but there is a workaround. You usually set the target to be the library and the executable to be any executable that depends on this library. However, this is usually not very useful because if you wanted to run this executable you could just set this executable to be the target and the library would be built anyway.
So people probably want to just build the library (to check if everything is OK, etc) without compiling or running any extra executable targets. In this case, the workaround is to choose a custom executable to run after building the library, and the error message is gone.
You have nothing useful you need to run after building the library, just choose any cheap command as a placeholder. Something like "pwd" or "ls".

Specifying libraries for cmake to link to from command line

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.

using cmake for pascal source files

Is there a way to tell CMake to compile .pas source files with standard add_executable and target_link_libraries calls (like for c and c++ projects)?
Currently, we just list the files and use add_custom_command / add_custom_target and manually set the linker flags, but it would be nice to have something more integrated.
Source file: http://code.google.com/p/hedgewars/source/browse/hedgewars/CMakeLists.txt
According to the CMake docs for the enable_language() command and this question: What are the possible values for the LANGUAGE variable in CMAKE, it looks like the answer is no, there is currently no such way to build Pascal source code with the standard add_executable and target_link_libraries.
You can open up an issue ticket on Kitware's CMake GitLab repo requesting such functionality be added. If you do so, add a link to it here.