How to use config.h - c++

I know that a lot of GNU applications use a config.h to set arguments for compile time options, like paths to resources with prefix from Autotools or Meson. For example, in some cases it is appropriate to find the location of the executable and load resources from there. Which I do on Windows and Linux. But for packaging on Linux and other UNIX based systems it seems better and usual to store the required paths inside config.h.
When and how to use config.h?
Thank you

It seems config.h is something worth thinking about and debated. There are some discussion here: and there:
Personally, I have not used it. I think the minimum is to rename it to YOURPACKAGE_config.h so that it will not be confused with another config.h from a different package.

Related

How to manage building a huge source code that uses gnu autotools?

I have multiple source codes which I have to cross-build and use together as one huge project. The building process of each source code is the same './configure-make-make install' commands with added parameters for cross compilation. So far I have been managing this by typing a really long configure command "./configure CC=....." in text editor and then copy pasting that on to terminal and running it. Then repeating the process for another source code. Taking care of multiple include paths, library paths, pkg-config paths etc. the process turns out to be very messy, error-prone and cumbersome. I have already used eclipse ide and have found no option for configuring the "./configure .." command to my need. Is there any elegant way to handle this problem? I would like a solution which will require me to write minimal amount of script/instruction.
Is there any elegant way to handle this problem?
If you want to automatize the configuration and compilation of several sub-projects which are actually one project, I suggest you to use the GNU/Autotools canonical way to deal with it with is Nested Autotools project
In that way you can do a project which contains all the other projects in the following fashion:
./UmbrellaProject
subproject1/
subproject2/
...
Makefile.am
Inside the parent project Makefile.am you will have a line at the beginning such as:
SUBDIRS = subproject1 subproject2
More information at the GNU Automake docs

Where does cmake look to find packages?

In Ubuntu 14.04, I am compiling a C++ program, which depends on the following packages: CUDA and OpenNI. In the CMakeListst.txt file for this program, there is the following:
find_package(CUDA)
find_package(OpenNI)
And the output to cmake is:
Found CUDA: /usr/local/cuda (found version "6.5")
-- Could NOT find OpenNI (missing: OpenNI_LIBRARY OpenNI_INCLUDE_DIR)
So, it seems that CUDA was found, but OpenNI was not. Now, I have definitely installed OpenNI, but perhaps not in the standard location. Whereas the CUDA files are in usr/local/cuda as stated, my OpenNI files are in ~/Libraries/OpenNI.
My question is: How do I tell cmake where to look for to define the OpenNI_LIBRARY and OpenNI_INCLUDE_DIR variables? Is there a file somewhere which cmake has paths defined for all these variables, which I might need to manually edit?
It looks in CMAKE_MODULE_PATH.
Append to this path using expressions like this
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
There is no unified way that tells you where a find script will attempt to look for a library.
This is a bit unfortunate, but the only way to know for sure is to check the source of the find script itself. Most find scripts rely on find_library and similar commands to locate their files, which will by default search in a number of locations that are obvious candidates (like /usr/local/ on Unixes).
Unfortunately, this alone does not get you very far. If you are stuck on a platform like Windows where there is no reasonable default location, or you want to avoid polluting the directory tree, you need another way. Most find scripts therefore allow injecting the location of the library in some way.
In my experience, the cleanest way to do this is through environment variables. They are flexible to configure and convenient to use. In particular, you can make them persistent by adding them to your user's environment, so you don't have to type them out each time you run CMake.
If you check for example the find script for CUDA that ships with CMake, you will notice that it uses the environment variables CUDA_PATH, CUDA_LIB_PATH, CUDA_INC_PATH and CUDA_BIN_PATH (along with a few others) for this purpose.
An alternative is to directly set the result variables of the find script in the cache from the command line via CMake's -D parameter.
In any case you will have to check the find script source to find out what is the best course of action.
A word of advice: Do not attempt to hardcode locations in your own CMakeLists. While this might seem like a quick solution, it's also a very dirty one that essentially makes your build system non-relocatable. Always reach for solutions that allow the user to configure the build system from the outside without having to change CMake code.
Even if this is a quite old question: If you call cmake with --debug-find it will tell you where it looks for a package that you requested through a find_package() call in your CMake script.
My personal preference, especially for packages residing in their very own dedicated location, is to define an environment variable <package_name>_DIR, which points to the package's configuration file (assuming that the lib provides one). See the find_package() documentation about the search procedure for more details.

Setting environment variables for scons to use globally on my system

