当前位置: 首页 > 编程日记 > 正文

google gn构建系统的介绍

GN语言和操作

  • GN语言和操作
    • 内容
    • 介绍
      • 使用内置的帮助
      • 设计理念
    • 语言
      • 字符串
      • 清单
      • 条件语句
      • 循环
      • 函数调用
      • 作用域和执行Scoping and execution
    • 命名事物
      • 文件和目录名称
    • 构建配置
    • 目标
    • CONFIGS
      • 公共配置
    • 模板
    • 其他特性
      • Imports
      • 路径处理
      • 模式
      • 执行脚本
  • 与Blaze的区别和相似之处

介绍

本页面描述了许多语言的细节和行为。

使用内置的帮助!

GN有一个广泛的内置帮助系统,为每个功能和内置变量提供参考。这个页面更高级。

gn help

你也可以看到2016年3月份的GNE幻灯片。演讲者笔记包含完整的内容。

设计理念

  • 编写构建文件不应该是一个创造性的努力。理想情况下,两个人应该产生相同的构建文件来实现相同的需求。除非绝对需要,否则不应有任何灵活性。做越多的事情越可能产生致命的错误。

  • 定义应该比代码更像代码。我不想编写或调试Prolog。但是我们团队的每个人都可以编写和调试C ++和Python。

  • 构建语言应该被视为构建应该如何工作。表达任意事物不一定容易甚至不可能。我们应该改变源代码和工具,使构建变得更简单,而不是把所有事情都变得更复杂以符合外部要求(在合理的范围内)。

  • 在有意义的时候就像Blaze一样(见下面的“与Blaze的区别和相似之处”)。

语言

GN使用非常简单的动态类型语言。类型是:

  • 布尔(truefalse)。
  • 64位有符号整数。
  • 字符串。
  • 列表(任何其他类型)。
  • 范围(Scopes)(有点像字典,仅是内置的东西(built-in stuff))。

有一些内置变量的值取决于当前的环境。了解gn help更多信息。

语言中故意有许多遗漏。例如没有用户定义的函数调用,(模板是最接近的)。按照上述设计理念,如果你需要这样的东西,你可能做错了。

变量sources有一个特殊的规则:赋值给它时,将应用一个排除模式列表。这被设计成自动过滤掉某些类型的文件。见gn help set_sources_assignment_filtergn help label_pattern了解更多。

语言书呆子的完整语法可以在gn help grammar获取到。

字符串

字符串用双引号括起来,并使用反斜杠作为转义字符。唯一支持的转义序列是:

  • \" (用于直接引用)
  • \$ (字面上的美元符号)
  • \\ (用于文字反斜杠)

任何其他反斜杠的使用都被视为文字反斜杠。所以,例如,\b在模式中使用不需要转义,大多数Windows路径"C:\foo\bar.h"也不需要。

使用$支持简单的变量替换,其中美元符号后的单词被替换为变量的值。如果没有非变量名字符来终止变量名称,可以选择{}包围名称。更复杂的表达式不被支持,仅支持变量名称替换。

a = "mypath"
b = "$a/foo.cc"  # b -> "mypath/foo.cc"
c = "foo${a}bar.cc"  # c -> "foomypathbar.cc"

b = "$a/foo.cc"  # b -> "mypath/foo.cc"
c = "foo${a}bar.cc"  # c -> "foomypathbar.cc"

您可以使用 “$0xFF” 语法对8位字符进行编码,因此带有换行符(十六进制0A)的字符串会如下所示,"look$0x0Alike$0x0Athis"

清单

没有办法得到一个列表的长度。如果你发现自己想要做这种事情,那么你就是想在构建中做太多的工作。

列表支持追加:

a = [ "first" ]
a += [ "second" ]  # [ "first", "second" ]
a += [ "third", "fourth" ]  # [ "first", "second", "third", "fourth" ]
b = a + [ "fifth" ]  # [ "first", "second", "third", "fourth", "fifth" ]

a += [ "second" ]  # [ "first", "second" ]
a += [ "third", "fourth" ]  # [ "first", "second", "third", "fourth" ]
b = a + [ "fifth" ]  # [ "first", "second", "third", "fourth", "fifth" ]

