Lines of
script/ygopro_编译.html
from check-in 6f99fc6a2a
that are changed by the sequence of edits moving toward
check-in d8be18d9bf:
1: <!DOCTYPE html>
2: <html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
3: <head>
4: <meta charset="utf-8" />
5: <meta name="generator" content="pandoc" />
6: <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
7: <title>ygopro_编译</title>
8: <style>
9: code{white-space: pre-wrap;}
10: span.smallcaps{font-variant: small-caps;}
11: div.columns{display: flex; gap: min(4vw, 1.5em);}
12: div.column{flex: auto; overflow-x: auto;}
13: div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
14:
15: ul.task-list[class]{list-style: none;}
16: ul.task-list li input[type="checkbox"] {
17: font-size: inherit;
18: width: 0.8em;
19: margin: 0 0.8em 0.2em -1.6em;
20: vertical-align: middle;
21: }
22: .display.math{display: block; text-align: center; margin: 0.5rem auto;}
23: </style>
24: <style type="text/css">@media screen and (min-aspect-ratio:1/1) {html {background-color: f8f8f8;background-image:linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%), linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%);background-size: 8px 8px;background-position: 0 0, 16px 8px;}body {border: solid #a0a0a0 1px ;border-radius: 20px ;padding: 26px ;margin: 16px ;color: #101010 ;background: linear-gradient(to right, #efefefff, #efefeffc);padding: 2em 11%;line-height: 2.1em;box-shadow: 0px 0px 1px rgba(160, 160, 160, 1), 0px 0px 1px rgba(160, 160, 160, 1);}}h1,h2,h3,h4,h5,h6 {font-size: 1.5em;color: #3F5770;border-bottom: 1px solid #dddddd;margin: 1.2em 0em;}a {list-style: none;border-right: 0.3em solid #5183C466;border-left: 0.3em solid #5183C466;padding: 0.2em 0.4em;margin-bottom: 0.2em;margin-top: 0.3em;background-color: white;text-decoration-color: blue;border-radius: 0.2em;}a:visited {color: blue;text-decoration-color: white;}a:active {color: red;}nav ul li {margin: 1.2em 0em;}p::before {}p {margin: 1.2em 0;letter-spacing: 0.15em;}.title {background-color: white;font-size: 2em;text-align: center;}b {background-color: white;list-style: none;border-right: 0.3em solid #5183C466;border-left: 0.3em solid #5183C466;padding: 0.2em 0.4em;margin-bottom: 0.2em;margin-top: 0.3em;border-radius: 0.2em;}details {border-bottom: 1px solid #dddddd;}details > summary {list-style: none;border-right: 0.3em solid #5183C466;border-left: 0.3em solid #5183C466;padding: 0.2em 0.4em;margin-bottom: 0.2em;margin-top: 0.3em;outline: none;border-radius: 0.2em;}pre {background: #f6f6f6;border-left: 0.5em solid #ccc;padding: 0.4em;border-radius: 0.2em;overflow-wrap:break-word;}pre:active {color: red;}code {font-family: "Verdana";}button {background: #ffffff;color: #20894d;}button:active {color: red;}</style>
25: <!--[if lt IE 9]>
26: <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
27: <![endif]-->
28: </head>
29: <body>
30: <header id="title-block-header">
31: <h1 class="title">ygopro_编译</h1>
32: </header>
33: <nav id="TOC" role="doc-toc">
34: <ul>
35: <li><a href="#前言" id="toc-前言"><span class="toc-section-number">1</span> 前言</a></li>
36: <li><a href="#新建文件夹" id="toc-新建文件夹"><span class="toc-section-number">2</span> 新建文件夹</a></li>
37: <li><a href="#编译器" id="toc-编译器"><span class="toc-section-number">3</span> 编译器</a></li>
38: <li><a href="#lua" id="toc-lua"><span class="toc-section-number">4</span> lua</a></li>
39: <li><a href="#sqlite3" id="toc-sqlite3"><span class="toc-section-number">5</span> sqlite3</a></li>
40: <li><a href="#freetype" id="toc-freetype"><span class="toc-section-number">6</span> freetype</a></li>
41: </ul>
42: </nav>
43: <h1 data-number="1" id="前言"><span class="header-section-number">1</span> 前言</h1>
44: <p>来,走起,我们来编译一个小且可用的 ygopro 。</p>
45: <p>功能不求全,<b>只要有</b>残局功能就够了。</p>
46: <h1 data-number="2" id="新建文件夹"><span class="header-section-number">2</span> 新建文件夹</h1>
47: <p>万事第一步,先新建个文件夹……</p>
48: <p>然后,不做了,等一年后再来看,进度 0%,哈哈,这才是正常轨迹。</p>
49: <p>上面虽然是玩笑话,但也估摸着是我的真实经历,只不过我这个拖延王<b>拖延了</b>大概六年。</p>
50: <p>好了,给这个文件夹改名吧。</p>
51: <p>我则取名叫:</p>
52: <pre><code>ygopro</code></pre>
53: <h1 data-number="3" id="编译器"><span class="header-section-number">3</span> 编译器</h1>
54: <p>编译时,一个<b>很麻烦</b>的东西就是编译器。</p>
55: <p>很长一段时间,我都不知道到哪里去下编译器,也不知道编译器的名字叫什么。</p>
56: <p>像这种基础性的东西难道不应该有某某一个人把它们汇总起来让人随便下吗?</p>
57: <p>后来我发现,诶,还真有,但那人的网站在百度上很难搜。</p>
58: <p>现在的搜索引擎,早不名副其实了。</p>
59: <p>我们要下载的编译器叫 msvc ,准确点,应该叫 MSVC 。</p>
60: <p>不过我懒得换大小写,后文直接叫 msvc 了。</p>
61: <p>msvc 是一家叫微软的公司出的,这公司现在很鸡贼,把 msvc
62: 的下载页面给隐藏了,狂推 vs 的下载。</p>
63: <pre><code>https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools</code></pre>
64: <p>下载下来之后,会有一个 exe ,直接进行执行。</p>
65: <p>然后就会有一大堆东西让你选,你挑着系统 sdk 与
66: c++编译工具安装就行了。</p>
67: <p>但这里会冒出来一个大问题:</p>
68: <p>下不动!</p>
69: <p>网络问题,我还真没法解决。</p>
70: <p>中国的网络封锁太强,自己看情况想办法绕过去吧。</p>
71: <p>就算我这写了一点解决网络问题的方法,以现在的封锁趋势,过一段时间也就不能用了。</p>
72: <p>不过,你还是有可能下得动的,因为彻底封死网络会伤某些人的心,所以现在是采用人群分化的方法来封锁网络,顺便还能挑起人群之间的内部矛盾。</p>
73: <p>安装好编译器之后,桌面上又没快捷方式,不知道该怎么打开。</p>
74: <p>这时应该打开 windows 的搜索功能,用快捷键就能打开了,我用的是 win8.1
75: 系统,可以用 win+s 组合键打开。</p>
76: <p>然后输入:</p>
77: <pre><code>comm</code></pre>
78: <p>你查字典大概是查不到这单词的,因为这是我记不住那个完整名称而记下来的简写。</p>
79: <p>全名应该是「命令行」这三个字的英文版。</p>
80: <p>你输入这单词之后会出现一堆黑框框,选「不带 x64 」的黑框框打开。</p>
81: <p>你这样打开之后,看起来它仅仅只是打开个 cmd
82: 控制台而已,其实它调用了一堆脚本来设置各组件的环境变量。</p>
83: <p>比较可惜的是,这些它设置的环境变量它不会告诉你,这就导致很多人其实做了无用功去重复做了这些脚本已经帮他们做好的事。</p>
84: <p>到这里,编译器就准备好了。</p>
85: <p>而且它也设置了 32 位的环境。</p>
86: <h1 data-number="4" id="lua"><span class="header-section-number">4</span> lua</h1>
87: <p>先下载 lua 的源码:</p>
88: <pre><code>https://www.lua.org/download.html</code></pre>
89: <p>直接下最新版本。</p>
90: <p>顺便一说, lua5.3 有 bug ,性能也不如 lua5.4 。</p>
91: <p>下完之后,解压,会出现一大堆文件,别怕。</p>
92: <p>先在 ygopro 下建一个文件夹:</p>
93: <pre><code>lib</code></pre>
94: <p>现在的目录结构是:</p>
95: <pre><code>ygopro
96: |——|—— lib</code></pre>
97: <p>再建一个文件夹:</p>
98: <pre><code>ygopro
99: |—— lib
100: |——|—— lua</code></pre>
101: <p>把 lua 源码的 src 文件夹复制过来:</p>
102: <pre><code>ygopro
103: |—— lib
104: |——|—— lua
105: |——|——|—— src</code></pre>
106: <p>注意哦,不是光把文件复制过来就可以了,你自己本身也需要对这些源码的特性有一个基本的了解。</p>
107: <p>比如 lua 的这个源码,就需要删除两个文件:</p>
108: <pre><code>lua.c
109: luac.c</code></pre>
110: <p>这是因为这两个文件里都有主函数。</p>
111: <p>这里要特别讲一下,什么叫主函数。</p>
112: <p>主函数就是应用程序的入口函数,相当于一座城堡的大门,想进城堡旅游,就得进门,不然进不去的。</p>
113: <p>有些人学程序学四个学期了仍然不知道什么是主函数,这其实都很正常,因为各人有各人的局限性。</p>
114: <p>好了,接下来就要开始编译了。</p>
115: <p>你也许会奇怪,这不是 lua 吗?</p>
116: <p>又不是 ygopro 。</p>
117: <p>怎么现在就要开始编译了?</p>
118: <p>编译其实分两步,一步是编译,一步是连接。</p>
119: <p>我们先编译,等到了最后再进行连接。</p>
120: <p>打开之前下载的 msvc ,把它的目录转到 ygopro ,然后输入:</p>
121: <pre><code>cl</code></pre>
122: <p>然后应该会报错。</p>
123: <p>加个参数:</p>
124: <pre><code>cl /c ./lib/lua/src/*.c</code></pre>
125: <p>那个梅花号是通配符,这样子会把那个目录下的所有后缀名为「 c
126: 」的文件都给编译了。</p>
127: <p>也许你会奇怪,这就编译完了?</p>
128: <p>原来编译这么简单。</p>
129: <p>别人都封装好了,当然简单了。</p>
130: <p>其实就这么简单的事,窗户纸不捅破,就一直<b>做不了</b>。</p>
131: <p>接下来,我们开优化:</p>
132: <pre><code>cl /O2 /c ./lib/lua/src/*.c</code></pre>
133: <p>代码速度慢一点,没啥大关系,还有编译器优化可以帮我们。</p>
134: <p>接下来讲点底层。</p>
135: <p>电脑里其实啥也没有,只有 01 ,我再强调一下,「 0 」、「 1 」。</p>
136: <p>那这些 01 是怎么运行的?</p>
137: <p>01
138: 根本就运行不了,必须有东西承载着它们,而承载它们的那个东西理所应当就是计算机的底层吧?</p>
139: <p>你可以把那个东西看成是一个开关,它明显有两种状态,一种是开,一种关。</p>
140: <p>于是我们可以「把开叫做 0 ,把关叫做 1 」,也可以「把开叫做 1
141: ,把关叫做 0 」</p>
142: <p>但这样子,我们人与人之间就不好互相交流了,于是有些组织就给这些名字定了规范。</p>
143: <p>好了,你现在已经把 01 与实物联系起来了,懂了。</p>
144: <p>然后再把刚才的忘掉。</p>
145: <p>因为刚才这个模型虽然合理,但其实是用来描述继电器的。</p>
146: <p>计算机内部使用的是半导体——它会有一个高电平,一个低电平。</p>
147: <p>于是我们可以像把开关的开关状态与 01
148: 联系起来一样,把半导体的电平高低状态与 01 联系起来。</p>
149: <p>这个所谓的电平具体是指啥,我已经忘了,不过总不外乎是「电压」、「电流」这些与电相关的量度。</p>
150: <p>你小时候家里经常停电吗?</p>
151: <p>如果有过停电或电烧电器的经历,那么应该会有「电不稳定」的印象。</p>
152: <p>电平受制于电的不稳定,所以它是不精确的。</p>
153: <p>电平是低于某个临界点,就属于低电平,高于某个临界点,就属于高电平。</p>
154: <p>这个临界点是人定的。</p>
155: <p>接下来,不讲底层了。</p>
156: <p>01 往上可以组建逻辑门,而汇编编程语言可以指导逻辑门的运行。</p>
157: <p>但问题在于各个商家给逻辑门定的汇编语言是不一样的,于是我们需要一个通用的汇编语言,而这就是
158: c 语言的别称——「便携式汇编语言」。</p>
159: <p>一门编程语言可以大致分为三部分:</p>
160: <p>语法、标准库、自定义库。</p>
161: <p>lua 会用到 c 语言的标准库,而我们从上面的过程可以看到系统肯定会有 c
162: 语言标准库。</p>
163: <p>加个参数:</p>
164: <pre><code>cl /MD /O2 /c ./lib/lua/src/*.c</code></pre>
165: <p>这样子, lua 就会采用系统自带的 c 语言标准库了。</p>
166: <p>但仅仅是这样子还不行,因为 ygopro 不是一个纯 c 语言的项目。</p>
167: <p>这里的 lua 需要采用 cpp ,也就是 c++的方式进行编译:</p>
168: <pre><code>cl /TP /MD /O2 /c ./lib/lua/src/*.c</code></pre>
169: <p>然后由于 cpp
170: 的特性,你会收到一堆报错,此时编译器会提醒你再加个参数:</p>
171: <pre><code>cl /EHsc /TP /MD /O2 /c ./lib/lua/src/*.c</code></pre>
172: <p>好,大功告成,这就算把 lua 编译完了。</p>
173: <p>不过,这时候,你的目录下会有一大堆的 obj 文件,不好看。</p>
174: <p>于是输入:</p>
175: <pre><code>lib /OUT:lua.lib *.obj</code></pre>
176: <p>这就把所有的 obj 文件合成了一个文件了。</p>
177: <p>所以可以把 obj 文件全部删了:</p>
178: <pre><code>del *.obj</code></pre>
179: <p>也就是说,我们由一堆文件中编译出了一个文件:</p>
180: <pre><code>lua.lib</code></pre>
181: <h1 data-number="5" id="sqlite3"><span class="header-section-number">5</span> sqlite3</h1>
182: <p>接下来,我们需要下载一个很厉害的软件,作者是理查德·希普。</p>
183: <p>这一回应该不会遇到网络问题了:</p>
184: <pre><code>https://www.sqlite.org/index.html</code></pre>
185: <p>虽然,这一回我们不会再遇到网络问题,但可能会遇到这个网站的质疑:</p>
186: <p>你到底是不是<b>人</b>?</p>
187: <p>这是因为有些中国人恶意进攻这个网站,于是理查德专门把防范机器人的机制加强了。</p>
188: <p>把解压后的目录复制过来:</p>
189: <pre><code>ygopro
190: |—— lib
191: |——|—— lua
192: |——|——|—— src
193: |——|—— sqlite3</code></pre>
194: <p>然后编译:</p>
195: <pre><code>cl /MD /O2 /c ./lib/sqlite3/*.c</code></pre>
196: <p>然后再连接与清理一下即可。</p>
197: <p>其实 sqlite3 非常强,但是 ygopro
198: 并没有对它擅加利用,这一点也体现在,你看这次的编译非常简单吧。</p>
199: <p>编译简单是因为没有设置那些解放 sqlite3 力量的宏。</p>
200: <h1 data-number="6" id="freetype"><span class="header-section-number">6</span> freetype</h1>
201: <p>下载:</p>
202: <pre><code>http://www.freetype.org</code></pre>
203: <p>目录结构:</p>
204: <pre><code>ygopro
205: |—— lib
206: |——|—— lua
207: |——|——|—— src
208: |——|—— sqlite3
209: |——|—— freetype
210: |——|——|—— src
211: |——|——|—— include
212: |——|——|—— builds</code></pre>
213: <p>编译:</p>
214: <pre><code>cl /MD /O2 /c /D FT2_BUILD_LIBRARY -I ./lib/freetype/include</code></pre>
215: <p>可以发现,上面添加了头文件所在的文件夹。</p>
6f99fc6a2a 2023-10-14 216: <p>但奇怪的是,怎么没看到c文件?</p>
217: <p>因为这一次要编译的文件太多了:</p>
218: <pre><code>str["freetype_文件表"] = {
219:
220: "src/autofit/autofit.c"
221: , "src/base/ftbase.c"
222: , "src/base/ftbbox.c"
223: , "src/base/ftbdf.c"
224: , "src/base/ftbitmap.c"
225: , "src/base/ftcid.c"
226: , "src/base/ftfstype.c"
227: , "src/base/ftgasp.c"
228: , "src/base/ftglyph.c"
229: , "src/base/ftgxval.c"
230: , "src/base/ftinit.c"
231: , "src/base/ftmm.c"
232: , "src/base/ftotval.c"
233: , "src/base/ftpatent.c"
234: , "src/base/ftpfr.c"
235: , "src/base/ftstroke.c"
236: , "src/base/ftsynth.c"
237: , "src/base/fttype1.c"
238: , "src/base/ftwinfnt.c"
239: , "src/bdf/bdf.c"
240: , "src/cache/ftcache.c"
241: , "src/cff/cff.c"
242: , "src/cid/type1cid.c"
243: , "src/gzip/ftgzip.c"
244: , "src/lzw/ftlzw.c"
245: , "src/pcf/pcf.c"
246: , "src/pfr/pfr.c"
247: , "src/psaux/psaux.c"
248: , "src/pshinter/pshinter.c"
249: , "src/psnames/psmodule.c"
250: , "src/raster/raster.c"
251: , "src/sfnt/sfnt.c"
252: , "src/sdf/sdf.c"
253: , "src/smooth/smooth.c"
254: , "src/truetype/truetype.c"
255: , "src/type1/type1.c"
256: , "src/type42/type42.c"
257: , "src/winfonts/winfnt.c"
258: , "src/svg/ftsvg.c"
259: , "builds/windows/ftsystem.c"
260: , "builds/windows/ftdebug.c"
261: }</code></pre>
262: <script>
263:
264: document.onclick = function(event) {
265:
266: var target = event.target
267:
268: if (target.tagName == "PRE"
269: || target.tagName == "CODE") {
270: if (window.getSelection().toString() !== "") {
271: return
272: }
273: var range = document.createRange();
274: range.selectNodeContents(target);
275: window.getSelection().removeAllRanges();
276: window.getSelection().addRange(range);
277: var successful = document.execCommand("copy");
278: target.removeAttribute("contenteditable");
279: window.getSelection().removeAllRanges();
280: }
281:
282: }
283:
284: </script>
285: </body>
286: </html>