clang 编译不过去这个是啥原因

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了clang 编译不过去这个是啥原因相关的知识,希望对你有一定的参考价值。

参考技术A 1,Buildllvm/clang/lldb/lld3.5.0等组件  1.0准备:  至少需要从llvm.org下载llvm,cfe,lldb,compiler-rt,lld等3.5.0版本的代码。  $tarxfllvm-3.5.0.src.tar.gz  $cdllvm-3.5.0.src  $mkdir-ptools/clang  $mkdir-ptools/clang/tools/extra  $mkdir-ptools/lld  $mkdir-pprojects/compiler-rt  $tarxfcfe-3.5.0.src.tar.xz-Ctools/clang--strip-components=1  $tarxfcompiler-rt-3.5.0.src.tar.xz-Cprojects/compiler-rt--strip-components=1  $tarxflldb-3.5.0.src.tar.xz-Ctools/clang/tools/extra--strip-components=1  $tarxflld-3.5.0.src.tar.xz-Ctools/lld--strip-components=1  1.1【可选】使用clang--stdlib=libc++时,自动添加-lc++abi。  libc++组件可以使用gcclibstdc++的supc++ABI,也可以使用c++abi,cxxrt等,实际上自动添加-lc++abi是不必要的,这里这么处理,主要是为了方便起见。实际上完全可以在“clang++-stdlib=libc++”时再手工添加-lc++abi给链接器。  这里涉及到链接时DSO隐式还是显式的问题,早些时候ld在链接库时会自动引入由库引入的依赖动态库,后来因为这个行为的不可控性,所以ld链接器的行为做了修改,需要显式的写明所有需要链接的动态库,才会有手工添加-lc++abi这种情况出现。  ---llvm-3.0.src/tools/clang/lib/Driver/ToolChain.cpp2012-03-2618:49:06.663029075+0800  +++llvm-3.0.srcn/tools/clang/lib/Driver/ToolChain.cpp2012-03-2619:36:04.260071355+0800  @@-251,6+251,7@@  switch(Type)  caseToolChain::CST_Libcxx:  CmdArgs.push_back("-lc++");  +CmdArgs.push_back("-lc++abi");  break;  caseToolChain::CST_Libstdcxx:  1.2【必要】给clang++添加-fnolibgcc开关。  这个开关主要用来控制是否连接到libgcc或者libunwind。  注:libgcc不等于libunwind。libgcc_eh以及supc++的一部分跟libunwind功能相当。  注:libgcc_s和compiler_rt的一部分相当。  这个补丁是必要的,不会对clang的正常使用造成任何影响,只有在使用“-fnolibgcc"参数时才会起作用。  之所以进行了很多unwind的引入,主要是为了避免不必要的符号缺失麻烦,这里的处理相对来说是干净的,通过as-needed规避了不必要的引入。  ---llvm-static-3.5.0.bak/tools/clang/lib/Driver/Tools.cpp2014-09-1013:46:02.581543888+0800  +++llvm-static-3.5.0/tools/clang/lib/Driver/Tools.cpp2014-09-1016:03:37.559019321+0800  @@-2060,9+2060,15@@  ".a");    CmdArgs.push_back(Args.MakeArgString(LibClangRT));  -CmdArgs.push_back("-lgcc_s");  -if(TC.getDriver().CCCIsCXX())  -CmdArgs.push_back("-lgcc_eh");  +if(Args.hasArg(options::OPT_fnolibgcc))  +CmdArgs.push_back("--as-needed");  +CmdArgs.push_back("-lunwind");  +CmdArgs.push_back("--no-as-needed");  +else  +CmdArgs.push_back("-lgcc_s");  +if(TC.getDriver().CCCIsCXX())  +CmdArgs.push_back("-lgcc_eh");  +      staticvoidaddProfileRT(  @@-7150,24+7156,50@@  boolisandroid=Triple.getEnvironment()==llvm::Triple::Android;  boolStaticLibgcc=Args.hasArg(options::OPT_static_libgcc)||  Args.hasArg(options::OPT_static);  +  +  +  if(!D.CCCIsCXX())  -CmdArgs.push_back("-lgcc");  +if(Args.hasArg(options::OPT_fnolibgcc))  +CmdArgs.push_back("--as-needed");  +CmdArgs.push_back("-lunwind");  +CmdArgs.push_back("--no-as-needed");  +else  +CmdArgs.push_back("-lgcc");    if(StaticLibgcc||isAndroid)  if(D.CCCIsCXX())  -CmdArgs.push_back("-lgcc");  +if(Args.hasArg(options::OPT_fnolibgcc))  +CmdArgs.push_back("--as-needed");  +CmdArgs.push_back("-lunwind");  +CmdArgs.push_back("--no-as-needed");  +else  +CmdArgs.push_back("-lgcc");  else  if(!D.CCCIsCXX())  CmdArgs.push_back("--as-needed");  -CmdArgs.push_back("-lgcc_s");  +if(Args.hasArg(options::OPT_fnolibgcc))  +CmdArgs.push_back("-lunwind");  +else  +CmdArgs.push_back("-lgcc_s");  if(!D.CCCIsCXX())  CmdArgs.push_back("--no-as-needed");      if(StaticLibgcc&&!isAndroid)  -CmdArgs.push_back("-lgcc_eh");  +if(Args.hasArg(options::OPT_fnolibgcc))  +CmdArgs.push_back("--as-needed");  +CmdArgs.push_back("-lunwind");  +CmdArgs.push_back("--no-as-needed");  +else  +CmdArgs.push_back("-lgcc_eh");  elseif(!Args.hasArg(options::OPT_shared)&&D.CCCIsCXX())  -CmdArgs.push_back("-lgcc");  +if(Args.hasArg(options::OPT_fnolibgcc))  +CmdArgs.push_back("--as-needed");  +CmdArgs.push_back("-lunwind");  +CmdArgs.push_back("--no-as-needed");  +else  +CmdArgs.push_back("-lgcc");    //AccordingtoAndroidABI,wehavetolinkwithlibdlifweare  //linkingwithnon-staticlibgcc.  ---llvm-static-3.5.0.bak/tools/clang/include/clang/Driver/Options.td2014-08-0712:51:51.000000000+0800  +++llvm-static-3.5.0/tools/clang/include/clang/Driver/Options.td2014-09-1013:36:34.598511176+0800  @@-788,6+788,7@@  deffomit_frame_pointer:Flag,Group;  deffopenmp:Flag,Group,Flags;  deffopenmp_EQ:Joined,Group,Flags;  +deffnolibgcc:Flag,Group,Flags;  deffno_optimize_sibling_calls:Flag,Group;  deffoptimize_sibling_calls:Flag,Group;  defforce__cpusubtype__ALL:Flag;  1.3llvm的其他补丁。  llvm/clang将gcctoolchain的路径hardcode在代码中,请查阅tools/clang/lib/Driver/ToolChains.cpp。  找到x86_64-redhat-linux之类的字符串。  如果没有你系统特有的gcctripplestring,请自行添加。  这个tripplestring主要是给llvm/clang搜索gcc头文件等使用的,不影响本文要构建的toolchain  1.4构建clang/llvm/lldb  本文使用ninja。顺便说一下,llvm支持configure和cmake两种构建方式。可能是因为工程太大,这两种构建方式的工程文件都有各种缺陷(主要表现在开关选项上,比如configure有,但是cmake却没有等)。llvm-3.4.1就是因为cmake工程文件的错误而导致了3.4.2版本的发布。  综合而言,cmake+ninja的方式是目前最快的构建方式之一,可以将构建时间缩短一半以上。  mkdirbuild  cdbuild  cmake\  -GNinja\  -DCMAKE_INSTALL_PREFIX=/usr\  -DCMAKE_BUILD_TYPE="Release"\  -DCMAKE_CXX_FLAGS="-std=c++11"\  -DBUILD_SHARED_LIBS=OFF\  -DLLVM_ENABLE_PIC=ON\  -DLLVM_TARGETS_TO_BUILD="all"\  -DCLANG_VENDOR="MyOS"..  ninja  ninjainstall  如果系统原来就有clang/clang++的可用版本,可以添加:  -DCMAKE_C_COMPILER=clang\  -DCMAKE_CXX_COMPILER=clang++\  这样就会使用系统的clang++来构建llvm/clang  2,测试clang/clang++。  自己找几个简单的c/cpp/objc等编译测试一下即可。完整测试可以在构建时作ninjacheck-all  3,libunwind/libc++/libc++abi,一套不依赖libgcc,libstdc++的c++运行库。  3.1从/pathscale/libunwind获取代码。  libunwind有很多个实现,比如gnu的libunwind,path64的libunwind,还有libcxxabi自带的Unwinder.  这里作下说明:  1),gnu的libunwind会有符号缺失和冲突。  2),libcxxabi自带的Unwinder是给mac和ios用的,也就是只能在darwin体系构建。目前Linux的实现仍然不全,等linux实现完整了或许就不再需要path64的unwind实现了。  暂时建议使用pathscale的unwind实现。  mkdir-pbuild  cdbuild  cmake-GNinja-DCMAKE_C_COMPILER=clang-DCMAKE_C_FLAGS="-m64"..  ninja  mkdir-p/usr/lib  cpsrc/libunwind.so/usr/lib  cpsrc/libunwind.a/usr/lib  3.2第一次构建libcxx.  必须先构建一次libcxx,以便后面构建libcxxabi。这里构建的libcxx实际上是使用gcc的libgcc/stdc++/supc++的。  打上这个补丁来禁止libgcc的引入:  diff-Nurlibcxx/cmake/config-ix.cmakelibcxxn/cmake/config-ix.cmake  ---libcxx/cmake/config-ix.cmake2014-06-2506:57:50.000000000+0800  +++libcxxn/cmake/config-ix.cmake2014-06-2509:05:24.980350544+0800  @@-28,5+28,4@@  check_library_exists(cprintf""LIBCXX_HAS_C_LIB)  check_library_exists(mccos""LIBCXX_HAS_M_LIB)  check_library_exists(rtclock_gettime""LIBCXX_HAS_RT_LIB)  -check_library_exists(gcc_s__gcc_personality_v0""LIBCXX_HAS_GCC_S_LIB)  编译安装:  mkdirbuild  cdbuild  cmake\  -GNinja\  -DCMAKE_INSTALL_PREFIX=/usr\  -DCMAKE_C_COMPILER=clang\  -DCMAKE_CXX_COMPILER=clang++\  ..  ninja  ninjainstall  3.3,测试第一次构建的libcxx。  使用"clang++-stdlib=libc++-otesttest.cpp-lstdc++"编译简单c++代码,检查是否出错。(如果前面构建clang是已经apply了c++abi的链接补丁,这里会出现找不到c++abi的情况,跳过即可)  使用"lddtest"查看test二进制动态库使用情况。可以发现,test依赖于libgcc_s/libc++/libstdc++。(多少有些不爽了吧?使用了libc++居然还要依赖libstdc++?)

