phpでgccコマンドが実効できない問題の解決法

2020年6月30日

テクノロジー

他のエンジニアがやっていないことを、やるのが、とてつもなく大好きな、ユゲタです。 仕事でプログラミングをやる時は、データベースの読み書きをしたり、読んだデータの一覧を表示したり、何かしらの表示処理をやったりする事が多いのですが、毎回毎回、同じような作業ばかりをすることが多く、まだ世の中で誰もやっていないような作業をするという事は、ほぼないと言ってもいいかもしれません。 確かに、誰もやったことが無い作業であれば、論文を書いて然るべきなのかもしれませんが、そんな大それた事を考える前に、自分が同じ作業を繰り返すぐらいなら、プログラムを使ってそれを効率化することの方が、前向きだと気が付き、自分に役立つフレームワークを作って作業スピードをアップしています。 そんな中、何かしらの不具合や問題が生じた時に、ネットでググると、誰かがすでに経験済みで、その対応方法が書かれているのが通常ですが、全く誰もその事象の対応を書いていないケースに遭遇することがあります。 もちろん、そのマイノリティ的な事象に、地雷を踏んだ感じがしてがっかりもするんですが、自己解決して、それを同じ事象で悩む人に解決策を残してあげるという必要性も感じて、モチベーションは上がりますよね。

本日のIT謎掛け

「マイノリティなトラブル」と、かけまして・・・ 「崖から落ちかけて、片手で淵に捕まっている状態」と、ときます。 そのココロは・・・ 頼れるのは自分の力量です。

マイノリティなトラブルありました

それは、とある、プログラミング学習サイトを作っていた時の話ですが、c言語のプログラムをwebブラウザで入力して、それを確認するために、submitした後で、サーバーでコンパイルして、実行して、その返り値を確認するという内容だったのですが、どうしてもphpエラーが出てしまいます。 どうやらgccコマンドをexecする際に、以下のようなエラーメッセージが出ているようでした。 collect2: fatal error: cannot find 'ld' compilation terminated. また、色々いじってみて、次のエラーも頻発していました。 「gcc: error trying to exec 'cc1': execvp: そのようなファイルやディレクトリはありません」 同じサーバーで実際にコマンドを実効すると、正常にコンパイルされることは確認できています。

ググった結果・・・

まず、「php gcc」で検索すると、phpをインストールする時のmake方法が大量に出てきてしまいます。 そらそうですよね。c言語のコンパイルをphpで行うなんて、通常やらない操作ですからね。 そこで、エラーメッセージでググってみると、海外サイトがいくつかヒットしました。 やはりこういう時は、英語の苦手意識があると、辛い感じです。 ひとまずそれは置いといて、見てみると、やはりコマンドでgccをすると、通常どおりコンパイルできるが、phpでexec(またはsystem)コマンドでgccを実効すると、同じようなエラーが出て困っているという質問サイトが多いようです。 ほぼ全てのサイトで、「gccを最新版に入れなおせ」とか、「特殊なライブラリを入れろ」という内容だったので、もちろんそれらを試してみたんですが、解決されませんでした。

自己解決への道

あまりネットの情報に頼らず自分で調査してみたところ、原因は、gccの関連モジュールへのパスが通っていない事が原因のようです。 これって、gccの実効した時に、任意の場所にシンボリックリンクを置いてあげれば解決するのではないか?と考えて、 gccが置かれている"/usr/bin/gcc"や"/usr/bin/ld"をシンボリックで"/bin/"に移動してみました。 今度は、includeする.hファイルが見つからないというエラーが出て、ここもパスが通っていない事が分かりました。 -Iオプションで、incudeパスをしていして上げると・・・コンパイルが通るようになりました。 ・・・でも、実はこのコンパイルした実行ファイルは、正常な動作をしないことが判明、どうやら、やっぱり内部では必要なデータが足りず、通常コンパイルすると8kのファイル容量にならないといけないところ、2kしか容量が無いため、ここで行き詰まってしまいました。

解決はいきなりやってくる

ニッチもサッチもいかない中、そういや、phpのPATHがどうなっているかを調べてみると・・・ OS側では、 echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin この値が返ってくるのに対して、phpでは、 echo $_ENV["PATH"] > 何も、path情報が入っていない状態でした。 setenv関数を使って、以下の関数を作ってみたところ・・・ function setenv(){ exec('echo $PATH' , $res); if($res){ $path = join(",",$res); putenv("PATH=" . $path); } } そして、コンパイルをする直前に、この関数を実行すると・・・ 正常にコンパイルすることができました!!! なるほどね。PHPのPATHが通っていないだけの話だったのか・・・ os側の設定を一切しなくてもいい方法にたどり着けて、汎用性の高い方法であることが分かりました。 システム連携するような処理で、色々と助かりそうなスニペットです。 結果オーライという事で、今回のissueを完了にしたいと思います。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。