【cmake】CMakeList添加库|添加头文件|添加路径|add_executable、add_library、target_link_libraries|添加编译选项|宏开关

2023-05-16

目录

官网查阅

开胃菜例子

CMakeLists生成和添加依赖库

CMakeLists更多小例子

生成.so共享库文件

调用.so共享库文件

生成一个可执行程序的 CMakeList

生成一个.so动态库的 CMakeList 

add_library(生成库),target_link_libraries(生成目标连接的库),set_target_properties

CMAKE 添加编译选项|-g编译参数/选项

包含文件的的目录include_directories

优化项|优化等级

Cmake设置优化等级| cmake 生成 debug和 release 版

设置默认构建类型

CMake设置编译参数/选项

如何在cmakelists中加入-ldl编译选项

CMake指定gcc,g++版本编译

CMake 关闭警告的方法

关闭编译器优化

CMakeLists 实现动态宏开关

去掉编译优化

CMake--List用法

CmakeLists.txt单行注释和多行注释 

CMakeList 通配符

其他未归类

add_custom_target  自定义命令

add_dependencies 

Cmake条件判断指令|if 判断优先级

设置编译时和程序运行时去哪个目录找动态库

#指定运行时动态库的加载路径

#指定链接时动态库的路径

cmake install 和打包设定

CMakeLists.txt单行注释和多行注释

target_link_libraries 中的PRIVATE, PUBLIC, INTERFACE 区别


作者:bandaoyu,持续更新,链接:https://blog.csdn.net/bandaoyu/article/details/115165199

官网查阅

CMake 3.22.0-rc1文档:https://cmake.org/cmake/help/latest/search.html?q=add_library

https://cmake.org/cmake/help/v3.23/manual/cmake-commands.7.html

 CMake Cookbook:《CMake菜谱(CMake Cookbook中文版)》 :https://www.bookstack.cn/read/CMake-Cookbook/content-preface-preface-chinese.md

开胃菜例子

CMakeLists生成和添加依赖库

原文;cmake之生成动态库:https://www.cnblogs.com/pandamohist/p/13408455.html

1、目录结构


│  CMakeLists.txt
│  index.txt
│  
├─build
├─include
│      hello.h
│      hi.h
│      
└─src
        hello.cxx
        hi.cxx  

2、CMakeLists.txt


cmake_minimum_required(VERSION 3.1)

#项目名
project(libhello)

# 1、指定库的目录变量
set(libhello_src src/hello.cxx)
# 指定头文件搜索路径
include_directories("${PROJECT_SOURCE_DIR}/include")



# 2、添加库(对应的两个项目)
add_library( hello_shared SHARED ${libhello_src})
add_library( hello_static STATIC ${libhello_src})
#  按照一般的习惯,静态库名字跟动态库名字应该是一致的,只是扩展名不同;
# 即:静态库名为 libhello.a; 动态库名为libhello.so ;
# 所以,希望 "hello_static" 在输出时,不是"hello_static",而是以"hello"的名字显示,故设置如下
# SET_TARGET_PROPERTIES (hello_static PROPERTIES OUTPUT_NAME "hello")


# 3、cmake在构建一个新的target时,会尝试清理掉其他使用这个名字的库,
# 因此,在构建libhello.a时,就会清理掉libhello.so.
# 为了回避这个问题,比如再次使用SET_TARGET_PROPERTIES定义 CLEAN_DIRECT_OUTPUT属性。
SET_TARGET_PROPERTIES (hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES (hello_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1)


# 4、按照规则,动态库是应该包含一个版本号的,
# VERSION指代动态库版本,SOVERSION指代API版本。
SET_TARGET_PROPERTIES (hello_static PROPERTIES VERSION 1.1 SOVERSION 1)
SET_TARGET_PROPERTIES (hello_shared PROPERTIES VERSION 1.1 SOVERSION 1)


# 5、若将libhello.a, libhello.so.x以及hello.h安装到系统目录,才能真正让其他人开发使用,
# 本例中,将hello的共享库安装到<prefix>/lib目录;
# 将hello.h安装<prefix>/include/hello目录。
#INSTALL (TARGETS hello hello_shared LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
#INSTALL (TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
#INSTALL (FILES hello.h DESTINATION include/hello)  

3、configure and generate


xxx/to/path

cd build
cmake ..
  

4、其他设置

  若需要指定输出路径,尝试下面的示例指令:


# 设置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 ${CMAKE_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)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/Bin)  

CMakeLists更多小例子

生成.so共享库文件


下面是我的几个文件:

1hello.cpp

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


2hello.hpp

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


3 main.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)


上面CmakeLists.txt里面, 共享库的名称是calculate_shared,这个是我们可以自己更改的。生成的可执行文件是main, 这个名称也是可以更改的。

不过需要注意的是,hello.cpp里面不用在包含hello.hpp 了。(汗,因为这个导致出错,提示说是重复定义函数了);

编译生成:

mkdir build
cd    build
cmake ..
make
我们就可以看到build生成了 如下的文件:

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

 libcalculate_shared.so就是生成的共享库文件。

他们的路径是:/home/fan/dev/cmake/4-exer/

下面有build文件夹,以及main.cpp, hello.cpp, hello.hpp, 

build文件夹下面有共享库 libcalculate_shared.so.so

调用共享库文件


所有的外部依赖库都是这样的,比如opencv ,openni, eigen等等,原理是一样的,只不过他们已经安装在系统里面了,可以查找,而这个则是需要我们自己去配置。

即我上面生成的共享库文件本质上和opencv的库是相同的。只不过这个共享库需要自己手动配置。

比如我又新建了一个工程,需要调用上面的共享库 libcalculate_shared.so。

main.cpp如下:

//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;
}


那么在CMakeLists.txt里面,我需要告诉CMake, 这个头文件可以在哪里找到,头文件所定义的函数又可以在哪里找到。

上面hello.hpp的路径是:/home/fan/dev/cmake/4-exer/hello.hpp

libcalculate_shared.so的路径是/home/fan/dev/cmake/4-exer/build/libcalculate_shared.so

则CMakeLists.txt如下:

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})


这里要注意一些细节(对于我这个渣渣来说的)

1、${   }这种形式代表一个变量,比如上面的,HELLO_INCLUE ,就是我自己定义的一个变量。

2、头文件包含到头文件所在的文件夹,即 /home/fan/dev/cmake/4-exer/

3、共享库要指明具体的共享库 ,精确到.so

其实主要的就是指明这个调用这个共享库的时候,使用的头文件,以及共享库本身所在的位置,然后包含链接就可以了。

安装过的共享库(例如opencv)就不用这么麻烦了,因为它的地址都放在了变量里面。

Opencv的依赖添加
比如Opencv, 它的头文件和.so文件都已经放在了系统变量里面,不用向上面自己定义了(上面例子里面的头文件和共享库文件的地址都是我自己设置的)

它的CMakeLists.txt如下:

find_package(OpenCV REQUIRED)

include_directories(${OPENCV_INCLUDE_DIRS})

target_link_libraries(MAIN ${OpenCV_LIBS})

只需要查找就可以了,OpenCV_LIBS  和  OPENCV_INCLUDE_DIRS  都是系统帮我们已经定义好的,所以比较容易

参考博客:

1、如何写自己的CmakeLists.txt   https://www.cnblogs.com/chaofn/p/10160555.html

2、 【OpenCV】使用CMake链接自己路径下面的OpenCV库 https://blog.csdn.net/twt520ly/article/details/81981473

原文链接:https://blog.csdn.net/qq_37761077/article/details/88750711

生成一个可执行程序的 CMakeList

#添加包含文件的的目录
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}) 

生成一个.so动态库的 CMakeList 

#用${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
)


原文链接:https://blog.csdn.net/bandaoyu/article/details/115165199

grep -nR  "common"  ./  --include=*.txt|grep -vE "src_bak|boost|erasure-code|doc|link.txt"

add_library(生成库),target_link_libraries(生成目标连接的库),set_target_properties

生成静态库:

add_library(libsugan ${SRC_LISTS})    #用${SRC_LISTS}生成静态库libsugan

ADD_LIBRARY(static_lib STATIC ${DIR_SUB_SRCS})

生成动态库(加SHARED  ):
add_library(libsugan  SHARED  ${SRC_LISTS})    #用${SRC_LISTS}生成动态库libsugan

target_link_libraries(libsugan      #生成静态库libsugan还需链接依赖库${OpenCV_LIBS}…
    ${OpenCV_LIBS}
    ${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so
    ${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
)

#上面的配置生成名字为libsugan的静态库,但Linux下对库的存储格式是lib+name.a,所以库libsugan存储出来的结果就是liblibsugan.a,看着很别扭。用下面这句,保证了存储出来的静态库叫做libsugan.a:

set_target_properties(libsugan PROPERTIES OUTPUT_NAME "sugan")

#但是请千万注意,在整个CmakeLists.txt里

#如果想链接生成的这个库必须使用    “add_library(libsugan ${SRC_LISTS})”指明的名字。
set_target_properties(libsugan PROPERTIES OUTPUT_NAME "sugan")

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

连接库:

target_link_libraries(demo libsugan)

target_link_libraries(app libsort.a)  #生成app 链入 libsort.a静态库

TARGET_LINK_LIBRARIES(app libsort.a)

原例子:

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
)


原文链接:https://blog.csdn.net/michaelhan3/article/details/69568362

CMAKE 添加编译选项|-g编译参数/选项

add_definitions 和add_compile_options,二者添加的编译选项是针对所有编译器的(包括c和c++编译器)。

add_definitions 和add_compile_options的区别是:

add_definitions 可用于添加任何标志,但旨在添加预处理器定义。

此命令已被替代方案取代:
使用 add_compile_definitions() 添加预处理器定义。
使用 include_directories() 添加包含目录。
使用 add_compile_options() 添加其他选项。

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

添加 -g编译参数/选项

方法一:add_definitions("-g")/ add_compile_options


在文件 CMakeLists.txt添加下面一条语句
add_definitions("-g")

添加其他编译参数/选项

例如下面的代码

#判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持

if(CMAKE_COMPILER_IS_GNUCXX)
    add_compile_options(-std=c++11)
    message(STATUS "optional:-std=c++11")   
endif(CMAKE_COMPILER_IS_GNUCXX)
 



使用add_compile_options添加-std=c++11选项,是想在编译c++代码时加上c++11支持选项。但是因为add_compile_options是针对所有类型编译器的,所以在编译c代码时,就会产生如下warning

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

虽然并不影响编译,但看着的确是不爽啊,要消除这个warning,就不能使用add_compile_options,而是只针对c++编译器添加这个option。

方法二:set

所以如下修改代码,则警告消除。

#判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持
if(CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
    message(STATUS "optional:-std=c++11")   
endif(CMAKE_COMPILER_IS_GNUCXX)


原文链接:https://blog.csdn.net/qinglongzhan/article/details/80743731

包含文件的的目录include_directories

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

add_definitions 可用于添加任何标志,但旨在添加预处理器定义。

此命令已被替代方案取代:
使用 add_compile_definitions() 添加预处理器定义。
使用 include_directories() 添加包含目录。
使用 add_compile_options() 添加其他选项。

优化项|优化等级

更多和详细解释:https://blog.csdn.net/bandaoyu/article/details/123700034

-O0禁止编译器进行优化。默认为此项。
-O1尝试优化编译时间和可执行文件大小。

-O2更多的优化,会尝试几乎全部的优化功能,但不会进行“空间换时间”的优化方法。

-O3在 -O2 的基础上再打开一些优化选项:-finline-functions, -funswitch-loops 和 -fgcse-after-reload 。

-Os对生成文件大小进行优化。它会打开 -O2 开的除了会那些增加文件大小的全部选项。

可以通过下面的命令查找工程中设置优化项的地方:

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

过滤掉含有 build、boost、erasure-code、doc、link.txt字样的结果

grep -nR  "\-O"  ./  --include=*.txt|grep  -vE  "build|src_bak|boost|erasure-code|doc|link.txt"

Cmake设置优化等级| cmake 生成 debug和 release 版

见文章:

https://blog.csdn.net/bandaoyu/article/details/123700034

    CMake 中有一个变量 CMAKE_BUILD_TYPE ,可以的取值是 Debug 、Release、 RelWithDebInfo 和 MinSizeRel。

当这个变量值为 Debug 的时候,CMake 会使用变量 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_C_FLAGS_DEBUG 中的字符串作为编译选项生成 Makefile ,

当这个变量值为 Release 的时候,工程会使用变量 CMAKE_CXX_FLAGS_RELEASE 和 CMAKE_C_FLAGS_RELEASE 选项生成 Makefile。

提供的级别为:

  • Release - Adds the -O3 -DNDEBUG flags to the compiler
  • Debug - Adds the -g flag
  • MinSizeRel - Adds -Os -DNDEBUG
  • RelWithDebInfo - Adds -O2 -g -DNDEBUG flags


链接: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.txt: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:CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMakeCache.txt:153:CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMakeCache.txt:156:CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG

 

cmake设置默认CMAKE_BUILD_TYPE

原文:[CMake] Set default build type in CMakeLists.txt

CMakeLists.txt里写入

IF (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING
        "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
ENDIF()

设置默认构建类型

CMake提供的默认构建类型是不包含用于优化的编译器标志。对于某些项目,您可能需要设置默认生成类型,以便不必记住设置它。
为此,您可以将以下内容添加到CMakeLists.txt文件顶层

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message("Setting build type to 'RelWithDebInfo' as none was specified.")
  set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
  # Set the possible values of build type for cmake-gui
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
    "MinSizeRel" "RelWithDebInfo")
endif()


作者:xingxingRealzyx
链接:https://www.jianshu.com/p/d761232e8e90

CMake设置编译参数/选项

而set命令设置CMAKE_C_FLAGS或CMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器的

对c编译器的

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

针对c++编译器的

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

如何在cmakelists中加入-ldl编译选项

cmakelists.txt中,在增加可执行程序后增加TARGET_LINK_LIBRARIES
eg:
add_executable(xx ${ALL_F} ${WE_F})
TARGET_LINK_LIBRARIES(dl)
TARGET_LINK_LIBRARIES(m)

set(CMAKE_C_FLAGS "-ldl")

在add_executable(${PROJECT_NAME} "main.cpp")后面添加
target_link_libraries(${PROJECT_NAME} dl)

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

CMake指定gcc,g++版本编译

系统默认的gcc/g++在/usr/bin目录下。

我们升级安装的gcc目录在/usr/local/bin目录下,现在我们希望使用升级后的gcc。

通过百度搜索出来的结果,大多是如下操作:

在CMakeLists.txt中调用编译器之前添加:

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

然而经过本人亲自实践,该方法不起作用(没有删掉build里面的东西重新cmake的原因?),正确的做法是:

执行cmake命令之前,在shell终端先设置如下两个变量:

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

可能还需要

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

/usr/local/gcc-xxx/lib 是你的新gcc的lib位置

然后再执行cmake等后续命令,这样就可以用指定的编译器版本了。

vim ~/.bashrc  source ~/.bashrc

CMake 关闭警告的方法

在CMakeLists.txt中添加add_definitions(-w)

应用于单个target

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

应用于所有target

  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()
  

注意:为GCC或/ WX添加-Werror以便MSVC将所有警告视为错误。这会将所有警告视为错误。这对于新项目来说可以方便地执行严格的警告。

另外, -Wall 并不意味着"所有错误";从历史意义上讲,它意味着"每个人都可以达成一致的所有错误""。从 -Wall -Wextra 开始,然后仔细阅读您的版本的GCC手册,并找到 else 编译器可以为您提供关于警告的信息。

CMake和编译器警告 https://www.it1352.com/784160.html

关闭编译器优化

(未验证)

1)add_compile_options(-fno-elide-constructors)    #关闭编译器优化

2)set(CMAKE_CXX_FLAGS "-fno-elide-constructors ${CMAKE_CXX_FLAGS}")

CMakeLists 实现动态宏开关

去掉编译优化

在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")

执行的时候

cmake  -DCMAKE_BUILD_TYPE=Release

也可以在上一层(调用本CMakeList.txt的)的CMakeList.txt中添加下面:

option (CMAKE_BUILD_TYPE "Use tutorial provided math implementation"  ON)

表示启用CMAKE_BUILD_TYPE 宏。

option (CMAKE_BUILD_TYPE "Use tutorial provided math implementation"  OFF) #表示关

参考:

《c++ - Optimize in CMake by default 》:https://stackoverflow.com/questions/41361631/optimize-in-cmake-by-default

《How to compile without optimizations -O0 using CMake》:https://unix.stackexchange.com/questions/187455/how-to-compile-without-optimizations-o0-using-cmake

例子

最近在工作中需要通过一份C代码控制逻辑走向,网上找了一下资料,发现可以通过在CMakeLists文件中动态定义宏开关,从而能够达到编译出不同逻辑流的代码。

具体步骤:

首先,我在src代码里编写了若干debug的输出:

#IFDEF DEBUG
 
    some print command;
 
#ENDIF
然后,在CMakeLists文件中添加DEBUG的定义:

IF (CMAKE_BUILD_TYPE STREQUAL DEBUG)
    ADD_DEFINITIONS(-DDEBUG)
ENDIF()
最后,在cmake的时候设置参数 -DCMAKE_BUILD_TYPE 为 DEBUG:

$ cmake .. -DCMAKE_BUILD_TYPE=DEBUG
$ make -j4
这样再运行可执行文件时就会打印出some print command的debug信息了。如果不想看到debug信息,只需在参数中不设置DEBUG参数,或者将DEBUG参数设置为其它值即可(以下两种方式二者选其一):

$ cmake ..
$ cmake .. -DCMAKE_BUILD_TYPE=RELEASE
到此 CMakeLists 实现动态宏开关介绍完成。

原文链接:https://blog.csdn.net/qq_19734597/article/details/104461963

CMake--List用法

CMake--List用法 :https://www.cnblogs.com/narjaja/p/8343765.html

CmakeLists.txt单行注释和多行注释 

单行注释:使用“#”
多行注释:使用“#[[ ]]”

在这里插入图片描述

CMakeList 通配符

  $<TARGET_OBJECTS:A>:

说明:

$<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>),表示使用 test.cc和构建A产生的对象 联合编译出test。

add_executable(test2   $<TARGET_OBJECTS:A>  $<TARGET_OBJECTS:B> ),表示使用构建A产生的对象  和 构建B产生的对象 联合编译出test。

例子:某个工程如下

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

使用 CMake 使用命令编译 test.cc
add_executable(test test.cc $<TARGET_OBJECTS:A>)

使用的A.o 的编译为
add_library(A   OBJECT  A.cc)

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

其他未归类

add_custom_target  自定义命令

https://www.bookstack.cn/read/CMake-Cookbook/content-chapter5-5.4-chinese.md

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
    )

定义了一个自定义命令: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

单独执行命令的方式是: cmake --build <dir> [<options>] [-- <build-tool-options>]

cmake --build  /home/mydir   --target   finish

与 add_executable(main main.cpp) 、add_library(mylib mylib.cpp) 的不同是,这两个会生成(产出)main、mylib文件。add_custom_target(comandname  ……)只会执行列出的操作,不会产生comandname文件

add_dependencies 

如果main 依赖a.so b.so TARGET_LINK_LIBRARIES(main a.so b.so c.so d.so) 

而a.so b.so 的生成晚于main(即编译脚本的顺序把a.so b.so 安排在后面编译),则需要ADD_DEPENDENCIES(main a.so b.so) 提前为main编译a.so b.so,否则可能会报错:符号的定义找不到 (这些符号恰恰就在a.so 和 b.so中)

详情见:https://blog.csdn.net/KingOfMyHeart/article/details/112983922

mark_as_advanced  

mark_as_advanced  将CMake 的缓存变量标记为高级。

mark_as_advanced([CLEAR|FORCE] VAR VAR2 VAR...)
将缓存的变量标记为高级变量。其中,高级变量指的是那些在CMake GUI中,只有当“显示高级选项”被打开时才会被显示的变量。如果CLEAR是第一个选项,参数中的高级变量将变回非高级变量。如果FORCE是第一个选项,参数中的变量会被提升为高级变量。如果两者都未出现,新的变量会被标记为高级变量;如果这个变量已经是高级/非高级状态的话,它将会维持原状。
该命令在脚本中无效。

原文链接:https://blog.csdn.net/hankern/article/details/120376405

Cmake条件判断指令|if 判断优先级

cmake(十六)Cmake条件判断指令:https://blog.csdn.net/wzj_110/article/details/116105719

一  基础语法

①  基本框架

②  优先级

③  条件的类型

cmake变量的使用

set(myVar foo) # Local myVar

set(result ${myVar}) # result = foo 

http://t.csdn.cn/uF1II

设置编译时和程序运行时去哪个目录找动态库

#指定运行时动态库的加载路径


SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)  #Use the install path for the RPATH
SET(CMAKE_INSTALL_RPATH   "\${ORIGIN}/lib" )     #The rpath to use for installed targets.

https://cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_RPATH.html?highlight=cmake_install_rpath

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

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

所以我们设置了RPATH ,并且RPATH 下有要找的动态库,程序就首先加载它

注意:

可以看到,RPATH与RUNPATH中间隔着LD_LIBRARY_PATH。为了让用户可以通过修改LD_LIBRARY_PATH来指定.so文件,大多数编译器都将输出的RPATH留空,并用RUNPATH代替RPATH。

linux cmake分别指定编译/运行时动态库链接路径:https://blog.csdn.net/JCYAO_/article/details/102519998



探讨CMake中关于RPATH的使用(https://www.cnblogs.com/rickyk/p/3875084.html):

CMake在默认情况下是会给你的exe加入相关RPATH的,可能给你加入你不想要的一些RPATH(就是一些Cmake认为的你的程序应该去哪里寻找需要的动态库的目,可以用“readelf -d 你的程序”来查看,例子:

[root]readelf -d  /opt/bin/ceph-osd

Dynamic section at offset 0x10a36e8 contains 59 entries:
  Tag        Type                         Name/Value
 ……
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [ld-linux-x86-64.so.2]
 0x000000000000000f (RPATH)              Library 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
 0x000000000000000d (FINI)               0xddee2c
……

仔细查阅寻找之后发现,CMake里面维护了3个比较重要的RPATH变量,即CMAKE_SKIP_RPATH,CMAKE_SKIP_BUILD_RPATH,CMKAE_INSTALL_RPATH.

CMAKE_SKIP_RPATH,简单说,就是强制CMake不在构建期间安装install期间给你加上它所认为的RPATH.(不在动态库中写入RUNPATH项)


cmake .. -DCMAKE_SKIP_RPATH=TRUE或CMakelist中加set(CMAKE_SKIP_BUILD_RPATH TRUE)  

   第二个和第三个变量也比较简单,就是分别在构建期间安装期间不允许CMake给你加入相关RPATH

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)

当然了,如果你之后想要追加RPATH,只需要对这三个变量设置成FALSE就可以了。

再谈CMake与RPATH()https://www.cnblogs.com/rickyk/p/3884257.html再谈CMake与RPATH():
 

CMake为了方便用户的安装,默认在make install之后会自动remove删除掉相关的RPATH,如果我们在运行环境上有个目录:${CMAKE_INSTALL_PREFIX}/lib,我们希望执行make install 之后,RPATH可以自动添加它,我们就可以这么写


set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)

需要注意的是,这个变量是全局变量,意味着你所有的target的RPATH都会在install的时候被写成这个

有没有简单的针对某个target呢,聪明的你应该已经想到了  

set_target_properties(myexe PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")  

这样就可以保证只针对当前的target进行make install的时候RPATH的写入了。

(扩展:已经生成的可执行文件的RPATH可以用patchelf  工具修改https://blog.csdn.net/bandaoyu/article/details/113181179)

#指定链接时动态库的路径

###################################################################################################################
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} )

类似上面,添加好所有需要的库,链接的时候就能找得到自定义路径lib下面的库了

linux cmake分别指定编译/运行时动态库链接路径:https://blog.csdn.net/JCYAO_/article/details/102519998

set_target_properties 设置目标属性语法是列出您要更改的所有文件,然后提供您接下来要设置的值。

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

cmake会先到*_DIR里指定.cmake文件里去找找不到了才会到/usr里去找

所以要小心cmake给你找的文件,如果在一台电脑里装了不止一个版本库(或:多个版本的源码编译后把库放到环境公共目录下)。

什么是RPATH?

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

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

#其实在Linux环境下,使用动态链接的程序会先链接 ld.so 这个库(OS X上是 dyld),然后通过 ld.so 来查找链接其它的库。

Cmake和RPATH

部署程序到机器上后,程序依赖的动态库 机器上的系统内不一定会有,或者自带了的版本不对,所以一般会在程序文件夹内附带其依赖的链接库,所以最好还是把 RPATH 加上。

Cmake对RPATH提供了很多选项支持,我们一般只关注这几个变量就好了:

CMAKE_SKIP_BUILD_RPATH  (就是不在 可执行文件里面添加Cmake自认为的 RPATH)
CMAKE_BUILD_WITH_INSTALL_RPATH (build的时候连接动态库时去INSTALL_RPATH下去找
CMAKE_INSTALL_RPATH (上面的INSTALL_RPATH的值,就用这个啦设置
CMAKE_INSTALL_RPATH_USE_LINK_PATH (用LINK_PATH的值给INSTALL_RPATH

不使用Cmake默认RPATH设置,加上完整的RPATH

Cmake默认RPATH设置是这样的:

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

Cmake在默认情况下, make install 会把安装的执行文件的 RPATH 删掉的(即执行文件搜索动态库是不是去RPATH 找),所以就会出现上面我执行安装好的执行文件报错的问题。

Cmake的默认设置我们肯定是不能使用的,我们需要安装的时候也要带上 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 install 和打包设定

//执行make install的时候 把static_lib  放到bin

install(TARGETS  static_lib  DESTINATION  bin)

//也可以使用变量

install(TARGETS  static_lib  DESTINATION  ${your_path})

//还可以一次指定多个对象,并按类型指定放入的目的地

install(TARGETS static_lib shared_lib exe  //static_lib shared_lib exe 这个三个对象
            RUNTIME DESTINATION bin  //可执行文件放在bin目录
            LIBRARY DESTINATION lib     //共享库文件放在lib目录
            ARCHIVE DESTINATION lib)  //静态库文件放在lib目录

命令第一个参数TARGETS指定需要安装的构建目标的列表,可以是静态库文件、动态库文件、可执行文件;安装时常常按照文件类型安装到不同的子目录,比如库文件放在lib目录,可执行文件放在bin目录。

针对不同文件类型,比如(RUNTIMEARCHIVELIBRARYPUBLIC_HEADER),可以分开进行配置,比如分别指定安装路径(DESTINATION)、设置文件权限(PERMISSIONS);如果不是在某个类别下的单独配置,那么就是针对所有类型。

值得一提的是,ARCHIVE一般是指静态库,LIBRARY则是指共享库,在不同平台上,略有差异,实际应用感觉不符合预期时查看一下官方文档即可,问题不大。

更多详情见文章:

cmake应用:安装和打包:https://zhuanlan.zhihu.com/p/377131996

CMakeLists.txt单行注释和多行注释

单行注释:使用“#”多行注释:使用“#[[ ]]”以下图为例

在这里插入图片描述

target_link_libraries 中的PRIVATE, PUBLIC, INTERFACE 区别

库的依赖关系为:

app-->libbar.so-->libfoo.so

链接选项barapp
PRIVATE传入foo传入bar
INTERFACE不传入foo传入bar,传入foo
PUBLIC传入foo传入bar,传入foo

链接选项:PRIVATE,INTERFACE,PUBLIC :https://zhuanlan.zhihu.com/p/493493849

网上关于 target_link_libraries 中的 PRIVATE, PUBLIC , INTERFACE  的解释大部分是错的,而且不是一般的错,是胡说。 因为这三个属性在不同的命令中使用时意义不同,有很多是从target_include_libraries中抄来的。

以下的解释主要场景是linux中,windows不存在这种关系,无需考虑。

我们来解释下,假设我们有一个程序 A  , A调用库B, B调用库C. 

A -> B -> C

A link B时不管是private还是public都没关系,毕竟A不需要导出符号,也没有人以API方式调用它。

现在主要问题就是B这个库用private还是public.  C是动态库。

如果B是动态或静态库,C是动态库,这个问题就会有影响。同样,如果B、C同为静态库时也会有问题。 

B用private link C,  此时A link B,但是不知道B->C这层关系,可以正常link B. 运行时,A->B->C 时,B找不到C中的函数。linux下没有直接依赖关系,所有的B/C的依赖都会转到到A下,可以用LDD命令验证,此时A只依赖于B, 不见C, 当B中的函数调用C中的函数时,因为没有加载C, 所以报找不到符号错误。解决的办法就是在A link B时,同样也写上C. 但是因为private的原因,A是不知道C中的符号这事,只能强制 link C到A才能解决。

如果B link C时用public 指示, 当编译A时,就会检查到C中的符号没有实现,此时你就会知道要把C link到A来解决这个问题了。

其实private/public 解决的是指示问题,本质上可以使用public 来解决, 可以减少坑。

下面是target_link_libraries中的解释,不想看英文的,直接拉到最后。

Link Inheritance

Similarly, for any target, in the linking stage, we would need to decide, given the item to be linked, whether we have to put the item in the link dependencies, or the link interface, or both, in the compiled target. Here the link dependencies means the item has some implementations that the target would use, and it is linked to the item, so that whenever we call the functions or methods corresponding to those implementations it will always be mapped correctly to the implementations in item via the link, whereas the link interface means the target becomes an interface for linking the item for other targets which have dependencies on the target, and the target does not have to use item at all.

Link Type    Description
PUBLIC    All the objects following PUBLIC will be used for linking to the current target and providing the interface to the other targets that have dependencies on the current target.
PRIVATE    All the objects following PRIVATE will only be used for linking to the current target.
INTERFACE    All the objects following INTERFACE will only be used for providing the interface to the other targets that have dependencies on the current target.
For example, if the fruit library has the implementation of functions, such as size and color, and the apple library has a function apple_size which called the size from the fruit library and was PRIVATE linked with the fruit library. We could create an executable eat_apple that calls apple_size by PUBLIC or PRIVATE linking with the apple library. However, if we want to create an executable eat_apple that calls the size and color from the fruit library, only linking with the apple library will cause building error, since the fruit library was not part of the interface in the apple library, and is thus inaccessible to eat_apple. To make the apple library to inherit the size and color from the fruit library, we have to make the linking of the apple library to the the fruit library PUBLIC instead of PRIVATE.

下面用人话(汉语)翻译下:

PUBLIC    在public后面的库会被Link到你的target中,并且里面的符号也会被导出,提供给第三方使用。

PRIVATE  在private后面的库仅被link到你的target中,并且终结掉,第三方不能感知你调了啥库

INTERFACE   在interface后面引入的库不会被链接到你的target中,只会导出符号。

---- 更新----------

target_link_libraries 会在目标程序中生成rpath, 这点请注意 。

原文链接:https://blog.csdn.net/znsoft/article/details/119035578

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【cmake】CMakeList添加库|添加头文件|添加路径|add_executable、add_library、target_link_libraries|添加编译选项|宏开关 的相关文章

  • rt-thread内核启动分析

    1 项目准备 上一节的基本环境 如rh thread 基本环境的搭建 硬件材料stm32f103C8T6 以及st link rt thread 内核启动官网分析 在分析rt thread代码的时候 由于rt thread的代码是十分优秀的
  • 达梦数据库sql语句记录

    登入 在ubuntu上安装好达梦数据 xff0c 并且生成实例 xff0c 在ubuntu上进行安装目录 xff0c 采用在tools目录下 xff0c 使用 disql进行命令行模式 xff0c 连接服务器 xff1a Conn sysd
  • vertx web开发(一)

    vertx web开发 最近在开发中 xff0c 由于spring 的大而全 xff0c 反而不实用于一下小项目 xff0c 因为spring boot在空载的情况 xff0c 至少其内存占用超过150M 而对于一些简单的项目反到不适用 而
  • kotlin协程实现原理

    传统runnable接口实现 在java中 xff0c 很多耗时的行为通过实现runnable接口 xff0c 并且通过线程运行下这些耗时的任务 xff0c 例如 xff1a span class token keyword public
  • PCL---RANSAC随机采样一致性算法

    前言 通过前面的文章 xff0c 我们基本上代建的相关环境 本文将继续基于此继续学习PCL相关采样一致性算法 基础代码下载 1 准备 1 1 Ransac算法介绍 RANSAC从样本中随机抽选出一个样本子集 xff0c 使用最小方差估计算法
  • PCL-使用potree可视化

    前言 在几篇文章中 xff0c 基本实现了对PCL相关操作 xff0c 最近在github上找到了Web端对点云数据可视化兼容很好的项目 Potree 对此本文将介绍如何使用Potree来进行web端的可视化 1 Potree 官方运行 P
  • PCL- Las文件处理

    前言 在对点云数据处理的时候 xff0c 很多时候激光雷达扫描的文件不一定是 pcd文件 xff0c 这个时候需要进行相关文件处理 xff0c 如Las xff0c laz e57等文件格式 xff0c 本文将介绍las文件的读写 1 引入
  • PCL-Window下安装

    1 安装编译工具链MSVC MSVC工具链是visual studio 自带的工具链 xff0c 因此安装visual studio社区版即安装完成相应的MSVC工具链 2 安装Clion 相比与Visual studio的界面来说 xff
  • STM32 串口详细讲解

    什么是串口 UART Universal Asynchronous Receiver Transmitter 通用异步收发器 USART Universal Synchronous Asynchronous Receiver Transmi
  • ubuntu 修改pip指定路径

    参考这篇文章 还有 这篇文章 第二篇更好一点 xff0c 亲测成功
  • CrowdHuman数据集介绍

    CrowdHuman数据集是旷世发布的用于行人检测的数据集 xff0c 图片数据大多来自于google搜索 CrowdHuman 数据集数据量比较大 xff0c 训练集15000张 xff0c 测试集5000张 xff0c 验证集4370张
  • CityPersons数据集介绍

    CityPersons数据集是cityscape的一个子集 xff0c 它只包含个人注释 有2975张图片用于培训 xff0c 500张和1575张图片用于验证和测试 一幅图像中行人的平均数量为7人 xff0c 提供了可视区域和全身标注 C
  • CUHK-SYSU数据集介绍

    该数据集是一个大规模的人员搜索基准 xff0c 包含18184张图像和8432个身份 根据图像来源 xff0c 数据集可以分为两部分 xff1a 街道捕捉和电影 xff1a 在街拍中 xff0c 图像通过手持摄像机收集 xff0c 跨越数百
  • ETHZ数据集介绍

    Ess等构建了基于双目视觉的行人数据库用于多人的行人检测与跟踪研究 该数据库采用一对车载的AVT Marlins F033C摄像头进行拍摄 xff0c 分辨率为640 480 xff0c 帧率13 14fps xff0c 给出标定信息和行人
  • Swin Transformer V2

    Swin Transformer V2 论文链接 xff1a https arxiv org pdf 2111 09833 pdf 代码链接 xff1a https github com microsoft Swin Transformer
  • Jetson_Xavier_NX使用教程1(刷机)

    刷机教程 一 xff1a 准备 1 xff1a 准备需要一个tf卡 xff0c 容量最好大点 xff0c 我买的128G的 2 xff1a 还有两个软件一个是格式化卡的软件 xff0c 一个是将镜像文件写入的卡的软件 格式化卡的软件 写入镜
  • Jetson_Xavier_NX使用教程2(简单实用)

    本文会介绍一些刷机后的基本操作 1 风扇控制 刚开始插入电源风扇不转我以外坏了 xff0c 后来才发现并没有 Xavier NX的风扇在系统内核中有一套自动控制温度和转速的算法 xff0c 经过我观察大约在40度左右的时候会自动开启风扇进行
  • NVIDIA Jetson NX使用教程3配置pytorch环境

    本节主要记录 xff0c 安装pytorch及torch vision 1 下载Pytorch 因为jetson属于arm架构的机器 xff0c 所以需要去nvidia的官网下载对应的安装包而不是pytroch的官网 官网链接 xff0c
  • Java 基于 IETF RFC 2617 身份认证

    IETF RFC 2617 身份认证 是基于 HTTP 协议进行验证的 xff0c 认证过程中需要发送两次 HTTP 请求 xff0c 第一次请求服务器返回 401 和 认证标识 xff08 nonce xff09 xff0c 第二次访问H
  • 判断一台机器是大端序还是小端序

    在几乎所有的机器上 xff0c 多字节对象都被存储为连续的字节序列 例如在C语言中 xff0c 一个类型为int的变量x地址为0x100 xff0c 那么其对应地址表达式 amp x的值为0x100 且x的四个字节将被存储在存储器的0x10

随机推荐

  • STL容器保存智能指针并将this指针通过emplace传入STL容器所造成的致命问题(【double free or corruption (out)】和【bad_weak_ptr】)

    我用std queue保存了一个Message类型的智能指针 queue lt shared ptr lt MessageA gt xff0c 然后在Message类型中来将this指针插入队列 xff0c 使用std queue push
  • 实时动态定位(RTK)

    内容来着网络 实时动态定位 xff1a Real Time Kinematic RTK技术的关键在于使用了GPS的载波相位观测量 xff0c 并利用了参考站和移动站之间观测误差的空间相关性 xff0c 通过差分的方式除去移动站观测数据中的大
  • 几个实用的 Bat 脚本命令

    文章目录 1 截图2 息屏后锁屏3 查看当前的路径4 倒计时5 密码输入6 比较两个文本的差异 1 截图 start snippingtool 2 息屏后锁屏 powershell Add Type 39 DllImport 34 user
  • 学习cmake的使用和CMakeLists.txt

    1 学习cmake的使用和CMakeLists txt 文章目录 1 学习cmake的使用和CMakeLists txt1 1 cmake外部构建基础1 2 让每个源文件目录都包含一个CMakeLists txt1 3 安装 1 4 构建静
  • ROS系统基础知识梳理(四) 串口通信

    ROS系统基础知识梳理 四 串口通信 学习ROS系统 xff0c 初步接触到ROS系统外接传感器 xff0c 传感器通过Uart通信向台式机发送数据 xff0c 内容涉及到ROS调用串口数据 串口数据校验 以及欧拉角转换四元数 任务系统 x
  • Keil5中添加新的.c和.h文件

    目录 在Project的文件夹中添加添加路径使用include 在Project的文件夹中添加 如图1所示 xff0c 在User的文件夹上右键 xff0c 添加已有文件 图1 添加路径 然后需要在options for Target xf
  • 学习c语言的总结

    学习时间 xff1a 早上9点 晚上9点 学习内容 xff1a 利用c语言对 的代码学习 xff0c 并根据自己的理解编写代码 xff0c 最后整合学习的代码和自己理解的代码 xff0c 编写出更优的代码 学习体会 xff1a 对一个问题举
  • C/C++程序编译成可执行程序步骤图文源码详解

    一个C 43 43 程序被编译为目标程序的过程中经历了四个部分 xff0c 分别是预处理 编译 汇编 链接 下面将通过一个简单的C 43 43 代码分别执行预处理 编译 汇编 链接四个步骤后的结果和基本原理讲解 注意 xff1a 博主是在u
  • 【linux】程序找不到动态库.so的解决办法|查看.so动态库信息|.so动态库加载顺序

    目录 找不到 so解决方法 方法一 xff1a 添加环境变量 方法二 xff1a 复制so文件到lib路径 方法三 xff1a xff08 推荐 xff09 添加ldconfig寻找路径 方法四 xff1a 在编译目标代码时指定该程序的动态
  • 使用Arduino开发ESP32(08):TCP Client与TCP Server使用

    文章目录 目的TCP Client使用说明常用方法基础使用演示作为WEB Client使用 TCP Server使用说明常用方法基础使用演示作为WEB Server使用 总结 目的 TCP是网络应用中常用的功能 xff0c 很多高级功能也是
  • ModBus学习笔记

    一 什么是ModBus xff1f 1 预备知识 xff08 1 xff09 什么是通讯协议 xff1f 通信协议是指双方实体完成通信或服务所必须遵循的规则和约定 通过通信信道和设备互连起来的多个不同地理位置的数据通信系统 xff0c 要使
  • Jetson TX2 将系统迁移到SD卡,系统文件修改方式

    系统迁移步骤 xff1a 格式化SD卡 复制系统到SD卡 修改系统文件 1 在原系统盘内 cd boot extlinux sudo vim extlinux conf 该文件初始内容如下 xff1a TIMEOUT 30 DEFAULT
  • svn中打标签的一种方法

    SVN创建标签的方法 方法一 xff1a TortoiseSVN客户端浏览创建 选中需要创建标签的目录 xff0c 右键 gt copy to 在弹出框中输入新建标签所在的URL地址 xff0c 填写log信息 xff0c 确定 方法二 x
  • (图解 HTTP)一篇文章带你深入了解 HTTP 协议

    文章目录 一 了解客户端和服务器通讯的过程二 HTTP 是不保存状态的协议三 请求 URI 定位资源四 告知服务器意图的 HTTP 方法1 GET xff1a 获取资源2 POST xff1a 传输实体主体3 PUT xff1a 传输文件4
  • VC编译选项

    C 在预处理输出中保留注释语句 c 只编译 xff0c 不连接 xff0c 相当于在 34 Build 34 菜单下选择了 34 Compile 34 D 定义常量和宏 xff0c 与源程序里的 define 有相同效果 E 预处理C C
  • C语言中String库函数

    为了以后学习以及查阅方便 xff0c 转贴在此 xff0c 若有雷同 xff0c 敬请包含 文中内容摘自 C程序设计教程 xff08 美 xff09 H M Deitel P J Deitel著 xff0c 薛万鹏等译 xff0c 机械工业
  • JAVA与海康威视人脸机对接,使用ISUP方式

    1下载DEMO包 下载地址 JAVA海康威视人脸机isup方式对接demo包 Java文档类资源 CSDN下载 2设置依赖 需要把examples jar和jna jar引入项目 3配置本地 config properties 把ip地址设
  • Keil工程

    文章目录 1 Keil工程添加源文件和头文件 xff08 c和 h xff09 的方法1 方式一2 方式二 2 keil工程生成的MAP文件取消优化 1 Keil工程添加源文件和头文件 xff08 c和 h xff09 的方法 1 方式一
  • 2020-09-28

    通用异步收发器 xff08 Universal Asynchronous Receiver Transmitter xff0c 通常称作UART xff0c 是一种串行 异步 全双工的通信协议 xff0c 在嵌入式领域应用的非常广泛 UAR
  • 【cmake】CMakeList添加库|添加头文件|添加路径|add_executable、add_library、target_link_libraries|添加编译选项|宏开关

    目录 官网查阅 开胃菜例子 CMakeLists生成和添加依赖库 CMakeLists更多小例子 生成 so共享库文件 调用 so共享库文件 生成一个可执行程序的 CMakeList 生成一个 so动态库的 CMakeList add li