Компилировать несколько исходных (основных и заголовочных) файлов и связать их в ROOT CINT?

Позвольте мне сначала установить контекст, это Корень Церна а также CINT а также ACLiC и т.п.

Предположим, у меня есть основной macro названный macro.cpp и два заголовка h1.cpp (содержит определение функции) и h1.h содержащий объявление функции, определенной в h1.cpp Точно так же у меня есть h2.cpp а также h2.h, Основная программа macro.cpp вызывает эти функции внутри h1 а также h2, Я успешно компилировал исходные файлы, используя:

   root [0] .L h1.cpp+
root [1] .L h2.cpp+
root [2] .L macro.cpp+

который породил три .so файлы macro_cpp.so, h1_cpp.so а также h2_cpp.so, Я хочу знать, что с ними делать? Как я link их, чтобы у меня было что-то вродеmacro.out«или что-то подобное (сингл executable какой-то файл), который я могу выполнить (хотя я не знаю, как!) и достичь того, чего я хотел достичь с помощью макроса.

Замечания: Если я просто загружу все файлы, используя .L file_name.cpp и т.д. и просто выполнить основной макрос, используя .x macro.cpp тогда все отлично работает и у меня есть результаты, но это не то, что я хочу! Я хочу скомпилировать, как мы делаем в обычном g++ и, кстати, на каждом форуме все продолжают давать советы по компиляции с использованием .L file_name.cpp+ или же ++ .. Мне бы очень хотелось узнать всю историю. Потому что никто не может объяснить дальше .L file_name.cpp+ .. что дальше ? Что делать с .so и т.п.

Я новичок, буду очень признателен за простой и пошаговый ответ и объяснение.

Благодарю.

Edit-1: Я работаю с:

g ++ (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.4) 5.4.0 20160609

Edit-2: Корень связанной информации:
ROOT 5.34 / 36 (v5-34-36 @ v5-34-36, 07 декабря 2016 г., 23:31:51 на linuxx8664gcc)
CINT / ROOT C / C ++ Версия интерпретатора 5.18.00, 2 июля 2010 г.

0

Решение

Если вы хотите скомпилировать и связать, вы можете использовать стандартный компилятор вместо Cint / Aclic.
Например, если вы работаете на платформе * nix, вы можете использовать приведенные ниже примеры файлов:

h1.h

int add_one(int a);

h1.cpp

#include "h1.h"
int add_one(int a)
{
return a+1;
}

h2.h

#include <TLorentzVector.h>

TLorentzVector multiply_by_two(const TLorentzVector v);

h2.cpp

#include "h2.h"
TLorentzVector multiply_by_two(const TLorentzVector v)
{
return 2.0*v;
}

macro.cpp

#include "h1.h"#include "h2.h"
#include <TLorentzVector.h>

#include <iostream>
using std::cout;
using std::endl;

int main()
{
int a = 0;
TLorentzVector v;
v.SetPtEtaPhiM(1.0, 0.0, 0.0, 0.0);
cout<<"calling add_one on "<<a<<": "<<add_one(a)<<endl;
cout<<"calling multiply_by_two on "<<v.Pt()<<": "<<multiply_by_two(v).Pt()<<endl;
return 0;
}

Тогда вы можете скомпилировать с

g++ -c -g -Wall `root-config --cflags` h1.cpp
g++ -c -g -Wall `root-config --cflags` h2.cpp
g++ -c -g -Wall `root-config --cflags` macro.cpp

и связать с

g++ `root-config --glibs` h1.o h2.o macro.o

Исполняемый файл будет a.out:

$ ./a.out
calling add_one on 0: 1
calling multiply_by_two on 1: 2

Вы можете положить эти g++ Команды в сценарии или, когда вы начинаете иметь несколько файлов и каталогов, вы можете написать свой make-файл (или cmake). Для этого последнего шага, см., Например, учебник здесь

http://www-pnp.physics.ox.ac.uk/~brisbane/Teaching/Makefiles/Tutorial_1_Makefiles_and_ROOT.pdf

Примечание 1: одно из преимуществ использования g++ является то, что вы получите четкие сообщения об ошибках, когда что-то не компилируется. Сообщения об ошибках от Cint могут
быть трудным для понимания — хотя это очень улучшено в root 6 с Cling.

Заметка 2Еще одно преимущество использования стандартного компилятора заключается в том, что вы сможете легко связать ваш основной исполняемый файл с библиотеками, отличными от root.

1

Другие решения

Этот ответ основан в основном на ответе user2148414, но если последует ответ, вы заметите, что были некоторые проблемы с методом связывания исходных файлов (* .cpp). Мой ответ также касается другого важного объекта, называемого TApplication это сыграет решающую роль в таких приложениях с корневыми библиотеками. Следующий шаг связывания:

g++ `root-config --glibs` h1.o h2.o macro.o

скорее всего, будет отображаться множество ошибок с жалобами на корневые объекты, такие как TWhateveruser2148414ответ TLorentzVector покажет проблемы). В комментариях к этому ответу можно найти обсуждение включения различных библиотек физики, которые могут решить эту проблему, но без обсуждения этого (и мне это неудобно :)) позвольте мне записать команду, которая решает все.

Эта процедура является однострочной, которая не требует компиляции отдельных файлов, создания файлов * .cpp и * .h, как описано в этот ответ затем скомпилируйте и скомпонуйте и создайте один исполняемый файл с именем «someExecutable», используя:

g++ macro.cpp h1.cpp h2.cpp `root-config --libs --cflags` -o someExecutable

или лучше (и это надо делать)

g++ -Wall -Wextra -Werror -pedantic -std=c++14 macro.cpp h1.cpp h2.cpp `root-config --libs --cflags` -o someExecutable

Это решит мой оригинальный ответ, но для полноты я хотел бы добавить еще несколько вещей.

TApplication

Моей первоначальной мотивацией было создать приложение, которое общается сROOT«но я не хотел работать с оболочкой ROOT, CINT, ACLiC и т. Д. И хотел полностью работать с g ++. user2148414и мой ответ решит часть создания приложения, но приложение не будет служить какой-либо цели, оно будет работать, создавать гистограммы, рисовать их и делать все, но все холсты закроются в конце, когда код достигнет «return 0;«Чтобы держать полотна открытыми, нам понадобится»TApplication«. Так что рассмотрим main из user2148414ответ, я собираюсь включить еще две строки и два аргумента main:

macro.cpp

    #include "h1.h"#include "h2.h"
#include <TLorentzVector.h>

#include <iostream>
using std::cout;
using std::endl;

int main(int argc, char* argv[])  //introduced arguments to main
{

// here I introduce TApplication

TApplication* SomeApp = new TApplication("SomeApp",&argc, argv);

int a = 0;
TLorentzVector v;
v.SetPtEtaPhiM(1.0, 0.0, 0.0, 0.0);
cout<<"calling add_one on "<<a<<": "<<add_one(a)<<endl;
cout<<"calling multiply_by_two on "<<v.Pt()<<": "<<multiply_by_two(v).Pt()<<endl;

//and just before returning 0
SomeApp->Run();

return 0;
}
0

По вопросам рекламы [email protected]