RSS

月別アーカイブ: 8月 2016

make ビルドツールの使い方

make の基本

makefile を作る。

    test.exe : test.c
        gcc -o test test.c

makeを実行する。

    make

 

makefile でなく、任意のファイル名の場合は次のように -f スイッチでそのファイルを指定する。

   make -f proj1.mk

 

サフィックス

「 .o は .c に依存する」 というルールは次のように書ける。

.c.o:
    gcc -c $<

test.o : test.h

$< はマクロの一種で、この場合、.c に置き換わる。なお、この例で .o に置き換えたいときは、$@ を使う

 

マクロ

マクロはコマンドの別名みたいなものである。例えば、 CC = gcc と書くと、CC がマクロとなり、 $(CC) が’gcc’として扱われる。

CC = gcc
test.o : test.c
    $(CC) -c test.o test.c

(注意) $(CC) の代わりに ${CC} としてもよい。

つぎの特殊なマクロがあらかじめ決められている。

特殊なマクロ 意味
$@ それが生成しようとしているターゲット名
$< ターゲットが 依存しているファイルのひとつ
$* ターゲット名から拡張子を除いたもの (例) test.c -> test
$? 依存ファイルで更新されたもののリスト

 

コメント

makefile 内でコメントを使う場合は、# に続く文字列がコメントとなる。つまり、Unix シェルと同じである。

 

広告
 
コメントする

投稿者: : 2016/08/31 投稿先 gcc, Linux

 

gdb デバッガの使い方

はじめに

gdb は昔ながらのコマンドベースのデバッガです。GUI 環境が利用できる場合は、IDE のデバッガを使ったほうが簡単です。

 

要件

gdb はデフォルトでインストールされていないので、インストールする必要があります。Ubuntu の場合は以下のようにするとインストールできます。

sudo apt-get install gdb

ソースファイルをコンパイルする際、-ggdb または -g オプションを指定する必要があります。ここで、-ggdb を使う場合、より多くのデバッグ情報を扱えうことができます。

(例) gcc -ggdb -o test test.c

 

起動

gdb コマンドを実行すると gdb が起動できます。簡単な使用法とコマンドオプションなどは –help オプションを付けて起動すると表示できます。

(例) gdb –help

実際にデバッグする場合は、下のように gdb コマンドを入力します。

gdb [options] [executable-file [core-file or process-id]] または
gdb [options] –args executable-file [inferior-arguments …]

ソースファイル (test.c) と実行ファイル (test) が同じ場所にある場合なら、次のよう gdb を実行すればコマンド入力待ちになります。

$ gdb test
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...done.
(gdb)

core-file はプログラムが異常終了したとき作成される core ファイルです。process-id はこのプログラムのプロセスIDを特に指定しなければ省略できます。

–args は実行ファイルの後にコマンドライン引数が続くことを意味します。

実行ファイルがカレントディレクトリ別のフォルダにある場合は、–exec=EXEFILE オプションを使用します。あるいは –cd=DIR オプションでそのフォルダに移動して実行します。

ソースを表示する場合は、実行ファイルと同じ場所にソースファイルを置いておくか、–directory オプションでソースファイルの場所を指定する必要があります。

 

 

よく使うコマンド

ヘルプ

コマンド入力待ち (gdb) で help と入力するとヘルプが表示されます。ここで表示されるのはコマンドのクラス一覧なので、さらにクラスを指定して help コマンドを実行するとそのクラスに所属するコマンドのヘルプが表示されます。

(gdb) help
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb)

 

下の例は、data クラスに所属するコマンドのヘルプを表示したものです。

(gdb) help data
Examining data.

List of commands:

agent-printf -- Agent-printf "printf format string"
append -- Append target code/data to a local file
append binary -- Append target code/data to a raw binary file
append binary memory -- Append contents of memory to a raw binary file
append binary value -- Append the value of an expression to a raw binary file
append memory -- Append contents of memory to a raw binary file
append value -- Append the value of an expression to a raw binary file
call -- Call a function in the program
disassemble -- Disassemble a specified section of memory
display -- Print value of expression EXP each time the program stops
dump -- Dump target code/data to a local file
dump binary -- Write target code/data to a raw binary file
dump binary memory -- Write contents of memory to a raw binary file
  ....
  ....

 

開始・続行・終了

コマンド 機能 入力例
run [args] または r 最初から実行開始する。
cont または c ブレークポイントで一時停止中のとき、続きを実行する。
next または n 次の行へ。現在の行が関数呼び出しの場合は関数全体を1行として実行する。
step または s 次の行へ。現在の行が関数呼び出しの場合は、関数の中の行へ。
quit または q gdb を終了する。 (gdb) quit

 

ソースの表示

コマンド 機能 入力例
list または l 現在の行から10行分ソースを表示する。
list [start, [end]] または l [start, [end]] ソースのstart から end までの行を表示する。 l 2,4
file filename 現在とは別のソースファイルを選択する。

 

