Extending CMake with a custom generator? - cmake

How would one add support for a new IDE/build system to CMake? Does it provide a mechanism to do this without modifying its code directly?

You have to write additional C++ code and build CMake to add a new generator. There is no mechanism to add a new generator without writing new code.
What IDE/build system are you thinking of adding to CMake?
Ask on the CMake mailing list ( http://www.cmake.org/mailman/listinfo/cmake ) whether or not anybody else is already working on a generator for the system you're thinking of. I know some recent work has been done to add a Ninja generator... It is not yet in the official CMake release, though: still in progress as of today.

Related

How to associate a feature flag (define) with external library in CMake?

FindProtobuf.cmake for Google Protocol Buffers creates a set of targets, for example protobuf::libprotobuf-lite one.
Now, in my project, I'm using this protobuf::libprotobuf-lite in target_link_libraries. And this works fine.
However, after upgrading to protobuf v3 I noticed that generated files have small blocks guarded by
#if LANG_CXX11
Yet, as it seems, this LANG_CXX11 is not defined by FindProtobuf.cmake. It seems I have to define it on my own if I want to use C++11 features with protobuf-generated code.
Obviously, I could just do it globally and be done with it. However, I would much more prefer to somehow "bind" the LANG_CXX11 with the protobuf::libprotobuf-lite target, so that I will get it whenever I used it and only where I use it.
target_compile_definitions will not work here since it doesn't accept imported targets while targets created by FindProtobuf.cmake are imported ones. And anyway, it seems like not the right thing to do.
The only idea I have for now (although not yet tested) is to create another custom target that would only link (PUBLIC) with protobuf::libprotobuf-lite and add the LANG_CXX11 define (PUBLIC as well). Then I would use this custom target instead of protobuf::libprotobuf-lite. But it doesn't feel good either.
How to do it properly with CMake? (I'm on version 3.8 if it matters.)

Config.cmake file for custom made shared libraries

I have this project that I have done for experimentation with Qt and shared libraries. This is basically a couple of Qt Widgets from the tutorials for Qt and what I think is the right CMakeLists configuration so a MylibConfig.cmake is automatically generated from a MylibConfig.cmake.in to share the library. The problem is that I don't want the end user to add the dependencies of my library to its own CMakeLists.txt. This is, in my case, the library depends on Qt4, but I want that the end user to not have to do find_package(Qt 4 REQUIRED). Imagine that I want to provide an enclosed functionality to someone that does not need or want to know about what my library is built on. Is there a way in the automatic generation of the MylibConfig.cmake that it automatically finds all necessary packages or is the only option to add the fin package manually in the MylibConfig.cmake.in?
Thank you very much.
In fact, both mentioned projects do find of dependencies from their *Config.cmake files. And nowadays that is the only option -- CMake can't help you to do it "automatically".
So, some way or another, your config module should do the same.
The easy way is to add find_dependency() calls (cuz you know exactly what other packages, your project is based on).
A little bit harder is to do it "automatically" (writing your own helper function) -- for example by inspecting properties of your target(s), "searching" where all that libraries come from and finally generating find_dependency() calls anyway.

How to get cmake to find size of type in third-party header mpi.h?

I am working on a free-software project which involves high performance computing and the MPI library.
In my code, I need to know the size of the MPI_Offset type, which is defined in mpi.h.
Normally such projects would be build using autotools and this problem would be easily solved. But for my sins, I am working with a CMake build and I can't find any way to perform this simple task. But there must be a way to do - it is commonly done on autotools projects, so I assume it is also possible in CMake.
When I use:
check_type_size("MPI_Offset" SIZEOF_MPI_OFFSET)
It fails, because mpi.h is not included in the generated C code.
Is there a way to tell check_type_size() to include mpi.h?
This is done via CMAKE_EXTRA_INCLUDE_FILES:
INCLUDE (CheckTypeSize)
find_package(MPI)
include_directories(SYSTEM ${MPI_INCLUDE_PATH})
SET(CMAKE_EXTRA_INCLUDE_FILES "mpi.h")
check_type_size("MPI_Offset" SIZEOF_MPI_OFFSET)
SET(CMAKE_EXTRA_INCLUDE_FILES)
It may be more common to write platform checks with autotools, so here is some more information on how to write platform checks with CMake.
On a personal note, while CMake is certainly not the most pleasant exercise, for me autotools is reserved for the capital sins. It is really hard to me to defend CMake, but in this instance, it is even documented. Naturally, setting a separate "variable" that you even have to reset after the fact, instead of just passing it as a parameter, is clearly conforming to the surprising "design principles" of CMake.

GNU Autotools, what is "*h.in" files?

I am new to autotools, and can't find out where from *.h.in files are created?
I am trying to create small hello_demo for my library, where I include *.h and use it. make throws me error, that *h.in not found.
Any guide how to make it proper way, will be very appreciate)
Assuming you're talking about config.h.in, it is generated by default by autoheader. You should not strictly need it though.
Make sure you're using autoreconf -fis to generate your autotools support files, that will call all the needed tools for the generation to work. I would also point you to my guide for the very minimal code you need to build a project, which does not involve autoheader at all.

Linker chooses "wrong" main with Boost.Test

When using Boost.Test, there is generally no need to define a main() function, since Boost.Test provides one itself.
I recently had to convert my project to use static linking of 3rd party libraries (on VS2010). Naturally, I had to link to multiple .libs so that the build succeeds, and my build ran just fine.
However, when I ran my test project, something really strange happened. It seems that one of the 3rd party .libs (libpng), required by one of my dependent libraries, contained a test file with a main() function defined within (pngtest.c, if you must know).
Since my project did not have a main() function, the linker chose that one as my "test" application. Thus, non of my tests run.
Does anyone know how I prevent this from happening? How can I tell the linker/compiler to use the Boost.Test main()?
Answering my own question, and clarifying #Tom's answer.
Turns out that the libpng build script I was using was not the the original shipping with libpng but one created by the OpenCV build system. The file pngtest.c was mistakenly included int the build.
The solution to the problem was to remove pngtest.c from the libpng build script.
The latest OpenCV version, does not include this file anymore.
For more details see my post to Boost mailing list here and my OpenCV bug report here.
Adi, I had the same problem. Looks like you were already all over this one. Thanks to Google and your efforts, I was able to figure it out.
Here's some info to round out the answer:
discussion:
http://boost.2283326.n4.nabble.com/Boost-Test-Linker-chooses-wrong-main-function-td4634872.html
solution:
http://code.opencv.org/issues/2322
Basically, I just excluded the pngtest.c file from the libpng project, and recompiled OpenCV. Looks like it will be fixed in the next release of OpenCV.
Thanks!