clang 编译不过去这个是什么原因
展开全部
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++?)
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询