CMakeLists用法总结

2023-05-16

分一下几个方面来描述:

1. 每一个LIB要编译成静态库或动态库如何描述,每一个TOOL要编译成可执行文件如何描述?
2. LIB和TOOL可能会依赖于其他LIB,该如何描述?
3. 每个LIB和TOOL都会include很多头文件,相同的头文件如何处理,私有的头文件如何处理?
4. CMake中的一些用法
5. LLVM中用到的技巧

先举一个简单的例子:
//
└─tutorial.c
└─TutorialConfig.h.in
└─CMakeLists.txt
└─include
 └─mysqrt.h
└─lib
└─CMakeLists.txt
 └─MakeTable.c
 └─mysqrt.c

在这个例子中,Top level和lib中会分别定义一个CMakeLists.txt用来指定编译规则。这个例子主要做了以下几件事:
1)用宏USE_MYMATH来控制是否使用自己定义的sqrt()
2) 定义了一个MakeTable.c文件生成sqrt()的一个结果表,在自己定义的sqrt()函数中查表得出简单的结果。

3)或者通过exp和log来计算sqrt的值,但前提是当前库支持exp和log,这些都通过check_function_exists检查是否支持,如果支持相应的宏就会打开。

4)通过CTest,定义相应的测试用例,检查执行结果是否正确。

Top Level中的
Tutorial.c:

// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
#include "mysqrt.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);
  printf ("call local sqrt\n");
#else
  double outputValue = sqrt(inputValue);
#endif

  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;
}

当cmake为头文件配置”@Tutorial_VERSION_MAJOR@”和
“@Tutorial_VERSION_MINOR@”两个值时,会从CMakeLists.txt中找到相应的值来替换配置文件中对应行。

TutorialConfig.h.in

// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

#cmakedefine USE_MYMATH

#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

CMakeList.txt定义如下:

cmake_minimum_required (VERSION 2.6)
project (Tutorial)

# The version number.
//"set"用来给对应的变量赋值
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
set(include_dir ${CMAKE_CURRENT_SOURCE_DIR}/include)

//"MESSAGE"用来打印信息,包括变量的值
MESSAGE(STATUS "include folder: " ${include_dir})

//"option"用来定义宏,"ON"表示打开,"OFF"表示关闭
option (USE_MYMATH "Use tutorial provided math implementation" ON)

//configure_file: 将一份文件拷贝到另一个位置并修改它的内容。
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )

# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
//"include_directories"用来指定build时需要的头文件路径
//"PROJECT_BINARY_DIR"是内置变量,表示工程编译的目录,也就是--prefix指定的目录
include_directories("${PROJECT_BINARY_DIR}" "${include_dir}")

if (USE_MYMATH)
    include_directories(${include_dir})
    //"add_subdirectory"用来添加外部项目目录,将指定的目录添加到build任务列表中。
    //在这里"lib"目录是否需要编译,是通过宏USE_MYMATH控制,
    //如果这个宏打开,就需要编译"lib",也就是需要通过"add_sudirectory"添加"lib"
    add_subdirectory(lib)
    set(EXTRAL_LIBS ${EXTRAL_LIBS} MathFunctions)
endif(USE_MYMATH)

# add the executable
// "add_executable"用来指定生成可执行文件,这里会生成Tutorial.out或者Tutorial.exe
add_executable(Tutorial tutorial.c)

// 由于tutorial.c中需要用到sqrt函数,这个函数要么来自于系统库,要么来自于自定义库,
//因此这里需要通过"target_link_libraries"指定链家的libraries
target_link_libraries(Tutorial m ${EXTRAL_LIBS}) # link to -lm