将列表追加到另一个列表,是追加第二个列表中的项目,而不是将列表追加为嵌套成员。

您可以从列表中删除项目:

a = [ "first", "second", "third", "first" ]
b = a - [ "first" ]  # [ "second", "third" ]
a -= [ "second" ]  # [ "first", "third", "fourth" ]

b = a - [ "first" ]  # [ "second", "third" ]
a -= [ "second" ]  # [ "first", "third", "fourth" ]

列表中的 - 运算符搜索匹配项并删除所有匹配的项目。从另一个列表中减去一个列表将删除第二个列表中的每个项目。

如果找不到匹配的项目,将会抛出错误,因此您需要事先知道该项目在移除之前确实已经存在。鉴于没有办法测试包含,主要的用例是建立一个文件或标志的主列表,并基于各种条件删除那些不适用于当前版本的构建。

从风格上来说,最好只添加到列表,并让每个源文件或依赖项只出现一次。这与Chrome团队用于GYP的建议相反(GYP倾向于列出所有文件,然后删除条件中不需要的文件)。

列表支持从零开始的下标以提取值:

a = [ "first", "second", "third" ]
b = a[1]  # -> "second"

b = a[1]  # -> "second"

[]运算符是只读的,不能用来改变列表。这个主要的用例是当一个外部脚本返回几个已知的值,并且你想提取它们。

在某些情况下,如果您要添加到列表中,则很容易覆盖列表。为了帮助理解这种情况,将非空列表分配给包含现有非空列表的变量是错误的。如果您想避开此限制,请首先将目标变量分配给空列表。

a = [“one”]
a = [“two”]#错误:用非空列表覆盖非空列表。
a = []#OK
a = [“two”]#OK

a = [“two”]#错误:用非空列表覆盖非空列表。
a = []#OK
a = [“two”]#OK

请注意,构建脚本的执行没有内在知识的底层数据的意义。例如,这意味着它不知道sources是一个文件名列表。所以,如果你删除一个项目,它必须匹配文字字符串,而不是指定一个不同的名称,那将解析为相同的文件名称。

条件语句

条件看起来像C:

  if(is_linux ||(is_win && target_cpu ==“x86”)){sources -= [ "something.cc" ]} else if(...){...} else {...}
sources -= [ "something.cc" ]} else if(...){...} else {...}

如果只能在某些情况下声明目标,则可以在大多数地方使用它们,甚至在整个目标周围使用它们。

循环

你可以使用foreach迭代一个列表。这是不鼓励的。构建应该做的大部分事情通常都可以在不做这件事情的情况下表达出来,如果你觉得有必要的话,这可能表明你在元构建中做了太多工作。

foreach(i,mylist){print(i)  # Note: i is a copy of each element, not a reference to it.
}
print(i)  # Note: i is a copy of each element, not a reference to it.
}

函数调用

简单的函数调用看起来像大多数其他语言

print("hello, world")
assert(is_win, "This should only be executed on Windows")

assert(is_win, "This should only be executed on Windows")

这些功能是内置的,用户不能定义新的功能。

一些函数在它们下面接受一个由{ }组成的代码块:

static_library(“mylibrary”){sources = [“a.cc”]
}
sources = [“a.cc”]
}

其中大多数用来定义目标。用户可以使用下面讨论的模板机制来定义新的函数。

确切地说,这个表达式意味着该块成为函数执行的参数。大多数块式函数都会执行块,并将结果范围视为要读取的变量字典。

作用域和执行(Scoping and execution)

文件和函数调用后面跟着{ }块引入新的作用域。作用域是嵌套的。当您读取一个变量时,将会以相反的顺序搜索包含的作用域,直到找到匹配的名称。变量写入总是进入最内层的作用域。

除了最内层的作用域以外,没有办法修改任何封闭作用域。这意味着当你定义一个目标时,例如,你在块内部做的任何事情都不会泄露到文件的其余部分。

if/ else/ foreach语句,即使他们使用{ },不会引入新的范围,所以更改将持续在语句之外。

命名事物

文件和目录名称

文件和目录名称是字符串,并被解释为相对于当前构建文件的目录。有三种可能的形式:

相对名称:

