LoginSignup
2
1

More than 3 years have passed since last update.

CERN ROOT における Makeのエラー

Last updated at Posted at 2020-05-07

導入

ここでは、CERNが配布して知るROOTを使ったMakefileを作成した際に躓いたメモを書く。

環境

  • Ubuntu 18.04.4 LTS
  • ROOT 6.20/04
  • gcc 7.5.0
  • GNU Make 4.1

問題点

いままで別のバージョンのLinuxなどで使ってきた以下のMakefileが使えなくなってしまった。
いままで使っていたMakefilは以下のとおりである。

Makefile_old
TARGET = macro

SRCS = $(TARGET).cc
OBJS = $(TARGET).o

ROOTCFLAGS = $(shell root-config --cflags)
ROOTLIBS   = $(shell root-config --libs)
ROOTGLIBS = $(shell root-config --glibs)

CXXFLAGS   = $(ROOTCFLAGS) -Wall -fPIC
CXXLIBS    = $(ROOTLIBS)
CC = g++ 

$(TARGET): $(OBJS)
        $(CC) $(CXXLIBS) $(OBJS) -o $@

# suffix rule
.cc.o:
        $(CC) $(CXXFLAGS) -c $<

# clean
clean:
        rm -f $(TARGET) $(OBJS)

基本的にはこれで使えたはずなのだが、本環境に移行した際に次のようなエラーが発生し、makeできなくなってしまった。

macro.o: 関数 `__static_initialization_and_destruction_0(int, int)' 内:
macro.cpp:(.text+0xcca): `TVersionCheck::TVersionCheck(int)' に対する定義されていない参照です
collect2: error: ld returned 1 exit status
Makefile:31: recipe for target 'macro' failed
make: *** [parmteqm2gpt] Error 1

ROOT forumを見てみると $ROOTSYS/lib が正しく通っていないことが原因なようだが、確認してみたところPATHは正しく通っていることがわかった。正確な話は後日気が向いたら追記していきたい。

該当するROOT forumのリンクは以下のものである。
https://root-forum.cern.ch/t/undefined-reference-to-tversioncheck-tversioncheck-int/21123/12

解決策

さて、上記問題点の原因を探るためにいろいろと探ってみたら、次のようなことがわかった。

1) libへのパスは通っている
2) ターミナル上からのコンパイル

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

は通らない。

3)オブジェクト生成を経由する

g++ $(root-config --cflags) -c macro.cpp
g++ $(root-config --libs) macro.o -o macro 

は通らない。

4) ターミナル上からのコンパイルでlibの引用を分割した

g++ $(root-config --libs) $(root-config --cflags) macro.cpp -o macro 

は通る(なんで!?)

そこで以下のようにMakefileを書き換えてみた。

Makefile_new
TARGET = macro

SRCS = $(TARGET).cpp
OBJS = $(TARGET).o

ROOTCFLAGS = $(shell root-config --cflags)
ROOTLIBS   = $(shell root-config --libs)
ROOTGLIBS = $(shell root-config --glibs)

CXXFLAGS   = $(ROOTCFLAGS) -Wall -fPIC
CXXLIBS    = $(ROOTLIBS)
CC = g++ 

$(TARGET):
        $(CC) $(SRCS) $(CXXLIBS) $(CXXFLAGS) -o $@

# # suffix rule
# .cc.o:
#       $(CC) $(CXXFLAGS) -c $<

# clean
clean:
        rm -f $(TARGET) $(OBJS)

なにをやったかというと、ただソースファイルから直接実行ファイルを生成しただけである。
こうすると、エラーを吐き出さずに問題なくmakeできた。

まとめ

自分の環境だと、従来のコンパイルの方法でうまくいかないことがわかった。この問題は、libの引数を分割し、一括で実行ファイルを生成する方法だとうまく行くことがわかった。しかし、原因はよくわかっていない。

*用語に関して間違った使い方をしているかもしれません。ぜひご指摘をおねがいいたします。また、上記エラーの原因について初歩的なミスが考えられるので、もしご存じの方がいらっしゃったら教えていただけるとうれしいです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1