install(TARGETS Tutorial DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" DESTINATION include)

//引入CTest, 添加相应的测试用例,正确的测试结果通过set_tests_properties指定。
//在这里也就是说sqrt(25) = 5,否则就会failed
#include(CTest)
MESSAGE(STATUS "Meditator testttttttttttt")
enable_testing()
add_test (TutorialRuns Tutorial 25)
add_test (TutorialComp25 Tutorial 25)
set_tests_properties(TutorialComp25 PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5")

//check_function_exists检查当前库是否支持log和exp,如果支持相应的宏就会打开。
include(CheckFunctionExists)
check_function_exists(log HAVE_LOG)
check_function_exists(exp HAVE_EXP)

mysqrt.c文件如下:

#include "mysqrt.h"
#include "Table.h"
double mysqrt(double input)
{
#if defined (HAVE_LOG) && defined (HAVE_EXP)
    return = exp(log(x) * 0.5);
#else
    if (input < 10)
        return sqrtTable[(int)input];
    else
        return 0;
#endif
}

MakeTable.c文件主要定义一个数组,保存一组sqrt(i)的值,其内容如下:

// A simple program that builds a sqrt table 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main (int argc, char *argv[])
{
  int i;
  double result;

  // make sure we have enough arguments
  if (argc < 2)
    {
    return 1;
    }

  // open the output file
  FILE *fout = fopen(argv[1],"w");
  if (!fout)
    {
    return 1;
    }

  // create a source file with a table of square roots
  fprintf(fout,"double sqrtTable[] = {\n");
  for (i = 0; i < 10; ++i)
    {
    result = sqrt((double)i);
    fprintf(fout,"%g,\n",result);
    }

  // close the table with a zero
  fprintf(fout,"0};\n");
  fclose(fout);
  return 0;
}

lib下的CMakeLists.txt的内容如下:

nclude_directories(${include_dir})
MESSAGE(STATUS "Meditator test cmake_current_souce_dir" ${CMAKE_CURRENT_SOURCE_DIR})

set(MAKETABLE_SRC MakeTable.c)
add_executable(MakeTable ${MAKETABLE_SRC})
target_link_libraries(MakeTable m) # link to -lm

//通过执行COMMAND,产生Table.h文件
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})

set(MYSQRT_SRC mysqrt.c)
add_library(MathFunctions ${MYSQRT_SRC} ${CMAKE_CURRENT_BINARY_DIR}/Table.h)

install(TARGETS MathFunctions DESTINATION bin)
install(FILES mysqrt.h DESTINATION include)

下面解释几个CMake内置变量
1.CMAKE_CURRENT_SOURCE_DIR
指的是当前处理的 CMakeLists.txt 所在的路径,处理不同目录下的CMaleLists,这个宏的值是不一样的。在Top level中这个值就是Top Level所在目录,在lib中这个值就是lib所在的目录。
2. CMAKE_BINARY_DIR
PROJECT_BINARY_DIR
<”projectname>_BINARY_DIR
这三个变量指代的内容是一致的,如果是 in source 编译,指得就是工程顶层目录,如果是 out-of-source 编译,指的是工程编译发生的目录。PROJECT_BINARY_DIR 跟其他指令稍有区别,现在,你可以理解为他们是一致的。
3. PROJECT_SOURCE_DIR
<”projectname>_SOURCE_DIR
用来表示当前project所在的目录
4. INCLUDE_DIRECTORIES
用来指定build时需要的头文件路径
5. LINK_DIRECTORIES
用来指定第三方库所在的路径,可以理解为gcc中的-L
6. ADD_DEFINITIONS
用来指定编译时需要打开的宏,即-DXXX
7. TARGET_LINK_LIBRARIES
用来指定工程所依赖的库
8. OPTION (USE_MYMATH “Use tutorial provided math implementation” ON)
在CMakeLists用option来控制当前USE_MYMATH是否打开,并在cmake-gui中会有对应的选项出现,默认是ON
9. CONFIGURE_FILE

  configure_file(<input> <output>
                 [COPYONLY] [ESCAPE_QUOTES] [@ONLY])

用法:将文件拷贝到然后替换文件内容中引用到的变量值。如果是相对路径,它的base路径是当前源码路径。必须是一个文件,而不是个路径。如果是一个相对路径,它的base路径是当前二进制文件路径。如果是一个已有的路径,那么输入文件将会以它原来的名字放到那个路径下。
该命令替换掉在输入文件中,以${VAR}格式或@VAR@格式引用的任意变量,如同它们的值是由CMake确定的一样。比如我们之前的例子中Tutorial_VERSION_MAJOR 和Tutorial_VERSION_MINOR会被CMakeLists中定义的宏所替代。而USE_MYMATH,HAVE_LOG,HAVE_EXP也会根据CMakeLists中的opthion和CheckFunctionExists所决定。
COPYONLY表示这些特殊的变量都不会被替换,仅仅只是替换文件;
@ONLY表示仅仅替换@VAR@格式的变量

