アプリケーション開発ポータルサイト
ServerNote.NET
ServerNote.NET厳選キャンペーン・クーポンはこちら!
カテゴリー【CORESERVERC/C++
レンタルサーバーCORESERVERにgcc/g++8.3をソースからインストールして使う
POSTED BY
2021-10-01
CORESERVERはgcc/g++の利用が可能となっているが、確認してみるとバージョンが低すぎる。

g++ --version

g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

これではC++14はおろか11のコードですら大量のコンパイルエラーが出たので、自分のホームディレクトリにソースから最新をインストールして以後そっちのg++を使うことにする。レンタルサーバーなので当然システムにはインストールできない。

ソースコードパッケージ取得、展開

wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-8.3.0/gcc-8.3.0.tar.gz
tar xvfzp gcc-8.3.0.tar.gz

依存ライブラリのダウンロード実行

cd gcc-8.3.0
./contrib/download_prerequisites

一旦gccディレクトリを出て、ビルドディレクトリを作成しそこからconfigure
インストール先は$HOME/.localとした。languagesはc,c++で充分。

cd ..
mkdir build
cd build/
../gcc-8.3.0/configure --prefix=$HOME/.local --enable-languages=c,c++ --disable-multilib --disable-bootstrap

コンパイル・インストール

make -j4
make install

ビルドは非常に負荷のかかる作業で、CORESERVERはレンタルサーバーなのでそういうことをしていると途中で強制終了させられる。そうなってもめげずにひたすらmakeやmake -j4と打っていればいつかはビルドは完了する。

$HOME/.local/binにgcc/g++、
$HOME/.local/include/c++にC++ヘッダファイル、
$HOME/.local/lib64にlibstdc++.soがあるので、コンパイル、実行時はこれらを使用しなくてはいけない。

テストで以下C++14ベースのvectorサンプルコードをコンパイル・実行してみる。

C/C++vector.cppGitHub Source
#include <iostream>
#include <string>
#include <memory>
#include <vector>

class A {
  std::string mName;
public:
  A(void) {
    std::cout << "A constructor" << std::endl;
    mName = std::string("えーでふぉると");
  }
  A(std::string name) {
    std::cout << "A constructor" << std::endl;
    mName = name;
  }
  virtual ~A(void) {
    std::cout << "A destructor" << std::endl;
  }
  void hello(void) {
    std::cout << "A said こんにちは my name is" <<  mName << std::endl;
  }
};

void sample_1(void) {
  std::cout << "enter sample_1" << std::endl;

  std::vector<std::shared_ptr<A>> vec = std::vector<std::shared_ptr<A>>();

  std::shared_ptr<A> a1 = std::make_shared<A>(std::string("えーいち"));
  std::shared_ptr<A> a2 = std::make_shared<A>(std::string("えーに"));
  std::shared_ptr<A> a3 = std::make_shared<A>(std::string("えーさん"));
  std::shared_ptr<A> a4 = std::make_shared<A>(std::string("えーよん"));

  vec.push_back(a1);
  vec.push_back(a2);
  vec.push_back(a3);
  vec.push_back(a4);

  std::cout << "vector count=" << vec.size() << std::endl;

  vec.at(0)->hello();
  vec.back()->hello();

  std::cout << "before vector clear" << std::endl;
  vec.clear();
  std::cout << "after vector clear" << std::endl;

  std::cout << "leave sample_1" << std::endl;
}

void sample_2(void) {

  std::cout << "enter sample_2" << std::endl;

  std::vector<std::shared_ptr<A>> vec = std::vector<std::shared_ptr<A>>();

  vec.push_back(std::make_shared<A>(std::string("えーいち")));
  vec.push_back(std::make_shared<A>(std::string("えーに")));
  vec.push_back(std::make_shared<A>(std::string("えーさん")));
  vec.push_back(std::make_shared<A>(std::string("えーよん")));

  std::cout << "vector count=" << vec.size() << std::endl;

  vec.at(0)->hello();
  vec.back()->hello();

  std::cout << "before vector clear" << std::endl;
  vec.clear();
  std::cout << "after vector clear" << std::endl;

  std::cout << "leave sample_2" << std::endl;
}

