[cmake] CMakeList agregar biblioteca | agregar archivo de encabezado | agregar ruta | add_executable, add_library, target_link_libraries | agregar opciones de compilación | cambio de macro

Tabla de contenido

Consulta el sitio web oficial

ejemplo de aperitivo

CMakeLists genera y agrega bibliotecas dependientes

Más pequeños ejemplos de CMakeLists

Generar archivo de biblioteca compartida .so

Llame al archivo de biblioteca compartida .so

Generar una CMakeList de programas ejecutables

Genere un CMakeList de una biblioteca dinámica .so 

CMAKE añade opciones de compilación |-g parámetros/opciones de compilación

El directorio include_directories que contiene el archivo

Elemento de optimización|Nivel de optimización

Cmake establece el nivel de optimización | cmake genera versiones de depuración y lanzamiento

Establecer el tipo de compilación predeterminado

CMake establece parámetros/opciones de compilación

Cómo agregar la opción de compilación -ldl a cmakelists

CMake especifica la compilación de la versión gcc, g ++

Cómo desactivar las advertencias en CMake

Desactivar las optimizaciones del compilador

CMakeLists implementa interruptores macro dinámicos

eliminar la optimización del compilador

CMake --Uso de la lista

CmakeLists.txt comentarios de una sola línea y comentarios de varias líneas 

Comodines de CMakeList

otro sin categorizar

comando personalizado add_custom_target

agregar_dependencias 

Cmake instrucción de juicio condicional|si prioridad de juicio

Establecer en qué directorio encontrar la biblioteca dinámica al compilar y ejecutar el programa

#Especifique la ruta de carga de la biblioteca dinámica en tiempo de ejecución

#Especifique la ruta de la biblioteca dinámica al vincular

cmake instalación y configuración de empaquetado

CMakeLists.txt comentarios de una sola línea y comentarios de varias líneas


Autor: bandaoyu, actualización continua, enlace: [cmake] CMakeList agregar biblioteca|agregar archivo de encabezado|agregar ruta|add_executable, add_library, target_link_libraries|agregar opción de compilación|macro switch_cmake agregar archivo de encabezado directorio_blog de bandaoyu-CSDN blog

Consulta el sitio web oficial

Documentación de CMake 3.22.0-rc1: https://cmake.org/cmake/help/latest/search.html?q=add_library

cmake-commands(7) — Documentación de CMake 3.23.5

 CMake Cookbook: "CMake Cookbook (CMake Cookbook versión china)": https://www.bookstack.cn/read/CMake-Cookbook/content-preface-preface-chinese.md

ejemplo de aperitivo

CMakeLists genera y agrega bibliotecas dependientes

Texto original; cmake genera una biblioteca dinámica: https://www.cnblogs.com/pandamohist/p/13408455.html

1. Estructura del directorio

│ CMakeLists.txt 
│ index.txt 
├─construir 
├─incluir 
│ hola.h 
│ hola.h 
└─src 
        hola.cxx 
        hola.cxx

2, CMakeLists.txt

cmake_minimum_required(VERSIÓN 3.1) 

#Project name 
project(libhello) 

# 1. Especifique la variable de directorio del 
conjunto de bibliotecas(libhello_src src/hello.cxx) 
# Especifique la ruta de búsqueda del archivo de encabezado 
include_directories("${PROJECT_SOURCE_DIR}/include") 



# 2. Agregar biblioteca (correspondiente a dos proyectos) 
add_library( hello_shared SHARED ${libhello_src}) 
add_library( hello_static STATIC ${libhello_src}) 
#Según la práctica general, el nombre de la biblioteca estática debe ser el mismo que el nombre de la biblioteca dinámica, pero el extensión es diferente; 
# Es decir: el nombre de la biblioteca estática es libhello.a; el nombre de la biblioteca dinámica es libhello.so; 
# Por lo tanto, se espera que "hello_static" se muestre como "hello" en lugar de " hello_static" al generar, por lo que la configuración es la siguiente 
# SET_TARGET_PROPERTIES ( hello_static PROPERTIES OUTPUT_NAME "hello") 


# 3. Cuando cmake crea un nuevo objetivo, intentará limpiar otras bibliotecas usando este nombre. #  
# Por lo tanto, al compilar libhello.a, limpiará libhello.so.
Para evitar este problema , por ejemplo, utilice SET_TARGET_PROPERTIES para definir de nuevo la propiedad CLEAN_DIRECT_OUTPUT.
SET_TARGET_PROPERTIES (hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) 
SET_TARGET_PROPERTIES (hello_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1) 


# 4. Según las reglas, la biblioteca dinámica debe contener un número de versión, 
# VERSION se refiere a la versión de la biblioteca dinámica y SOVERSION se refiere a la versión de la API. 
SET_TARGET_PROPERTIES (hello_static PROPERTIES VERSION 1.1 SOVERSION 1) 
SET_TARGET_PROPERTIES (hello_shared PROPERTIES VERSION 1.1 SOVERSION 1) 


# 5. Solo cuando libhello.a, libhello.so.x y hello.h están instalados en el directorio del sistema, otros pueden desarrollarlos y usarlos. 
# En este ejemplo, instale la biblioteca compartida de hello en el directorio <prefix>/lib; 
# Instale hello.h en el directorio <prefix>/include/hello. 
#INSTALAR (OBJETIVOS hello hello_shared DESTINO DE BIBLIOTECA lib DESTINO DE ARCHIVO lib)
#INSTALL (OBJETIVOS hello hello_static BIBLIOTECA DESTINO lib ARCHIVO DESTINO lib) 
#INSTALL (ARCHIVOS hello.h DESTINO include/hello)

3, configurar y generar

xxx/a/ruta 

cd construir 
cmake ..

4. Otras configuraciones

  Si necesita especificar la ruta de salida, pruebe el siguiente comando de ejemplo:

# 设置VS会自动新建Debug和Release文件夹
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Lib) 
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Lib) 
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CM AKE_BINARY_DIR}/Bin) 

# 设置分别设置Debug和Release输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Lib) 
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Lib) 
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../../build/Debug) 

set(CMAKE_ ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Lib) 
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Lib) 
conjunto(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/Bin)

Más pequeños ejemplos de CMakeLists

Generar archivo de biblioteca compartida .so


Estos son algunos de mis archivos:

1hola.cpp

//hello.cpp
 int Calculate_sum_Of_Two_Number(int x,int y)
{
   int z=0;
   z=x+y;
   return (z);
}


2hola.hpp

//hello.hpp
#ifndef     __HELLO_H
#define     __HELLO_H
int Calculate_sum_Of_Two_Number(int x,int y);
#endif


3 principal.cpp