Is there any way to set environment variables for my system which scons will use, without me having to change the SConstruct file? For example, I would like to use MinGW instead of VC++ for my C++ builds on Windows. I can, of course, do this in my SConstruct file:
env = Environment(tools = ['mingw'])
But if I do that, then I'm editing things into my build files that make it specific to my particular system configuration. That defeats the whole purpose of a portable build system, in my opinion. If I upload that as part of my repository for others to build, they may not be using MinGW. They may want to use VC++, or Clang, and I don't think they should have to modify the build file (or anything else in the repository for that matter) in order to build the program or library. Ideally, anyone with in an environment with a functional C++ toolchain and scons installed should be able to just type scons on the command line, and things should go smoothly for them. Isn't that the (or a) goal of scons? Or am I misunderstanding its purpose?
Another thing is paths. The above line is not even enough, I have to still import the path to the MinGW binaries. I've read the justification for this. But it's just more system specific information which I have to put in my build files, which may be used by others where the chosen paths are not applicable.
I think you have indeed understood the purpose of SCons regarding it being portable and multi-platform :)
The issue here is if you have multiple compilers to choose from on your system, how to tell SCons which one to use. By default SCons will look for and use the compiler specific to your system (VC++ on windows or g++ on linux for example).
I can think of at least 2 ways of telling SCons which compiler to use, both of which will require extra logic in the build scripts, but can be done in a portable manner:
Environment variables
command line arguments
I would consider always using the system-specific compiler unless the user invokes scons with arguments/variables instructing it to use a different one.
If you choose to use Environment variables, you can just use standard python code, as follows, and explained here:
import os
some_var = os.environ['SOME_VAR']
Or, if you choose to use command line arguments, you can find everything you need here.
Personally, I would prefer command line options, as its more explicit than env vars. With env vars, the users may get undesired results due to env vars they didnt realize were set.
Try editing the file site_init.py in one of these directories:
%ALLUSERSPROFILE/Application Data/scons/site_scons
%USERPROFILE%/Local Settings/Application Data/scons/site_scons
%APPDATA%/scons/site_scons
%HOME%/.scons/site_scons
./site_scons
In that file, add a line like this:
DefaultEnvironment(tools = ['mingw'])
or maybe this:
DefaultEnvironment(tools = ['default', 'mingw'])

How to generate CMakeLists.txt?