10. Function的用法

function(<name>[arg1 [arg2 [arg3 ...]]])
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...

endfunction(<name>)

定义一个函数名为,参数名为arg1 arg2 arg3(…)。 函数体内的命令直到函数被调用的时候才会去执行。其中ARGC变量表示传递给函数的参数个数。 ARGV0, ARGV1, ARGV2代表传递给函数的实际参数。 ARGN代表超出最后一个预期参数的参数列表,例如,函数原型声明时,只接受一个参数,那么调用函数时传递给函数的参数列表中,从第二个参数(如果有的话)开始就会保存到ARGN。
举一个简单的例子

cmake_minimum_required(VERSION 2.8)  
 project(ArgumentExpansion)  

function (argument_tester arg)  
    message(STATUS "ARGN: ${ARGN}")  
    message(STATUS "ARGC: ${ARGC}")  
    message(STATUS "ARGV: ${ARGV}")  
    message(STATUS "ARGV0: ${ARGV0}")  

    list(LENGTH ARGV  argv_len)  
    message(STATUS "length of ARGV: ${argv_len}")  
    set(i 0)  
    while( i LESS ${argv_len})  
         list(GET ARGV ${i} argv_value)  
         message(STATUS "argv${i}: ${argv_value}")  
         math(EXPR i "${i} + 1")  
    endwhile()   
endfunction ()  
argument_tester(arg0 arg1 arg2 arg3) 

====output====
-- ARGN: arg1;arg2;arg3
-- ARGC: 4
-- ARGV: arg0;arg1;arg2;arg3
-- ARGV0: arg0
-- ARGV1: arg1
-- length of ARGV: 4
-- argv0: arg0
-- argv1: arg1
-- argv2: arg2
-- argv3: arg3

11. LIST用法

set(SRC)  
list(APPEND SRC a.cpp b.cpp)  
list(APPEND SRC c.cpp d.cpp)  

function(tst_arguments src_list)  
    message("src_list = "${src_list})  
endfunction()  

message("SRC = "${SRC})  
tst_arguments(${SRC})  

==== output ====  
SRC = a.cppb.cppc.cppd.cpp  
src_list = a.cpp  

12. CMAKE_PARSE_ARGUMENTS

CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)  

prefix是一个前缀
是一个列表,里面可以包含一些你感兴趣的KeyWord或者叫宏,随后可以通过它来看看你所需要的KeyWord是否被设置。只有当调用的地方使用option,表示这个宏是打开的。
是一个单值参数的KeyWord列表。
是一个多值参数的KeyWord列表(如list)

function(tst_arguments)  
  CMAKE_PARSE_ARGUMENTS(  
    TEST "" "NAME;COMMAND;BASELINE"  
       "ARGSLIST"  
       ${ARGN}  
  )  

  message("TEST_DEFAULT_ARGS is ${TEST_DEFAULT_ARGS} from ${ARGN}")  
  message("TEST_NAME is ${TEST_NAME}")  
  message("TEST_COMMAND is ${TEST_COMMAND}")  
  message("TEST_ARGSLIST is ${TEST_ARGSLIST}")  
  message("TEST_BASELINE is ${TEST_BASELINE}")  

endfunction(tst_arguments) 

这里的前缀是TEST,我们设置单值参数的KeyWord(NAME;COMMAND;BASELINE),这将在随后的函数调用中注明KeyWord和Value的关系,我们设置多值参数的KeyWord(”ARGSLIST”)。
调用函数:

TEST_ARGUMENT(  
    NAME  
      testiso  
    COMMAND  
      "RunMe"  
    ARGSLIST  
      ${SRC}  
    BASELINE  
      "/home/sakaue/iWork"  
)  

==== output ====  
TEST_DEFAULT_ARGS is  from NAME;testiso;COMMAND;RunMe;ARGSLIST;a.cpp;b.cpp;c.cpp;d.cpp;BASELINE;/home/sakaue/iWork  
TEST_NAME is testiso  
TEST_COMMAND is RunMe  
TEST_ARGSLIST is a.cpp;b.cpp;c.cpp;d.cpp  
TEST_BASELINE is /home/sakaue/iWork  

