LoginSignup
2
3

More than 5 years have passed since last update.

SConsことはじめ その2

Last updated at Posted at 2015-10-15

ここの続き。
今回は、共有ライブラリを作る手順と、インストールのターゲットの作成方法。(make installみたいなの。)

共有ライブラリを作成する

入力パラメータとして渡した名前nameを、"Hello <name>!"として標準出力する関数を提供するライブラリを作成してみる。

まずはヘッダlibhello.h

libhello.h
#ifndef __LIBHELLO_H__
#define __LIBHELLO_H__

void hello(char* in_name);

#endif /* __LIBHELLO_H__ */

次に、ソースlibhello.c

libhello.c
#include <stdio.h>

void hello(char* in_name) {
  printf("Hello %s!\n", in_name);
}

共有ライブラリを作成するSConstructは、以下。SharedLibrary()関数を使って、共有ライブラリを作成する。

env = Environment()

# Create a shared library
lib_target = "libhello"
lib_sources = ["libhello.c"]
env.SharedLibrary(target=lib_target, source=lib_sources)

ここまでで作成されたファイルは、以下。

$PROJ_ROOT
├── libhello.c
├── libhello.h
└── SConstruct

ここで一度、sconsコマンドを実行すると、$PROJ_ROOTlibhello.soが作成されるはず。

$PROJ_ROOT
├── libhello.c
├── libhello.h
├── libhello.os
├── libhello.so <= (*)
└── SConstruct

共有ライブラリの利用者側プログラム

libhello.soを利用する側のプログラムhelloを作成する。ライブラリが提供するhello()を呼び出すだけのプログラム。

hello.c
#include "libhello.h"

int main(void) {
  hello("World");
  return 0;
}

helloを作成するコードを追加したSConstructは以下。

env = Environment()

# Create a shared library
lib_target = "libhello"
lib_sources = ["libhello.c"]
env.SharedLibrary(target=lib_target, source=lib_sources)

# Create a exectable using libhello.so
bin_target = "hello"
bin_sources = ["hello.c"]
env.Program(target=bin_target, source=bin_sources, parse_flags="-I. -L. -lhello")

ここまでで、共有ライブラリlibhello.soと、呼び出し側のhelloプログラムが作成されるはずなので、sconsコマンドを実行する。ビルドが正常に完了すると、以下のように、それぞれのファイルが作成されているはず。

$PROJ_ROOT
├── hello <= 実行可能形式のプログラム
├── hello.c
├── hello.o
├── libhello.c
├── libhello.h
├── libhello.os
├── libhello.so <= 共有ライブラリ
└── SConstruct

実行してみる

libhello.soのありかをhelloに教えてあげるために、LD_LIBRARY_PATHlibhello.soのパスを設定する。
正常に実行されると、Hello World!という文字列が標準出力に出力される。

$ LD_LIBRARY_PATH=. ./hello
Hello World!

インストールターゲットを定義する

共有ライブラリをインストールするターゲットを定義してみる。
これまでに作成したSConstructを若干いじって以下のようにする。

env = Environment()

# Create a shared library
lib_target = "libhello"
lib_sources = ["libhello.c"]
libhello = env.SharedLibrary(target=lib_target, source=lib_sources)

# Create a exectable using libhello.so
bin_target = "hello"
bin_sources = ["hello.c"]
env.Program(target=bin_target, source=bin_sources, parse_flags="-I. -L. -lhello")

env.Install(dir="/usr/local/lib", source=libhello)

変更したのは、env.SharedLibrary()の戻り値をlibhello変数に受けているところと、最後の行である。(差分)
ここで、scons /usr/local/libコマンドを実行すると、/usr/local/liblibhello.soがインストールされているはずである。

$ sudo scons /usr/local/lib
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
Install file: "libhello.so" as "/usr/local/lib/libhello.so"
scons: done building targets.

インストールターゲットを改良する

sconsコマンドのターゲットに、フルパスを渡すのは面倒なので、Aliasという機能を使う。最終行を追加した。(差分)

env = Environment()

# Create a shared library
lib_target = "libhello"
lib_sources = ["libhello.c"]
libhello = env.SharedLibrary(target=lib_target, source=lib_sources)

# Create a exectable using libhello.so
bin_target = "hello"
bin_sources = ["hello.c"]
env.Program(target=bin_target, source=bin_sources, parse_flags="-I. -L. -lhello")

env.Install(dir="/usr/local/lib", source=libhello)
env.Alias("install", ["/usr/local/lib"])

今度は、scons installコマンドを実行する。先ほどと同様、/usr/local/libにインストールされるはずである。

$ sudo scons install    
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
Install file: "libhello.so" as "/usr/local/lib/libhello.so"
scons: done building targets.

ソースコード

2
3
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
3