I need some pointers/advice on how to automatically generate CMakeLists.txt files for CMake. Does anyone know of any existing generators? I've checked the ones listed in the CMake Wiki but unfortunately they are not suitable for me.
I already have a basic Python script which traverses my project's directory structure and generates the required files but it's really "dumb" right now. I would like to augment it to take into account for example the different platforms I'm building for, the compiler\cross-compiler I'm using or different versions of the libraries dependencies I might have. I don't have much\expert experience with CMake and an example I could base my work or an already working generator could be of great help.
I am of the opinion that you need not use an automated script for generating CMakeLists.Txt as it is a very simple task to write one, after you have understood the basic procedure. Yeah I do agree that understanding the procedure to write one as given in CMake Wiki is also difficult as it is too much detailed.
A very basic example showing how to write CMakeLists.txt is shown here, which I think will be of use to everyone, even someone who is going to write CMakeLists.txt for the first time.
Well i dont have much of an experience in Cmake either, but to perform a cross platform make a lot of files need to be written and modified including the CMakeLists.txt file, i suggest that you use this new tool called the ProjectGenerator Tool, its pretty cool, it does all the extra work needed and makes it easy to generate such files for 3'rd party sources with little effort.
Just read the README carefully before using it.
Link:
http://www.ogre3d.org/forums/viewtopic.php?f=1&t=54842
I think that you are doing this upside down.
When using CMake, you are supposed to write the CMakeLists.txt yourself. Typically, you don't need to handle different compilers as CMake has knowledge about them. However, if you must, you can add code in the CMakeFiles to do different things depending on the tool you are using.
CLion is an Integrated development environment that is fully based on CMake project file.
It is able to generate itself the CMakeLists.txt file when using the import project from source
However this is quite probable that you have to edit this file manually as your project grows and for adding external dependency.
I'm maintaining a C++ software environment that has more than 1000 modules (shared, static libraries, programs) and uses more than 20 third parties (boost, openCV, Qt, Qwt...). This software environment hosts many programs (~50), each one picking up some libraries, programs and third parties. I use CMake to generate the makefiles and that's really great.
However, if you write your CMakeLists.txt as it is recommended to do (declare the module as being a library/program, importing source files, adding dependencies...). I agree with celavek: maintaining those CMakeLists.txt files is a real pain:
When you add a new file to a module, you need to update its CMakeLists.txt
When you upgrade a third party, you need to update the CMakeLists.txt of all modules using it
When you add a new dependency (library A now needs library B), you may need to update the CMakeLists.txt of all programs using A
When you want a new global settings to be changed (compiler setting, predefined variable, C++ standard used), you need to update all your CMakeLists.txt
Then, I see two strategies to adress those issues and likely the one mentioned by OP.
1- Have CMakeLists.txt be well written and be smart enough not to have a frozen behaviourto update themselves on the fly. That's what we have in our software environment. Each module has a standardized file organization (sources are in src folder, includes are in inc folder...) and have simple text files to specify their dependencies (with keywords we defined, like QT to say the module needs to link with Qt). Then, our CMakeLists.txt is a two-line file and simply calls a cmake macro we wrote to automatically setup the module. As a MCVE that would be:
CMakeLists.txt:
include( utl.cmake )
add_module( "mylib", lib )
utl.cmake:
macro( add_module name what )
file(GLOB_RECURSE source_files "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
if ( what STREQUEL "lib" )
add_library( ${name} SHARED ${source_files} )
elseif ( what STREQUEL "prg" )
add_executable( ${name} ${source_files} )
endif()
# TODO: Parse the simple texts files to add target_link_libraries accordingly
endmacro()
Then, for all situations exposed above, you simply need to update utl.cmake, not the thousand of CMakeLists.txt you have...
Honestly, we are very happy with this approach, the system becomes very easy to maintain and we can easily add new dependencies, upgrade third parties, change some build/dependency strategies...
However, there remains a lot of CMake scripts to be written. And CMake script language sucks...the tool's very powerful, right, but the script's variable scope, the cache, the painful and not so well documented syntax (just to check if a list is empty you must ask for it's size and store this in a variable!), the fact it's not object oriented...make it a real pain to maintain.
So, I'm now convinced the real good approach may be to:
2- completly generate the CMakeLists.txt from a more powerful language like Python. The Python script would do things similar to what our utl.cmake does, instead it would generate a CMakeLists.txt ready to be passed CMake tool (with a format as proposed in HelloWorld, no variable, no function....it would only call standard CMake function).
I doubt such generic tool exists, because it's hard to produce the CMakeLists.txt files that will make everyone happy, you'll have to write it yourself. Note that gen-cmake does that (generates a CMakeLists.txt), but in a very primitive way and it apparently only supports Linux, but it may be a good start point.
This is likely to be the v2 of our software environment...one day.
Note : Additionally, if you want to support both qmake and cmake for instance, a well written Python script could generate both CMakeLists and pro files on demand!
Not sure whether this is a problem original poster faced, but as I see plenty of „just write CMakefile.txt” answers above, let me shortly explain why generating CMakefiles may make sense:
a) I have another build system I am fairly happy with
(and which covers large multiplatform build of big collection
of interconnected shared and static libraries, programs, scripting
language extensions, and tools, with various internal and external
dependencies, quirks and variants)
b) Even if I were to replace it, I would not consider cmake.
I took a look at CMakefiles and I am not happy with the syntax
and not happy with the semantics.
c) CLion uses CMakefiles, and Cmakefiles only (and seems somewhat interesting)
So, to give CLion a chance (I love PyCharm, so it's tempting), but to keep using my build system, I would gladly use some tool which would let me
implement
make generate_cmake
and have all necessary CMakefiles generated on the fly according to the current
info extracted from my build system. I can gladly feed the tool/script with information which sources and headers my app consists of, which libraries and programs it is expected to build, which -I, -L, -D, etc are expected to be set for which component, etc etc.
Well, of course I would be much happier if JetBrains would allow to provide some direct protocol of feeding the IDE with the information it needs
(say, allowed me to provide my own command to compile, to run, and to
emit whatever metadata they really need - I suppose they mainly need incdirs and defines to implement on the fly code analysis, and libpaths to setup LD_LIBRARY_PATH for the debugger), without referring to cmake. CMakefiles as protocol are somewhat complicated.
Maybe this could be helpful:
https://conan.io/
The author has given some speeches about cmake and how to create modular projects using cmake into CPPCon. As far as I know, this tool require cmake, so that I suppose that generate it when you integrate new packages, or create new packages. Recently I read something about how to write a higher level description of the C/C++ project using a YAML file, but not sure if it is part of conan or not (what I read was from the author of conan). I have never used, and it is something pending for me, so that, please if you use it and fit your needs, comment your opinions about it and how it fit your scenario.
I was looking for such a generator but at the end I decided to write my own (partly because I wanted to understand how CMake works):
https://github.com/Aenteas/cmake-generator
It has a couple of additional features such as creating python wrappers (SWIG).
Writing a generator that suits everyone is impossible but I hope it will give you an idea in case you want to make your customized version.

Locating etc and share directories on Linux

I'm writing a program for Linux in C++, and I need to store some additional data, such as images. Stuff like that is usually in /usr/share on Linux.
The user can decide where to install the software (I'm using CMake), thus I should either use /usr/share, /usr/local/share, /home/theuser/somefolder/share or whatever, depending on where he installed it.
I usually go about doing this by figuring out the absolute path to my binary, cutting the trailing "bin" from the path and replacing it with "share". However, this is quite cumbersome and not the least elegant, so I was wondering how other people did it. I'm using boost, but I can't find any respective functions.
I only need the share directory for this project, but I'd also be interested in how you do this with the etc directory (my approach doesn't quite work there, because the binary can be in /usr/bin while the configuration files are in /etc)
The build system should pass the desired install location as a define during the build process. So
gcc -DDATA_DIR=/custom/build/location ...
This means that the install location can't be changed after the code is built, but is the only way to be certain that the code knows where to look, without reading that information somewhere at runtime.
You could use default directories paths.