//main.cpp
#include "hello.hpp"
#include <stdio.h>
int main(void)
{
   int a=0,b=0,c=0;
   printf("please input two parameter:");
   scanf("%d",&a);
   scanf("%d",&b);
   c=Calculate_sum_Of_Two_Number(a,b);
   printf("the sum is : %d",c);
   return 0;
}


4 CMakeLists.txt

#要求的Cmake最低版本
CMAKE_MINIMUM_REQUIRED( VERSION 2.8)
 
#工程名称
PROJECT(main)
 
#设置编译器编译模式:
set( CMAKE_BUILD_TYPE "Debug" )
 
#生成共享库
#get the shared package
#here needs no .hpp
add_library(calculate_shared SHARED  hello.cpp)
 
#生成可以执行的文件
add_executable(main main.cpp)
 
#连接共享库
target_link_libraries(main calculate_shared)


En el CmakeLists.txt anterior, el nombre de la biblioteca compartida es compute_shared, que podemos cambiar nosotros mismos. El archivo ejecutable generado es principal, y este nombre también se puede cambiar.

Sin embargo, debe tenerse en cuenta que no es necesario incluir hello.hpp en hello.cpp. (Khan, debido a esto causó un error, el indicador decía que la función se definió repetidamente);

Compilar genera:

mkdir build
cd build
cmake ..
make
podemos ver que build generó los siguientes archivos:

CMakeCache.txt cmake_install.cmake main
CMakeFiles libcalculate_shared.so Makefile

 libcalculate_shared.so es el archivo de biblioteca compartida generado.

Su ruta es: /home/fan/dev/cmake/4-exer/

Hay carpetas de compilación a continuación, así como main.cpp, hello.cpp, hello.hpp, 

Hay una biblioteca compartida libcalculate_shared.so.so en la carpeta de compilación

Llame al archivo de la biblioteca compartida


Todas las bibliotecas dependientes externas son así, como opencv, openni, eigen, etc. El principio es el mismo, pero se han instalado en el sistema y se pueden encontrar, y esto debe configurarse nosotros mismos.

Es decir, el archivo de biblioteca compartida que generé anteriormente es esencialmente el mismo que la biblioteca opencv. Es solo que esta biblioteca compartida debe configurarse manualmente por sí misma.

Por ejemplo, creé un nuevo proyecto y necesito llamar a la biblioteca compartida anterior libcalculate_shared.so.

main.cpp es el siguiente:

//main.cpp
#include <stdio.h>
#include <iostream>
#include "hello.hpp"
using namespace std;
int main(void)
{
   int x=2,y=3;
   int z=0;
   z=Calculate_sum_Of_Two_Number(x,y);
   cout<<"the result is:"<<z<<endl;
   return 0;
}


Luego, en CMakeLists.txt, necesito decirle a CMake dónde se puede encontrar este archivo de encabezado y dónde se pueden encontrar las funciones definidas en el archivo de encabezado.

La ruta de hello.hpp anterior es: /home/fan/dev/cmake/4-exer/hello.hpp

La ruta de libcalculate_shared.so es /home/fan/dev/cmake/4-exer/build/libcalculate_shared.so

Entonces CMakeLists.txt es el siguiente:

CMAKE_MINIMUM_REQUIRED( VERSION 2.8)
 
PROJECT(main)
#设置编译器编译模式:
SET( CMAKE_BUILD_TYPE "Debug" )
 
SET(HELLO_INCLUE 
    /home/fan/dev/cmake/4-exer/)
 
SET(HELLO_SO 
    /home/fan/dev/cmake/4-exer/build/libcalculate_shared.so)
 
INCLUDE_DIRECTORIES(${HELLO_INCLUE})
 
add_executable(main main.cpp)
 
target_link_libraries(main ${HELLO_SO})


Preste atención a algunos detalles aquí (para mi escoria)

1. La forma de ${ } representa una variable, como la anterior, HELLO_INCLUE, que es una variable definida por mí mismo.

2. El archivo de encabezado se incluye en la carpeta donde se encuentra el archivo de encabezado, es decir, /home/fan/dev/cmake/4-exer/

3. La biblioteca compartida debe especificar la biblioteca compartida específica, precisa para .so

De hecho, lo principal es especificar el archivo de encabezado utilizado al llamar a la biblioteca compartida y la ubicación de la biblioteca compartida en sí, y luego incluir el enlace.

La biblioteca compartida instalada (como opencv) no tiene por qué ser tan problemática, porque su dirección se coloca en la variable.

Adición de dependencia de Opencv
Por ejemplo, Opencv, sus archivos de encabezado y archivos .so se han colocado en las variables del sistema, por lo que no es necesario que los defina usted mismo (las direcciones de los archivos de encabezado y los archivos de biblioteca compartidos en el ejemplo anterior se establecen mediante mí mismo)

Su CMakeLists.txt es el siguiente:

find_package (OpenCV REQUERIDO)

incluir_directorios(${OPENCV_INCLUDE_DIRS})

target_link_libraries(PRINCIPAL ${OpenCV_LIBS})

Simplemente búsquelo, OpenCV_LIBS y OPENCV_INCLUDE_DIRS ya están definidos por el sistema, por lo que es más fácil

Blog de referencia:

1. Cómo escribir su propio CmakeLists.txt https://www.cnblogs.com/chaofn/p/10160555.html

2. [OpenCV] Use CMake para vincular la biblioteca OpenCV en su ruta https://blog.csdn.net/twt520ly/article/details/81981473

Enlace original: https://blog.csdn.net/qq_37761077/article/details / 88750711

Generar una CMakeList de programas ejecutables

#添加包含文件的的目录
include_directories(${cppzmq_INCLUDE_DIR})             

#用${SOURCE_FILES}指定的文件,生成可执行文件sample_project 
add_executable(sample_project ${SOURCE_FILES}) 

#生成可执行文件sample_project 需要连接 ${CMAKE_THREAD_LIBS_INIT}指定的库
target_link_libraries (sample_project  ${CMAKE_THREAD_LIBS_INIT}) 

Genere un CMakeList de una biblioteca dinámica .so 

#用${SRC_LISTS}指定的所有的源文件生成一个库,名字叫libsugan
add_library(libsugan ${SRC_LISTS})   

#生成libsugan库需要链接 ${OpenCV_LIBS}、 ${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so、${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
target_link_libraries(libsugan                 
    ${OpenCV_LIBS}
    ${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so
    ${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
)


Enlace original: https://blog.csdn.net/bandaoyu/article/details/115165199

grep -nR "común" ./ --include=*.txt|grep -vE "src_bak|boost|código de borrado|doc|enlace.txt"

add_library (generar biblioteca), target_link_libraries (generar biblioteca vinculada de destino), set_target_properties

Generar una biblioteca estática:

add_library(libsugan ${SRC_LISTS}) #Usar ${SRC_LISTS} para generar la biblioteca estática libsugan

o

ADD_LIBRARY(static_lib ESTÁTICA ${DIR_SUB_SRCS})

Generar biblioteca dinámica (más COMPARTIDO):
add_library(libsugan   COMPARTIDO   ${SRC_LISTS}) #Usar ${SRC_LISTS} para generar biblioteca dinámica libsugan

target_link_libraries(libsugan #Generando la biblioteca estática libsugan también necesita vincular la biblioteca dependiente ${OpenCV_LIBS}...
    ${OpenCV_LIBS}
    ${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so
    ${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
)

#La configuración anterior genera una biblioteca estática llamada libsugan, pero el formato de almacenamiento de la biblioteca en Linux es lib+name.a, por lo que el resultado almacenado en la biblioteca libsugan es liblibsugan.a, lo que parece extraño. Use la siguiente oración para asegurarse de que la biblioteca estática almacenada se llame libsugan.a:

set_target_properties(libsugan PROPIEDADES SALIDA_NOMBRE "sugan")

#Pero tenga cuidado, en todo CmakeLists.txt

#Si desea vincular la biblioteca generada, debe usar el nombre especificado por "add_library(libsugan ${SRC_LISTS})".
set_target_properties(libsugan PROPIEDADES SALIDA_NOMBRE "sugan")

add_executable(demo ./src/main.cpp)
target_link_libraries(demo libsugan)

Biblioteca de enlaces:

target_link_libraries (libsugan de demostración)

target_link_libraries(app libsort.a) #Generar enlace de la aplicación en la biblioteca estática libsort.a

TARGET_LINK_LIBRARIES(aplicación libsort.a)

ejemplo original:

add_library,target_link_libraries,set_target_properties,target_link_libraries使用联系:https://blog.csdn.net/michaelhan3/article/details/69568362

#工程名字
project(Camera_sugan)                  

#编译最低cmake版本
cmake_minimum_required(VERSION 2.6)    

#设置c++编译器
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )  

#在整个电脑上找opencv包
find_package(OpenCV REQUIRED)    

#包含头文件路径
include_directories(             
    ./include/inudev/
    ./src/
)

#将所有的源文件列为一个集合,集合名字叫做SRC_LISTS
set(SRC_LISTS                   
    ./src/inuitive.cpp
    ./src/runCamera_Qfeeltech.cpp
)

#将集合里的所有的源文件生成一个静态库,该静态库的名字libsugan,
注意,在整个CmakeLists里都要用libsugan这个
add_library(libsugan ${SRC_LISTS})   

#名字来代替之前那个集合生成的库。
target_link_libraries(libsugan    #链接静态库需要的依赖库
    ${OpenCV_LIBS}
    ${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so
    ${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
)


Enlace original: https://blog.csdn.net/michaelhan3/article/details/69568362

CMAKE añade opciones de compilación |-g parámetros/opciones de compilación

add_definitions y add_compile_options, las opciones de compilación agregadas por los dos son para todos los compiladores (incluidos los compiladores c y c ++).

La diferencia entre add_definitions y add_compile_options es:

add_definitions se puede usar para agregar cualquier indicador, pero está diseñado para agregar definiciones de preprocesador.

Este comando ha sido reemplazado por una alternativa:
agregar definiciones de preprocesador con add_compile_definitions().
Utilice include_directories() para agregar directorios de inclusión.
Use add_compile_options() para agregar opciones adicionales.

agregar_definiciones: https://cmake.org/cmake/help/latest/command/add_definitions.html

Añadir -g parámetro/opción de compilación

Método 1: add_definitions("-g")/ add_compile_options


Agregue la siguiente instrucción
add_definitions("-g") en el archivo CMakeLists.txt

Agregar parámetros/opciones de compilación adicionales

Por ejemplo el siguiente código

#Juzgue el tipo de compilador, si es un compilador gcc, agregue soporte c++11 a las opciones de compilación

if(CMAKE_COMPILER_IS_GNUCXX)
    add_compile_options(-std=c++11)
    mensaje(ESTADO "opcional:-std=c++11")   
endif(CMAKE_COMPILER_IS_GNUCXX)
 



Use add_compile_options para agregar la opción -std=c++11 para agregar opciones de compatibilidad con c++11 al compilar el código de c++. Pero debido a que add_compile_options es para todo tipo de compiladores, al compilar código c, se generará la siguiente advertencia

J:\workspace\facecl.gcc>make b64
[ 50%] Building C object libb64/CMakeFiles/b64.dir/libb64-1.2.1/src/cdecode.c.obj
cc1.exe: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C
[100%] Building C object libb64/CMakeFiles/b64.dir/libb64-1.2.1/src/cencode.c.obj
cc1.exe: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C
Linking C static library libb64.a
[100%] Built target b64

Aunque no afecta la compilación, es realmente incómodo de ver.Para eliminar esta advertencia, no puede usar add_compile_options, sino solo agregar esta opción para el compilador de c ++.

Método 2: establecer

Así que modifique el código de la siguiente manera, se elimina la advertencia.

#Juzgue el tipo de compilador, si es un compilador gcc, agregue compatibilidad con c++11 a las opciones de compilación si
(CMAKE_COMPILER_IS_GNUCXX)
    establece(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
    mensaje(ESTADO "opcional: -std=c++11")   
endif(CMAKE_COMPILER_IS_GNUCXX)


Enlace original: https://blog.csdn.net/qinglongzhan/article/details/80743731

El directorio include_directories que contiene el archivo

include_directories(${cppzmq_INCLUDE_DIR}) //Agregar el directorio que contiene el archivo

add_definitions se puede usar para agregar cualquier indicador, pero está diseñado para agregar definiciones de preprocesador.

Este comando ha sido reemplazado por una alternativa:
agregar definiciones de preprocesador con add_compile_definitions().
Utilice include_directories() para agregar directorios de inclusión.
Use add_compile_options() para agregar opciones adicionales.

Elemento de optimización|Nivel de optimización

Explicación más detallada: https://blog.csdn.net/bandaoyu/article/details/123700034

-O0 deshabilita la optimización del compilador. Este es el valor predeterminado.
-O1 intenta optimizar el tiempo de compilación y el tamaño del ejecutable.

-O2 está más optimizado y probará casi todas las funciones de optimización, pero no realizará el método de optimización de "espacio por tiempo".

-O3 abre algunas opciones de optimización sobre la base de -O2: -finline-functions, -funswitch-loops y -fgcse-after-reload.

-Os optimiza el tamaño del archivo generado. Activará todas las opciones de -O2 excepto aquellas que aumentan el tamaño del archivo.

Puede usar el siguiente comando para encontrar el lugar donde se establecen los elementos de optimización en el proyecto:

grep -nR "\-O" ./ --include=*.txt

Filtre los resultados que contengan las palabras build, boost, erasure-code, doc, link.txt

grep -nR "\-O" ./ --include=*.txt|grep -vE "build|src_bak|boost|borrado-código|doc|enlace.txt"

Cmake establece el nivel de optimización | cmake genera versiones de depuración y lanzamiento

Ver artículo:

[gcc] nivel de optimización de gcc -O1 -O2 -O3 -Os -Ofast -Og|gcc fuera de optimización-CSDN blog

    Hay una variable CMAKE_BUILD_TYPE en CMake, los valores posibles son Debug, Release, RelWithDebInfo y MinSizeRel.

Cuando el valor de esta variable es Depurar, CMake usará las cadenas en las variables CMAKE_CXX_FLAGS_DEBUG y CMAKE_C_FLAGS_DEBUG como opciones de compilación para generar Makefile,

Cuando el valor de esta variable es Release, el proyecto utilizará las opciones de la variable CMAKE_CXX_FLAGS_RELEASE y CMAKE_C_FLAGS_RELEASE para generar Makefile.

Los niveles que se ofrecen son:

  • Release - Agrega las  -O3 -DNDEBUG banderas al compilador
  • Depuración - Agrega la  -g bandera
  • MinSizeRel - Añade -Os -DNDEBUG
  • RelWithDebInfo - Agrega  -O2 -g -DNDEBUG banderas


Enlace: https://www.jianshu.com/p/d761232e8e90
 

CMakeCache.txt:89:CMAKE_ASM_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMakeCache.txt:92:CMAKE_ASM_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMakeCache.txt:95:CMAKE_ASM_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
CMakeCache. texto:123: CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMakeCache.txt:126:CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMakeCache.txt:129:CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
CMakeCache.txt:150:CM AKE_C_FLAGS_MINSIZEREL:STRING=-O -DNDEBUG
CMakeCache.txt:153:CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMakeCache.txt:156:CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG

 

cmake establecer por defecto CMAKE_BUILD_TYPE

原文[CMake] Establecer el tipo de compilación predeterminado en CMakeLists.txt

CMakeLists.txtescribir en

IF (NO CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING
        "Elija el tipo de compilación, las opciones son: Debug Release RelWithDebInfo MinSizeRel." FORCE)
ENDIF()

Establecer el tipo de compilación predeterminado

El tipo de compilación predeterminado proporcionado por CMake es no incluir indicadores de compilación para la optimización. Para algunos proyectos, es posible que desee establecer un tipo de compilación predeterminado para que no tenga que acordarse de configurarlo.
Para hacer esto, puede agregar lo siguiente al nivel superior de su archivo CMakeLists.txt

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  ​​message("Estableciendo el tipo de compilación en 'RelWithDebInfo' ya que no se especificó ninguno.")
  set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Elija el tipo de compilación". FORCE)
  # Establezca los valores posibles del tipo de compilación para cmake-gui
  set_property(CACHE CMAKE_BUILD_TYPE CADENAS DE PROPIEDAD "Depurar" "Liberar"
    "MinSizeRel" "RelWithDebInfo")
endif()


Autor: xingxingRealzyx
Enlace: https://www.jianshu.com/p/d761232e8e90

CMake establece parámetros/opciones de compilación

El comando set para establecer las variables CMAKE_C_FLAGS o CMAKE_CXX_FLAGS es solo para los compiladores c y c++ respectivamente.

para el compilador c

set(CMAKE_C_FLAGS"-O3 -fopenmp -fPIC -Wno-obsoleto -Wenum-compare -std=c++14")

para el compilador c++

set(CMAKE_CXX_FLAGS "-O3 -fopenmp -fPIC -Wno-obsoleto -Wenum-compare -std=c++14")

Cómo agregar la opción de compilación -ldl a cmakelists

En cmakelists.txt, agregue TARGET_LINK_LIBRARIES después de agregar programas ejecutables,
por ejemplo:
add_executable(xx ${ALL_F} ${WE_F})
TARGET_LINK_LIBRARIES(dl)
TARGET_LINK_LIBRARIES(m)

establecer (CMAKE_C_FLAGS "-ldl")


Agregar target_link_libraries(${PROJECT_NAME} dl) después de add_executable(${PROJECT_NAME} "main.cpp")

target_link_libraries(exe1 -Wl, - -whole-archive lib1 -Wl, -  no-whole-archive)

CMake especifica la compilación de la versión gcc, g ++

El gcc/g++ predeterminado del sistema está en el directorio /usr/bin.

El directorio gcc que actualizamos e instalamos está en el directorio /usr/local/bin, y ahora queremos usar el gcc actualizado.

La mayoría de los resultados obtenidos a través de la búsqueda de Baidu son los siguientes:

Agregue antes de invocar el compilador en CMakeLists.txt:

CONJUNTO(CMAKE_C_COMPILER "/usr/local/bin/gcc")
CONJUNTO(CMAKE_CXX_COMPILER "/usr/local/bin/g++")

Sin embargo, después de mi propia práctica, este método no funciona (¿la razón para no eliminar las cosas en la compilación y volver a hacer?), La forma correcta es:

Antes de ejecutar el comando cmake, configure las siguientes dos variables en el terminal de shell:

exportar CC=/usr/local/bin/gcc
exportar CXX=/usr/local/bin/g++

también puede necesitar

exportar LD_LIBRARY_PATH=/usr/local/gcc-xxx/lib:$LD_LIBRARY_PATH

/usr/local/gcc-xxx/lib es la ubicación lib de su nuevo gcc

Luego ejecute los comandos subsiguientes, como cmake, para que se pueda usar la versión del compilador especificada.

vim ~/.bashrc fuente ~/.bashrc

Cómo desactivar las advertencias en CMake

Agregar add_definitions(-w) en CMakeLists.txt

Aplicado a un solo objetivo

  if(CMAKE_COMPILER_IS_GNUCC)
 target_compile_options(main PRIVATE"-Wall")
 endif()
 if(MSVC)
 target_compile_options(main PRIVATE"/ W4")
 endif()
  

aplicar a todos los objetivos

  if(CMAKE_COMPILER_IS_GNUCC)
 set(CMAKE_CXX_FLAGS"$ {CMAKE_CXX_FLAGS} -Wall")
 endif()
 if(MSVC)
 set(CMAKE_CXX_FLAGS"$ {CMAKE_CXX_FLAGS} / W4")
 endif()
  

NOTA: Agregue -Werror para GCC o /WX para que MSVC trate todas las advertencias como errores. Esto trata todas las advertencias como errores. Esto es útil para nuevos proyectos para hacer cumplir advertencias estrictas.

Además, -Wall no significa "todos los errores"; históricamente, significa "todos los errores en los que todos pueden estar de acuerdo". Comience con -Wall -Wextra, luego lea atentamente su versión del manual de GCC y encuentre  más que  el compilador pueda brindar usted información acerca de las advertencias.

CMake y advertencia del compilador https://www.it1352.com/784160.html

Desactivar las optimizaciones del compilador

(Inconfirmado)

1) add_compile_options(-fno-elide-constructors) #Cerrar optimización del compilador

2)establecer(CMAKE_CXX_FLAGS "-fno-elide-constructores ${CMAKE_CXX_FLAGS}")

CMakeLists implementa interruptores macro dinámicos

eliminar la optimización del compilador

Añadir en CMakeList:

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release)
endif()

set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")

al ejecutar

cmake -DCMAKE_BUILD_TYPE=Liberar

También puede agregar lo siguiente al CMakeList.txt de la capa anterior (llamado este CMakeList.txt):

opción (CMAKE_BUILD_TYPE "Usar tutorial provisto de implementación matemática"   ON )

Indica que la macro CMAKE_BUILD_TYPE está habilitada.

opción (CMAKE_BUILD_TYPE "Usar tutorial provisto de implementación matemática"   DESACTIVADO ) #表示关

referencia:

《c++ - Optimizar en CMake por defecto 》:https://stackoverflow.com/questions/41361631/optimize-in-cmake-by-default

《Cómo compilar sin optimizaciones -O0 usando CMake》:https://unix.stackexchange.com/questions/187455/how-to-compile-without-optimizations-o0-using-cmake

ejemplo

Recientemente, necesito controlar la dirección lógica a través de un código C. Busqué información en Internet y descubrí que es posible definir dinámicamente interruptores de macro en el archivo CMakeLists, de modo que se puedan compilar códigos con diferentes flujos lógicos.

Pasos específicos:

Primero, escribí varias salidas de depuración en el código src:

#IFDEF DEBUG
 
    algún comando de impresión;
 
#ENDIF
Luego, agregue la definición de DEBUG en el archivo CMakeLists:

IF (CMAKE_BUILD_TYPE STREQUAL DEBUG)
    ADD_DEFINITIONS(-DDEBUG)
ENDIF()
Finalmente, establezca el parámetro -DCMAKE_BUILD_TYPE en DEBUG durante cmake:

$ cmake .. -DCMAKE_BUILD_TYPE=DEBUG
$ make -j4
De esta manera, la información de depuración de algún comando de impresión se imprimirá cuando el archivo ejecutable se ejecute nuevamente. Si no desea ver la información de depuración, simplemente no configure el parámetro DEBUG en el parámetro, o configure el parámetro DEBUG en otros valores (elija uno de los dos métodos siguientes):

$ cmake ..
$ cmake .. -DCMAKE_BUILD_TYPE=RELEASE
Esta implementación de CMakeLists de la introducción del cambio dinámico de macros está completa.

Enlace original: https://blog.csdn.net/qq_19734597/article/details/104461963

CMake --Uso de la lista

CMake: uso de la lista: https://www.cnblogs.com/narjaja/p/8343765.html

CmakeLists.txt comentarios de una sola línea y comentarios de varias líneas 

Comentarios de una sola línea: use "#"
Comentarios de varias líneas: use "#[[ ]]"

inserte la descripción de la imagen aquí

Comodines de CMakeList

  $<OBJETIVO_OBJETIVO:A>:

ilustrar:

$<TARGET_OBJECTS:objLib>¶
New in version 3.1.

List of objects resulting from build of objLib.
构建 objLib 产生的对象列表

add_executable(test test.cc $<TARGET_OBJECTS:A>), significa usar test.cc y el objeto generado por la construcción A para compilar test de forma conjunta.

add_executable(test2 $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B> ), significa usar el objeto generado por la compilación A y el objeto generado por la compilación B para compilar conjuntamente la prueba.

Ejemplo: Un proyecto es el siguiente

-  CMakeLists.txt
-  include
    -  a.hh
-  lib
    -  CMakeLists.txt
    -  a.cc
-  src
    -  CMakeLists.txt
    -  main.cc
-  test
    -  CMakeLists.txt
    -  test.cc

Use CMake para compilar test.cc con el comando
add_executable(test test.cc $<TARGET_OBJECTS:A>)

La compilación de Ao utilizada es
add_library(A OBJECT A.cc)

De: https://stackoverflow.com/questions/35696103/cmake-wildcard-for-target-objects

otro sin categorizar

comando personalizado add_custom_target

Capítulo 5 Operaciones durante la configuración y compilación- 5.4 Ejecución de comandos personalizados durante la compilación: Ⅱ Uso de add_custom_target - 《CMake Cookbook (versión china de CMake Cookbook)》 - 书栈网· BookStack

add_custom_target(finish 
    COMMAND ${CMAKE_COMMAND} -E echo compile finish
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${SOURCE_DIR}/config ${SOURCE_DIR}/etc
    COMMAND ${CMAKE_COMMAND} -E copy ${SOURCE_DIR}/log.txt ${SOURCE_DIR}/etc
    )

Se define un comando personalizado: finalizar, y la ejecución de este comando realizará las siguientes operaciones:

COMMAND ${CMAKE_COMMAND} -E echo compile finish
COMMAND ${CMAKE_COMMAND} -E copy_directory ${SOURCE_DIR}/config ${SOURCE_DIR}/etc
COMMAND ${CMAKE_COMMAND} -E copy ${SOURCE_DIR}/log.txt ${SOURCE_DIR}/etc

La forma de ejecutar comandos por separado es: cmake --build <dir> [<opciones>] [-- <construir-herramienta-opciones>]

cmake --build /home/mydir --objetivo de finalización

La diferencia entre add_executable(main main.cpp) y add_library(mylib mylib.cpp) es que estos dos generarán (salida) archivos main y mylib. add_custom_target(comandname...) solo realizará las operaciones enumeradas y no generará archivos de nombre de comando

agregar_dependencias 

Si main depende de a.so b.so TARGET_LINK_LIBRARIES(main a.so b.so c.so d.so) 

Y a.so b.so se genera más tarde que main (es decir, el orden de compilación de scripts organiza a.so b.so para que se compile más tarde), entonces se requiere ADD_DEPENDENCIES(main a.so b.so) para compilar un .so para main por adelantado b.so, de lo contrario, se puede informar un error: no se puede encontrar la definición del símbolo (estos símbolos están solo en a.so y b.so)

Para obtener más información, consulte: La función básica de add_dependencies en el Blog-CSDN de cmake_KingOfMyHeart

marcar_como_avanzado  

mark_as_advanced Marque las variables de caché de CMake como avanzadas.

mark_as_advanced([CLEAR|FORCE] VAR VAR2 VAR...)
Marca las variables almacenadas en caché como avanzadas. Entre ellas, las variables avanzadas se refieren a aquellas variables que se mostrarán solo cuando "Mostrar opciones avanzadas" esté activado en la GUI de CMake. Si CLEAR es la primera opción, las variables avanzadas en los argumentos volverán a cambiar a variables no avanzadas. Si FORCE es la primera opción, las variables en los argumentos se promocionan a variables avanzadas. Si no está presente, la nueva variable se marcará como avanzada; si la variable ya es avanzada/no avanzada, permanecerá así.
Este comando no es válido en un script.

Enlace original: https://blog.csdn.net/hankern/article/details/120376405

Cmake instrucción de juicio condicional|si prioridad de juicio

cmake (16) Cmake instrucción de juicio condicional: https://blog.csdn.net/wzj_110/article/details/116105719

una   gramática básica

① Marco básico

② Prioridad

③ Tipos de condiciones

Establecer en qué directorio encontrar la biblioteca dinámica al compilar y ejecutar el programa

#Especifique la ruta de carga de la biblioteca dinámica en tiempo de ejecución


SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #Utilice la ruta de instalación para RPATH
SET(CMAKE_INSTALL_RPATH "\${ORIGIN}/lib" ) #La ruta de acceso que se utilizará para los destinos instalados.

CMAKE_INSTALL_RPATH — Documentación de CMake 3.0.2

Cuando el programa se está ejecutando, el orden (prioridad) de búsqueda de bibliotecas dinámicas es el siguiente:

1. RPATH, agregue el directorio especificado por el parámetro -rpath al compilar y vincular
2. El directorio especificado por la variable de entorno LD_LIBRARY_PATH
3. Archivo de configuración /etc/ld.so.conf.
4. /usr/lib , /lib y /usr/local/lib , las rutas predeterminadas del sistema.

Entonces configuramos RPATH, y hay una biblioteca dinámica debajo de RPATH, el programa la cargará primero

Aviso:

Se puede ver que LD_LIBRARY_PATH está separado entre RPATH y RUNPATH. Para permitir que los usuarios especifiquen .soarchivos modificando LD_LIBRARY_PATH, la mayoría de los compiladores dejan el RPATH de salida vacío y reemplazan RPATH con RUNPATH.

Linux cmake especifica la ruta del enlace de la biblioteca dinámica de compilación/tiempo de ejecución: https://blog.csdn.net/JCYAO_/article/details/102519998



Analice el uso de RPATH en CMake (https://www.cnblogs.com/rickyk/p/3875084.html):

De forma predeterminada, CMake agregará RPATH relevante a su exe, y puede agregar algunos RPATH que no desea (es decir, donde Cmake cree que su programa debe ir para encontrar la biblioteca dinámica requerida, puede usar "readelf -d su programa" para ver, ejemplo:

[raíz] readelf -d /opt/bin/ceph-osd

La sección dinámica en el desplazamiento 0x10a36e8 contiene 59 entradas:
  Tipo de etiqueta Nombre/Valor
 0x0000000000000001
 (NECESARIO) Biblioteca compartida: [libstdc++.so.6]
 0x0000000000000001 (NECESARIO) Biblioteca compartida: [libm.so.6] 0x0000000000000001
 (NECESARIO) Biblioteca compartida : [libgcc_s.so.1]
 0x0000000000000001 (NECESARIO) Biblioteca compartida: [libc.so.6]  0x000000000000000f (RPATH) Biblioteca rpath: [/opt/lib_upgrade/osd:/opt/lib:/opt/lib_upgrade/ceph-common :/opt/lib:/opt/lib/ceph:/opt/lib/ceph/erasure-code:/opt/lib/ceph/compressor:/opt/lib/ceph/crypto:/opt/lib/rados-classes :/opt/lib_upgrade_reserve/ceph]  0x000000000000000c (INIT) 0x34ffe0
 0x0000000000000001 (NECESARIO) Biblioteca compartida: [ld-linux-x86-64.so.2]


 0xddee2c
……

Después de una revisión cuidadosa, descubrí que hay tres variables RPATH importantes mantenidas en CMake, a saber, CMAKE_SKIP_RPATH, CMAKE_SKIP_BUILD_RPATH y CMKAE_INSTALL_RPATH.

CMAKE_SKIP_RPATH, en pocas palabras, obliga a CMake a no agregar el RPATH que piensa durante la construcción e instalación (no escriba el elemento RUNPATH en la biblioteca dinámica).

cmake .. -DCMAKE_SKIP_RPATH=TRUE o agregar set(CMAKE_SKIP_BUILD_RPATH TRUE) a CMakelist

   La segunda y la tercera variables también son relativamente simples, es decir, CMake no puede agregarle RPATH relevante durante la construcción y la instalación, respectivamente.

cmake .. -DCMAKE_SKIP_BUILD_RPATH=TRUE 或CMakelist中加set(CMAKE_SKIP_BUILD_RPATH=TRUE)
cmake .. -DCMAKE_SKIP_INSTALL_RPATH=TRUE 或CMakelist中加set(CMAKE_SKIP_INSTALL_RPATH=TRUE)

Por supuesto, si desea agregar RPATH más tarde, solo necesita establecer estas tres variables en FALSO.

Habla sobre CMake y RPATH() nuevamente https://www.cnblogs.com/rickyk/p/3884257.html Habla sobre CMake y RPATH() nuevamente :
 

Para facilitar la instalación del usuario, CMake eliminará y eliminará automáticamente el RPATH relevante después de hacer la instalación por defecto.Si tenemos un directorio en el entorno operativo: ${CMAKE_INSTALL_PREFIX}/lib, esperamos que después de ejecutar make install, RPATH podemos agregarlo automáticamente, podemos escribir

set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) 

Cabe señalar que esta variable es una variable global, lo que significa que la RPATH de todos sus objetivos se escribirá así al instalar. ¿Es simple 

para un determinado objetivo? lo he pensado
set_target_properties(myexe PROPIEDADES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

De esta manera, se puede garantizar que el RPATH se escribe solo cuando se realiza la instalación para el objetivo actual.

(Extensión: El RPATH del archivo ejecutable que se ha generado se puede modificar con la herramienta patchelf [linux] El programa no encuentra la solución de la librería dinámica .so|Ver información de la librería dinámica .so|librería dinámica cargando order_linux- vdso.so .1 No se puede encontrar el blog de bandaoyu - blog de CSDN )

#Especifique la ruta de la biblioteca dinámica al vincular

###################################################################################################################
set(OPENCV_DYNAMIC_LIBS  "${CMAKE_CURRENT_SOURCE_DIR}/../lib")       # 动态 opencv native 库路径
add_library(libopencv_core SHARED IMPORTED )
set_target_properties(libopencv_core PROPERTIES   IMPORTED_LOCATION "${OPENCV_DYNAMIC_LIBS}/libopencv_core.so")
add_library(libopencv_highgui SHARED IMPORTED )
set_target_properties(libopencv_highgui PROPERTIES   IMPORTED_LOCATION "${OPENCV_DYNAMIC_LIBS}/libopencv_highgui.so")
add_library(libopencv_imgproc SHARED IMPORTED )
set_target_properties(libopencv_imgproc PROPERTIES   IMPORTED_LOCATION "${OPENCV_DYNAMIC_LIBS}/libopencv_imgproc.so")
add_library(libopencv_video SHARED IMPORTED )
set_target_properties(libopencv_video PROPERTIES   IMPORTED_LOCATION "${OPENCV_DYNAMIC_LIBS}/libopencv_video.so")

set(mOpenCV_LIBS  libopencv_core libopencv_highgui  libopencv_imgproc libopencv_video)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
target_link_libraries(main ${mOpenCV_LIBS} )

Similar a lo anterior, agregue todas las bibliotecas requeridas, y puede encontrar la biblioteca en la ruta personalizada lib al vincular

Linux cmake especifica la ruta del enlace de la biblioteca dinámica de compilación/tiempo de ejecución: https://blog.csdn.net/JCYAO_/article/details/102519998

set_target_properties La sintaxis para establecer propiedades de destino es enumerar todos los archivos que desea cambiar y luego proporcionar los valores que desea establecer a continuación.

set_target_properties:https://cmake.org/cmake/help/v3.0/command/set_target_properties.html?highlight=set_target_properties

cmake primero irá al archivo .cmake especificado en *_DIR para encontrarlo, y luego irá a /usr para encontrarlo si no se puede encontrar

Así que tenga cuidado con los archivos que encuentra cmake para usted, si hay más de una biblioteca de versiones instalada en una computadora (o: compile múltiples versiones del código fuente y coloque la biblioteca en el directorio público del entorno).

¿Qué es RPATH?

程序运行时,搜索动态库的顺序(优先级)优先级是这样的:

1. RPATH ,编译链接时加入 -rpath 参数 指定的目录
2. LD_LIBRARY_PATH  这个环境变量指定的目录
3. /etc/ld.so.conf 配置文件。
4. /usr/lib 、 /lib 和 /usr/local/lib ,系统默认路径。

#En realidad, en el entorno Linux, los programas  que usan enlaces dinámicosld.so primero se vincularán a  esta biblioteca (en OS X  dyld) y luego se usarán  ld.so para buscar y vincular otras bibliotecas.

Cmake y RPATH

Después de implementar el programa en la máquina, la biblioteca dinámica de la que depende el programa puede no existir en el sistema de la máquina, o la versión que viene con él es incorrecta, por lo que la biblioteca de enlaces de la que depende generalmente se incluye en el programa. carpeta, por lo que es mejor poner  RPATH plus.

Cmake proporciona una gran cantidad de soporte de opciones para RPATH, generalmente solo nos enfocamos en estas variables:

CMAKE_SKIP_BUILD_RPATH (es decir, no agregue el RPATH que Cmake considera en el archivo ejecutable)
CMAKE_BUILD_WITH_INSTALL_RPATH (vaya a INSTALL_RPATH para buscar al vincular la biblioteca dinámica al compilar)
CMAKE_INSTALL_RPATH (el valor de INSTALL_RPATH anterior, use esta configuración)
CMAKE_INSTALL_RPATH_USE _LINK_PATH (use el valor de LINK_PATH a INSTALL_RPATH)

No use la configuración predeterminada de RPATH de Cmake, más RPATH completo

La configuración predeterminada de RPATH de Cmake es la siguiente:

set(CMAKE_SKIP_BUILD_RPATH FALSE)            # FALSE-->设定编译时加上要RPATH
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)    # FALSE-->编译时RPATH不使用INSTALL_RPATH
set(CMAKE_INSTALL_RPATH "")                  # 设置INSTALL_RPATH为空
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) # FALSE-->INSTALL_RPATH不使用LINK_PATH,安装的执行文件不加上RPATH

De forma predeterminada, Cmake   eliminará  el make install archivo de ejecución instalado  (es decir, si el archivo de ejecución busca la biblioteca dinámica), por lo que habrá un problema de notificación de errores cuando ejecute el archivo de ejecución instalado anteriormente.RPATHRPATH

Definitivamente no podemos usar la configuración predeterminada de Cmake , y también debemos traer la configuración cuando necesitemos instalar  RPATH .

set(INSTALL_LIB_DIR "${PROJECT_BINARY_DIR}/lib") # 假设安装目录在编译目录的lib子目录内
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# 确保链接库不在 系统默认安装的目录 上时更改到项目lib上

list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES ${CMAKE_INSTALL_RPATH} isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
set(CMAKE_INSTALL_RPATH "${INSTALL_LIB_DIR}")
endif("${isSystemDir}" STREQUAL "-1")

cmake instalación y configuración de empaquetado

//Al ejecutar make install, coloque static_lib en bin

install(OBJETIVOS static_lib DESTINO bin)

// También puedes usar variables

install(OBJETIVOS static_lib DESTINO ${tu_ruta})

//También puede especificar varios objetos a la vez y especificar el destino de la entrada por tipo

install(TARGETS static_lib shared_lib exe //static_lib shared_lib exe estos tres objetos
            RUNTIME DESTINATION bin //Los archivos ejecutables se colocan en binel directorio
            LIBRARY DESTINATION lib //Los archivos de biblioteca compartidos se colocan en libel directorio
            ARCHIVE DESTINATION lib) //Los archivos de biblioteca estática se colocan en libel directorio

El primer parámetro del comando TARGETSespecifica la lista de objetivos de compilación que deben instalarse, que pueden ser archivos de biblioteca estática, archivos de biblioteca dinámica y archivos ejecutables; durante la instalación, a menudo se instalan en diferentes subdirectorios según el tipo de archivo, como como archivos de biblioteca en el directorio, libarchivo ejecutable enbin el directorio.

Los diferentes tipos de archivos, como ( RUNTIMEARCHIVELIBRARY, PUBLIC_HEADER), se pueden configurar por separado, como especificar la ruta de instalación ( DESTINATION) y configurar los permisos de archivo ( PERMISSIONS); si no es una configuración separada en una determinada categoría, entonces es para todos los tipos .

Vale la pena mencionar que ARCHIVEgeneralmente se refiere a bibliotecas estáticas, LIBRARYpero se refiere a bibliotecas compartidas. Existen ligeras diferencias en diferentes plataformas. Si la aplicación real no cumple con las expectativas, solo consulte la documentación oficial y el problema no es grande.

Ver el artículo para más detalles:

aplicación cmake: instalación y embalaje: https://zhuanlan.zhihu.com/p/377131996

CMakeLists.txt comentarios de una sola línea y comentarios de varias líneas

Comentarios de una sola línea : use "#" Comentarios de varias líneas : use "#[[ ]]" La siguiente figura es un ejemplo

inserte la descripción de la imagen aquí

PRIVADO, PÚBLICO, INTERFAZ diferencia en target_link_libraries

Las dependencias de la biblioteca son:

aplicación-->libbar.so-->libfoo.so

opciones de enlace bar aplicación
PRIVADO pasar foo barra entrante
INTERFAZ no pasa en foo pasar en bar, pasar en foo
PÚBLICO pasar foo pasar en bar, pasar en foo

Opciones de enlace: PRIVADO, INTERFAZ, PÚBLICO: https://zhuanlan.zhihu.com/p/493493849

La mayoría de las explicaciones sobre PRIVADO, PÚBLICO e INTERFAZ en target_link_libraries en Internet son incorrectas, y no es un error general, es una tontería. Debido a que estos tres atributos tienen diferentes significados cuando se usan en diferentes comandos, muchos de ellos se copian de target_include_libraries.

El escenario principal para la siguiente explicación es que en Linux, esta relación no existe en Windows, por lo que no hay necesidad de considerarla.

Expliquemos, supongamos que tenemos un programa A, A llama a la biblioteca B y B llama a la biblioteca C. 

A -> B -> C

No importa si el enlace A B es privado o público. Después de todo, A no necesita exportar símbolos y nadie lo llama a través de la API.

Ahora la pregunta principal es si usar la biblioteca privada o pública para la biblioteca de B. C es una biblioteca dinámica.

Si B es una biblioteca dinámica o estática y C es una biblioteca dinámica, este problema tendrá un impacto. De manera similar, si B y C son bibliotecas estáticas, habrá problemas. 

B usa el enlace privado C, en este momento A enlaza B, pero no conoce la relación entre B->C, normalmente puede enlazar B. En tiempo de ejecución, cuando A->B->C, B no puede encontrar la función en C . No existe una relación de dependencia directa en Linux, todas las dependencias de B/C se transferirán a A, lo que se puede verificar con el comando LDD. En este momento, A solo depende de B, no de C. Cuando una función en B llama a función en C, debido a que C no está cargado, se informa un error de símbolo que no se puede encontrar. La solución es escribir también C cuando A vincula a B. Pero por razones privadas, A no conoce los símbolos en C, por lo que solo se puede resolver forzando la vinculación de C con A.

Si se usa la instrucción pública cuando B enlaza C, al compilar A se comprobará que los símbolos en C no están implementados, y entonces sabrás que necesitas enlazar C con A para solucionar este problema.

De hecho, privado/público resuelve el problema de la instrucción, que puede resolverse usando público en esencia, lo que puede reducir las trampas.

La siguiente es la explicación en target_link_libraries. Si no quiere leer en inglés, simplemente llévelo hasta el final.

Herencia de enlaces

De manera similar, para cualquier objetivo, en la etapa de vinculación, tendríamos que decidir, dado el elemento que se vinculará, si tenemos que colocar el elemento en las dependencias del enlace, o la interfaz del enlace, o ambos, en el objetivo compilado. Aquí, las dependencias de enlace significan que el elemento tiene algunas implementaciones que usaría el objetivo, y está vinculado al elemento, de modo que cada vez que llamemos a las funciones o métodos correspondientes a esas implementaciones, siempre se asignará correctamente a las implementaciones en el elemento a través de la enlace, mientras que la interfaz de enlace significa que el objetivo se convierte en una interfaz para vincular el elemento para otros objetivos que tienen dependencias en el objetivo, y el objetivo no tiene que usar el elemento en absoluto.

Tipo de enlace Descripción
PUBLIC Todos los objetos que siguen a PUBLIC se utilizarán para enlazar con el objetivo actual y proporcionar la interfaz a los otros objetivos que tienen dependencias en el objetivo actual.
PRIVADO Todos los objetos que siguen a PRIVADO solo se utilizarán para vincular al objetivo actual.
INTERFAZ Todos los objetos que siguen a INTERFACE solo se utilizarán para proporcionar la interfaz a los otros objetivos que tienen dependencias en el objetivo actual.
Por ejemplo, si la biblioteca de frutas tiene la implementación de funciones, como el tamaño y el color, y la biblioteca de manzanas tiene una función tamaño_manzana que llamó al tamaño de la biblioteca de frutas y se vinculó de forma PRIVADA con la biblioteca de frutas. Podríamos crear un ejecutable eat_apple que llame a apple_size mediante un enlace PÚBLICO o PRIVADO con la biblioteca de Apple. Sin embargo, si queremos crear un ejecutable eat_apple que llama el tamaño y el color de la biblioteca de frutas, solo vincular con la biblioteca de Apple provocará un error de construcción, ya que la biblioteca de frutas no formaba parte de la interfaz en la biblioteca de Apple y, por lo tanto, es inaccesible para eat_apple. Para hacer que la biblioteca de manzanas herede el tamaño y el color de la biblioteca de frutas, tenemos que vincular la biblioteca de manzanas a la biblioteca de frutas PÚBLICA en lugar de PRIVADA.

Lo siguiente está traducido en dialecto humano (chino):

PÚBLICO La biblioteca detrás de público se vinculará a su objetivo, y los símbolos que contiene también se exportarán para que los usen terceros.

PRIVADO La biblioteca detrás de privado solo está vinculada a su objetivo y finalizada, el tercero no puede percibir qué biblioteca ha ajustado

INTERFAZ La biblioteca importada después de la interfaz no se vinculará a su destino, solo se exportarán los símbolos.

---- renovar----------

target_link_libraries generará rpath en el programa de destino, tenga en cuenta esto.

Enlace original: https://blog.csdn.net/znsoft/article/details/119035578

Supongo que te gusta

Origin blog.csdn.net/Vincent20111024/article/details/129327542
Recomendado
Clasificación