CMake I compiles static, dynamic, and object libraries

catalogue

1, Source file

1.Message.h

2.Message.cpp

3.helloworld.cpp

2, Cmakelists txt

1. Source file

2.CMake language description

(1)cmake_minimum_required

(2)project

(3)add_library

(4)add_executable

(5)target_link_libraries

3, cmake configuration and compilation

1.cmake configuration

2. Build / compile

[Extension] compile dynamic library

(1) Modify cmakelists txt

(2) Configure and build

[Extension] compile object library

(1) Modify cmakelists txt

(2) Build and compile

(3) Modify library name

Last Introductory article There is only one file. It is a little more complicated today. Add a Message class and compile it into a static library or dynamic library.

1, Source file

1.Message.h

#pragma once
#include <iosfwd>
#include <string>

class Message
{
private:
	std::string _message;
	std::ostream& printObject(std::ostream& os);

public:
	Message(const std::string& m) :_message(m)
	{
	}
	friend std::ostream& operator<<(std::ostream& os, Message& obj)
	{
		return obj.printObject(os);
	}
};

2.Message.cpp

#include "Message.h"
#include <iostream>
#include <string>
std::ostream &Message::printObject(std::ostream &os)
{
	os<<"This is message:"<<std::endl;
	os<<_message;
	return os;
}

3.helloworld.cpp

#include "Message.h"
#include <iostream>
#include <string>

int main()
{
	Message sayHello("Hello C++");
	std::cout<<sayHello<<std::endl;

	Message sayBye("Bye C++");
	std::cout<<sayBye<<std::endl;
	
	return EXIT_SUCCESS;
}

2, Cmakelists txt

1. Source file

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(buildLib LANGUAGES CXX)

#Generate the necessary build instructions and compile the specified source code into the library.
add_library(message 
	STATIC
	Message.cpp
	Message.h
	)

add_executable(helloworldexe helloworld.cpp)
#Link the library to the executable.
target_link_libraries(helloworldexe message)

2.CMake language description

(1)cmake_minimum_required

Set the minimum version required for CMake. If you use a version of CMake that is lower than that version, a fatal error is issued.

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

(2)project

It declares the name of the project (buildLib) and the supported programming language (CXX stands for C + +).

project(buildLib LANGUAGES CXX)

(3)add_library

Create target - static library. The name of the library (message) is the same as the source file name.

add_library(message STATIC Message.cpp Message.h)

CMake accepts other values as add_ Valid values for the second parameter of Library:

  • STATIC: used to create a STATIC library, that is, a packaged archive of compiled files for use when linking other targets, such as executable files.
  • SHARED: used to create dynamic libraries, that is, libraries that can be dynamically linked and loaded at run time.
  • OBJECT: used to create an OBJECT library. The given add_ The source code in the list of library is compiled into the target file, they are not archived in the static library, and they cannot be linked to shared objects. Using OBJECT libraries is particularly useful if you need to create static and dynamic libraries at once.
  • MODULE: it is also a DSO group. Unlike SHARED libraries, they are not linked to any targets in the project, but can be loaded dynamically. This parameter can be used to build runtime plug-ins.  

CMake can also generate special types of libraries, which will not produce output in the construction system, but it is very useful for dependencies between organizational goals and construction requirements:

  • IMPORTED: this type of Library target represents a library located outside the project. The main purpose of such libraries is to build on existing dependencies. Therefore, the IMPORTED library will be considered immutable. We will demonstrate examples of using the IMPORTED Library in other chapters of this book.
  • INTERFACE: similar to the IMPORTED library. However, the type library is variable and has no location information. It is mainly used for target construction outside the project. We will demonstrate an example of the INTERFACE library in Section 5 of this chapter.
  • ALIAS: as the name suggests, this library defines aliases for library targets that already exist in the project. However, you cannot select an ALIAS for the IMPORTED library.

(4)add_executable

Instructs CMake to create a new target: the executable (helloworlddex).

add_executable(helloworldexe helloworld.cpp)

(5)target_link_libraries

Link the target library (message) to the executable target (Hello World exe).

target_link_libraries(helloworldexe message)

3, cmake configuration and compilation

1.cmake configuration

Use cmake To configure and generate buildlib SLN project:

2. Build / compile

Use cmake --build To build and generate static libraries and executable files:

[Extension] compile dynamic library

The source code of generating dynamic library in Windows platform is different from that of static library.

In the Windows platform, when we export the dynamic library, in addition to generating A dll is generated in addition to the dynamic library lib file. This lib files and static libraries Unlike the lib file, it does not store the binary files generated by the code, but all the symbol tables that need to export symbols. So this lib file and compiled static library The lib file is much smaller than the.

The exported symbol table needs to be specified in the source code. If we want to export a symbol (symbols here can refer to various types such as classes and functions):

  • Method 1: it needs to be preceded by__ declspec(dllexport) flag. In this way, the relevant information of this symbol will be exported The symbol table in lib.
  • Method 2: in cmakelists Txt (cmake_windows_export_all_symbols on)

If we don't have any in our source code__ declspec(dllexport) and not in cmakelists If "export all symbols" is set in txt, we can still successfully compile the dynamic library, but the symbol table will not be generated lib file. This is also a common problem in compiling dynamic libraries on Windows platform.

(1) Modify cmakelists txt

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_library(message SHARED Message.cpp Message.h)

(2) Configure and build

[Extension] compile object library

(1) Modify cmakelists txt

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(buildLib LANGUAGES CXX)

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

add_library(message-objs
	OBJECT
	Message.cpp
	Message.h
	)
	
set_target_properties(message-objs
	PROPERTIES
	POSITION_INDEPENDENT_CODE 1
	)
#Get dynamic library
add_library(message-shared
	SHARED 
	$<TARGET_OBJECTS:message-objs>
)
#Get static library
add_library(message-static
	STATIC
	$<TARGET_OBJECTS:message-objs>
	)
	
add_executable(helloworldexe helloworld.cpp)

target_link_libraries(helloworldexe message-static)

1. You need to ensure that the compiled target file is independent of the generation location. You can use set_ target_ The properties command is used to set the corresponding properties of the message objs target. (on some platforms and / or older compilers, you may need to explicitly set the position_index_code attribute for the target.)

2. Generator expression syntax of reference object library: $< target_ OBJECTS:message-objs>

(2) Build and compile

(3) Modify library name

#Modify dynamic library name
set_target_properties(message-shared
	PROPERTIES
	OUTPUT_NAME "shared-message"
	)

#Modify static library name
set_target_properties(message-static
	PROPERTIES
	OUTPUT_NAME "static-message"
	)

 

Keywords: cmake

Added by Valect on Fri, 07 Jan 2022 14:36:54 +0200