下面以LLVM中用得比较多的一个function举例:

macro(add_llvm_library name)
  if( BUILD_SHARED_LIBS )
    llvm_add_library(${name} SHARED ${ARGN})
  else()
    llvm_add_library(${name} ${ARGN})
  endif()
  set_property( GLOBAL APPEND PROPERTY LLVM_LIBS ${name} )
  ...
  ...
endmacro(add_llvm_library name)

function(llvm_add_library name)
  cmake_parse_arguments(ARG
    "MODULE;SHARED;STATIC"
    "OUTPUT_NAME"
    "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
    ${ARGN})
  list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS})
  if(ARG_ADDITIONAL_HEADERS)
    # Pass through ADDITIONAL_HEADERS.
    set(ARG_ADDITIONAL_HEADERS ADDITIONAL_HEADERS ${ARG_ADDITIONAL_HEADERS})
  endif()
  if(ARG_OBJLIBS)
    set(ALL_FILES ${ARG_OBJLIBS})
  else()
    llvm_process_sources(ALL_FILES ${ARG_UNPARSED_ARGUMENTS} ${ARG_ADDITIONAL_HEADERS})
  endif()

这个function在LLVM的很多CMakeLists中都会用,比如lib/IR目录

add_llvm_library(LLVMCore
  AsmWriter.cpp
  Attributes.cpp
  AutoUpgrade.cpp
  BasicBlock.cpp
  Comdat.cpp
  ConstantFold.cpp
  ConstantRange.cpp
  Constants.cpp
  Core.cpp
  DIBuilder.cpp
  ...
  ...

  )
add_dependencies(LLVMCore intrinsics_gen)

从上面的CMakeLists中我们可以看到,在llvm_add_library( nameSHARED n a m e S H A R E D {ARGN})中
name = LLVMCore;ARGN是依赖的那些.cpp文件。因此传递给cmake_parse_arguments的是
share *.cpp。因此
前缀是ARG,
ARG_SHARED = TRUE,
ARG_MODULE=FALSE,
ARG_STATIC=FALSE。
由于*.cpp不跟其它任何参数匹配,所以
ARG_UNPARSED_ARGUMENTS = *.cpp
注意_UNPARSED_ARGUMENTS用来表示那些不匹配的参数。

我们在LLVM中可以看到,lib中的CMakeLists***一般是不要指定头文件路径*的,比如像LLVM中的:

#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"

主要原因基于以下两点:
1.CMake使用 include_directories 命令来添加头文件包含路径,且 include_directories 命令具有继
承性。下级目录继承了上级目录中CMakeLists.txt 里面 include 的 directrories。但是平级目录之间的 CMakeList.txt 里面的include_directories 不能共享。
2. 在默认情况下,会查找当前目录下的所有头文件,不包括查找子目录下的头文件

在LLVM的CMakeLists.txt还看到很多这样的代码:

include(AddLLVM)
include(TableGen)

这里的AddLLVM和TableGen是什么呢?这里面定义了很多函数,比如之前用的比较多的llvm_add_library都定义在llvm/cmake/modules里面。但是在include这些module之前必须指定CMAKE_MODULE_PATH,llvm中是这样描述的:

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

