欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    了 CMake 3.15,在 Windows 上用 GNU 風格的命令行使用 Clang 編譯器成為可能。這也意味著可以用Mingw-w64工具鏈來使用Clang。文末附上下載地址

    雖然可以用Mingw-w64(或MinGW)工具鏈來配置Clang,但如果你決定使用LLVM repo的Clang,它將無法正常工作。這是因為LLVM Clang for Windows是使用Microsoft Visual Studio構建的,所有內置的宏和包含的搜索路徑都是為使用Visual Studio而設置的。所以即使與MinGW工具鏈一起使用,它仍然會嘗試包含MSVC標準庫頭。

    我們做了一些實驗,發現了一個可能的工作流程,就是使用CLion與MinGW工具鏈和Clang編譯器相結合。

    這是我們的發現:

    1. 從https://www.msys2.org安裝MSYS2,請遵循其安裝指南。
    2. 使用pacman工具獲取必要的軟件包。我們安裝了以下文件(pacman -S):mingw-w64-x86_64-gccmingw-w64-x86_64-clangmingw-w64-x86_64-lldmingw-w64-x86_64-dgbmingw-w64-x86_64-makemingw-w64-x86_64-pollymingw-w64-x86_64-compiler-rt

    此Clang編譯器使用mingw-w64構建,并具有與該工具鏈相對應的路徑和宏。

    現在我們準備建立CLion工具鏈。轉到Settings/Preferences | Build, Execution, Deployment | Toolchains:

    配置了新的工具鏈后,就可以開始構建項目了。您可以使用默認的ld連接或設置lld有-DCMAKE_LINKER=lld。

    使用Clang編譯器提供的高級工具

    從理論上講,所有Clang工具都應該可以正常工作。但是,涉及編譯器-rt可能會出現問題。編譯器-rt是一組運行時庫,在Clang中使用消毒劑和配置文件是必需的,當前的compile_rt軟件包是使用MinGW構建的。但是Clang需要使用Clang和lld構建的編譯器。

    在我們的案例中,我們想使用配置文件引導的優化。進行此工作的一種方法是獲取與MSYS2中的Clang版本完全相同的版本的editor-rt源代碼。這可能具有挑戰性,因此另一個解決方案是克隆LLVM monorepo并構建所需的工具。

    對于-fprofile-instr-generate,僅構建compile -rt和llvm-profdata來合并探查器結果可能就足夠了。但是,要可靠地使用所有工具,最好也構建Clang和lld。

    幸運的是,我們已經具有該構建所需的設置。

    最后一步是將<msys2_path>/mingw64/lib\clang/<clang_version>/libwindows中的二進制文件替換為<compiler-rt_path>/cmake-build-release-mingw_clang/libwindows或<llvm_build_path>/lib/clang/<clang_version>/lib/windows中的庫。

    使用Clang進行性能分析

    有了正確的編譯器-rt庫,現在就可以使用與-fprofile-instr-generate / -fprofile-instr-use標志設置的相同的工具鏈。因為我們已經有了源代碼,所以讓我們為此實驗構建LLVM。我們還將使用-DLLVM_ENABLE_LTO=Thin進行更多優化。轉到Settings/Preferences | Build, Execution, Deployment | CMake:

    使用此CMake配置,您可以構建Clang編譯器并使用它,例如,構建自己的項目。這將生成相關的探查器信息,稍后應將其與我們之前構建的工具llvm-profdata合并。使用合并的profile_merged.profdata文件,您最終可以構建Clang編譯器的優化版本:

    使用自定義Clang和lld

    要讓gcc風格的-fprofile-generate/-fprofile-use標志正確工作,需要改變Clang路徑,并將-DCMAKE_LINKER設置為新構建的ld。你還需要一些額外的LLVM技巧:-femulated-tls和鏈接pthread


    然后,應重復使用-fprofile-instr-generate / -fprofile-instr-use執行的所有步驟。

    結論

    現在可以在Windows上使用Clang,并且不需要安裝Microsoft Visual Studio!

    我們希望在不久的將來,使用高級的clang工具將變得更加容易,并且不再需要手動構建。讓我們知道,如果您發現其他方法可以達到相同的效果!

    今天的內容你學會了嗎?前往慧都網免費下 最新版嘗試一下,并在評論分享你的想法。

    LLVM里面的Clang已經可以替換MSVC的cl.exe(MSVC的編譯過程的組織程序-driver),作為Visual Studio的獨立工具鏈,能生成PDB文件支持在Visual Studio里面的源代碼調試。為了支持替換cl.exe,clang構建會生成可執行文件clang-cl.exe,接收cl.exe的大部分參數而在內部轉換成LLVM的參數形式。

    雖然看起來是生成了一個單獨的clang-cl.exe,它實際上就是clang.exe的一個副本,如果程序名是clang.exe,還可以在命令行傳遞"--driver-mode=cl"參數啟用cl.exe的參數解析模式。所以clang-cl.exe和clang.exe是一樣的,都接受"--target=i686-pc-windows", 但是為什么clang-cl.exe卻不能解析"-triple i686-pc-windows"而clang.exe卻可以呢?

    程序本身通過檢查自身的文件名(argv[0])來檢測是不是要運行在兼容MSVC cl.exe的模式,如果文件名是"clang-cl.exe",則把對應的DriverMode放到main函數開始處的變量TargetAndMode里面(ToolChain::getTargetAndModeFromProgramName)。下面的代碼顯示了對應關系,可以看到把文件名clang.exe改成cl.exe也會有一樣的效果。

    // llvm_root\tools\clang\tools\driver\driver.cpp
    const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
      // A list of known driver suffixes. Suffixes are compared against the
      // program name in order. If there is a match, the frontend type is updated as
      // necessary by applying the ModeFlag.
      static const DriverSuffix DriverSuffixes[]={
          {"clang", nullptr},
          {"clang++", "--driver-mode=g++"},
          {"clang-c++", "--driver-mode=g++"},
          {"clang-cc", nullptr},
          {"clang-cpp", "--driver-mode=cpp"},
          {"clang-g++", "--driver-mode=g++"},
          {"clang-gcc", nullptr},
          {"clang-cl", "--driver-mode=cl"},
          {"cc", nullptr},
          {"cpp", "--driver-mode=cpp"},
          {"cl", "--driver-mode=cl"},
          {"++", "--driver-mode=g++"},
      };
    

    在上面從程序名解析出target和mode后,main函數里面緊接著的代碼檢查了返回的mode和命令行參數,只要以一個滿足則進入ClangCLMode。不過這里解析出來的ClangCLMode只用來處理命令行參數的分隔和cl.exe特有的環境變量,包括"CL"和"_CL_"。

    // llvm_root\tools\clang\tools\driver\driver.cpp
      auto TargetAndMode=ToolChain::getTargetAndModeFromProgramName(argv[0]);
    
      bool ClangCLMode=false;
      if (StringRef(TargetAndMode.DriverMode).equals("--driver-mode=cl") ||
          std::find_if(argv.begin(), argv.end(), [](const char *F) {
            return F && strcmp(F, "--driver-mode=cl")==0;
          }) !=argv.end()) {
        ClangCLMode=true;
      }
    

    再從main函數進入Driver類的對象TheDriver的BuildCompilation方法后,會調用 ParseDriverMode方法,里面會根據程序名重新獲得driver mode(ToolChain::getTargetAndModeFromProgramName),然后把driver mode字符串傳給下面的setDriverModeFromOption方法。這個方法根據傳入的driver mode選項設置成員變量Mode.

    // llvm_root\tools\clang\lib\driver\driver.cpp
    void Driver::setDriverModeFromOption(StringRef Opt) {
      const std::string OptName=getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
      if (!Opt.startswith(OptName))
        return;
      StringRef Value=Opt.drop_front(OptName.size());
    
      const unsigned M=llvm::StringSwitch<unsigned>(Value)
                             .Case("gcc", GCCMode)
                             .Case("g++", GXXMode)
                             .Case("cpp", CPPMode)
                             .Case("cl", CLMode)
                             .Default(~0U);
    
      if (M !=~0U)
        Mode=static_cast<DriverMode>(M);
    

    上面的Driver類的對象已經知道當前Mode,比如CLMode,下面會組織整個編譯過程,包括調用編譯器(clang.exe -cc1)和鏈接器(MSVC的link或者lld-link)。

    BuildCompilation緊接著會調用ParseArgStrings。ParseArgStrings調用下面的getIncludeExcludeOptionFlagMask,根據Driver的當前Mode得到include mask和exclude mask兩個掩碼,用于后面(在調用鏈ParseArgString->ParseArg->ParseOneArg的最后的方法ParseOneArg里面)決定是否接受命令行參數。比如在CLMode下就只會接受ClOption和CoreOption。

    // llvm_root\tools\clang\lib\driver\driver.cpp
    std::pair<unsigned, unsigned> Driver::getIncludeExcludeOptionFlagMasks() const {
      unsigned IncludedFlagsBitmask=0;
      unsigned ExcludedFlagsBitmask=options::NoDriverOption;
    
      if (Mode==CLMode) {
        // Include CL and Core options.
        IncludedFlagsBitmask |=options::CLOption;
        IncludedFlagsBitmask |=options::CoreOption;
      } else {
        ExcludedFlagsBitmask |=options::CLOption;
      }
    
      return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask);
    }
    

    那么CLOption和CoreOption都有哪些具體參數呢?Clang的所有命令行參數選項都定義在llvm_root\tools\clang\include\clang\driver\Options.td里面,由tablegen轉成C/C++頭文件而被代碼引用。下面是從里面截取的target的定義,看到"--target="選項是同時屬于DriverOption和CoreOption,而CoreOption在CLMode和非CLMode下均能使用。

    def target : Joined<["--"], "target=">, Flags<[DriverOption, CoreOption]>,
      HelpText<"Generate code for the given target">;

    以下是"-target"的定義,沒有定義Flags,所以在CLMode下也就不能解析,這也就解釋了最開始"clang-cl.exe"不接受"-triple i686-pc-windows"參數。

    def target_legacy_spelling : Separate<["-"], "target">, Alias<target>;
網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有