Cmake preliminary (1)

Source: Internet
Author: User

From: What you do not know OSG Chapter 1: cmake preliminary (1) http://bbs.osgchina.org/forum.php? MoD = viewthread & tid = 1189 & fromuid = 3434

The main purpose of this chapter is not to introduce the common classes and functions of openscenegraph, but to introduce an important partner of openscenegraph, cmake is a powerful auxiliary development tool favored by more and more open-source software.

Cmake is defined as a cross-platform, open-source, and scalable software compilation and generation system. If you are familiar with qmake (an automatic engineering generation tool for open-source development library QT) or automake (a common engineering generation tool for Unix systems) will certainly help you gain a deeper understanding of it. To describe in one sentence, cmake's job is to generate makefile scripts on different platforms to create compilation rules for the entire software project, as well as its internal dependencies with other software tools.

Do not consider makefile as a dedicated product for Unix/Linux programmers. The development of Windows programs is also inseparable from the makefile concept. In fact, those powerful and dazzling ide environments (such as the well-known Visual Studio) provide developers with too many convenient conditions, as a result, everyone is gradually learning to do well. Press a button to find a menu item, or reluctantly enter a string of "start" characters in the Command window ...... Everything can be mastered? Sorry, there won't be so many cheap things in the world. In more cases, you have to use the most basic text editor, hitting one row and one row.

The above is what we are about to learn-have you ever yawned? Are there any situations that do not have Visual Studio, windows, progress bars, or even the mouse available? Well, I am looking forward to the next article. (^_^)

Otherwise, welcome to the first chapter of the Free tutorial "OSG you do not know. To do well, you must first sharpen your tools. Now let's take a look at it -- maybe you still have a third-party compilation tool, cmake.

 

1.1 cmake Overview

Good soldiers are no longer in service, and the grain is not carried three times.

Cmake may be equivalent to such an heroic general. Although it seems so troublesome, it is so unmeasurable, but after truly understanding its temper, it can be handy, and then lead thousands of troops and horses.

. When compiling an osgfile in Windows, you just need to drag the cmakelists.txt file of the root directory to the cmake-Gui window, and then set the corresponding options to generate the OSG Visual Studio project file (or, according to my preferences, generate nmake makefile files available), and then compile the OSG dynamic link library.

The job that Linux users need is exactly the same. Execute the following in the root directory:
  1. # Cmake.-dcmake_build_type = release
Copy the code and directly call the generated makefile script:
  1. # Make; make install
Just copy the code.

However, the source cmakelists.txt file in the sub-directory is invalid. The reason is very simple: the system cannot find many parameters and macros configured in the cmakelists file in the root directory. Therefore, an error message is generated and the execution cannot continue.
Cmake can generate different scripts or engineering files for different operating systems and IDE environments, such as Visual Studio solution, Mac OSX xcode file, and Unix/Linux makefile files.

Having said so much, I wonder how much information you have extracted for yourself? Maybe you are still suffering from annoying problems-why can't I generate the FreeType plug-in? Why can't OSG find my third-party library? So what do many configuration options mean? This article cannot answer so many questions. Maybe some of them will be answered in subsequent texts. Maybe some of them have not been explored by the author and other researchers, maybe some of them will only be answered by yourself ...... Maybe you may have thought about it. If my project uses cmake for configuration, then a command will output the Link Library and executable files in a neat manner, let other colleagues scratching their heads talk at a Glance-How cool should they be?

So, this is the purpose of writing this article: To help you, initially learn to use cmake to write your own project configuration script, and initially learn to understand and read other people's cmake configuration script code, therefore, we can read and understand the wide variety of configuration options in openscenegraph, and find them in the not-too-vast cmake script code (which is much simpler than OSG's source code.
1.2 Basic knowledge of cmake scripts

I don't know what readers want to know when they learn a new programming language? Syntax? Keyword? Application Scope? Function interface? These are of course important, but this article will first explain the organization structure of the cmake script language, which will help you fully understand this unfamiliar tool, in addition, in the face of version replacement and new functions, it will not be confused, but targeted, busy and not messy.

Cmake includes the following basic concepts:
  • Cmakelists.txt

This is the carrier of the cmake script code and configuration parameters. If it is not in the source code directory, A project cannot use the cmake configuration program to generate an automatic makefile script.

  • Source code tree and binary tree