CMakeLists用法总结 的相关文章

  • Android Studio Build Output控制台输出乱码解决

    Android Studio版本升级到4 0之后 xff0c 出现Build Output控制台输出乱码的现象 该情况在Android Studio版本3 6及以上就会出现 解决方法 xff1a 点击Android Studio 菜单栏He
  • 1230---KVM Windows 虚拟机磁盘如何快速扩容

    KVM Windows 虚拟机磁盘如何快速扩容 前言 xff1a 由于KVM虚拟机直接构建于宿主机内核之上 xff0c 对于充分利用宿主机硬件性能有天然的优势 网上针对KVM Linux 虚拟机运维的文章很多 xff0c 但针对KVM Wi
  • Android中的IPv6

    什么是IPv6 IPv6 的全称是Internet Protocol version 6 Internet Protocol 译为 互联网协议 xff0c 所以 IPv6 就是互联网协议第6版 它对比于 IPv4 所带来的是地址池的扩容 x
  • 浅谈Android下的注解

    什么是注解 java lang annotation xff0c 接口 Annotation xff0c 在JDK5 0及以后版本引入 注解是代码里的特殊标记 xff0c 这些标记可以在编译 类加载 运行时被读取 xff0c 并执行相应的处
  • 浅析Java中的final关键字

    一 final关键字的基本用法 在Java中 xff0c final关键字可以用来修饰类 方法和变量 xff08 包括成员变量和局部变量 xff09 下面就从这三个方面来了解一下final关键字的基本用法 1 修饰类 当用final修饰一个
  • volatile与Java内存模型

    1 volatile特点 volatile的两大特点是可见性和有序性 xff1b volatile的内存语义 xff1a 当写一个volatile变量时 xff0c JMM会把该线程对应的本地内存中的共享变量值立即刷新回主内存中 当读一个v
  • 隐藏Detected problems with API compatibility警告弹窗

    如果在Android9 0亦即API 28或以上的系统中运行debug app时 xff0c 出现如下警告弹窗 xff1a Detected problems with API compatibility visit g co dev ap
  • JAVA中枚举如何保证线程安全

    枚举类型到底是什么类呢 xff1f 是enum吗 xff1f 明显不是 xff0c enum就和class一样 xff0c 只是一个关键字 xff0c 他并不是一个类 xff0c 那么枚举是由什么类维护的呢 xff0c 首先写一个简单的枚举
  • ‘sed‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

    在使用adb命令查看task和Activity的时候 xff0c 发现报错 sed 不是内部或外部命令 xff0c 也不是可运行的程序 或批处理文件 看样子是没有配置sed的环境变量 xff0c 或者没有sed工具 从网上找了一下 xff0
  • win11 我们无法设置移动热点

    有可能是因为Windows移动热点服务被禁用 启动移动热点服务 1 使用该配件的键 43 热键启动运行 WindowsR 2 要打开 服务 xff0c 请在 打开 框中键入此文本并单击 确定 xff1a services msc 3 选中W
  • 链栈(java 实现)

    Node类 xff1a package LinkStack public class Node String name int age Node next public Node public Node String name int ag
  • Android之WindowManager介绍

    WindowManager android中真正展示给用户的是window和view activity在android中所其的作用主要是处理一些逻辑问题 xff0c 比如生命周期的管理 建立窗口等 在android中 xff0c 窗口的管理
  • https://dl.bintray.com/umsdk/release/com/facebook/react/react-native/maven-metadata 502 Bad Gateway

    https dl bintray com umsdk release com facebook react react native maven metadata xml 39 Received status code 502 from s
  • Android UI深度理解:Activity UI视图结构

    Activity UI视图结构 每个Activity都会获得一个窗口 xff0c 那就是Window xff0c 它用于绘制用户的UI界面 Window是一个抽象类 xff0c 提供了绘制窗口的一组通用API xff0c PhoneWind
  • 学习嵌入式必读十本书,从C语言到ARM

    学习嵌入式必读的十本书籍 xff0c 按照C语言 数据结构 Linux C 43 43 QT 单片机 ARM的顺序给大家推荐 01 C语言 凡是计算机 电子 通信 自动化 机械专业的同学 xff0c 大一的时候必学C语言 xff0c 而且大
  • 研一(研究生)看论文文献必须要知道的几个网站

    找论文看文献必备的几个网站 明确研究方向查找论文看英文文献看文献方法想说的几句话 明确研究方向 刚进入研究生阶段的同学们都干劲十足 xff0c 充满无限期待 但是没有正确的方向很容易让你的努力白费 xff0c xff08 有人会说丰富了自己
  • 【网络教程】群晖自动更新 Docker 映像与容器(Watchtower)【转】

    群晖自动更新 Docker 映像与容器 xff08 Watchtower xff09 更多内容
  • git多账号配置

    什么叫多账号配置 xff0c 也就是说假如你在公司用的gitlab服务器 xff0c 但是自己还有用到GitHub xff0c 那么此时你在本地就需要配置多个ssh key 步骤如下 xff1a 利用ssh keygen t rsa f g
  • Ubuntu 18.04和windows建立共享文件夹

    1 安装samba sudo apt install samba sudo apt install cifs utils 2 创建共享目录 mkdir home yourname share yourname是home下一个文件夹 xff0
  • Linux权限详解,多用户多组各种权限配置原理

    网上有太多关于Linux权限详解 xff0c 这里不啰嗦那些 主要解释下这些权限是杂用的 xff0c 否则知道了什么用户 组之类的权限也配不好 一 权限分类 r xff1a 读取权限 xff0c 数字代号为 34 4 34 w xff1a

