gomodule版本号gomod版本管理
大家好,今天给各位分享go module 版本号的一些知识,其中也会对go mod 版本管理进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!
本文目录
be going to结构在初中英语教学中地位和作用Pokemon go Incense怎么用Pokemon go熏香使用方法Cmake如何入门?be going to结构在初中英语教学中地位和作用这个结构表示一般将来时,在初中英语教学中很重要,有专门的一单元来讲这个结构,这个结构在英语教学中地位和作用在语法中占比很重要。
“begoingto
+动词原形”结构用来表示按照主观意图打算或按计划,安排将要做的事,有“打算、就要”的意思。也常用于表示从迹象上表明将要发生的事情,多指个人主观臆断的推测。
Pokemon go Incense怎么用Pokemon go熏香使用方法点击屏幕下方精灵球,在打开的菜单中选择右边的items,在这里找到incense,点选,道具出现在屏幕上后再点一下,就会看到周围有一圈粉色气息,会持续半个小时,在此期间会有pokemon不断跑到粉色气息范围里来,你所处位置越繁华,来的越多越快。
如果是不怎么繁华的地方的话30分钟过去也来不了几只……另外,注意你选择的是哪一种熏香,如果是普通的incense,效果范围会跟着你行动并只对你有效;如过是LureModule,效果只能维持在选定的pokestop周围但对周围的所有玩家有效,特效也从粉色气息变成更加华丽的类似撒花瓣的效果。
Cmake如何入门?WhyCMake?
先回答括号中的问题:被逼的。
这三个字是认真的。
不管CMake是否是一个优秀的构建工具,不管你是否认同CMake,都无法否认CMake目前是C++的defactobuildsystem[1]。
所以在社区以及生态的影响下,使用CMake作为构建工具的项目会越来越多。
一个佐证是,即使是微软、Google以及Facebook这三家公司都有自己的C++构建系统,他们开源的项目仍支持使用CMake构建;并且CMake是除了官方构建系统之外的推荐构建系统。
如何学习CMake
首先反对认为CMake不需要入门的观点:
cmake还需要入门?这种工具性质的东西,你只要用到哪里学到哪里就行了,如果需要入门那就说明这个工具做的不怎么样。
这句话后半句是符合事实的,CMake这个工具不仅是做的不怎么样,而且做的....一言难尽....以至于这个问题下就有回答说不要跳CMake这个坑的;更多的吐槽可以参考如何评价CMake这个问题。
所以自CMakev3.0开始(严格的来说是v3.2[2]),社区开始了浩浩荡荡的ModernCMake的运动,试图通过引入一些新的特性并搭配推荐做法来提升用户的生活质量。
嗯,另一个广泛喊着modernization的社区刚好是C++社区...
又恰好这俩的现代化用法的相同之处在于需要摒弃老的、传统的观念&使用方法,使用新的、现代化的惯用法。
打一个可能不太准
的比喻:说CMake用到哪学到哪就行了和说C++用到哪学到哪就行了一样;如果你本身对这块领域已经很有经验,那么这样做是没问题的;但是对于一个新人来说,无异于让他自己去踩雷。另一个上来就直接扔给对方一个CMakedocumentation让他学的做法也是非常糟糕的;这就好比一个新手说要学习C++,你直接朝他扔了cppreference...
学习(Modern)CMake的合适路径
0x00起手式
这里假设题主以及其他想入门CMake的人像我一样鶸,下面是我个人总结的比较适合的学习路径。
首先默念三遍并记住口诀:
Declareatarget
Declaretarget'straits
It'sallaboutt
然后clonehttps://github.com/ttroy50/cmake-examples这个项目到本地,把里面的
01-basic(跳过E-installing,因为和依赖有关,后面会说)
02-sub-projects
两个目录认真的学习一遍,最好自己能够动手跟着做一遍。
每学习完一个小节,把前面的三句口诀复习一下
每遇到一个不认识的命令,在EffectiveModernCMake这个页面里搜索一下,看看这个命令是否取代了某个老命令。
cmake-examples这个项目大概是我在Github上能找到的最符合“深入浅出”这四个字的。不仅例子符合ModernCMake,并且每个步骤都会有详细的注释来解释“是什么,为什么”。
例如第一节的HelloCMake,只有短短的几行:
#SettheminimumversionofCMakethatcanbeused
#Tofindthecmakeversionrun
#$cmake--version
cmake_minimum_required(VERSION3.5)
#Settheprojectname
project(hello_cmake)
#Addanexecutable
add_executable(hello_cmakemain.cpp)
而StaticLibrary一节,也只包含了最核心的内容:
cmake_minimum_required(VERSION3.5)
project(hello_library)
############################################################
#Createalibrary
############################################################
#Generatethestaticlibraryfromthelibrarysources
add_library(hello_librarySTATIC
src/Hello.cpp
)
target_include_directories(hello_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
############################################################
#Createanexecutable
############################################################
#Addanexecutablewiththeabovesources
add_executable(hello_binary
src/main.cpp
)
#linkthenewhello_librarytargetwiththehello_binarytarget
target_link_libraries(hello_binary
PRIVATE
hello_library
)
考虑到我给这个项目也提过PR,这里也算有私心吧XD。
而之所以先看01和02是因为这两个目录里的内容已经涵盖了至少80%的使用场景;一下学太多很容易出现遭遇知识洪水的无力感而早早放弃。
对于入门学习来说,知识是螺旋上升的;同时照着优秀的例子learningbydoing可以很好缓解恐惧感。这里算是给蓝色的回答提供教材。
EffectiveModernCMake这里的作用类似于C++那几本Effective。
0x01紧跟步伐&拓展
前面讲过,CMake目前正处于现代化运动当中,新版本的迭代也非常快(最新版已经是v3.16了,并且已经内建支持了PCH),因此有一些之前认为是modernpractice的做法可能在后续的版本已经显得不那么好了。(别紧张,前面说过知识是螺旋式上升的)
所以如果你还想在这个方面有所深入,最好的方式就看各种会议的talk,包括他们的slides。
这里个人比较推荐的几个有:
EffectiveCMake:arandomseletionofbestpractices--DanielPfeifer
EmbracingModernCMake:HowtorecognizeandusemodernCMakeinterfaces--StephenKellyATDublinC++Meetup
ModernCMakeformodulardesign--MathieuRopertATCppCon-2017
MoreModernCMake:WorkingWithCMake3.12AndLater--DenizBahadirATMeetingC++2018
对应的slides和演讲的视频都可以搜到。
建议:不要试图一次全看懂,遇到不理解或者不认可的可以先跳过
如果你发现上面的几个slides的推荐做法有冲突也别紧张,说不定就是moremodern对modern的一次修正呢。
这里顺带举个例子来说明一下moderncmake发展的有多快。
因为CMake的变量很容易泄露到其他作用域去,所以ModernCMake有一个惯用法就是AvoidUnnecessaryVariables。对于项目的源文件,不依赖变量直接加到target上,同时可以通过generatorexpression设置不同平台的文件:
add_executable(hello_cmakemain.cpp)
target_source(hello_cmake
PRIVATE
foo.h
foo.cpp
lt;lt;BOOL:${WIN32}>:
#forWindows
>
lt;lt;NOT:lt;BOOL:${WIN32}>>:
#forPOSIX
>
)
在v3.11之前,add_xxx()定义一个target时,一定要有一个文件(sourceparameter),但是自v3.11开始这个约束被去掉了。所有源码文件可以通过target_source()引入,避免出现创建library时有一个源码文件孤零零的放在add_library()中显得很不协调。
0x02第三方
依赖引入如何引入&管理第三方依赖是一个时常能够在C++社区引发广泛讨论的话题。
众所周知,迄今为止C++至少有89种构建系统以及至少64种依赖管理方案,这还是建立在连module都没有情况下。
ModernCMake下引入第三方依赖目前整体上主要有两种方式。
第一种是Install&FindPackage
安装可以有多种途径,包括不仅限于:Linux系统的各包管理器;vcpkg或者conan这样单独包管理器;甚至自己cmakebuild&install。
安装好第三方库之后就可以在CMake种使用find_package()引入依赖。
好处是,CMake编写方便,以及可以使用不支持CMake的第三方库
但是这种方式的缺点也很明显:操作复杂度和二进制模块的ABI问题。
注:headeronly的库也可以安装,但是不影响以下讨论。
操作复杂度:
使用系统包管理器安装的库版本都比较老,想要新的且指定版本的库需要费工夫
vcpkg不支持库版本指定,一不小心所有
依赖都更新了;想一想没有gomod甚至没有vendor机制前的gopackageconan倒是支持版本控制,库更新的也勤快,并且可以针对项目单独指定依赖;但是库少是真的,并且对CMake使用上是侵入式的
另外一个蛋疼的是ABI。如果你安装的依赖库是希望被不同的项目直接使用,那么你迟早会掉到这个坑里。
在Windows上使用MSVC作为编译器的话,闭着眼睛都能发现:
Debug和Releasebuild是无法兼容链接在一起的
/MT和/MD是无法链接在一起的
X86和X64是无法链接在一起的
甚至有时候不同minor版本的构建也是无法链接在一起的(官方保证ABI但是帮同事解决链接问题时又遇到)
那么请问你应该安装的二进制是哪个配伍的呢?
Linux上坑稍微少一点,但是如果库作者自己不注意,或者安装的时候flags手抖了,也容易出现问题。
哦,注意你的GCC是不是开了CXX_11_ABI....
当然你也可以像vcpkg一样把允许所有的组合下二进制都构建安装一遍...
但是这里还有一个坑:多个ABI版本的二进制库如果要共存,需要库作者仔细谨慎的编写Install模块!
前面推荐的slides里有不少关于如何正确编写Export&Install的内容;以及,你现在可以把cmake-examples里的例子看完了:-)。
如果依赖不怎么经常变化的话,通过dockerimage把第三方包都装好,感觉上可能会比较省事?
第二种方式是源码依赖。
源码依赖的意思是说,你可以访问依赖的完整源代码,因此构建的时候是第三方依赖先构建,然后再构建你的工程。
注意,源码依赖模式下,第三方依赖一样也可以是静态库、动态库。
优点是,你可以精细控制整个构建过程;因为工具链&参数是统一的,所以没有ABI的问题。
缺点有如下几个:
构建时间长,因为第三方依赖也要构建;同时不同的项目如果依赖同一个库,需要分别构建。
需要依赖库支持CMake,或者有人为依赖库提供好CMake工程描述
源码依赖在CMake中通过add_subdirectory()添加依赖源码文件夹实现。
也可以通过ExternalProjectAdd以及v3.11开始提供的FetchContentModule来完成自动化。
Google是源码依赖的拥趸,他们开源的abseil-cpp、grpc-cpp等都推荐使用源码依赖的方式进行构建。
研究过Chromium的人想必这辈子都忘不了depot_tools和gclient....
这里单独提一下FetchContentModule。
这个模块是v3.11开始有的,并且在v3.14得到了进一步完善。它的核心功能是帮你从指定的VCS地址(比如gitrepo,SVNrepo)或者URL下载依赖,并自动通过add_subdirectory()进入你的工程。
并且这一切发生在configurationstage。
grpc-cpp的官方文档就提供了使用FetchContent来引入的例子:
include(FetchContent)
FetchContent_Declare(
gRPC
GIT_REPOSITORYhttps://github.com/grpc/grpc
GIT_TAGv1.25.0
)
FetchContent_MakeAvailable(gRPC)
add_executable(my_exemy_exe.cc)
target_link_libraries(my_exegrpc++)
如果你决定使用FetchContent,不妨考虑一下CPM这个CMake扩展。
CPM在FetchContent和传统的Packagedependency的基础之上做了很多整合,支持:
指定一个全局的三方源码依赖缓存文件夹,避免多个项目重复拉取同一个版本的依赖源码
通过参数fallback到find_package()的方式使用localpackage。
依赖的options控制
最后,希望能在有生之年看到defactopackagemanager出现的那天。。
好了,本文到此结束,如果可以帮助到大家,还望关注本站哦!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 931614094@qq.com 举报,一经查实,本站将立刻删除。