int main(int argc, char **argv) {
  std::cout << "enter main" << std::endl;

  sample_1();

  sample_2();

  std::cout << "leave main" << std::endl;

  return 0;
}

コンパイルは以下のようにローカルインストールしたg++、パスを指定する

$HOME/.local/bin/g++ -I$HOME/.local/include/c++ -L$HOME/.local/lib64 vector.cpp

出来上がった実行ファイルa.outをlddにかけてみても、ローカルのライブラリを見てくれてはいないのでNOT FOUNDがあるが、

ldd a.out
./a.out: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./a.out)
./a.out: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by ./a.out)
./a.out: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./a.out)
        linux-vdso.so.1 =>  (0x00007ffdc5f52000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f87a155e000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f87a125c000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f87a1046000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f87a0c78000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f87a1865000)

これは何も指定せずそのまま以下のように実行してしまうとエラーになるが、

./a.out

./a.out: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./a.out)
./a.out: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by ./a.out)
./a.out: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./a.out)

実行時ライブラリの場所をソースインストールしたローカルlib64をLD_LIBRARY_PATHに指定すれば、そこのlibstdc++を読みにいってくれるので、無事実行できる。

export LD_LIBRARY_PATH=$HOME/.local/lib64

./a.out
enter main
enter sample_1
A constructor
A constructor
A constructor
A constructor
vector count=4
A said こんにちは my name isえーいち
A said こんにちは my name isえーよん
before vector clear
after vector clear
leave sample_1
A destructor
A destructor
A destructor
A destructor
enter sample_2
A constructor
A constructor
A constructor
A constructor
vector count=4
A said こんにちは my name isえーいち
A said こんにちは my name isえーよん
before vector clear
A destructor
A destructor
A destructor
A destructor
after vector clear
leave sample_2
leave main

CGIとしてWEBから実行するなら通常.htaccessに

public_html/.htaccess

SetEnv LD_LIBRARY_PATH "/virtual/hogeuser/.local/lib64"

と書いておけば上記のように無事実行されると期待したが、どうもCORESERVERは.htaccessでのSetEnvを許可していないようでInternal Serer Errorになってしまう。

ということは独自パスにあるダイナミックリンクライブラリはCGIでは使えないということになる。
このような場合は、以下のようにlibstdcをスタティックリンクする指令-static-libstdc++ -static-libgccを与えてコンパイルする。

$HOME/.local/bin/g++ -I$HOME/.local/include/c++ -L$HOME/.local/lib64 -static-libstdc++ -static-libgcc vector.cpp

これなら単体でもCGI経由でもLD_LIBRARY_PATHの指定は不要で実行可能となる。スタティックリンクなのでファイルサイズは相当になってしまうため、気になるならデバッグを捨てて以下のようにstripする。

strip a.out
オーディオブック配信サービス【audiobook.jp(オーディオブックドットジェイピー)】
オーディオブックとは、書籍をプロの声優・ナレーターが読み上げた「耳で聴く本」。 書籍や講演会を音声化...READ MORE
世界各国の動物園でも利用!動物のプロが認めるドッグフード【ブッチ・ドックフード】
ブッチは、一般的なペットフードとは一線を画した、理想的な栄養バランスを持つプレミアムフードです。 本...READ MORE
乾燥肌・敏感肌にエイジングケア化粧水【NULL フェイスローション】
男性のお肌のため「うるおい」「低刺激」「エイジングケア*」にアプローチする化粧水が完成しました! 30日...READ MORE
※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【webmaster/管理人】
自営業プログラマー
ご連絡は以下アドレスまで★

☆ServerNote.NETショッピング↓
ShoppingNote
☆お仲間ブログ↓
一人社長の不動産業務日誌
【キーワード検索】