随机推荐

  • 1.tow sum

    文章目录 题目c 43 43 版本java版本利用hashmap正确做法 题目 Two Sum Easy Given an array of integers return indices of the two numbers such t
  • 2. Add Two Numbers

    2 Add Two Numbers Medium 59971568Share You are given two non empty linked lists representing two non negative integers T
  • Linux VNC server的安装及简单配置使用

    Linux VNC server的安装及简单配置使用 转 xff1a http www 2cto com os 201309 241104 html Linux VNC server的安装及简单配置使用 摘要 xff1a Linux vnc
  • 3. Longest Substring Without Repeating Characters

    Longest Substring Without Repeating Characters Given a string find the length of the longest substring without repeating
  • 4. Median of Two Sorted Arrays

    Median of Two Sorted Arrays Hard There are two sorted arrays nums1 and nums2 of size m and n respectively Find the media
  • 7. Reverse Integer

    文章目录 Reverse IntegersolutionAlgorithm Reverse Integer Easy Given a 32 bit signed integer reverse digits of an integer Ex
  • 8. String to Integer (atoi)

    String to Integer atoi Implement atoi which converts a string to an integer The function first discards as many whitespa
  • 9. Palindrome Number

    Palindrome Number Easy Determine whether an integer is a palindrome An integer is a palindrome when it reads the same ba
  • 1071. Greatest Common Divisor of Strings

    1071 Greatest Common Divisor of Strings Easy 30985Share For strings S and T we say 34 T divides S 34 if and only if S 61
  • 这个问题搞了我一天

  • 150逆波兰式

    文章目录 150 Evaluate Reverse Polish NotationSolution 150 Evaluate Reverse Polish Notation Medium Evaluate the value of an a
  • 收到礼物最大值

    题目描述 在一个m n的棋盘的每一个格都放有一个礼物 xff0c 每个礼物都有一定价值 xff08 大于0 xff09 从左上角开始拿礼物 xff0c 每次向右或向下移动一格 xff0c 直到右下角结束 给定一个棋盘 xff0c 求拿到礼物
  • 64. Minimum Path Sum

    64 Minimum Path Sum Given a m x n grid filled with non negative numbers find a path from top left to bottom right which
  • 找出亲密对数

    题目内容 xff1a 求数n之内的亲密对数 所谓 亲密对数 xff0c 即A的所有因子 xff08 包含1但不包含其本身 xff09 之和等于B xff0c 而B的所有因子之和等于A 输入格式 某个数字n 输出格式 xff1a 此数字n之内
  • 5. Longest Palindromic Substring

    5 Longest Palindromic Substring Given a string s find the longest palindromic substring in s You may assume that the max
  • 516. Longest Palindromic Subsequence

    516 Longest Palindromic Subsequence Given a string s find the longest palindromic subsequence s length in s You may assu
  • 第一讲_网站架构的演变及海量数据的解决方案

    文章目录 看透springMVC 读书笔记 第一讲单机类型CS结构 xff08 Client Server xff09 BS结构 xff08 Browser Server xff09 BS结构网络传输方式OSI七层模型 TCP IP四层模型
  • 10. Regular Expression Matching

    10 Regular Expression Matching Given an input string s and a pattern p implement regular expression matching with suppor
  • 866. Prime Palindrome

    866 Prime Palindrome Find the smallest prime palindrome greater than or equal to N Recall that a number is prime if it s
  • CMakeLists用法总结

    分一下几个方面来描述 xff1a 1 每一个LIB要编译成静态库或动态库如何描述 xff0c 每一个TOOL要编译成可执行文件如何描述 xff1f 2 LIB和TOOL可能会依赖于其他LIB xff0c 该如何描述 xff1f 3 每个LI