CMake calling another build system - cmake

I need to work on a codebase that uses another build system, in this case Fastbuild.
I would like to work on it using CLion, which means I need a CMakeLists.txt. It easy enough to import all the files I want to work on.
How can I set it up to call an external script when I want to build an executable?

Related

cmake: package config for installing arbitrary file dependencies for a target

I am creating a cmake package config file (a Foo-config.cmake) for a pre-existing .dll not created by cmake.
The annoying thing is that the .dll depends on some data files.
When a user consumes my package in his own cmake project, I want the INSTALL target to install both the .dll and data files to his specified install location. I don't want him to have to write extra install() rules to do that.
Is it good practice to write the install() rules directly in my Foo-config.cmake? Or is there a better way to do this, maybe with set_target_properties()? I just couldn't find the appropriate property for associating arbitrary file dependencies to a target.
In an alternate universe where this .dll didn't already exist and I had to create it myself using cmake, would I need to create a custom Foo-config.cmake, or is there something in cmake that can automatically generate it for me to achieve the same thing?
FWIW the .dll is an internal legacy library and is normally built by Visual Studio and uploaded in a .zip file to our internal artifactory. I want us to migrate away from manually pulling down .zip files from artifactory and manually integrating the files into Visual Studio projects.
I've since found that there are a couple different ways to do this:
In the config file, simply create one or more variables for the files/dirs you want to install. Then install those using install(FILES) and/or install(DIRECTORY). More info: https://stackoverflow.com/a/46361538/189341
Use file(GET_RUNTIME_DEPENDENCIES). More info:
https://discourse.cmake.org/t/installing-a-pre-built-module-and-its-various-dependencies/5227
How to use cmake file( GET_RUNTIME_DEPENDENCIES in an install statement?
Is it good practice to write the install() rules directly in my Foo-config.cmake?
No.
From 480 *-config.cmake and *Config.cmake files on my system none calls install().
Or is there a better way to do this, maybe with set_target_properties()?
No.
In an alternate universe where this .dll didn't already exist and I had to create it myself using cmake, would I need to create a custom Foo-config.cmake
No. This is unrelated to if you create a .dll or not. If .dll exists, there is no need to create Foo-config.cmake anyway. It is your choice that you want to (or make users to) use find_package.
is there something in cmake that can automatically generate it for me
No.
If you don't intent to support find_package features - VERSION OPTIONAL_COMPONENTS PATHS HINTS CONFIGS etc. - then just go with include(). find_package is just include() with some extra options.
If you want to have install() in your find_package, then just protect it with a variable, like if (FOO_DO_INSTALL) install(....) endif().

Variable interpolation in -D option

As a package manager for a Linux distribution, I want to install docs into a separate prefix. With CMake projects, the docs installation location is controlled by CMAKE_INSTALL_DOCDIR from GNUInstallDirs module. Unfortunately, unlike the other directory variables, this one contains the project name so I cannot just use cmake "-DCMAKE_INSTALL_DOCDIR=$myDocPrefix/doc".
With GNU Make, I would run make "DOCDIR=$myDocPrefix/doc/\$(PROJECT_NAME)" and have Make interpolate it but the documentation of CMake’s -D option does not mention interpolation and I understand that CMake uses much more complex system of cache entries where interpolation might be problematic (especially if the referenced variable is not yet in cache).
I could pass tailor-made CMAKE_INSTALL_DOCDIR to each CMake project but would be bothersome as I would have to do that in every package definition manually; being able to define configureCmakeProject function and have it take care of everything automatically would be better. When setting it manually, I would also want to make sure it matches the PROJECT_NAME of the respective CMake project – well, I could resign on that and just use $packageName from the package definition instead but keeping packages as close to upstream as possible is preferred.
Alternately, I could try to grep CMakeLists.txt for project command but that seems fragile and might still result in misalignments. I doubt it is possible to extract it using some CMake API since the project is not configured at the time and we actually need the value to configure the project.
Is there a way I can configure CMAKE_INSTALL_DOCDIR to use custom prefix but still keep the project name set by the CMake project?

Google Test inside OpenWrt

I'd like to execute GMOCK and GTEST tests inside OpenWRT.
I have x86_64 machine. My package is for x32 device.
I tried copy headers manually, but, of course, it does not work.
It is important to run tests inside the device, this is the main reason.
Is it false that the only possible way for me is to compile inside the device?(Such approach is strongly not desired)
If not, how to add gtest&gmock to the package?
You can make a custom package for gtest. Then use that as a dependency for your package. For the headers you will need to setup an InstallDev section in the gtest openwrt package makefile. Use this section to copy the header files to the staging directory where they can be used by your package for compilation.
Follow the documentation for openwrt here:
https://openwrt.org/docs/guide-developer/packages#use_packed_source_code_archive

cmake suppress finding package and set path manually

I'm currently automating my the installation process for multiple instances of an application. This application uses cmake for building and uses some libraries for which no findModule.cmake files exist. Since I'm could find a good example how to generate a findModule.cmake file for existing libraries for example OpenCascade. When setting up the buildprocess manually one can easily adapt the include and lib path in ccmake. Since I want to automate this I'm looking for a way to do this by passing the options to cmake on the command line. Here is how I try to achieve this for OpenCascade:
cmake -DOCC_FOUND:INTERNAL=TRUE -DOCC_INCLUDE_DIR:PATH=/usr/include/opencascade -DOCC_LIBRARY:FILEPATH=/usr/lib/libTKernel.so -DCMAKE_BUILD_TYPE:STRING=Release ..
Unfortunately this doesn't work. Since the option for building are build-depended, passing a previously configured CMakeCache.txt file is not working.
Thanks for any suggestions to achieve what I'm trying to do.

Making my program compile on both windows and linux, what should I do about libraries?

I'm using CMake to generate my makefiles and VC solutions. I have my program running on linux just fine. I'm using a bunch of libraries, e.g. Lua. On my linux computer I just link to them and make sure in include the headers. All of the .so files are in some standard place. On Windows though I'm not sure what to do. Should I just include the entire Lua project into my own repository and link to that instead? Do I install Lua to some standard place like c:\program files\lua5.1 and link to that? Something else?
Your libraries can be in any place, you just need to say - where are they.
Before running cmake set up pathes of all your extern libs with some .bat file:
set LIBRARYPATH =path\to\your\library\
set include=%include%;%LIBRARYPATH%\include
set lib=%lib%;%LIBRARYPATH%\lib
Start cmd, run this .bat and then cmake should find all
I would provide a configuration field/variable for ccmake that the user can or must specify.
The mark_as_advanced can be used to make a custom variable only appear in the advanced mode. This would be suitable if you have a standard path (as you have mostly on windows). Yet, it still let's the user specify the value if needed.
Or you can simply set a variable the with the 'set' command if you don't want it in advanced.
Just make sure you check if the users entered a valid value.