"foo.cc"
"src/foo.cc"
"../src/foo.cc"

"src/foo.cc"
"../src/foo.cc"

源代码树绝对名称:

“//net/foo.cc”
“//base/test/foo.cc”

“//base/test/foo.cc”

系统绝对名称(罕见,通常用于包含目录):

"/usr/local/include/"
"/C:/Program Files/Windows Kits/Include"

"/C:/Program Files/Windows Kits/Include"

构建配置

目标

目标是构建图中的一个节点。它通常代表将要生成的某种类型的可执行文件或库文件。目标取决于其他目标。内置的目标类型(请参阅gn help <targettype>以获取更多帮助)是:

  • action:运行一个脚本来生成一个文件。
  • action_foreach:为每个源文件运行一次脚本。
  • bundle_data:声明数据加入到Mac / iOS包。
  • create_bundle:创建一个Mac / iOS包。
  • executable:生成一个可执行文件。
  • group:引用一个或多个其他目标的虚拟依赖关系节点。
  • shared_library:.dll或.so。
  • loadable_module:.dll或.so只能在运行时加载。
  • source_set:一个轻量级的虚拟静态库(通常比真正的静态库更可取,因为它的构建速度会更快)。
  • static_library:.lib或.a文件(通常你会想要一个source_set)。

您可以使用模板来扩展它制作自定义目标类型(请参见下文)。在Chrome中,一些更常用的模板是:

  • component:源集或共享库,取决于构建类型。
  • test:测试可执行文件 在移动设备上,这将为测试创建适当的本机应用程序类型。
  • app:可执行文件或Mac / iOS应用程序。
  • android_apk:制作一个APK。有很多其他的Android模版,看//build/config/android/rules.gni

CONFIGS

配置文件是命名对象,用于指定标志集,包含目录和定义。他们可以被应用到一个目标,并推到相关的目标。

要定义一个配置:

config("myconfig") {includes = [ "src/include" ]defines = [ "ENABLE_DOOM_MELON" ]
}
includes = [ "src/include" ]defines = [ "ENABLE_DOOM_MELON" ]
}

要将配置应用于目标:

executable("doom_melon") {configs = [ ":myconfig" ]
}
configs = [ ":myconfig" ]
}

构建配置文件通常指定设置默认配置列表的目标默认值。目标可以根据需要添加或删除。所以在实践中你通常会使用configs += ":myconfig"追加到默认列表。

请参阅gn help config有关如何声明和应用配置的更多信息。

公共配置

目标可以将设置应用于依赖它的其他目标。最常见的例子是一个第三方目标,它需要一些定义或包含目录头才能正确编译。您希望这些设置既适用于第三方库本身的编译,也适用于使用该库的所有目标。

要做到这一点,你写一个你想要应用的设置的配置:

config("my_external_library_config") {includes = "."defines = [ "DISABLE_JANK" ]
}
includes = "."defines = [ "DISABLE_JANK" ]
}

然后这个配置作为“公共”配置被添加到目标。它既适用于目标,也适用于直接依赖目标的目标。

shared_library("my_external_library") {...# Targets that depend on this get this config applied.public_configs = [ ":my_external_library_config" ]
}
...# Targets that depend on this get this config applied.public_configs = [ ":my_external_library_config" ]
}

依赖目标又可以通过将目标作为“公共”依赖项添加到另一个级别,从而将依赖关系树转发到另一个级别。

static_library("intermediate_library") {...# Targets that depend on this one also get the configs from "my external library".public_deps = [ ":my_external_library" ]
}
...# Targets that depend on this one also get the configs from "my external library".public_deps = [ ":my_external_library" ]
}

通过把它设置成all_dependent_config一个目标可以转发一个配置给所有的依赖者,直到达到一个链接边界为止。这是强烈不鼓励的,因为它将比必要的构建配置超出更多的标志和定义。使用public_deps来控制哪些标志适用于哪里来代替它。

在Chrome中,更喜欢build/buildflag_header.gni用于定义的构建标题头文件系统,以防止大多数编译器定义的错误。

模板

模板是GN重用代码的主要方式。通常情况下,模板会扩展到一个或多个其他目标类型。