ブレークポイント

コマンド 機能 入力例
break または b 現在の行にブレークポイントを設定する。
break n または b n 行 n にブレークポイントを設定する。 b 8
info break または i break ブレークポイントの状態を表示する。
delete または d すべてのブレークポイントを削除する。
delete n または d n info break で表示されるブレークポイント番号 n のブレークポイントを削除する。
(gdb) info break
Num     Type           Disp Enb Address  
1       breakpoint     keep y   ...
(gdb) delete 1
No breakpoint number 8.
(gdb) delete 1
(gdb)

 

変数の調査

コマンド 機能 入力例
print x または p x 変数 x の内容を表示する。
(gdb) print i
$1 = 0
display x プログラムの実行が停止するごとに変数 x の値を表示する。
undisplay display の操作をすべて取り消す。
print x=c 変数 x の値を c に変更する。
(gdb) print i = 1
$3 = 1

 

 

 
コメントする

投稿者: : 2016/08/31 投稿先 C, gcc, Linux

 

gcc コンパイラの使い方

はじめに

gcc は C/C++ コンパイラです。コマンド gcc を実行して「見つからない」というメッセージが表示されたら、インストールされていないのでインストールする必要があります。Ubuntu なら下のようにします。

sudo apt-get install gcc

これだけだと、C 言語だけしかコンパイルできないので、C++ も使う場合は下のようにして g++ をインストールします。

sudo apt-get install g++

 

ついでに make もインストールしておきます。これはビルドツールです。

sudo apt-get install make

 

基本的な使用方法

文字列を表示するだけの簡単なプログラム (HelloWorld.c etc) など、単純な使い方は次のようになります。

gcc HelloWorld.c

このコマンドを実行するとエラーがなければ、a.out というファイルが作成されます。この a.out が実行ファイルですが、通常は -o オプションを使って実行ファイルの名前を指定します。

gcc -o HelloWorld HelloWorld.c

このコマンドを実行すると、HelloWorld という名前のファイルが作成されますが、これが実行ファイルです。

ソースファイルが C++ の場合は gcc の代わりに g++ (あるいはオプション -x c++) を使用します。

g++ -o HelloWorld HelloWorld.cpp

一般的には次のような形式でコマンド入力します。options はオプションで “gcc –help” と入力すると英語で説明が表示されます。file はソースファイルやオブジェクトファイルです。

gcc [options] file…

主なオプション

コンパイルオプション

オプション 意味
-c コンパイルのみを行う。.o ファイルが作成される。
-g デバッグ情報を生成する。gdb を使う場合にも指定することができる。(ただし、-ggdb のほうが多くのデバッグ情報を生成する)
-std=… C コンパイラの仕様を指定する。(例) C 言語の新しい仕様 C11 でコンパイルする場合 -std=c11
-ggdb gdb 用のデバッグ情報を生成する。
-Idir ディレクトリ dir の中のヘッダファイルを検索する。(例) -Iinc
-Ldir ライブラリファイルを検索するディレクトリを指定する。(例) -Llib
-o 出力ファイルの名前を指定する。
-O 最適化を行う。-O0 は最適化を行わない。-O2, -O3 はより高度な最適化を行う。
-S アセンブラソースを出力する。(参考) -masm=intel とすると Intel 記法、指定なしだと AT&T 記法。
-w すべての警告メッセージの出力を禁止する。
-x language 入力ファイルの言語を指定する。c, c++, objective-c, assembler などが指定できる。(注意) 実際には他に必要なヘッダやライブラリの指定が必要。

 

リンクオプション

gcc はコンパイルの後、リンカを呼び出してリンクも行うことができる。このため gcc でリンカのオプションも指定できる。リンカオプションは gcc コマンドの最後に追加する。

オプション 意味
-llibrary library を探してリンクする。(例) -lncurses
-s すべてのシンボルテーブルと再配置情報を削除する。gdb を使う場合は指定しないこと。
-S 出力ファイルがアセンブラソースになる。
-static 静的なライブラリを作成する。
-shared 動的ななライブラリ (.so) を作成する。(例) gcc -shared test.c -o libtest.so

 

実は C や C++ 以外にも対応している

gcc は以下の言語に対応している。デフォルトは C だが -x オプションで他の言語を指定できる。ただし、-x だけを指定してもエラーになる。その言語で必要なライブラリやヘッダを別途指定しなければならない。

  • C
  • C++
  • Objective-C
  • Go Language (gcc 4.7.1 以上)
 
コメントする

投稿者: : 2016/08/31 投稿先 gcc

 

C: fork / execvp 関数でプロセスを起動

fork / execvp 関数の使用例

/******************************************************

     fork / execvp 関数のテスト

 ******************************************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

/* コマンドの定義 */
char *args[] = {"ls", "-l", "/usr", NULL};