The meanings of the source tree and binary tree are well understood: hidden) and their directory tree structures. The latter includes platform-related solutions or makefile scripts, target file (. (OBJ), compiled dynamic/static libraries, executable files, and other files generated during the compilation process.

Cmake allows in-source build and out-of-source build. The former will generate the corresponding makefile script, target file and result in the same directory of the source code; the latter will execute compilation and generation in different directories, and the source code tree will remain unchanged, it is very helpful for code version updates, search management, and packaging and publishing.

For Windows users, you can enter a new working path in the "where to build binaries" column of cmake-Gui to implement the out-of-source mode; linux users can simply execute the cmake command in an external directory, for example:
  1. # Cmake/home/myproject-dcmake_build_type = release
Copy the code. The/home/myprojectfile contains the cmakelists.txt file.

For OSG with rapid development and feature addition, "code generated out-of-the-Tree" is of course the preferred compilation solution. In this case, when we are not satisfied with the temporary file capacity of G, we only need to delete its directory without affecting the OSG source code.

  • Cmakemodules Module

One project depends on the header file and library file of another project (. lib). This is an indispensable part of both commercial and open-source software development processes: some functions of QT In the GUI development library depend on libjpeg and libpng; commercial GIS engine skyline relies on gdal. Even some large Microsoft games rely on open source engineering openal.

So how can we tell our project where these header files and Lib files are located? If you are familiar with the Visual Studio environment, you can set their paths on the "C/C ++" and "linker" tabs of the project properties. In Linux programming, you need to manually add the-I,-l, and-l parameters in the script to ensure that the # include macro will not be at a loss, and the compiler will not generate a damn lnk2001 or lnk2019 error.

For developers who use cmake to generate automatic scripts, the work of searching for header files and library files is handed over to each module in cmakemodules.

In the root directory of the OSG, there is a sub-directory folder that is not very noticeable. This is the cmakemodules. Among them, the file content is very rich, and the name is clear at a glance: findfreetype. cmake, findgdal. cmake, and so on. If the user machine is properly configured, these extensions are. the cmake search script can automatically obtain the path information of the dependent Library (but it does not automatically append them to the Project attributes); otherwise, we will repeatedly set freetype_include_dir When configuring the OSG, gdal_library and other options are also from these scripts.

The specific search Script reading and writing methods will be discussed later. If you are interested, you may want to use the text editing tool to open it now. Maybe they are not as complicated as you think.

  • Cmake basic macro

You may have noticed that, as we described the cmake command line in Linux in the previous article, there is an unspecified macro parameter:-dcmake_build_type = release. It can be simply divided into three parts.-D is the command prefix, cmake_build_type is the keyword of the macro command, and release is assigned a value. The meaning of this built-in macro logo should be said to be self-evident. It sets the compilation type to be used in the project. The available values include debug, release, relwithdebinfo, and minsizerel. Similar to the settings we made in tools such as Visual Studio, this will change the debugging level of the project and the information generated by compilation.

In addition to cmake_build_type, cmake also contains some basic built-in macro commands, such:

Cmake_module_path: Set the additional path for searching the cmakemodules module (. cmake.

Cmake_include_path, which is used to automatically search for additional paths that depend on the header file of the Project. By default, the search path specified in the script is used.

Cmake_library_path, which is used to automatically search for additional paths that depend on the project library file. By default, the search path specified in the script is used.

Cmake_install_prefix: Specifies the installation path. This is a major configuration item. When the generation of the chain and executable files is complete, copy the .lib,.dll,.exe and header files to an independent folder for calling and re-copying. In the Visual Studio environment, we use the install project to complete the installation, while in Unix/Linux, we are familiar with make install. The default installation directory is/usr/local/or C:/program files /.

  • Cmake Cache Information

The cached file.

Cmakecache.txt stores all automatically searched or manually configured paths and script parameters. When we update the source code of the project and prepare to re-compile it, using this cache information file can effectively accelerate the cmake configuration process, you can directly drag the file to the cmake-Gui window, or run the following command in the command line mode:
  1. # Cmake-C cmakecache.txt
Copy the Code. At this time, the system will automatically read all the information of the previous configuration. users using cmake-Gui can modify the parameters again in the dialog box and generate a new solution or MAKEFILE file, for the generation of the next project compilation.
1.3 Hello, world

Cmake is an extensible scripting language. To learn to read and write cmake script code, you must understand its basic syntax and its interface expansion rules. All these learning is based on practice. Otherwise, even the best tutorial textbooks and reference documents are only a piece of paper.

So what about the boring keywords of the xianluo column? Or should I open any text editor and try it? I think the latter is a faster way to the palace of cmake creators.

So let's start the journey of the cmake project without understanding any cmake script specification entries. Is it crazy? It doesn't matter. We use the developer's favorite "Hello World" as the first practical project. The Lexical and syntax rules involved in the coding process are explained in a little bit. We only want to give readers the initial impression of cmake script development, so that they can be more comfortable when reading the next section.

Now let us assume that there is such a project, which includes a dynamic link library named hellolib and a test executable program dependent on this library. The folder structure is as follows:



The hellolib sub-project defines and implements a class named hello. This class has only one public method, sayhello (), which is used to print the simple character "Hello cmake" on the screen. Therefore, the directory contains the header file hello and the source file hello. CPP, and expect to generate hellolib. DLL dynamic link library, so that all programs dependent on hellolib can print out friendly welcome statements. (Although this looks naive, ^_^)

The test sub-project has only one source file test. cpp. It only calls the sayhello () method in the main function and immediately ends its mission. Because of the existence of the helloliblibrary, testis expected to generate an executable file named test.exe and execute its own simple tasks in the console window.

The source code of these three files is as follows:
  1. /* HELLO */
  2. # Ifndef h_helloworld
  3. # Define h_helloworld
  4. # If defined (_ msc_ver) | defined (_ cygwin _) | defined (_ mingw32 __)
  5. # Ifdef helloworld_library
  6. # Define helloworld_export _ declspec (dllexport)
  7. # Else
  8. # Define helloworld_export _ declspec (dllimport)
  9. # Endif
  10. # Else
  11. # Define helloworld_export
  12. # Endif
  13. Class helloworld_export hello
  14. {
  15. Public:
  16. Void sayhello ();
  17. };
  18. # Endif
Copy code
  1. /* Hello. cpp */
  2. # Include <iostream>
  3. # Include "hello"
  4. Void Hello: sayhello ()
  5. {
  6. STD: cout <"Hello cmake! "<STD: Endl;
  7. }
Copy code
  1. /* Test. cpp */
  2. # Include <Hello>
  3. Int main (INT argc, char ** argv)
  4. {
  5. Hello OBJ;
  6. OBJ. sayhello ();
  7. Return 0;
  8. }
Copy code
Now we add a cmakelists.txt file to each folder (so there are 3 files in total) to form a complete cmake automatic compilation script tree. Dependencies determine the properties, dependencies, source code files, and compilation rules of the current project.

The implementation code of the cmake script in the root directory is as follows:
  1. Project (helloworld)
  2. Cmake_minimum_required (version 2.4.7)
  3. Add_subdirectory (hellolib)
  4. Add_subdirectory (test)
Copy the code. Do not rush to read the following content. First, check the cmake script code. Maybe you will find that they are easy to understand, right? First, specify the name of the entire project as helloworld, then specify "the required minimum cmake version" as 2.4.7, and add two subdirectories hellolib and test-this is only the content translated based on the English keywords, but it is exactly what this script means. The key here is the add_subdirectorycommand, which indicates that the system goes to the next level to search for the location of the cmakelists.txt script and execute the task of generating a specific sub-project.

The task of the subproject hellolib is to generate the dynamic link library hellolib. DLL (or libhellolib. so, Unix/Linux), defines a hello class and instructs the dynamic link library to output it so that programs dependent on the hellolib library can declare its instance and call its functions.

Its script implementation code is as follows:
  1. Add_definitions (-dhelloworld_library)
  2. Add_library (hellolib shared
  3. Hello. cpp
  4. )
Copy the code. Here, another important command: add_definitions is used to define the pre-compiled macro required by the program. Its inherent parameter format is usually the name of the macro added by-D. For example, a helloworld_library macro is defined here, and the output mode of the Hello class is set in the program. (In Win32, dllexport is often used to specify the output of functions and classes, while in other systems, special instructions are not required.) Of course, using # define for definition also plays the same role, however, if this type of work can be selectively completed in the compilation script, it will naturally bring more flexibility and platform compatibility to the project.

The second important command is add_library. Obviously, its task is to instruct the cmake system to add a new library Sub-Project. The parameter format is as follows:
  1. (Library name library type source file)
Copy the code library name to hellolib, which is also the name of the final generated Link Library; Type: shared, that is, dynamic link library (. DLL or. so), and static means to generate a static link library (. lib or. a); only one source code file is required for the library, that is, hello. CPP, which contains the header file "hello. the CPP file is in the same directory, so you do not have to specify it.

Do not care about the indent format written in add_library, or even the case. It is only a typographical and easy-to-use method, and there is no mandatory requirement.

That's simple. A new link library project is created. If you use cmake to automatically generate a Visual Studio solution, you should be able to see this sub-project figure. What? In the Visual Studio menu, select "file-> New-> project" and think it is simpler? This may be the case for the moment, but why don't we come to a conclusion later?

According to our previous conventions, now we need to create an executable project named test(.exe) and use it to call the hello: sayhello () method and print the string "Hello cmake !".

How can I use Visual Studio? In the same solution, select File> New> project again. Select create a Win32 console project and set test. drag CPP to the source file directory. Next, set "Additional header file directory" to "hello" in "project properties-> C/C ++; in "project properties-> linker", specify "additional library file" as hellolib. DLL; then specify the dependency between hellolib and test, compile and generate, and everything is done-well, some trouble, right? Maybe you will look forward to it later. Can cmake's approach be as simple as just creating a Linked Library? You are right. It is as simple as that:
  1. Include_directories ($ {project_source_dir}/hellolib)
  2. Add_executable (Test
  3. Test. cpp
  4. )
  5. Target_link_libraries (test hellolib)
The copy Code involves the concept of a "variable", namely $ {project_source_dir }. For those who are proficient in C/C ++ programming, you are not familiar with such situations, for example:
  1. STD: String str1 = "ABC ";
  2. STD: String str2 = str1 + "def ";
  3. STD: String str3 = "str1 + Def ";
Copy the code. Here, str2 is assigned "abcdef", while str3 is an incredible "str1 + Def ". The role and scope of variable str1 are self-evident.

The same is true for variables in cmake: You can use the set command to set and pass various user variables, or directly use the built-in global variables, such as project_source_dir. Note that all usage of variable values must follow "$ {......}" Otherwise it will be recognized as a normal string, just like the result stored in str3; but for cmake, It is enclosed by quotation marks, you can also use "$ {......}" To specify the content in the variable, for example:
  1. Set (my_system "cmake building system ")
  2. Message ("$ {my_system} is good for developers .")
Copy the code to display the complete "cmake building system is good for developers." dialogue, rather than the meaningless my_system symbol. Of course, you do not need to explain the meaning of the message command too much-it must be used to display debugging or warning information through the console window or dialog box.

Note that cmake variables can be "Introspective. If a variable named my_name is assigned "Wang", the $ {my_name} _ lib variable is equivalent to the wang_lib variable, the use of $ {my_name} _ lib} in the script is equivalent to the use of $ {wang_lib.

Note that the variable type in cmake is only the • string • type! However, it can be flexibly recognized as string, Boolean, integer, or floating point by different script commands, which saves the trouble of type conversion.

Is this tedious explanation helpful to your learning and understanding, or is it annoying? Then we will return to the script code. After understanding the meaning of project_source_dir, You can naturally guess what the content of this variable is, that is, the root directory of the entire project. It is automatically detected and assigned by the system, so we don't need to worry about it. This variable is obviously crucial for the dependency settings between each sub-project and the header file and source file path settings! This is self-evident.

In the cmake script of the test sub-project, we first use the include_directories command to set the location of the additional header file directory, and then use add_executable to specify the name of the executable program to be compiled and the relevant source file; finally, use target_link_libraries to set the link library file on which test depends, that is, the hellolib library just created.

That's all. Then, start your cmake-Gui window or command line to generate your favorite project or makefile and compile and run it. The results are exquisite and simple, and the process is not complicated, and there are not many gains. Isn't this a pleasant feeling?


Cmake preliminary (1)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.