CMAKE for a build a simple framework - cmake

I have my mind crashing with cmake. After this answer I have tried to make a simple example and put it in github because there are a lot of file inside directories and could be boring copy everything here.
What I'd like to do is to build a simple frameworks for handling my qt/opencv/opengl experiments. What I like to have is a repository with those directories:
root*
|-apps
|---test1*
|
|-build
|-cmake*
|
|-modules
|---foo*
(The * signed directory are the ones with some cmake files like CmakeLists.txt or FindXXModule.cmake)
In modules i can write the modules (for example a module for face recognition, a module for draw a red cube in opengl, a module that contains my personal qt widget extension).
Than I need an easy way for create an application and link some modules on it. For that I thought to create a cmake directory where to put the FindXXModule.cmake and in the apps just say: find_package(XXModule).
Note that for now I don't care about installing this repository and the tree structure must be this one (so if I am in a apps/test2 I know I can refer to the cmake directory as ../../cmake or the module directory is ../../modules)
I have wrote a little example with the app named test1 that uses the module foo and i put it in a github repository.
For now I can compile the application test1 with cmake calling cmake path_to_test1_CmakeLists.txt and I am happy about that. But if I try to launch cmake path_to_root_CmakeLists.txt it does not work because the file Findfoo.cmake is read two time (and i did't be able to use some if for not reading it twice).
Then, if i run the test1 cmake a foo directory with cmake cache etc are created in root/cmake and I don't want it. I want all file cmake has to generate are in root/build directory.
So, those are my 2 question:
How create a CmakeLists.txt that can build all the apps and all the future test i will write in the modules directory
How avoid that launching cmake of a single app will create files in the cmake directory.
Sorry if my english and my idea of how cmake works are not good.. i hope it is clear.
EDIT:
One more thing. In Findfoo.cmake I have a bad hack: for adding the real CMakeLists.txt inside a modules/foo when I call the cmake from test1 I have to add a subdirectory that is not in the tree.. Maybe this kind of hack could be deleted reviewing the enteire structure..

As you say you want to put the whole directory structure into source control. This means these folder structure is same on every location where you do a checkout. So why creating the Findfoo.cmake if you have a relative path the the foo directory?
I suggest to put a CMakelists.txt file in to root that adds all subdirectories. To reduce confusion between files generated by CMake and original files, you should create a folder called ./build (or even ../build) and run CMake in that directory with the root directory as first argument. This creates all CMake generated files in the ./build directory and gives you the possibility to clean it up easily. This way of working is called out-of-source build and its highly recommended to use cmake in this way. See this question for an example.

Related

Can CLion project files be stored in a specified folder by default?

I've been using CLion for a little while now, and I quite like it, except that it stores it's prject files by default in my CMake project. I am wondering if I can set a default place it stores it's project files(like compiled executables) in specific directory, per project.(So not one big folder that might interfere with other projects). The reason I want to do that is because I don't like having it in my git project(yes, I know about .gitignore) Anyone know how to do that?
Thanks!
To use a different folder for CLion building
In the CLion menu:
Build,Execution,Deployment -> Cmake -> Generation Path
Change the value to the folder path you want.
To include source code from a different folder out of current
In your CMakeLists.txt, add subdirectory like following:
add_subdirectory(<PATH_OF_YOUR_ANOTHER_CMAKE_PROJECT>)
Be aware PATH_OF_YOUR_ANOTHER_CMAKE_PROJECT can be anywhere on your computer, which does not have to be in your current project folder or one of the sub-folders.

Directory and files not showing up in QtCreator tree after opening a CMakeList.txt file

I apologize for the basic question but being new to Cmake, I have a hard time doing very simple things.
So basically, I'm working on the pixhawk firmware : https://github.com/PX4/Firmware which uses extensively CMake/make files.
Under the src folder, I've created my own folder containing two subfolders which contain themselves their CMakeLists.txt file and the source code (no CMakeLists.txt in my own folder).
However, when I open the top CMakeLists.txt in QtCreator, my own newly created folder (along with its sub-folder and containing files) doesn't appear in the tree, which is very inconvenient to work directly from QtCreator.
What should I modify in the top CMakeLists.txt to get it display in QtCreator ? I thought that a simple include_subdirectory would do the job but it didn't (because, if my memory's right, cmake was complaining that there is no CMakeLists.txt in my own folder, only in its sub-folders).
Ps : if by any chance, you're a drone developer and know about pixhawk, it would be very nice if you could take some time to answer the questions I posted there : http://discuss.px4.io/t/cmake-help/4523
Hum maybe you can simply add this to your top CmakeList ?
add_subdirectory(myfolder/app1)
add_subdirectory(myfolder/app2)