Swift 赋值评估无效的原因是啥?

【中文标题】Swift 赋值评估无效的原因是啥?【英文标题】:What was the reason for Swift assignment evaluation to void?Swift 赋值评估无效的原因是什么? 【发布时间】:2016-03-14 09:18:56 【问题描述】:

这个问题是关于HISTORY(不是你目前对此事的看法)。

在阅读有关放弃对 Swift 的递增/递减运算符的支持的文章时,我读到了这样的文本“Swift 已经偏离了 C,因为 =、+= 和其他类似赋值的操作返回 Void(出于多种原因)”。

所以在过去的某个时候,开发人员出于某些原因有意识地决定评估分配为无效。

我正在寻找那些历史(现在)的原因。几乎就像这个线程是关于Scala 的历史原因一样。

【问题讨论】:

您能否提供有关放弃对增量/减量的支持的文章的链接?我有兴趣阅读它。 @FreeNickname,当然,看看:github.com/apple/swift-evolution/blob/master/proposals/… 在 C 中你可以使用 if i=1 之类的东西。赋值的结果返回您可以使用的值。很快,这样的语句将无法编译,原因(我认为是这样)是为了避免不必要的副作用。我可以同意这个想法,另一方面我真的不明白,为什么要++i,i++。 --i, i-- 应该从语言中删除。我至少读了两遍这篇文章,但对我来说仍然不是很清楚。 @user3441734,这可能是原因,但我认为不是。因为在 Swift 中,if 只接受布尔表达式,如果我没记错的话。所以即使i = 1 返回ifif i = 1 也不会编译,因为在Swift 中1 不是布尔值。 @greenoldman,谢谢你的链接) 我不能专门谈论 Swift,但有些人认为使用表达式来表示它的值和副作用是一种不好的做法,因为这样的代码很难理解。它还可能导致像 i = ++i + i++; 这样的代码,在 C 和 C++ 中具有未定义的行为。 【参考方案1】:

至少有一个原因是比较操作更安全。在用 C、Objective-C 等写的时候,你写过多少次了:

if (x = 2)

而不是

if (x == 2)

较新版本的编译器已针对上述情况引入了特定警告,但令人惊讶的是,多年来,缺少一个等号导致我的代码中出现难以识别的错误。

使用 Swift 类型系统,这将不是什么问题,因为返回的值很可能不符合 BooleanType 协议,但如果符合 (if x = false),您可能仍然会遇到这些错误。许多 Swift 旨在消除人们遇到的常见错误原因,包括这个。

这在 Swift 编程语言一书中的"Basic Operators" 下有说明:

与 C 和 Objective-C 中的赋值运算符不同,赋值 Swift 中的运算符本身并不返回值。下列 声明无效:

if x = y 
    // this is not valid, because x = y does not return a value

此功能可防止赋值运算符 (=) 被 实际使用等于运算符 (==) 时的意外。经过 使 if x = y 无效,Swift 帮助你避免这些 代码中的错误。

【讨论】:

我这辈子(作为开发人员 30 多年)从未犯过这个错误,但我写了很多 x=y=2 之类的代码。我为别人的错误感到受到惩罚:-)

以上是关于clang 编译不过去这个是啥原因的主要内容,如果未能解决你的问题,请参考以下文章

Unity的工程导出Xcode编译卡死,Clang占爆内存,是啥原因呢?

make的过去式和过去分词是啥?

解答VS2013编译报错不准确是什么原因

查找过去一小时内修改的文件的最简单方法是啥?

build的过去式和过去分词是啥?

编译不过去,暂时存一下