# Declares a script that compiles IDL files to source, and then compiles those
#source files.
template("idl") {#Always base helper targets on target_name so they're unique。Target name#will be the string passed as the name when the template is invoked.idl_target_name =“$ {target_name} _generate”action_foreach(idl_target_name){...}#Your template should always define a target with the name target_name.#When other targets depend on your template invocation, this will be the#destination of that dependency.source_set(target_name){...deps = [ ":$idl_target_name" ]  # Require the sources to be compiled.}
}

#source files.
template("idl") {#Always base helper targets on target_name so they're unique。Target name#will be the string passed as the name when the template is invoked.idl_target_name =“$ {target_name} _generate”action_foreach(idl_target_name){...}#Your template should always define a target with the name target_name.#When other targets depend on your template invocation, this will be the#destination of that dependency.source_set(target_name){...deps = [ ":$idl_target_name" ]  # Require the sources to be compiled.}
}

通常,您的模板定义将放入.gni文件中,用户将导入该文件以查看模板定义:

import("//tools/idl_compiler.gni")idl("my_interfaces") {sources = [ "a.idl", "b.idl" ]
}
idl("my_interfaces") {sources = [ "a.idl", "b.idl" ]
}

当时声明一个模板会在范围内的变量周围创建一个闭包。当模板被调用时,魔术变量invoker被用来从调用范围中读取变量。模板通常会将感兴趣的值复制到自己的范围中:

template("idl") {source_set(target_name){sources = invoker.sources}
}
source_set(target_name){sources = invoker.sources}
}