Is it possible to keep *.erl sources and *.beam output in the same directory with intellij-erlang?

I want to set up my HelloWorld intellij-erlang project with all files in the same directory so I can easily switch between IDEA and emacs/vim.
<my-project>/hello.erl
<my-project>/hello.beam
Now, if I configure the output directory to be the same as the source, hello.erl gets emptied as part of the build and the compilation fails.
I assumed it's something to do with copying resources to the output directory, so I've configured intellij-erlang to exclude *.erl from the resources with a !?*.erl pattern, but this does not have any effect, hello.erl still gets emptied before the compilation takes place.
As an experiment, I've also tried using separate src and out directories, and intellij-erlang always copies the *.erl to out irrespective of the resource patterns.
Based on all this, I would conclude that intellij-erlang cannot work with all files in the same directory. Have I missed anything?
Erlang programs should be build on standard OTP directory structure. Build tools like rebar (used by intellij) or erlang.mk build on this conventions. And so should all IDE's.
Intellij does it, just like you notice. And so does Emacs's plugin (that I use and can confirm). I would guess so does Vim's one.
So if you would like to be able to switch easily between your IDE's you should try to keep to this convetion of keeping you source files in src and compiled files in bin (and headers in include).

Let CMake rescan a directory (Usage of GLOB_RECURSE)

When using GLOB_RECURSE to add a certain directory structure to a list, CMake doesn't detect if new files are added to the directory.
How can I make CMake rescan the directory structure on every run, so that new files are detected?
You have to touch CMakeLists.txt whenever you change the directory contents.
What you're doing goes counter to official advice, but I do it too. You could knock up a script which monitors a directory for changes, but CMake considers this to be not its business.
The reason, I suspect, is that directory modification timestamp attributes aren't very cross-platform.

Proper approach to sharing CMake module across projects?

I have written a CMake module that contains a couple of useful macros that I would like to use across a number of other CMake projects. However, I'm not sure where to put the module.
I would like to be able to do this inside each project that uses the macro:
include(MyModule)
However, I'm not sure if there is an easy and cross-platform way of achieving this. In fact, I can't even get it to work on Unix. I put the module (MyModule.cmake) in the following locations:
/usr/lib/cmake/
/usr/lib/cmake/Modules
/usr/local/lib/cmake
/usr/local/lib/cmake/Modules
...and the project with the include() was unable to load the module.
What is the correct location for this module? Is there a better approach?
I should also point out that the macros are not related to "finding" a third-party library and therefore have nothing to do with find_package().
Put the module in a directory of your choice, and then add that directory to CMAKE_MODULE_PATH using list(APPEND).
You can even host that module somewhere and then download it via file(DOWNLOAD). If you download it to the same directory as the current CMake script being processed, you just include(MyModule.cmake) and don't need to modify CMAKE_MODULE_PATH.
You could download the file to a common location on disk and then add a check using if(EXISTS "${module_location_on_disk}") to skip the download if it's already downloaded. Of course, more logic will be required if your module changes, or you want to have a common location and multiple versions of the module, but that's out of those scope of your question.