Help us understand the problem. What is going on with this article?

SConsことはじめ その2

More than 3 years have passed since last update.

ここの続き。
今回は、共有ライブラリを作る手順と、インストールのターゲットの作成方法。(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.

ソースコード

https://github.com/toshiyukihina/scons-shared-lib

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした