CMake 用法导览

2023-11-15

原文地址:http://www.cnblogs.com/coderfenghc/archive/2013/01/20/2846621.html


Preface : 本文是CMake官方文档CMake Tutorial (http://www.cmake.org/cmake/help/cmake_tutorial.html) 的翻译。通过一个样例工程从简单到复杂的完善过程,文档介绍了CMake主要模块(cmake, ctest, cpack)的功能和使用环境;从中可以一窥cmake的大体形貌。正文如下:

     本文下述内容是一个手把手的使用指南;它涵盖了CMake需要解决的公共构建系统的一些问题。这些主题中的许多主题已经在Mastering CMake一书中以单独的章节被介绍过,但是通过一个样例工程看一看它们如何工作也是非常有帮助的。本指南可以在CMake源码树的Tests/Tutorial路径下找到。每一步都有它自己的子路径,其中包含该步骤的一个完整的指南。

作为基础的起始点(步骤1)
  最基本的工程是一个从源代码文件中构建可执行文件的例子。对于简单工程,只要一个两行的CMakeLists文件就足够了。这将会作为我们指南的起点。这份CMakeLists文件看起来像是这样:

1
2
3
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
add_executable(Tutorial tutorial.cxx)

  注意到这个例子在CMakeLists文件中使用了小写。CMake支持大写、小写、混合大小写的命令。tutorial.cxx中的源代码用来计算一个数的平方根,并且它的第一版非常简单,如下所示:

// A simple program that computes the square root of a number
// 计算一个数的平方根的简单程序
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int  main ( int  argc, char  *argv[])
{
   if  (argc < 2)
     {
     fprintf (stdout, "Usage: %s number\n" ,argv[0]);
     return  1;
     }
   double  inputValue = atof (argv[1]);
   double  outputValue = sqrt (inputValue);
   fprintf (stdout, "The square root of %g is %g\n" ,
           inputValue, outputValue);
   return  0;
}

      我们添加的第一个特性用来为工程和可执行文件指定一个版本号。虽然你可以在源代码中唯一指定它,但是你在CMakeLists文件中指定它可以提供更好的灵活性。如下所示,我么可以通过添加一个版本号来修改CMakeLists文件:

cmake_minimum_required (VERSION 2.6)
project (Tutorial)
# 版本号
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
# 配置一个头文件,通过它向源代码中传递一些CMake设置。
configure_file (
   "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
   "${PROJECT_BINARY_DIR}/TutorialConfig.h"
   )
# 将二进制文件树添加到包含文件的搜索路径中,这样我们可以找到TutorialConfig.h
include_directories( "${PROJECT_BINARY_DIR}" )
# 添加可执行文件
add_executable(Tutorial tutorial.cxx)

      由于配置过的文件将会被写到二进制文件目录下,我们必须把该目录添加到包含文件的搜索路径清单中。然后,以下的代码就可以在源目录下创建一份TotorialConfig.h.in文件:

1
2
3
// 与tutorial相关的配置好的选项与设置;
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

      当CMake配置这份头文件时,@Tutorial_VERSION_MAJOR@和@Tutorial_VERSION_MINOR@的值将会被从CMakeLists文件中传递过来的值替代。下一步,我们要修改tutorial.cxx来包含configured头文件然后使用其中的版本号。修改过的源代码展列于下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 计算平方根的简单程序。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
  
int  main ( int  argc, char  *argv[])
{
   if  (argc < 2)
     {
     fprintf (stdout, "%s Version %d.%d\n" ,
             argv[0],
             Tutorial_VERSION_MAJOR,
             Tutorial_VERSION_MINOR);
     fprintf (stdout, "Usage: %s number\n" ,argv[0]);
     return  1;
     }
   double  inputValue = atof (argv[1]);
   double  outputValue = sqrt (inputValue);
   fprintf (stdout, "The square root of %g is %g\n" ,
           inputValue, outputValue);
   return  0;
}

引入库(步骤2)

     现在我们将会在我们的工程中引入一个库。这个库会包含我们自己实现的计算一个数的平方根的函数。可执行文件随后可以使用这个库文件而不是编译器提供的标准开平方函数。在本指南中,我们将会把库文件放到一个子目录MathFunctions中。它包含下述的单行CMakeLists文件:

1
add_library(MathFunctions mysqrt.cxx)

     源文件mysqrt.cxx有一个叫做mysqrt的函数,它提供了与编译器的sqrt函数类似的功能。为了使用新的库,我们在顶层的CMakeLists中增加一个add_subrirectory调用,这样这个库也会被构建。我们也要向可执行文件中增加另一个头文件路径,这样就可以从MathFunctions/mysqrt.h头文件中找到函数的原型。最后的一点更改是在向可执行文件中引入新的库。顶层CMakeLists文件的最后几行现在看起来像是这样:

1
2
3
4
5
include_directories ( "${PROJECT_SOURCE_DIR}/MathFunctions" )
add_subdirectory (MathFunctions)
# 引入可执行文件
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial MathFunctions)

  现在,让我们考虑下让MathFunctions库变为可选的。在本指南中,确实没有必要这样画蛇添足;但是对于更大型的库或者依赖于第三方代码的库,你可能需要这种可选择性。第一步是为顶层的CMakeLists文件添加一个选项:

1
2
3
# 我们应该使用我们自己的数学函数吗?
option (USE_MYMATH
         "Use tutorial provided math implementation"  ON)

  这将会在CMake的GUI中显示一个默认的ON值,并且用户可以随需改变这个设置。这个设置会被存储在cache中,那么用户将不需要在cmake该工程时,每次都设置这个选项。第二处改变是,让链接MathFunctions库变为可选的。要实现这一点,我们修改顶层CMakeLists文件的结尾部分:

1
2
3
4
5
6
7
8
9
# 添加MathFunctions库吗?
if  (USE_MYMATH)
   include_directories ( "${PROJECT_SOURCE_DIR}/MathFunctions" )
   add_subdirectory (MathFunctions)
   set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
# 添加可执行文件
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})

  这里用USE_MYMATH设置来决定是否MathFunctions应该被编译和执行。注意到,要用一个变量(在这里是EXTRA_LIBS)来收集所有以后会被连接到可执行文件中的可选的库。这是保持带有许多可选部件的较大型工程干净清爽的一种通用的方法。源代码对应的改变相当直白,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 计算一个数平方根的简单程序
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
#include "MathFunctions.h"
#endif
  
int  main ( int  argc, char  *argv[])
{
   if  (argc < 2)
     {
     fprintf (stdout, "%s Version %d.%d\n" , argv[0],
             Tutorial_VERSION_MAJOR,
             Tutorial_VERSION_MINOR);
     fprintf (stdout, "Usage: %s number\n" ,argv[0]);
     return  1;
     }
  
   double  inputValue = atof (argv[1]);
  
#ifdef USE_MYMATH
   double  outputValue = mysqrt(inputValue);
#else
   double  outputValue = sqrt (inputValue);
#endif
  
   fprintf (stdout, "The square root of %g is %g\n" ,
           inputValue, outputValue);
   return  0;
}

  在源代码中,我们也使用了USE_MYMATH。这个宏是由CMake通过TutorialConfig.h.in配置文件中的下述语句行提供给源代码的:

1
#cmakedefine USE_MYMATH

安装与测试(步骤3)
  下一步我们会为我们的工程引入安装规则以及测试支持。安装规则相当直白,对于MathFunctions库,我们通过向MathFunctions的CMakeLists文件添加如下两条语句来设置要安装的库以及头文件:

1
2
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

  对于应用程序,在顶层CMakeLists文件中添加下面几行,它们用来安装可执行文件以及配置头文件:

1
2
3
4
# 添加安装目标
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"       
          DESTINATION include)

  这就是要做的全部;现在你应该可以构建tutorial工程了。然后,敲入命令make install(或者从IDE中构建INSTALL目标)然后它就会安装需要的头文件,库以及可执行文件CMake的变量CMAKE_INSTALL_PREFIX用来确定这些文件被安装的根目录。添加测试同样也只需要相当浅显的过程。在顶层CMakeLists文件的的尾部补充许多基本的测试代码来确认应用程序可以正确工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 应用程序是否运行?
add_test (TutorialRuns Tutorial 25)
 
# 它是否对25做了开平方运算
add_test (TutorialComp25 Tutorial 25)
  
set_tests_properties (TutorialComp25
   PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5" )
 
# 它是否能处理是负数作为输入的情况
add_test (TutorialNegative Tutorial -25)
set_tests_properties (TutorialNegative
   PROPERTIES PASS_REGULAR_EXPRESSION "-25 is 0" )
 
# 它是否可以处理较小的数字。
add_test (TutorialSmall Tutorial 0.0001)
set_tests_properties (TutorialSmall
   PROPERTIES PASS_REGULAR_EXPRESSION "0.0001 is 0.01" )
 
# 用法信息是否可用?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage
   PROPERTIES
   PASS_REGULAR_EXPRESSION "Usage:.*number" )

  第一个测试用例仅仅用来验证程序可以运行,没有出现段错误或其他的崩溃,并且返回值必须是0。这是CTest所做测试的基本格式。余下的几个测试都是用PASS_REGULAR_EXPRESSION 测试属性来验证测试代码的输出是否包含有特定的字符串。在本例中,测试样例用来验证计算得出的平方根与预定值一样;当指定错误的输入数据时,要打印用法信息。如果你想要添加许多测试不同输入值的样例,你应该考虑创建如下所示的宏:

1
2
3
4
5
6
7
8
#定义一个宏来简化添加测试的过程,然后使用它
macro (do_test arg result)
   add_test (TutorialComp${arg} Tutorial ${arg})
   set_tests_properties (TutorialComp${arg}
     PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)<br># 做一系列基于结果的测试
do_test (25 "25 is 5" )
do_test (-25 "-25 is 0" )

  对于每个do_test宏调用,都会向工程中添加一个新的测试用例;宏参数是测试名、函数的输入以及期望结果。

增加系统内省(步骤4)

  下一步,让我们考虑向我们的工程中引入一些依赖于目标平台上可能不具备的特性的代码。在本例中,我们会增加一些依赖于目标平台是否有log或exp函数的代码。当然,几乎每个平台都有这些函数;但是对于tutorial工程,我们假设它们并非如此普遍。如果该平台有log函数,那么我们会在mysqrt函数中使用它去计算平方根。我们首先在顶层CMakeLists文件中使用宏CheckFunctionExists.cmake测试这些函数的可用性:

1
2
# 该系统提供log和exp函数吗?<br>include (CheckFunctionExists.cmake)
check_function_exists ( log  HAVE_LOG)<br>check_function_exists ( exp  HAVE_EXP)

  下一步,如果CMake在对应平台上找到了它们,我们修改TutorialConfig.h.in来定义这些值;如下:

// 该平台提供exp和log函数吗?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

  这些log和exp函数的测试要在TutorialConfig.h的configure_file命令之前被处理,这一点很重要。最后,在mysqrt函数中,如果log和exp在当前系统上可用的话,我们可以提供一个基于它们的可选的实现:

1
2
3
// 如果我们有log和exp两个函数,那么使用它们<br>#if defined (HAVE_LOG) && defined (HAVE_EXP)
   result = exp ( log (x)*0.5);
#else // 否则使用替代方法

添加一个生成文件以及生成器(步骤5)
  在本节,我们会展示你应该怎样向一个应用程序的构建过程中添加一个生成的源文件。在本范例中,我们会创建一个预先计算出的平方根表作为构建过程的一部分。MathFunctions子路径下,一个新的MakeTable.cxx源文件来做这件事。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 一个简单的用于构建平方根表的程序
#include <stdio.h>
#include <stdlib.h><br>#include <math.h>
  
int  main ( int  argc, char  *argv[])
{
   int  i;
   double  result;
  
   // 确保有足够多的参数
   if  (argc < 2)
     {
     return  1;
     }
   
   // 打开输出文件
   FILE  *fout = fopen (argv[1], "w" );
   if  (!fout)
     {
     return  1;
     }
   
   // 创建一个带有平方根表的源文件<br>  fprintf(fout,"double sqrtTable[] = {\n");
   for  (i = 0; i < 10; ++i)
     {
     result = sqrt ( static_cast < double >(i));
     fprintf (fout, "%g,\n" ,result);
     }
  
   // 该表以0结尾
   fprintf (fout, "0};\n" );
   fclose (fout);
   return  0;
}

  注意到这个表是由合法的C++代码生成的,并且被写入的输出文件的名字是作为一个参数输入的。下一步是将合适的命令添加到MathFunction的CMakeLists文件中,来构建MakeTable可执行文件,然后运行它,作为构建过程的一部分。完成这几步,需要少数的几个命令,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
# 首先,我们添加生成该表的可执行文件<br>add_executable(MakeTable MakeTable.cxx)
# 然后添加该命令来生成源文件
add_custom_command (
   OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
   COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
   DEPENDS MakeTable
   )
  
# 为包含文件,向搜索路径中添加二进制树路径
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
<br># 添加main库
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h  )

  首先,MakeTable的可执行文件也和其他被加入的文件一样被加入。然后,我们添加一个自定义命令来指定如何通过运行MakeTable来生成Table.h。这是通过将生成Table.h增加到MathFunctions库的源文件列表中来实现的。我们还必须增加当前的二进制路径到包含路径的清单中,这样Table.h可以被找到并且可以被mysqrt.cxx所包含。当该工程被构建后,它首先会构建MakeTable可执行文件。然后它会运行MakeTable来生成Table.h文件。最后,它会编译mysqrt.cxx(其中包含Table.h)来生成MathFunctions库。到目前为止,拥有我们添加的完整特性的顶层CMakeLists文件看起来像是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
  
# 版本号
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
 
# 本系统是否提供log和exp函数?
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
  
check_function_exists ( log  HAVE_LOG)
check_function_exists ( exp  HAVE_EXP)
 
# 我们应该使用自己的math函数吗?
option(USE_MYMATH
   "Use tutorial provided math implementation"  ON)
 
# 配置一个头文件来向源代码传递一些CMake设置。
configure_file (
   "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
   "${PROJECT_BINARY_DIR}/TutorialConfig.h"
   )
 
# 为包含文件的搜索路径添加二进制树,这样才能发现TutorialConfig.h头文件。
include_directories ( "${PROJECT_BINARY_DIR}" )
 
# 添加MathFunctions库吗?
if  (USE_MYMATH)
   include_directories ( "${PROJECT_SOURCE_DIR}/MathFunctions" )
   add_subdirectory (MathFunctions)
   set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
  
# 添加可执行文件
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})
  
# 添加安装的目标
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"       
          DESTINATION include)
  
# 测试1 :应用程序可以运行吗?
add_test (TutorialRuns Tutorial 25)
  
# 测试2 : 使用信息可用吗?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage
   PROPERTIES
   PASS_REGULAR_EXPRESSION "Usage:.*number"
   )
 
# 定义一个可以简化引入测试过程的宏
macro (do_test arg result)
   add_test (TutorialComp${arg} Tutorial ${arg})
   set_tests_properties (TutorialComp${arg}
     PROPERTIES PASS_REGULAR_EXPRESSION ${result}
     )
endmacro (do_test)
  
# do a bunch of result based tests
# 执行一系列基于结果的测试
do_test (4 "4 is 2" )
do_test (9 "9 is 3" )
do_test (5 "5 is 2.236" )<br>do_test (7 "7 is 2.645" )
do_test (25 "25 is 5" )
do_test (-25 "-25 is 0" )
do_test (0.0001 "0.0001 is 0.01" )

  TutorialConfig.h文件看起来像是这样:

// Tutorial的配置选项与设置如下
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
  
// 该平台提供exp和log函数吗?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

  然后,MathFunctions工程的CMakeLists文件看起来像是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 首先,我们添加生成这个表的可执行文件
add_executable(MakeTable MakeTable.cxx)
# 添加生成源代码的命令
add_custom_command (
   OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
   DEPENDS MakeTable
   COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
   )
# 为包含文件向搜索路径中添加二进制树目录
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
  
# 添加main库
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h)
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

构建一个安装器(步骤6)

  下一步假设我们想要向其他人分发我们的工程,这样他们就可以使用它。我们想同时提供在许多不同平台上的源代码和二进制文档发行版。这与之前我们在“安装与测试(步骤3)”做过的安装有一点不同,那里我们仅仅安装我们从源码中构建出来的二进制文件。在本例子中,我们会构建支持二进制安装以及类似于cygwin,debian,RPM等具有包管理特性的安装包。为了完成这个目标,我们会使用CPack来创建Packaging with CPack一章中描述的特定平台的安装器。

1
2
3
4
5
6
7
# 构建一个CPack驱动的安装包
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE
      "${CMAKE_CURRENT_SOURCE_DIR}/License.txt" )
set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}" )
set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}" )
include (CPack)

   需要做的全部事情就这些。我们以包含InstallRequiredSystemLibraries开始。这个模块将会包含许多在当前平台上,当前工程需要的运行时库。第一步我们将一些CPack变量设置为保存本工程的许可证和版本信息的位置。版本信息使用了我们在本指南中先前设置的变量。最后,我们要包含CPack模块,它会使用这些变量以及你所处的系统的一些别的属性,然后来设置一个安装器。下一步是以通常的方式构建该工程然后随后运行CPack。如果要构建一个二进制发行包,你应该运行:

1
cpack -C CPackConfig.cmake

  为了创建一个源代码发行版,你应该键入:

1
cpack -C CPackSourceConfig.cmake

增加对Dashboard的支持(步骤7)

  增加对向一个dashboard提交我们的测试结果的功能的支持非常简单。我们在本指南的先前步骤中已经定义了我们工程中的许多测试样例。我们仅仅需要运行这些测试样例然后将它们提交到dashboard即可。为了包含对dashboards的支持,我们需要在顶层CMakeLists文件中包含CTest模块。

1
2
# 支持dashboard脚本
include (CTest)

  我们也可以创建一个CTestConfig.cmake文件,在其中来指定该dashboard的工程名。

1
set (CTEST_PROJECT_NAME "Tutorial" )

   CTest 将会在运行期间读取这个文件。为了创建一个简单的dashboard,你可以在你的工程下运行CMake,然后切换到二进制树,然后运行ctest -DExperimental. 你的dashboard将会被更新到Kitware的公共dashboard.

 


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