模板执行时的当前目录将是调用的构建文件的目录,而不是模板源文件。这是因为从模板调用者传入的文件是正确的(这通常是模板中大多数文件处理的原因)。但是,如果模板本身有文件(可能会生成一个运行脚本的动作),则需要使用绝对路径(“//foo/…”)来引用这些文件,以说明当前目录在调用时将不可预知。查看gn help template更多信息和更完整的例子。

其他特性

Imports

您可以使用import函数将.gni文件导入到当前作用域。这不是 C++意义上的包含。导入的文件是独立执行的,生成的作用域被复制到当前文件中(C ++在include指令出现的当前上下文中执行包含的文件)。这样可以缓存导入的结果,还可以防止包含多个包含文件在内的一些更“创造性”的用途。

通常情况下,一个.gni会定义构建参数和模板。了解gn help import更多信息。

您的.gni文件可以定义不导出到文件临时变量,通过使用名称中的前面的下划线来包含它,就像_this

路径处理

通常情况下,您需要创建一个文件名或相对于不同目录的文件名列表。运行脚本时,这种情况尤为常见,这些脚本是以构建输出目录作为当前目录执行的,而构建文件通常是指与其包含的目录相关的文件。

您可以使用rebase_path转换目录。查看gn help rebase_path更多的帮助和例子。将相对于当前目录的文件名转换为相对于根目录的典型用法是:new_paths = rebase_path("myfile.c", root_build_dir)

模式

模式用于为自定义目标类型的给定输入集生成输出文件名,并自动从sources变量中移除文件(请参阅参考资料gn help set_sources_assignment_filter)。

他们就像简单的正则表达式。了解gn help label_pattern更多信息。

执行脚本

有两种方法来执行脚本。GN中的所有外部脚本都是Python。第一种方法是作为构建步骤。这样的脚本将需要一些输入,并生成一些输出作为构建的一部分。调用脚本的目标是使用“action”目标类型声明的(请参阅参考资料gn help action)。

执行脚本的第二种方法是在构建文件执行期间同步。这在某些情况下是必要的,以确定要编译的文件集合,或获取构建文件可能依赖的某些系统配置。构建文件可以读取脚本的标准输出(stdout)并以不同的方式对其执行操作。

同步脚本的执行由exec_script函数完成(详见gn help exec_script参考资料)。因为同步执行一个脚本需要暂停当前的构建文件执行,直到Python进程完成执行,依靠外部脚本是慢的,应该尽量减少。

为了防止滥用,允许调用的文件exec_script可以在顶层.gn文件中列入白名单。Chrome做到这一点需要额外的代码审查这样的补充。看gn help dotfile

您可以同步读取和写入在同步运行脚本时不鼓励但偶尔需要的文件。典型的用例是传递一个比当前平台的命令行限制长的文件名列表。请参阅gn help read_file以及gn help write_file如何读取和写入文件。如果可能,应该避免这些功能。

超过命令行长度限制的操作可以使用响应文件绕过此限制,而不同步写入文件。看gn help response_file_contents

与Blaze的区别和相似之处

Blaze是Google的内部构建系统,现在已经作为Bazel公开发布。它启发了一些其他系统,如Pants和Buck。

在Google的同类环境中,对条件的需求非常低,并且可以通过少量的手段(abi_deps)来获得。Chrome使用各地的条件,需要添加这些是文件看起来不同的主要原因。

GN还增加了“配置”的概念来管理一些棘手的依赖和配置问题,同样不会出现在服务器上。Blaze有一个“配置”的概念,就像一个GN工具链,但内置在工具本身。GN工具链的工作方式是试图以一种简洁的方式将这个概念分离到构建文件中的结果。

GN保留了一些GYP概念,比如“全部依赖”设置,这些设置在Blaze中有些不同。这部分是为了使现有的GYP代码更容易转换,GYP结构通常会提供更细粒度的控制(根据具体情况而定,好或坏)。

GN也使用GYP名称,比如“sources”而不是“srcs”,因为缩写似乎是不必要的,尽管它使用了Blaze的“deps”,因为“dependencies”很难打字。Chromium还在一个目标中编译多种语言,因此指定目标名称前缀的语言类型被删除(例如,从cc_library)。

相关文章:

【数据结构】邻接表的储存结构 建立图的邻接表算法

【数据结构】邻接矩阵及其实现 一个图的邻接矩阵的表示是唯一的&#xff0c;但其邻接表表示不唯一&#xff0c;这是因为在邻接表结构中&#xff0c;各便表结点的链接次序取决于建立邻接表时的算法以及输入的次序。 一般而言邻接矩阵适合存储稠密图&#xff0c;邻接表适合存储…

报错:该字符串未被识别为有效的DateTime

报错&#xff1a;该字符串未被识别为有效的DateTime □ 背景 前端的搜索条件中包含关于时间的字符串&#xff0c;由jquery ui的datepicker产生时间字符串。 服务端对时间做了一次转换&#xff1a;DateTime.Parse(Request["时间字段"].ToString())。 搜索的时候没有选…

Nagios监控笔记上

Nagios软件介绍及服务端安装部署实战1. Nagios服务端安装1.1 准备3台服务器或者虚拟机器管理IP地址角色备注192.168.1.80Nagios监控服务器192.168.1.81Lamp服务器被监控的客户端服务器192.168.1.82Lamp服务器被监控的客户端服务器1.2 解决perl编译问题&#xff1a;后面编译的软…

liunx查看python的site-packages路径

有时候我们在liunx上想修改查看python的包路径可以试试以下命令 from distutils.sysconfig import get_python_lib print(get_python_lib()) 如图&#xff1a;

【ACM】杭电OJ 2010

注意格式&#xff01;&#xff01;&#xff01;注意格式&#xff01;&#xff01;&#xff01; 空格的设置 \n的设置 #include <stdio.h> int main () {int i,m,n,g,s,b,flag;while(scanf("%d%d",&m,&n)!EOF){flag0;for(im;i<n;i){gi%10;bi/100…

中科院 工程硕士专业课 复试考试前的辅导安排

同学们大家好&#xff1a;学校定于12月6日、7日组织专业课辅导&#xff0c;1月初进行专业课复试及资格审查。辅导具体日程安排如下&#xff1a;12月6日下午13:00 数据结构&#xff08;报考软件工程、计算机技术领域考生&#xff09; 人文楼教一阶12月7日上午9:00 信号与系统…

TCP性能和发送接收Buffer的关系

本文希望解析清楚&#xff0c;当我们在代码中写下 socket.setSendBufferSize 和 sysctl 看到的rmem/wmem系统参数以及最终我们在TCP常常谈到的接收发送窗口的关系&#xff0c;以及他们怎样影响TCP传输的性能。 先明确一下&#xff1a;文章标题中所说的Buffer指的是sysctl中的 …

PHP 异常类 Exception 高洛峰 细说PHP

/** 1.自定义的异常类&#xff0c;必须是系统类Exception的子类* 如果继承Exception类&#xff0c;重写了构造方法,一定要调用一下父类的构造方法。*/class MyException extends Exception{//必须继承Exception类function __construct($mess){parent::__construct($mess);}func…

【ACM】杭电OJ 2023

注意最后又两个\n #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn 1000; int a[maxn][maxn]; double grade[maxn]; double average[maxn]; int main () {int m,n,i,j,flag,count;//n个学生&#xff0c;m门…

Hadoop学习笔记—7.计数器与自定义计数器

一、Hadoop中的计数器 计数器&#xff1a;计数器是用来记录job的执行进度和状态的。它的作用可以理解为日志。我们通常可以在程序的某个位置插入计数器&#xff0c;用来记录数据或者进度的变化情况&#xff0c;它比日志更便利进行分析。 例如&#xff0c;我们有一个文件&#x…

win10安装spacemacs

1、下载emacs最新版 26.1 2、解压emacs到你的安装目录,我的系统是D:/Program File/。执行/bin目录下的addpm.exe 这一步会在开始菜单创建快捷方式 3、在系统环境变量中添加新项HOME(具体环境变量设置方式请自行google)&#xff0c;该变量的路径决定了emacs启动时.emacs.d目录…

【ACM】杭电OJ 2024

注意&#xff1a; 1、getchar() 2、scanf和gets的区别 3、判断条件 C语言的合法标识符 1、由字母&#xff0c;数字&#xff0c;下划线组成 2、且首字符不能是数字 #include <iostream> #include <cstdio> #include <cstring> using namespace std; in…

王振的开发板_Android

任务一&#xff1a; 任务内容&#xff1a;主界面框架的搭建 发布时间&#xff1a;2016-8-26 已完成 任务二&#xff1a; 任务内容&#xff1a;我的 主界面的开发 发布时间&#xff1a;2016-8-27 已完成 任务三&#xff1a; 任务内容&#xff1a;发布界面 动画开发 发布时间&a…

JAX-RS(基于Jersey) + Spring 4.x + MyBatis构建REST服务架构

0. 大背景 众所周知&#xff0c;REST架构已经成为现代服务端的趋势。 很多公司&#xff0c;已经采用REST作为App, H5以及其它客户端的服务端架构。 1. 什么是JAX-RS? JAX-RS是JAVA EE6 引入的一个新技术。 JAX-RS即Java API for RESTful Web Services&#xff0c;是一个Java 编…

c语言宏嵌套和展开规则

基本原则&#xff1a; 在展开当前宏函数时&#xff0c;如果形参有#或##则不进行宏参数的展开&#xff0c;否则先展开宏参数&#xff0c;再展开当前宏。 #是在定义两边加上双引号 #define _TOSTR(s) #sprintf(_TOSTR(test ABC)) printf(_TOSTR("test ABC")); print…

【ACM】杭电OJ 2027

注意输出格式&#xff01;&#xff01;&#xff01;&#xff01; #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn 10000; char s1[maxn]; int main () {int n,j,i,a,e,o,u;scanf("%d",&n)…

搜索引擎广告过滤Chrome插件

搜索广告屏蔽Chrome插件:自动过滤&#xff1a;百度&#xff0c;360&#xff0c;搜狗&#xff0c;google&#xff0c;bing的搜索广告&#xff0c;让魏则西的悲剧不再重演。珍爱生命&#xff0c;远离搜索广告&#xff01;下载&#xff1a;FuckAd.zip 安装&#xff1a;方法自行百度…

Scala程序设计:Java虚拟机多核编程实战(国内第一本Scala图书)

Scala程序设计&#xff1a;Java虚拟机多核编程实战(国内第一本Scala图书) 基本信息 作者&#xff1a; (美)Venkat Subramaniam 译者&#xff1a; 郑晔 李剑 丛书名&#xff1a; 图灵程序设计丛书 出版社&#xff1a;人民邮电出版社 ISBN&#xff1a;9787115232953 上架时间&am…

emacs快捷键

https://blog.wozouwokan.com/%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91/2015/07/14/spacemacs/ 超全开发快捷键&#xff1a;https://edward852.github.io/post/%E9%80%9A%E7%94%A8%E4%BB%A3%E7%A0%81%E7%BC%96%E8%BE%91%E5%99%A8spacemacs/ spc f T快速定位当前文件在neotree中的…

python 小程序,输错三次密码锁定账户

1 [rootsun ~]# cat 7.py 2 #!/usr/bin/python3 # -*- codingUTF-8 -*-4 5 usera_name usera6 usera_passwd aresu7 usera_status on8 userb_name userb9 userb_passwd bresu 10 userb_status on 11 ng 0 12 13 14 name raw_input(请输入用户名&#xff1a;) 15 …

【数据结构】图的深度优先遍历 广度优先遍历

文件操作比直接输入方便许多 #include <stdio.h> #include <stdlib.h> #include <string.h> #define M 20/*邻接表的储存结构*/ typedef struct node /*表结点 或者 边表结点*/ {int adjvex;struct node *next; }edgenode;typedef struct vnode /*头结点*/ …

C++ Primer(第4版)(评注版)

《C Primer(第4版)(评注版)》基本信息原书名&#xff1a; C Primer (4th Edition) 原出版社&#xff1a; Addison-Wesley Professional; 4 edition 作者&#xff1a; (美)Stanley B.Lippman Josee Lajoie Barbara E.Moo 译者&#xff1a; 陈硕 丛书名&#xff1a; 传世经典书丛…

win10安装emacs+spacemacs,建议用官方安装方式

1、下载emacs最新版 26.1 官网下载地址&#xff1a;https://www.gnu.org/software/emacs/download.html#nonfree 2、解压emacs到你的安装目录,我的系统是D:/Program File/。执行/bin目录下的addpm.exe 这一步会在开始菜单创建快捷方式 3、在系统环境变量中添加新项HOME(具体环…

【ACM】杭电OJ 2028

int 会 WA &#xff0c;注意使用 long long 先除后乘&#xff0c;避免超出范围&#xff0c;但好像本题先乘后除也AC #include <iostream> #include <cstdio> #include <cstring>long long lcm(long long a,long long b) {long long c,t,ma,nb;if(a<b) {…

IIS8 添加配置 WCF服务

今天在Windows8.1 操作系统部署了半天的WCF 一直老是在报错、在这里做个记录 防止下次忘记 在网上查了半天。终于知道原来IIS&#xff18;不支持WCF服务SVC的请求。所以必须要给IIS&#xff18;添加WCF服务 的Managed Handler。 添加步骤&#xff1a; &#xff11;打开IIS&a…

spacemacs各种问题修复方法

快捷键操作时报 tr不是内部命令 ------说明是缺少tr命令&#xff0c;win10可以安装coreutils for gnuwin32工具集&#xff0c;然后把bin目录加到系统path路径即可 没有ispell, flycheck error ------缺少ispell命令&#xff0c;windows下面用aspell替换&#xff0c;需要安装…

2016/08/27 What I Learned About Going Fast at eBay and Google

每天推荐一个英文视频 http://v.qq.com/page/i/2/d/i0...https://www.youtube.com/watch... 本日看点

【ACM】杭电OJ 2030

注意getchar()的使用&#xff0c;以及汉字占两个字节&#xff0c;因为比较特殊&#xff0c;可以单独记忆 #include <iostream> #include <cstdio> #include <cstring> int main () {char c;int n,i,sum;scanf("%d",&n);getchar();while(n--)…

背景图自适应屏幕居中显示,且不变形

html&#xff1a;<div classitem><div class container /> </div> css:.item {width: 100%;height: 100%;.container {max-width: 100%;height: auto;min-height: 600px; // 这里可监听屏幕变化&#xff0c;改变最小高度position: absolute;left: 50%;top:…

emacs按键绑定详解

key-binding: https://crazylxr.github.io/spacemacas-zh_CH-doc/binding-keys.html 概述&#xff1a;Emacs的键绑定方式看起来花样繁多&#xff0c;其本质上都是同一个机制 (define-key keymap key def) 这里的key是你要绑定的键。keymap是这个key所属的集合&#xff0c;不…