【问题标题】:Setting up ROOT from Cern in Xcode, linking the librariers correctly在 Xcode 中从 Cern 设置 ROOT,正确链接库
【发布时间】:2016-08-26 03:40:22
【问题描述】:

我想在我的 Xcode IDE 中从 CERN 设置 ROOT,但在链接库时遇到问题。我正在使用 root 6.04.14 和 xcode 7.3。 我创建了一个模拟项目,其中只有一个 .cpp,其中包含一个来自根目录的基本类(#include "TFile.h")。我可以通过以下方式从命令行编译:

clang++ -std=c++11 -I/opt/root/root-6.04.14/include/root -L/opt/root/root-6.04.14/lib/root -lCore main.cpp

现在开始在 Xcode IDE 中设置所有内容。我在头文件搜索路径中包含了“/opt/root/root-6.04.14/include/root”,Xcode 没有抱怨,所以我猜它找到了头文件。我尝试将“/opt/root/root-6.04.14/lib/root -lCore”添加到库搜索路径,但出现错误: 在 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cmath:301 包含的文件中: /opt/root/root-6.04.14/include/root/Math/math.h:65:11:错误:全局命名空间中没有名为“log1p”的成员;你的意思是简单的'log1p'吗? 返回 ::log1p(x); ^~ /opt/root/root-6.04.14/include/root/Math/math.h:63:15:注意:此处声明的“log1p” 内联双 log1p(双 x){ ^ /opt/root/root-6.04.14/include/root/Math/math.h:76:11:错误:全局命名空间中没有名为“expm1”的成员;你的意思是简单的'expm1'吗? 返回 ::expm1(x); ^~ /opt/root/root-6.04.14/include/root/Math/math.h:74:15:注意:此处声明的“expm1” 内联双 expm1( 双 x) {

等等…… 此外,当我查看 Xcode 正在运行的终端命令时(至少我认为它是这样做的),没有包含“-L/opt/root/root-6.04.14/lib/root -lCore”。然后我尝试将“-L/opt/root/root-6.04.14/lib/root -lCore”放入其他链接器标志。现在它包含在终端命令中,但仍然给我同样的错误。

问题1: 我注意到 Xcode 正在运行“/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang”,而我一直在使用 clang++,区别在哪里,我该如何更改? 问题2: 将目录添加到库搜索路径并通过链接器标志将其放入有什么区别? 问题3: 大佬,我哪里搞砸了?

【问题讨论】:

    标签: c++ xcode root-framework


    【解决方案1】:

    您可能已经知道这一点,但以防其他人偶然发现此问题,这是我在 xcode 中设置我的 ROOT (v6.06.04) 的方式。为了演示,让我们从一个全新的 xcode 项目从头开始。

    假设我们要在 xcode 中运行以下程序(注意它使用 ROOT 类)

    #include <iostream>
    #include "TApplication.h"
    #include "TCanvas.h"
    #include "TGraph.h"
    #include <vector>
    
    int main(int argc, const char * argv[]) {
        // Create a TApplication so that we can get plot the histogram
        TApplication* myApp = new TApplication("myApp", 0, 0) ;
    
        // Create some vector information
        std::vector<double> x(100), y(100) ;
    
        for (int i=0; i<x.size(); i++) {
            x[i] = i * (10.0/x.size()) ;
            y[i] = std::cos(x[i]) ;
        }
    
        // Create a TGraph
        TGraph* graph = new TGraph(x.size(), &x[0], &y[0]) ;
    
        // Create a canvas and draw the graph
        TCanvas* canvas = new TCanvas("canvas","canvas") ;
        graph->Draw("ap0") ;
        canvas->Update() ;
    
        // Run the TApplication to produce all of the plots
        myApp->Run() ;
        return 0;
    }
    

    如果您只是将此程序复制并粘贴到 xcode 中,您会看到 xcode 无法识别 ROOT 标头,并且您会收到错误 'XXX.h' file not found。这显然是因为我们需要告诉 xcode 在哪里可以找到标头。

    1. 在左侧菜单中单击您的项目
    2. 在“构建设置”下单击“+”->“添加用户定义的设置”。

    1. 这将在“用户定义”部分下添加一个参数。调用新参数“ROOTSYS”并将其指向您的 ROOT 安装的顶层目录。对我来说这是/Users/user/root_cern/root_v6.06.04/。 (注意:这一步不是绝对必要的,但可以减少其余的痛苦,并允许您更新您的 ROOT 安装,而无需更改下面的头文件和库路径)

    2. 现在(仍在“构建设置”中)转到“搜索路径”->“用户标题搜索路径”。在此字段中添加路径“$(ROOTSYS)/include”

    3. 将“搜索路径”->“始终搜索用户路径”字段设置为

    此时,我们标题上的严重错误已经消失了!不幸的是,该程序无法构建。查看构建错误表明存在大量链接错误!显然,我们需要更新链接器标志以包含我们要编译的所有 ROOT 库。

    1. 打开终端并运行$ROOTSYS/bin/root-config --libs。对我来说,输出是:

      -L/Users/user/root_cern/root_v6.06.04/lib -lCore -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lMultiProc -lpthread - wl,-rpath,/Users/user/root_cern/root_v6.06.04/lib -stdlib=libc++ -lm -ldl

    2. 复制上述root-config 的输出并将其粘贴到“构建设置”->“链接”->“其他链接器标志”下。请注意,您可以使用 $(ROOTSYS) 替换您的 ROOT 安装目录路径的所有实例,并且您将来更新您的 ROOT 版本时不必更新它们。

    现在程序应该可以正常构建了!如果您仍然收到链接错误,请确保您尝试构建的 TARGET 继承了项目中的链接信息。通过转到您正在构建的目标的“其他链接器标志”并将其设置为$(inherited) 来执行此操作。您将获得 cos(x) 函数的方便图。

    几点说明:

    • 如果您不使用 TApplication,程序将在您有机会查看您的绘图之前结束。
    • 您可以通过 xcode GUI 或在绘图菜单栏中选择“文件”->“退出根”来结束程序。
    • 如果您尝试编写一个希望 ROOT 能够流式传输到文件的类,事情会变得更加复杂。可以通过向目标添加额外的“运行脚本”构建阶段来实现。不过现在,这应该可以帮助您入门。

    【讨论】:

      猜你喜欢
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-31
      • 1970-01-01
      • 2013-06-07
      • 1970-01-01
      • 2022-07-05
      • 2018-05-25
      相关资源
      最近更新 更多