CMake 用法导览 的相关文章

  • GDB调试工具命令速查

    1 生成调试信息 一般来说GDB主要调试的是C C 的程序 要调试C C 的程序 首先在编译时 我们必须要把调试信息加到可执行文件中 使用编译 gcc g 的 g 参数可以做到这一点 gcc g test c g g test cpp 如果
  • VS C++ 程序运行错误: 0xc0...07b错误等

    问题1的出现 找不到动态库 解决方式 这个问题就是你需要找到这个动态库 并且放到exe目录同级目录 问题2的出现 今天在使用动态库的时候发现了一点问题 就是我修改了我原来的库文件 当我在另外的项目中使用的时候 我只进行了lib库和头文件的替
  • [编程工具]使用NPIO(C#)读取xls,xlsx(Excel)表格

    目录 0 前言 1 NPIO 获取 2 NPIO 使用 1 打开 xlsx 2 XSSFWorkbook ISheet IRow ICell 3 样例 读取 xlsx 为字符列表 3 结束 0 前言 有些时候我们需要做一些小工具来来修改和读
  • [游戏开发]UGF 配表导出工具

    0 前言 整理一下 之前做的一个配表导出工具 主要作用就是将 excel 的内容导出为数据和代码 不用每次配表都重新处理 项目的源码还有exe 都上传到了百度云 链接如下 链接 https pan baidu com s 1xW9Rc cx
  • Sublime Text的安装与配置记录

    Sublime Text作为一款优质的Code编辑器 已更新至第4个版本 本文记录关于Sublime Text 4 版本4126 的安装 汉化 以及常用配置方法 安装 访问官网下载安装包 https www sublimetext com
  • 雪花算法(SnowFlake)

    简介 现在的服务基本是分布式 微服务形式的 而且大数据量也导致分库分表的产生 对于水平分表就需要保证表中 id 的全局唯一性 对于 MySQL 而言 一个表中的主键 id 一般使用自增的方式 但是如果进行水平分表之后 多个表中会生成重复的
  • C语言之详解静态变量static

    在C语言中static是用来修饰变量和函数的 这篇文章详细介绍了static主要作用 文章中有详细的代码实例 需要的朋友可以参考阅读 在C语言中 static是用来修饰变量和函数的 static主要作用为 1 修饰局部变量 静态局部变量 2
  • gdb调试教程

    gdb调试是c c 代码调试最重要的工具了 我们今天来系统熟悉一下 太长不看版 注意 如果针对cmake项目 需要把编译模式从release改成debug 否则无法定位到准确的行数 进入gdb debugger界面 gt gdb filen
  • Keil消除特定警告办法

    使用的是KEIL5 27版本 介绍两种消除警告的办法 1 屏蔽所有警告 这个功能感觉有点自欺欺人了 不过也记下来给需要的人使用 Keil gt Options gt C C gt Warmings 选择No Warmings 一键屏蔽所有警
  • Source Insight设置黑色背景

    今天使用Source Insight看C代码 觉得背景白色太亮 觉得应该可以调背景颜色 通过百度 搜索到了CSDN上的相关文章 受益良多 但是文章后面附的style文件下载需30积分 无奈囊中羞涩 只好自己按照文章的说明调颜色 首先将背景调
  • LLVM+clang+VS Code 搭建 C++ 编译环境(windows)

    可参考LLVM clang VS Code 搭建 C 编译环境 windows
  • TortoiseGit保存git的账号密码

    TortoiseGit保存git的账号密码 问题 电脑安装了git和TortoiseGit 但是每次commit pull push时都需要输入密码 而且是无限弹密码框 输入密码之后 还继续弹框 之前看了许多解决方案都不太行 例如 1 修改
  • 静态代码扫描工具汇总

    一 概述 在软件开发过程中 开发团队往往要花费大量的时间和精力发现并修改代码缺陷 传统的代码评审 同事复审 通过人工方式来检查缺陷仍然是一件耗时耗力的事情 而静态代码扫描工具能够在代码构建过程中帮助开发人员快速 有效的定位代码缺陷并及时纠正
  • CMake 用法导览

    原文地址 http www cnblogs com coderfenghc archive 2013 01 20 2846621 html Preface 本文是CMake官方文档CMake Tutorial http www cmake
  • 如何使用git send-email

    How to Use git send email 建议使用git send email发送补丁 更多关于发送补丁的信息请参考Community 本文介绍如何使用git send email 安装 send email 你的git可能已经安
  • 在IntelliJ IDEA上将WSDL生成Java代码

    最近接触了一个android项目 但是需要自己用webService的方法获取数据 而且只给了一个wsdl的地址 今天介绍如何利用wsdl生成Java客户端并且进行测试 一 安装一个IntelliJ IDEA Windows平台 自行选择x
  • [编程工具]MarkDown编辑查看以及使用语法

    目录 0 前言 1 markDown语法 2 markDown 3 MD正确打开方式 4 结尾 结束啦感谢观看 5 参考连接 0 前言 本文介绍了markDown的编辑查看 使用浏览器查看以及Vscode中查看编辑MD 最后介绍了MD的常用
  • Android Studio编译报错:sdk:minSdkVersion 1 cannot be smaller than version 7 declared in library

    背景 有一个以前的项目从Eclipse迁移到Android Studio 结果编译的时候报错如下 Error Execution failed for task lDrawer processDebugAndroidTestManifest
  • 基于C#的数据库文件管理助手

    我们经常会遇到这样的问题 在数据库中的文件存放的是web格式或者是绝对路径 以及使用的是百度上传或者其他上传组件 造成了很多异步上传的冗余文件 如果客户需要我们导出企业官网中的产品图片 我们该如何处理 很简单 当然是自己写个工具来读取 然后
  • Snipaste介绍、安装、使用技巧(截图贴图工具)

    一 简介 Snipaste 是一个简单但强大的截图贴图工具 也可以让你将截图贴回到屏幕上 下载并打开 Snipaste 按下 F1 来开始截图 再按 F3 截图就在桌面置顶显示了 就这么简单 你还可以将剪贴板里的文字或者颜色信息转化为图片窗

随机推荐

  • 简短的char*与char[]

    include
  • 这就是搜索引擎——索引压缩

    对于海量数据 建立倒排索引往往需要较大的磁盘空间 尤其是一些常见的单词 这些单词对应的倒排列表可能有几百兆 如果搜索引擎在相应用户查询的时候 用户查询包含了常见的单词 就需要将大量的倒排列表信息从磁盘读入内存 由于磁盘读写速度往往是个瓶颈
  • RLHF 技术:如何能更有效?又有何局限性?

    编者按 自ChatGPT推出后 基于人类反馈的强化学习 RLHF 技术便成为大模型构建和应用人员关注的热点 但该方法一些情况下效果却差强人意 有些基础模型经RLHF调优后反而表现更差 RLHF技术的适用性和具体操作细节似乎成谜 这篇文章探讨
  • 平板电脑黑苹果EFI_保姆级别教你安装黑苹果,提供大量EFI与工具驱动!

    最近无聊 在电脑上装了个黑苹果 可能是我的机型比较好找吧 安装的过程中没有遇到太大的问题 接下教大家安装 也为大家准备了大量的EFI N卡驱动 蓝牙驱动 键盘驱动等工具 需要工具的小伙伴可以点击此处 所需要工具 1 黑果镜像 2 U盘 3
  • Python音视频剪辑库MoviePy1.0.3中文教程导览及可执行工具下载

    前往老猿Python博文目录 一 简介 MoviePy是一个用于视频编辑的Python模块 可用于进行视频的基本操作 如剪切 拼接 标题插入 视频合成 也称非线性编辑 视频处理或创建高级效果 它可以读写最常见的视频格式 MoviePy能处理
  • Xshell连接Ubuntu详细过程

    一 打开虚拟机VMware 二 启动虚拟机 输入密码 进入Ubuntu系统界面 三 鼠标右键 选择 在终端打开 出现终端对话框 四 在命令行输入 sudo apt get install openssh server 安装openssh s
  • 2017校招Java开发笔试题集

    美丽联合 二分查找要求结点 A 有序 顺序存储 B 有序 链接存储 C 无序 顺序存储 D 无序 链接存储 答案选 A 引入线索二叉树的目的是 A 加快查找结点的前驱或后继结点的速度 B 为了能在二叉树中方便插入和删除 C 为了能方便找到双
  • 使用STM32CubeMx配置STM32输入捕获功能

    输入捕获原理 在输入捕获模式下 当检测到ICx信号上相应的边沿后 计数器的当前值被锁存到捕获 比较寄存 器 TIMx CCRx 中 当发生捕获事件时 相应的CCxIF标志 TIMx SR寄存器 被置1 如果开放 了中断或者DMA操作 则将产
  • tools:context=".MainActivity的作用

    http blog csdn net caiwenfeng for 23 article details 8373569
  • Spring AOP 的搭建与源码分析

    AOP 面向切面编程 一 AOP 概述 AOP 的实现步骤 示例 二 通过 EnableAspectJAutoProxy 了解 AOP 原理 1 分析 EnableAspectJAutoProxy 2 复习 Spring 容器启动后 bea
  • Jq手搓一个简易版分页器

    分页器的效果如下 1 分页器dom结构 前面要有你将渲染列表的dom结构 这里省略 div class news trends fy div class left img src imags nof icon left png 左箭头 di
  • python异步爬虫

    本文主要包括以下内容 线程池实现并发爬虫 回调方法实现异步爬虫 协程技术的介绍 一个基于协程的异步编程模型 协程实现异步爬虫 线程池 回调 协程 我们希望通过并发执行来加快爬虫抓取页面的速度 一般的实现方式有三种 线程池方式 开一个线程池
  • 2023华为od机试统一考试B卷【雨花石难题】

    题目描述 MELON是一个热爱雨花石的人 他拥有一堆数量为n的精美雨花石 每块石头的重量都不相同 现在 MELON想要将这些雨花石平均分给他的朋友S和W 以使两人所得到的石头的重量相等 你需要设计一个程序 来帮助MELON确认是否可以实现这
  • 近期思维片段

    1 感觉360这样的公司就是让少数明眼人讨厌 让大多数人不知不觉接受 2 点子 lt 我买了 gt 购物分享 把自己买过的经验分享出来 3 不要负面思维 No negative thinking 4 突然想起几年前那些熟悉的名字 现在都没有
  • js匹配数组中对应的值_JS 数组中查找符合条件的数据索引

    日常工作中经常会需要我们前端获取后端为我们传递的数据放在页面中渲染的问题 大批量的数据后端会根据具体的情况来放在数组中传递给我们 但是如果遇到数组中有需要特殊需要处理的数据怎么办 原来100个数据 渲染规则完全一致 这个时候我们用一个循环就
  • 阿里云服务器安装宝塔面板图文教程

    购买完云服务器ECS后 对于新手而言如何搭建Web环境是比较棘手的 分享一款简单易用的主机面板 宝塔面板 分享阿里云服务器安装宝塔面板图文教程 本文以 Linux云服务器 CentOS 7 4 64位系统为例 一 开放安全组端口 什么是安全
  • 【已解决】使用pyaudio内录声卡声音及相关问题

    使用pyaudio内录声卡声音及相关问题解决 目录 使用pyaudio内录声卡声音及相关问题解决 1 实现代码 1 1 Recorder类 1 2 调用方法 2 问题一 选择设备实现内录 外录 解决报错 OSError Errno 9999
  • java中的异常

    throw和throws的区别 相同 都是用于做异常的抛出处理的 不同点 使用的位置 throws 使用在函数上 throw使用在函数内 后面接受的内容的个数不同 throws 后跟的是异常类 可以跟多个 用逗号隔开 throws只声明异常
  • python中rsa解密_python中的RSA加密和J中的解密

    我对密码学完全陌生 我想从服务器端生成RSA密钥对并将其发送到所有客户端 浏览器 但在此之前 我只需在python中加密数据并发送到索引 html文件 并尝试用JavaScript解密 问题是当我通过random generator Ran
  • CMake 用法导览

    原文地址 http www cnblogs com coderfenghc archive 2013 01 20 2846621 html Preface 本文是CMake官方文档CMake Tutorial http www cmake