int main()
{
  pid_t pid;

  /* fork 関数でプロセスを親子に分ける */
  if ((pid = fork()) == 0)
  {
    /* 子プロセス */
    execvp("/bin/ls", args);
  }
  else if (pid > 0)
  {
    /* 親のプロセス */
    puts("New process started\n");
    wait(0);
  }

  return EXIT_SUCCESS;
}

実行例

$ ./execvpTest
New process started

total 76
drwxr-xr-x   2 root root 36864 Aug 31 09:55 bin
drwxr-xr-x   2 root root  4096 Apr 13 05:14 games
drwxr-xr-x  47 root root 12288 Aug 31 09:55 include
drwxr-xr-x  71 root root  4096 Aug 28 09:58 lib
drwxr-xr-x  10 root root  4096 Aug 10 05:34 local
drwxr-xr-x   2 root root  4096 Aug 31 09:55 sbin
drwxr-xr-x 150 root root  4096 Aug 17 07:01 share
drwxr-xr-x   8 root root  4096 Aug 30 11:18 src
 
コメントする

投稿者: : 2016/08/31 投稿先 C, gcc

 

タグ:

C: fork /execv 関数でプロセスを起動

/******************************************************

     form / execv 関数のテスト

 ******************************************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

/* コマンドの定義 */
char *args[] = {"ls", "-l", "/usr", NULL};

int main()
{
  pid_t pid;

  /* fork 関数でプロセスを親子に分割する。*/
  if ((pid = fork()) == 0)
  {
    /* 子プロセス */
    execv("/bin/ls", args);
  }
  else if (pid > 0)
  {
    /* 親プロセス */
    puts("New process started\n");
    wait(0);
  }

  return EXIT_SUCCESS;
}

実行例

$ ./execvTest
New process started

total 76
drwxr-xr-x   2 root root 36864 Aug 31 09:55 bin
drwxr-xr-x   2 root root  4096 Apr 13 05:14 games
drwxr-xr-x  47 root root 12288 Aug 31 09:55 include
drwxr-xr-x  71 root root  4096 Aug 28 09:58 lib
drwxr-xr-x  10 root root  4096 Aug 10 05:34 local
drwxr-xr-x   2 root root  4096 Aug 31 09:55 sbin
drwxr-xr-x 150 root root  4096 Aug 17 07:01 share
drwxr-xr-x   8 root root  4096 Aug 30 11:18 src
 
コメントする

投稿者: : 2016/08/31 投稿先 C, gcc

 

タグ:

C: system でコマンドを起動する。

fork / exec* 関数を使わなくても system 関数で簡単にコマンドを実行できる。

#include <stdio.h>
#include <stdlib.h>

/* system 関数を使って、コマンドプロセッサへ argv[1] が指す文字列を渡す。*/
int main(int argc, char* argv[]) {
  if (argc < 2) {
    puts("Usage: system command");
    exit(EXIT_FAILURE);
  }

  /* コマンドライン引数で渡された文字列を実行する。空白を含む場合は " で囲むこと。*/
  system(argv[1]);

  puts("Done.");

  return EXIT_SUCCESS;
}

実行例

$ ./system "ls ~"
bin  cgi-bin  data  html  lib  temp  workspace
Done.
 
コメントする

投稿者: : 2016/08/31 投稿先 C, g++

 

タグ:

C: fork, execl の使用例

fork と execl 関数を使ってプロセスを起動する例

/******************************************************

     execl 関数のテスト

 ******************************************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

int main(int argc, char* argv[])
{
  /* プロセス ID */
  pid_t pid;

  if (argc < 2) {
    puts("Usage: execlpTest dir");
    return 9;
  }

  /* 新しいプロセスを作成する。*/
  if ((pid = fork()) == 0) {
    /* 子プロセス */
    if (argc > 1)
    {
      /* 子プロセスで "ls -l argv[1]" を実行する。*/
      execl("/bin/ls", "ls", "-l", argv[1], NULL);
    }
  }
  else if (pid > 0) {
    /* 親プロセス */
    if (argc > 1) {
      /* 子プロセスを起動したことを表示する。*/
      puts("New process started\n");
    }
    wait(0);
  }

  return 0;
}

実行例

$ ./execTest
Usage: execlpTest dir
$ ./execTest ~
New process started

total 20
drwxrwxr-x  2 user user 4096 Aug 27 18:02 bin
lrwxrwxrwx  1 user user   16 Aug 10 10:49 cgi-bin -> /usr/lib/cgi-bin
drwxrwxr-x  2 user user 4096 Aug 10 10:48 data
lrwxrwxrwx  1 user user   13 Aug 10 10:49 html -> /var/www/html
drwxrwxr-x  3 user user 4096 Aug 11 20:08 lib
drwxrwxr-x  2 user user 4096 Aug 26 15:36 temp
drwxrwxr-x 22 user user 4096 Aug 17 11:18 workspace
user@ubuntu16:~/workspace/C/exec$
 
コメントする

投稿者: : 2016/08/30 投稿先 C, gcc

 

タグ: