cmake, several questions - c++

I'm new to cmake.
Are there any good tutorials that go deeper into the matter?
Are there any articles about "good practices" with cmake?
Are here any good overviews about all cmake commands and what they do? The original cmake docs are rather confusing and messed up in my opinion...
Now for something more specific:
As far as I found out, you have to tell cmake every source file (.cpp) that should be compiled. Isn't it possible to simply tell "just compile everything you find in folder /src" (like you can simply define an include folder without havinf to define every single .h file)?
What's the best way to tell cmake to also compile files that are not in the /src dir? I have another folder for external source code, that also has subdirectories and everything. Do I have to write (again..) every single .cpp file into the cmake script to let it know that the external code should be compiled, too?
Basically I'm looking for the quickest and best way to add new source/header files to a project without having to constantly adjust the cmake files.

You can just glob *.cpp *.h etc, but if your list of files changes CMake won't notice unless you touch your CMakeLists.txt file.
The best practice is to constantly adjust your CMake files, though. You'll get consistent behavior if you list the files, which is what is really important.
It really isn't that much work in practice, really.
Using a CMakeLists.txt file for each directory, and using add_subdirectory is usually the easiest way to manage it. That way you don't deal with paths beyond the current and child scope.
Here is a CMake Tutorial

Related

clarify on CMAKE library installation

The odd is that I can understand CMAKE documents, but I still can not figure out how to use it in a little more complicated scenario.
I want to install a SHARED LIB, to let someone else use it.
I know I can install it with CMAKE install command, but my first question is that my code still works without installing the library. The library is built and put under cmake_build_debug dir.
All I did is:
FILE(GLOB SHAREAD_SRC
${CMAKE_CURRENT_SOURCE_DIR}/Interface/*.cpp
)
set(MY_LIB mylib)
add_library(${MY_LIB} SHARED ${SHAREAD_SRC})
add_executable(run_src src/my_src.cpp ${HEADERS})
target_link_libraries(run_src ${MY_LIB})
I can now include the library's header in my source code and start to use it.
My question is,
in add library command, should I also include my library's header files? Currently i only include the source files to build the library, since whenever I use the library, I know where physically the library headers are(since i made this library), and for those others who also want to use this lib, i would provide them the header and the built lib target, so whereever they want to put them, no problem.
some answers talk about the install command saying that without the header files included in add_library, Why add header files into ADD_LIBRARY/ADD_EXECUTABLE command in CMake, otherwise you won't see headers in IDE-generated project. My headers are in this project, so I don't understand this issue. Why do I need to install this library? What is the purpose of install if the user downloaded my header file and have the built binary?
Thanks for helping! Appreciation in advance.
Except for the mentioned reason that specified files gonna be "visible" in IDE there is one more: explicit better than implicit (yeah Pythonish statement) -- meaning that you give a hint to the reader of your CMakeLists.txt of what exact files your library consists of. And yes, using GLOB for sources is the known bad practice for many reasons -- IRL it's not really hard to maintain the list of sources explicitly and makes your build system less error-prone. In some circumstances, you can gain some more benefits of having headers mentioned explicitly (e.g. using install(TARGET ... PUBLIC_HEADERS ...) but this is the other subject :)
You didn't specify your workflow (how do you build and distribute your project/library). However, the primary goal of install is to form the built image of your project -- i.e. what targets/files/directories gonna be installed and into what directory layout. It's needed to build other projects dependent on yours or produce packages (w/ CPack) to distribute or deploy 'em somewhere.
Also, to let others use your built library in CMake way please read how to make a package section in the manual. So, others can just do find_package(YourProject) and use it (link w/ it via target_link_libraries) -- easy peasy!

How to create a Makefile for an existing project

I'd like to create a Makefile for a moderately sized C++ project (~110 .cpp and .h files) that was created in Xcode. I don't own a mac, so I can't just go into xcode and export a Makefile.
From my understanding of using Makefiles for simpler projects, I could go through and create a target in my Makefile for each .cpp file, including its prerequisites... but that would require manually looking through each file and sorting out what its dependencies are.
It's my understanding that autoconf is a good tool for this sort of problem, but I haven't been able to figure out how to set it up and I'm not even sure that it's the right tool for the job. So before I go even further down this rabbit hole --
What is the best way to create a Makefile for an existing project without one?
It is rather subjective as to the best tool. Perhaps look at SCONS or gradle to compare for your particular needs.
I think Pbxbuild may help you.
Pbxbuild (not to be confused with the OS X tool of the same name) is used to take Xcode project files and build the code. It does this by creating GNUmakefiles, and using Make to build those.
Any build system (generator) will require some learning on your part. I would suggest using CMake, if you do not mind that CMake will be required wherever anybody tries to build your source. Otherwise I would suggest using the Autoconf/Automake/Libtool combo.

Good practices when adding downloaded c++ source code to my project

I am trying to use gnuplot++, but this is really a more general question about downloaded source code. I have downloaded the gnuplot++ source code and it consists of multiple .h and .cc files. I would like to use it in othercopy projects in the future so I am reluctant to add all the files into my project directory.
From what I understand gcc will look in /usr/local/include for header files, so I have put the code there for now. But what is the best way to compile and link the code?
Should I use the makefile to include the directory of the source code?
Should I keep it somewhere easy to find like /usr/local/include?
How do I know the best way to compile the code in gnuplot++?
Typically, if the project itself doesn't come with install instructions, I usually add it somewhere "public", e.g. /usr/local/project/{lib,include,src,...} where "project" in this case would be gnuplot++.
In this case, there doesn't appear to be any support for building this into a library, which makes it a little more awkward, as you need the sources included in your project itself. I'd still keep those sources separate, but you may prefer to just put them into a separate directory within the project [or spend an hour or three making a library of it].
For general practice, yes, keep the source for gnuplot++ (or any other similar 3rd-party project) separate from your own application source code. This makes it much easier to manage updates to the 3rd party projects, etc.
Yes, I would use the makefile for your application to also include the path to the headers for gnuplot++ and I would not copy those files directly into /usr/local/include. Instead, I would consider a couple options: do nothing and point your include path in your makefile to the gnuplot++ directory, or put symbolic links in /usr/local/include to point to the gnuplot++ files.
As for the best way to compile gnuplot++, I would have to look at gnuplot++ myself and see what it has to say, perhaps in a README file or similar.
In general, when using third-party libraries, you build and install those libraries according to the installation description that comes with the downloaded source.
If there is no installation guideline, it is typically a set of steps like
./configure
make
make install
Then it is the responsibility of the library to ensure the relevant headers and library files are easily locatable for use in your project.
gnuplot++ is an exception here, because it does not seem to come with its own build structure.
The best advice in cases such as this is to put the source from gnuplot++ in a directory within your project (possibly parallel to your own sources) and include the files in your own build setup.

How to copy qt source files to my project and let them compile pass?

In my project, I use QWizard and QWizardPages, but at last I found these classes have too much restrict, and I want to modify their source code. But I think it's not a good idea to directly modify qt source, but copy them to my project folder and rename the class names. Is their somebody do the same thing before? I can't compile the files successfully, it seems qMywizard.cpp include the generated moc file of qMywizard.h at the end, and the moc file can't be compile without the QMyWizardPrivate definition. I'm also afraid that many macros can't be recognized when files change location. Can anyone give me some advice?
Qt source is in git. Clone it, make a branch, write your modifications there and compile it with their build system. Also, make sure to understand and follow the license obligations on modifications (especially if you are using the LGPL).

Cleaning up a VC++ 6 project

I'm working with a very old and large VC6++ project and it's all messed up. There are unused files and folders everywhere, copies of folders and it's just a mess to clean it up by hand in its current state.
It will be done eventually, but is there any simple way to check what files and folders are used when it does a clean compile?
The project settings doesnt help me at all because it simply uses copies of folders and additional include directories.
Any suggestions?
Well, if you want to parse the compiler output you can get which files are actually used. I also find this when googling around, you might want to try (I haven't tried it myself). My way would be to clean the build, list all source files, build, and for each source find its corresponding .obj. The ones without .obj are not used. Note that this only works for source files, unused header files stay undetected.
VC6 will produce a makefile for you:
http://msdn.microsoft.com/en-us/library/aa233950%28v=vs.60%29.aspx
You can use the generated makefile (and the associated .dep file) as a starting point and edit it down to the list of files that get used in a build.
This will let you see the header files that the project depends on in addition to the .c/.cpp/.lib files that might show in the build log. One thing to keep in mind is that you'll probably also want to make sure you track the .dsw and .dsp workspace and project files.
If you're a bit adventurous, you might be able to convince the makefile to actually copy the source files to some other location for you with an appropriate override of the certain macros and/or dependencies. But that would probably be more trouble than it's worth for a one-time effort.
Finally, there's a commercial product, CopyWiz by Kinook Software, that seems to have features that might do what you're looking for (and it supports VC++ 6). Note: I'm not sure if it will do what you want, but it may be worth a look.
Yes. Run Process Monitor from SysInternals. It can capture all file system events and filter them based on the path and other factors.
So, set the filter to the root of your source tree, only succesfull file reads (VC looks for headers in many places), and build your project. You'll probably still see several thousand events. So, save them to file, sort by path, and remove duplicate paths (headers especially will have many duplicate entries)