随笔 - 298  文章 - 377  trackbacks - 0
<2016年4月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(34)

随笔分类

随笔档案

文章档案

相册

收藏夹

搜索

  •  

最新评论

阅读排行榜

评论排行榜

共5页: 1 2 3 4 5 
I'm working on a simple XOR program (with some file i/o). It uses some include files. Here they are:


Code:
#include <cstdlib>
#include <fstream>
#include <cstring>

using namespace std;

Now this does not compile. It throws errors at me, the same way as if I did not include <fstream> at all.

I am pretty sure that it is not my programs logic because when I used ".h" it worked perfectly. *sigh*, why must I trouble myself so much just to use "ANSI" standard. It works don't it?

I'll post some of the errors in a minute, Windows is freaking out on me. (As usual, Linux rules hehe)
re: vmware下调整linux的分辨率 聂文龙 2007-05-12 01:54
./vmware-install.pl
  新版的老版的还是有些不同的。现在把步骤帖一下
  安装步骤:

  1.mysql

  在如下页面下载mysql的for linux rpm包
  http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm
  http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm

  存至/home/tmp目录

  命令列表:


cd /home/tmp
rpm -ivh MySQL-3.23.52-1.i386.rpm #安装mysql server
rpm -ivh MySQL-client-3.23.52-1.i386.rpm #安装mysql client
/usr/mysql/safe_mysqld & #启动mysql server
mysql #运行mysql 客户端,并开放root用户的远程访问权限。以便调试
use mysql
update user set host = '%' where user = 'root' and host <> 'localhost';
flush privileges;
quit

  至此mysql安装完成

  2.apache

  在如下页面下载apache的for linux 的源码包

  http://www.apache.org/dist/httpd/apache_1.3.26.tar.gz">http://www.apache.org/dist/httpd/apache_1.3.26.tar.gz

  存至/home/tmp目录

  命令列表:


cd /home/tmp
tar -zxvf apache_1.3.26.tar.gz
mv apache_1.3.26.tar.gz apache
cd apache
./configure --prefix=/usr/local/apache --enable-module=so
make
make install

安装apache至/usr/local/apache 并配置apache支持dso方式

  3.php

  在如下页面下载php的for linux 的源码包

  http://www.php.net/get_download.php?df=php-4.2.3.tar.gz">http://www.php.net/get_download.php?df=php-4.2.3.tar.gz

  存至/home/tmp目录

  命令列表:


cd /home/tmp
tar -zxvf php-4.2.3.tar.gz
mv php-4.2.3.tar.gz php
cd php
./configure --prefix=/usr/local/php --with-apxs=/usr/local/apache/bin/apxs --with-config-file-path=/usr/local/lib --enable-track-vars --with-xml --with-mysql
make
make install
cp php.ini-dist /usr/local/lib/php.ini

以dso方式安装php至/usr/local/php 设置配置文件目录为/usr/local/lib 开启mysql,xml支持

  4.配置

vi /usr/local/apache/conf/httpd.conf
对apache做如下配置
#将ServerAdmin q3boy@younet.com一行改为您的邮箱地址

#DocumentRoot "/home/httpd/html/" 此处为html文件主目录

# 同上

#Options FollowSymLinks MultiViews 为安全起见,去掉"Indexes"

#
# DirectoryIndex default.php default.phtml default.php3 default.html default.htm
#
#设置apache的默认文件名次序

#AddType application/x-httpd-php .php .phtml .php3 .inc
#AddType application/x-httpd-php-source .phps
#设置php文件后缀


  存盘退出

vi /usr/local/lib/php.ini
#register-golbals = On

  存盘退出

  5.启动服务
  /usr/local/apache/bin/apachectl start

  6.备注
  apache在linux下的默认最大进程数为256,无论如何修改httpd.conf都不能超过这个限制。如果想加大这个限制,在编译apache前编辑/home/tmp/apache/src/include/httpd.h,将其中#define HARD_SERVER_LIMIT 256 一行改为#define HARD_SERVER_LIMIT 2048后再编译apache,

  apache 1.3.26中mod_so似乎已经不是默认模块了。编译时候需加上--enable-module=so,我第一次编译没加此参数,结果php编译时无法找到apxs

  php 4.2.3中默认配置文件路径似乎变了。编译时需加上 --with-config-file-path=/usr/local/lib 参数,我第一次编译完php.ini放了n个地方都没有用。不得已。只能加上这个参数。

  p.s. 不保证本文所述步骤适用于其他版本

  附:相关文件下载地址

  php:
  http://www.php.net/get_download.php?df=php-4.2.3.tar.gz">http://www.php.net/get_download.php?df=php-4.2.3.tar.gz
  apache:
  http://www.apache.org/dist/httpd/apache_1.3.26.tar.gz">http://www.apache.org/dist/httpd/apache_1.3.26.tar.gz
  mysql server:
  http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm
  mysql client:
  http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm">http://www.mysql.com/downloads/down...3.52-1.i386.rpm

re: 在Linux下安装和使用MySQL 聂文龙 2007-05-10 23:52
安装MySQL
假设你把所有必须的源码或者包都放在了/tmp下。如果你下载的是RPM包的话,那比较简单;如果你下载的是二进制包(你没有rpm程序或者你想自定义的话),那么会稍微麻烦一点。

RPM包安装

你必须成为root用户才能使用rpm安装程序,以下是安装过程:

$ cd /tmp
$ su
# rpm -Uvh MySQL*(安装和MySQL相关的所有包)

这将安装你下载的所有3个MySQL包。如果你的系统是RedHat Linux的话,建议使用RPM安装方式,因为所有的工作都由rpm程序帮你搞好了。

源码安装

相对于用RPM安装来讲,用二进制源码安装是稍微麻烦了点。但是我们可以在安装脚本中可以自定义安装的相关参数,而不用象rpm方式只能安装默认的来安装。

安装二进制源代码

如果你下载的是二进制源代码,它的名字类似于: mysql-3.22.21-pc-linux-gnu-i686.tar.gz。你必须成为root用户,然后解压到 /usr/local目录,操作步骤如下:

$ cd /usr/local
$ su
# tar -zxvf /tmp/mysql-3.22.21-pc-linux-gnu-i686.tar.gz

在所有文件解压完后,一个名字叫mysql-3.22.21-pc-linux-gnu-i686的目录将被创建出来。我们为这个目录做个符号链接,并给它一个更友好的名字mysql (免得叫mysql-3.22.21-pc-linux-gnu-i686这么长):

# ln -s mysql-3.22.21-pc-linux-gnu-i686 mysql

如果以后有新版本的MySQL的话,你可以仅仅将源码解压到新的路径,然后只需要做个符号链接就可以了。这样非常方便,数据也更加安全。

 

建立一个MySQL 用户

好,现在我们将建立一个能运行MySQL守护程序的用户帐号,并且所有MySQL文件都归此帐户拥有。使用 Linuxconf或者useradd命令去添加一个叫 mysql 的帐号,在添加之前,确保没有人注册了这个帐户,还要暂时禁止login功能(不过一般都是在没有其他人登陆的情况下调试机器,因此这个步骤可免)

 

为MySQL做准备

首先让我们将MySQL目录和文件的拥有权改成 mysql 用户和root组:

# cd /usr/local
# chown -R mysql:root mysql-3.22.21-pc-linux-gnu-i686 mysql

然后运行一个小脚本程序,以建立初始化的MySQL数据库。请以一个mysql 用户的身份完成这个任务,这也是我们能够直接使用这个帐户的唯一机会。

# su mysql
$ cd mysql
$ scripts/mysql_install_db
$ exit

如果没有任何出错信息显示的话,那就可以了。

 

自动运行MySQL

在MySQL二进制包里面,有一个叫myslq.server的启动脚本程序。把它复制到/etc/rc.d/init.d目录里面:

# cd /etc/rc.d/init.d
# cp /usr/local/mysql/support-files/mysql.server mysql

接着把它的属性改为“x”(executable,可执行)

# chmod +x mysql

最后,运行chkconfig把MySQL添加到你系统的启动服务组里面去。

# /sbin/chkconfig --del mysql
# /sbin/chkconfig --add mysql

 

测试MySQL

MySQL里面有一个简单的数据库例子test ,而且它的内部数据库一直保持对权限和帐户的监视,因而先运行mysql看看是否可以工作。

首先启动MySQL:

# /etc/rc.d/init.d/mysql start

如果一切正常,你将看到以下的信息出现:

Starting mysqld daemon with databases from /var/lib/mysql

如果你安装的是RPM包,那么程序大都安装在/usr/local/mysql/bin。在此目录下运行客户端程序:

# mysql

然后你可以看到屏幕显示出以下信息:

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 2 to server version: 3.22.21

Type 'help' for help.

mysql>

接着,用show databases命令可以将安装的数据库列出来:

mysql> show databases;

你就可以看到:

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (0.00 sec)

如果一切正常的话,那说明MySQL可以完全工作了!恭喜你!如果要退出程序,输入:exit

mysql> exit;

Bye

更改管理员密码

在一切正常后,要做的第一件事情是更改管理员的密码。你可以运行mysqladmin (请注意,此命令不一定在你的path中,所以最好是转到此命令的目录中直接执行):

# mysqladmin -u root password newpassword

此命令把root用户的口令变成newpassword。当然你可以把口令换成其它,因为这个很容易破解。

re: Linux上安装GCC编译器过程 聂文龙 2007-05-10 02:47
安装gcc后,你的系统就具有编译c/c++等源码的功能,我的安装过程如下
注意:要把安装过程中所用到的软件包复制到相关的目录
1.
输入命令rpm -i gcc-3.2.3-34.i386.rpm
error: Failed dependencies:
cpp = 3.2.3-34 is needed by gcc-3.2.3-34
glibc-devel >= 2.2.90-12 is needed by gcc-3.2.3-34
libgcc >= 3.2.3-34 is needed by gcc-3.2.3-34
Suggested resolutions:
glibc-devel-2.3.2-95.3.i386.rpm

2.
输入命令rpm -i gcc-3.2.3-34.i386.rpm glibc-devel-2.3.2-95.20.i386.rpm libgcc-3.2.3-34.i386.rpm cpp-3.2.3-34.i386.rpm
error: Failed dependencies:
glibc-headers is needed by glibc-devel-2.3.2-95.20
glibc-headers = 2.3.2 is needed by glibc-devel-2.3.2-95.20
Suggested resolutions:
glibc-headers-2.3.2-95.3.i386.rpm

3.
输入命令rpm -i gcc-3.2.3-34.i386.rpm glibc-devel-2.3.2-95.20.i386.rpm libgcc-3.2.3-34.i386.rpm cpp-3.2.3-34.i386.rpm glibc-headers-2.3.2-95.20.i386.rpm
error: Failed dependencies:
kernel-headers is needed by glibc-headers-2.3.2-95.20
kernel-headers >= 2.2.1 is needed by glibc-headers-2.3.2-95.20
Suggested resolutions:
glibc-kernheaders-2.4-8.34.i386.rpm
[root@remote_server eyesompack]#

4. 输入以下才能成功安装
rpm -Uvh gcc-3.2.3-34.i386.rpm glibc-devel-2.3.2-95.20.i386.rpm libgcc-3.2.3-34.i386.rpm cpp-3.2.3-34.i386.rpm glibc-headers-2.3.2-95.20.i386.rpm glibc-kernheaders-2.4-8.34.i386.rpm

5.
安装后输入命令gcc,则有如下返回
gcc: no input files


re: In function `_start': 聂文龙 2007-05-10 02:36
文件中包含了"stdlib.h"等头文件,但是编译的时候总是出现这个问题,怎么回事?
[biti@cvs isep]$ gcc convert.c
/usr/lib/gcc-lib/i386-pc-linux/2.96/../../../crt1.o: In function `_start':
/usr/lib/gcc-lib/i386-pc-linux/2.96/../../../crt1.o(.text+0x18): undefined reference to `main'
/tmp/ccW206Pr.o: In function `StructToString':
/tmp/ccW206Pr.o(.text+0x1d4): undefined reference to `itoa'
/tmp/ccW206Pr.o(.text+0x210): undefined reference to `itoa'
/tmp/ccW206Pr.o(.text+0x25f): undefined reference to `itoa'
/tmp/ccW206Pr.o(.text+0x2b8): undefined reference to `itoa'
/tmp/ccW206Pr.o: In function `PrintStruct':
/tmp/ccW206Pr.o(.text+0x912): undefined reference to `itoa'
/tmp/ccW206Pr.o(.text+0x948): more undefined references to `itoa' follow
collect2: ld returned 1 exit status


gcc没安装正确,检查一下/etc/ld.so.conf中的路径是否正确。

#include <stdio.h>必须放在最前面
#include <stdlib.h>必须放在#include <stdio.h>的后面
Linux/Unix环境下的Make和Makefile详解

无论是在Linux还是在Unix环境中,make都是一个非常重要的编译命令。不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或make install。利用make工具,我们可以将大型的开发项目分解成为多个更易于管理的模块,对于一个包括几百个源文件的应用程序,使用make和makefile工具就可以简洁明快地理顺各个源文件之间纷繁复杂的相互关系。而且如此多的源文件,如果每次都要键入gcc命令进行编译的话,那对程序员来说简直就是一场灾难。而make工具则可自动完成编译工作,并且可以只对程序员在上次编译后修改过的部分进行编译。因此,有效的利用make和makefile工具可以大大提高项目开发的效率。同时掌握make和makefile之后,您也不会再面对着Linux下的应用软件手足无措了。

  但令人遗憾的是,在许多讲述Linux应用的书籍上都没有详细介绍这个功能强大但又非常复杂的编译工具。在这里我就向大家详细介绍一下make及其描述文件makefile。

  Makefile文件

  Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。makefile 文件是许多编译器--包括 Windows NT 下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改 makefile 文件而已。

  在 UNIX 系统中,习惯使用 Makefile 作为 makfile 文件。如果要使用其他文件作为 makefile,则可利用类似下面的 make 命令选项指定 makefile 文件:

  $ make -f Makefile.debug

  例如,一个名为prog的程序由三个C源文件filea.c、fileb.c和filec.c以及库文件LS编译生成,这三个文件还分别包含自己的头文件a.h 、b.h和c.h。通常情况下,C编译器将会输出三个目标文件filea.o、fileb.o和filec.o。假设filea.c和fileb.c都要声明用到一个名为defs的文件,但filec.c不用。即在filea.c和fileb.c里都有这样的声明:

  #include "defs"

  那么下面的文档就描述了这些文件之间的相互联系:

  ---------------------------------------------------------
  #It is a example for describing makefile
  prog : filea.o fileb.o filec.o
  cc filea.o fileb.o filec.o -LS -o prog
  filea.o : filea.c a.h defs
  cc -c filea.c
  fileb.o : fileb.c b.h defs
  cc -c fileb.c
  filec.o : filec.c c.h
  cc -c filec.c
  ----------------------------------------------------------

  这个描述文档就是一个简单的makefile文件。

  从上面的例子注意到,第一个字符为 # 的行为注释行。第一个非注释行指定prog由三个目标文件filea.o、fileb.o和filec.o链接生成。第三行描述了如何从prog所依赖的文件建立可执行文件。接下来的4、6、8行分别指定三个目标文件,以及它们所依赖的.c和.h文件以及defs文件。而5、7、9行则指定了如何从目标所依赖的文件建立目标。

  当filea.c或a.h文件在编译之后又被修改,则 make 工具可自动重新编译filea.o,如果在前后两次编译之间,filea.C 和a.h 均没有被修改,而且test.o还存在的话,就没有必要重新编译。这种依赖关系在多源文件的程序编译中尤其重要。通过这种依赖关系的定义,make 工具可避免许多不必要的编译工作。当然,利用Shell脚本也可以达到自动编译的效果,但是,Shell 脚本将全部编译任何源文件,包括哪些不必要重新编译的源文件,而 make 工具则可根据目标上一次编译的时间和目标所依赖的源文件的更新时间而自动判断应当编译哪个源文件。

  Makefile文件作为一种描述文档一般需要包含以下内容:

  ◆ 宏定义
  ◆ 源文件之间的相互依赖关系
  ◆ 可执行的命令

  Makefile中允许使用简单的宏指代源文件及其相关编译信息,在Linux中也称宏为变量。在引用宏时只需在变量前加$符号,但值得注意的是,如果变量名的长度超过一个字符,在引用时就必须加圆括号()。

  下面都是有效的宏引用:

  $(CFLAGS)
  $2
  $Z
  $(Z)

  其中最后两个引用是完全一致的。

  需要注意的是一些宏的预定义变量,在Unix系统中,$*、$@、$?和$<四个特殊宏的值在执行命令的过程中会发生相应的变化,而在GNU make中则定义了更多的预定义变量。关于预定义变量的详细内容,宏定义的使用可以使我们脱离那些冗长乏味的编译选项,为编写makefile文件带来很大的方便。

  ---------------------------------------------------------
  # Define a macro for the object files
  OBJECTS= filea.o fileb.o filec.o
  # Define a macro for the library file
  LIBES= -LS
  # use macros rewrite makefile
  prog: $(OBJECTS)
  cc $(OBJECTS) $(LIBES) -o prog
  ……
  ---------------------------------------------------------

  此时如果执行不带参数的make命令,将连接三个目标文件和库文件LS;但是如果在make命令后带有新的宏定义:

  make "LIBES= -LL -LS"

  则命令行后面的宏定义将覆盖makefile文件中的宏定义。若LL也是库文件,此时make命令将连接三个目标文件以及两个库文件LS和LL。

  在Unix系统中没有对常量NULL作出明确的定义,因此我们要定义NULL字符串时要使用下述宏定义:

  STRINGNAME=

  Make命令

  在make命令后不仅可以出现宏定义,还可以跟其他命令行参数,这些参数指定了需要编译的目标文件。其标准形式为:

  target1 [target2 …]:[:][dependent1 …][;commands][#…]
  [(tab) commands][#…]

  方括号中间的部分表示可选项。Targets和dependents当中可以包含字符、数字、句点和"/"符号。除了引用,commands中不能含有"#",也不允许换行。

  在通常的情况下命令行参数中只含有一个":",此时command序列通常和makefile文件中某些定义文件间依赖关系的描述行有关。如果与目标相关连的那些描述行指定了相关的command序列,那么就执行这些相关的command命令,即使在分号和(tab)后面的aommand字段甚至有可能是NULL。如果那些与目标相关连的行没有指定command,那么将调用系统默认的目标文件生成规则。

  如果命令行参数中含有两个冒号"::",则此时的command序列也许会和makefile中所有描述文件依赖关系的行有关。此时将执行那些与目标相关连的描述行所指向的相关命令。同时还将执行build-in规则。

  如果在执行command命令时返回了一个非"0"的出错信号,例如makefile文件中出现了错误的目标文件名或者出现了以连字符打头的命令字符串,make操作一般会就此终止,但如果make后带有"-i"参数,则make将忽略此类出错信号。

  Make命本身可带有四种参数:标志、宏定义、描述文件名和目标文件名。其标准形式为:

  Make [flags] [macro definitions] [targets]

  Unix系统下标志位flags选项及其含义为:

  -f file  指定file文件为描述文件,如果file参数为"-"符,那么描述文件指向标准输入。如果没有"-f"参数,则系统将默认当前目录下名为makefile或者名为Makefile的文件为描述文件。在Linux中, GNU make 工具在当前工作目录中按照GNUmakefile、makefile、Makefile的顺序搜索 makefile文件。
  -i   忽略命令执行返回的出错信息。
  -s   沉默模式,在执行之前不输出相应的命令行信息。
  -r   禁止使用build-in规则。
  -n   非执行模式,输出所有执行命令,但并不执行。
  -t   更新目标文件。
  -q   make操作将根据目标文件是否已经更新返回"0"或非"0"的状态信息。
  -p   输出所有宏定义和目标文件描述。
  -d   Debug模式,输出有关文件和检测时间的详细信息。

  Linux下make标志位的常用选项与Unix系统中稍有不同,下面我们只列出了不同部分:

  -c dir   在读取 makefile 之前改变到指定的目录dir。
  -I dir   当包含其他 makefile文件时,利用该选项指定搜索目录。
  -h   help文挡,显示所有的make选项。
  -w   在处理 makefile 之前和之后,都显示工作目录。

  通过命令行参数中的target ,可指定make要编译的目标,并且允许同时定义编译多个目标,操作时按照从左向右的顺序依次编译target选项中指定的目标文件。如果命令行中没有指定目标,则系统默认target指向描述文件中第一个目标文件。

  通常,makefile 中还定义有 clean 目标,可用来清除编译过程中的中间文件,例如:

  clean:
  rm -f *.o

  运行 make clean 时,将执行 rm -f *.o 命令,最终删除所有编译过程中产生的所有中间文件。

  隐含规则

  在make 工具中包含有一些内置的或隐含的规则,这些规则定义了如何从不同的依赖文件建立特定类型的目标。Unix系统通常支持一种基于文件扩展名即文件名后缀的隐含规则。这种后缀规则定义了如何将一个具有特定文件名后缀的文件(例如.c文件),转换成为具有另一种文件名后缀的文件(例如.o文件):

  .c:.o
  $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
  系统中默认的常用文件扩展名及其含义为:
  .o  目标文件
  .c  C源文件
  .f  FORTRAN源文件
  .s  汇编源文件
  .y  Yacc-C源语法
  .l  Lex源语法

  在早期的Unix系统系统中还支持Yacc-C源语法和Lex源语法。在编译过程中,系统会首先在makefile文件中寻找与目标文件相关的.C文件,如果还有与之相依赖的.y和.l文件,则首先将其转换为.c文件后再编译生成相应的.o文件;如果没有与目标相关的.c文件而只有相关的.y文件,则系统将直接编译.y文件。

  而GNU make 除了支持后缀规则外还支持另一种类型的隐含规则--模式规则。这种规则更加通用,因为可以利用模式规则定义更加复杂的依赖性规则。模式规则看起来非常类似于正则规则,但在目标名称的前面多了一个 % 号,同时可用来定义目标和依赖文件之间的关系,例如下面的模式规则定义了如何将任意一个 file.c 文件转换为 file.o 文件:

  %.c:%.o
  $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
  #EXAMPLE#

  下面将给出一个较为全面的示例来对makefile文件和make命令的执行进行进一步的说明,其中make命令不仅涉及到了C源文件还包括了Yacc语法。本例选自"Unix Programmer's Manual 7th Edition, Volume 2A" Page 283-284

下面是描述文件的具体内容:

  ---------------------------------------------------------
  #Description file for the Make command
  #Send to print
  P=und -3 | opr -r2
  #The source files that are needed by object files
  FILES= Makefile version.c defs main.c donamc.c misc.c file.c \
  dosys.c gram.y lex.c gcos.c
  #The definitions of object files
  OBJECTS= vesion.o main.o donamc.o misc.o file.o dosys.o gram.o
  LIBES= -LS
  LINT= lnit -p
  CFLAGS= -O
  make: $(OBJECTS)
  cc $(CFLAGS) $(OBJECTS) $(LIBES) -o make
  size make
  $(OBJECTS): defs
  gram.o: lex.c
  cleanup:
  -rm *.o gram.c
  install:
  @size make /usr/bin/make
  cp make /usr/bin/make ; rm make
  #print recently changed files
  print: $(FILES)
  pr $? | $P
  touch print
  test:
  make -dp | grep -v TIME>1zap
  /usr/bin/make -dp | grep -v TIME>2zap
  diff 1zap 2zap
  rm 1zap 2zap
  lint: dosys.c donamc.c file.c main.c misc.c version.c gram.c
  $(LINT) dosys.c donamc.c file.c main.c misc.c version.c \
  gram.c
  rm gram.c
  arch:
  ar uv /sys/source/s2/make.a $(FILES)
  ----------------------------------------------------------

  通常在描述文件中应象上面一样定义要求输出将要执行的命令。在执行了make命令之后,输出结果为:

  $ make
  cc -c version.c
  cc -c main.c
  cc -c donamc.c
  cc -c misc.c
  cc -c file.c
  cc -c dosys.c
  yacc gram.y
  mv y.tab.c gram.c
  cc -c gram.c
  cc version.o main.o donamc.o misc.o file.o dosys.o gram.o \
  -LS -o make
  13188+3348+3044=19580b=046174b

  最后的数字信息是执行"@size make"命令的输出结果。之所以只有输出结果而没有相应的命令行,是因为"@size make"命令以"@"起始,这个符号禁止打印输出它所在的命令行。

  描述文件中的最后几条命令行在维护编译信息方面非常有用。其中"print"命令行的作用是打印输出在执行过上次"make print"命令后所有改动过的文件名称。系统使用一个名为print的0字节文件来确定执行print命令的具体时间,而宏$?则指向那些在print文件改动过之后进行修改的文件的文件名。如果想要指定执行print命令后,将输出结果送入某个指定的文件,那么就可修改P的宏定义:

  make print "P= cat>zap"

  在Linux中大多数软件提供的是源代码,而不是现成的可执行文件,这就要求用户根据自己系统的实际情况和自身的需要来配置、编译源程序后,软件才能使用。只有掌握了make工具,才能让我们真正享受到到Linux这个自由软件世界的带给我们无穷乐趣。

re: In function `_start': 聂文龙 2007-05-10 01:50
先用gcc编译源文件,但不链接库文件。我把源程序保存为temp.c:

代码:
gcc -c temp.c -o temp.o这时用nm就可以看到temp.o中有x这个符号,x前面的T表示x这个符号在text段:

代码:
[kj501@s2023 c]$ nm temp.o
U printf
00000000 T x然后再用ld来链接,生成的可执行文件为a.out。

代码:
ld -e x -o a.out temp.o -lc -dynamic-linker /lib/ld-linux.so.2要注意此时链接的库文件必须包含标准C库文件libc(程序中使用了标准库函数printf,如果不用,可以不加)和加载动态库的/lib/ld-linux.so.2(因为libc缺省链接的是动态库)。不然是不会成功的。
链接完成后,用ldd查看,可以看到链接的动态库文件:

代码:
[kj501@s2023 c]$ ldd a.out
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/libc.so.6 (0x4002a000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)现在就可以运行程序了。

代码:
[kj501@s2023 c]$ ./a.out
Hello, world!
Segmentation fault能出来结果,但也有段错误,是什么地方出来问题,我还没有想清楚。
re: In function `_start': 聂文龙 2007-05-10 01:46
环境 red hat 9 kernel (2.4.20-8)
程序抄自《ARM & Linux 嵌入式系统教程》
代码
/**********************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>

#define DEMO_MAJOR 125
#define COMMAND1 1
#define COMMAND2 2

static int demo_init(void);
static int demo_open(struct inode *inode,struct file *file);
static int demo_close(struct inode *inode,struct file *file);
static ssize_t demo_read(struct file *file,char *buf,size_t count,loff_t *offset);
static int demo_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
static void demo_cleanup(void);

int demo_param = 9;
static int demo_initialized = 0;
static volatile int demo_flag = 0;
static struct file_operations demo_fops = {
owner:THIS_MODULE,
llseek:NULL,
read:demo_read,
write:NULL,
ioctl:demo_ioctl,
open:demo_open,
release:demo_close,
};

static int demo_init(void)
{
int i;
if(demo_initialized == 1)
return 0;
i = register_chrdev(DEMO_MAJOR,"demo_drv",&demo_fops);
if(i<0)
{
printk(KERN_CRIT"DEMO:i=%d\n",i);
return -EIO;
}
printk(KERN_CRIT"DEMO:demo_drv registerred successfully:)=\n");

demo_initialized = 1;
return 0;
}

static int demo_open(struct inode *inode,struct file *file)
{
if(demo_flag==1)
{
return -1;
}
printk(KERN_CRIT"DEMO:demo device open \n");
MOD_INC_USE_COUNT;
demo_flag = 1;
return 0;
}

static int demo_close(struct inode *inode,struct file *file)
{
if(demo_flag==0)
return 0;
printk(KERN_CRIT "DEMO:demo device close\n");
MOD_DEC_USE_COUNT;
demo_flag = 0;
return 0;
}

static ssize_t demo_read(struct file *file,char *buf,size_t count,loff_t *offset)
{
printk(KERN_CRIT "DEMO:demo is reading,demo_parm=%d\n",demo_param);
return 0;
}

static int demo_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
if(cmd==COMMAND1)
{
printk(KERN_CRIT "DEMO:set command COMMAND1\n");
return 0;
}
if(cmd==COMMAND2)
{
printk(KERN_CRIT "DEMO:set command COMMAND2\n");
return 0;
}
printk(KERN_CRIT "DEMO:set command WRONG\n");
return 0;
}

static void demo_cleanup(void)
{
if(demo_initialized==1)
{
unregister_chrdev(DEMO_MAJOR,"demo_drv");
demo_initialized = 0;
printk(KERN_CRIT "DEMO:demo device is cleanup\n");
}
return;
}

#ifdef MODULE
MODULE_AUTHOR("DEPART 901");
MODULE_DESCRIPTION("DEMO driver");
MODULE_PARM(demo_param,"i");
MODULE_PARM_DESC(demo_param,"parameter send to driver");
int init_module(void)
{
return demo_init();
}
void cleanup_module(void)
{
demo_cleanup();
}
#endif

//////////////////////////////////////////
编译及出错提示
gcc -Wall -DMODULE -D__KERNEL__ -DLINUX -I/usr/src/linux-2.4.20-8/include -I -c demo.c -o demo.o
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crt1.o(.text+0x18): In function `_start':
../sysdeps/i386/elf/start.S:77: undefined reference to `main'
/tmp/ccEOwLAP.o(.text+0x28): In function `demo_init':
: undefined reference to `register_chrdev'
/tmp/ccEOwLAP.o(.text+0x44): In function `demo_init':
: undefined reference to `printk'
/tmp/ccEOwLAP.o(.text+0x5d): In function `demo_init':
: undefined reference to `printk'
/tmp/ccEOwLAP.o(.text+0x9c): In function `demo_open':
: undefined reference to `printk'
/tmp/ccEOwLAP.o(.text+0xa7): In function `demo_open':
: undefined reference to `__this_module'
/tmp/ccEOwLAP.o(.text+0xb5): In function `demo_open':
: undefined reference to `__this_module'
/tmp/ccEOwLAP.o(.text+0xea): In function `demo_close':
: undefined reference to `printk'
/tmp/ccEOwLAP.o(.text+0xf5): In function `demo_close':
: undefined reference to `__this_module'
/tmp/ccEOwLAP.o(.text+0x103): In function `demo_close':
: undefined reference to `__this_module'
/tmp/ccEOwLAP.o(.text+0x12e): In function `demo_read':
: undefined reference to `printk'
/tmp/ccEOwLAP.o(.text+0x151): In function `demo_ioctl':
: undefined reference to `printk'
/tmp/ccEOwLAP.o(.text+0x169): In function `demo_ioctl':
: undefined reference to `printk'
/tmp/ccEOwLAP.o(.text+0x17b): In function `demo_ioctl':
: undefined reference to `printk'
/tmp/ccEOwLAP.o(.text+0x1a3): In function `demo_cleanup':
: undefined reference to `unregister_chrdev'
/tmp/ccEOwLAP.o(.text+0x1bd): In function `demo_cleanup':
: undefined reference to `printk'
/tmp/ccEOwLAP.o(.data+0x20): undefined reference to `__this_module'
collect2: ld returned 1 exit status
make: *** [demo.o] Error 1



多了一个 "-I"
gcc -Wall -DMODULE -D__KERNEL__ -DLINUX -I/usr/src/linux-2.4.20-8/include -I -c demo.c -o demo.o
gcc -Wall -DMODULE -D__KERNEL__ -DLINUX -I/usr/src/linux-2.4.20-8/include -c demo.c -o demo.o

re: In function `_start': 聂文龙 2007-05-10 01:41
Lex和Yacc应用方法(一).初识Lex
Lex(Lexical Analyzar 词法分析生成器),Yacc(Yet Another Compiler Compiler
编译器代码生成器)是Unix下十分重要的词法分析,语法分析的工具。经常用于语言分
析,公式编译等广泛领域。遗憾的是网上中文资料介绍不是过于简单,就是跳跃太大,
入门参考意义并不大。本文通过循序渐进的例子,从0开始了解掌握Lex和Yacc的用法。

<本系列文章的地址:http://blog.csdn.net/liwei_cmg/category/207528.aspx>

一.Lex(Lexical Analyzar) 初步示例

先看简单的例子(注:本文所有实例皆在RetHat Linux下完成):

一个简单的Lex文件 exfirst.l 内容:

%{
#include "stdio.h"
%}
%%
[\n] ;
[0-9]+ printf("Int : %s\n",yytext);
[0-9]*\.[0-9]+ printf("Float : %s\n",yytext);
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);
[\+\-\*\/\%] printf("Op : %s\n",yytext);
. printf("Unknown : %c\n",yytext[0]);
%%

在命令行下执行命令flex解析,会自动生成lex.yy.c文件:
[root@localhost liweitest]flex exfirst.l

进行编译生成parser可执行程序:
[root@localhost liweitest]cc -o parser lex.yy.c -ll

[注意:如果不加-ll链结选项,cc编译时会出现以下错误,后面会进一步说明。]

/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crt1.o(.text+0x18): In function `_start':
../sysdeps/i386/elf/start.S:77: undefined reference to `main'
/tmp/cciACkbX.o(.text+0x37b): In function `yylex':
: undefined reference to `yywrap'
/tmp/cciACkbX.o(.text+0xabd): In function `input':
: undefined reference to `yywrap'
collect2: ld returned 1 exit status


创建待解析的文件 file.txt:

title
i=1+3.9;
a3=909/6
bcd=4%9-333

通过已生成的可执行程序,进行文件解析。

[root@localhost liweitest]# ./parser < file.txt
Var : title
Var : i
Unknown : =
Int : 1
Op : +
Float : 3.9
Unknown : ;
Var : a3
Unknown : =
Int : 909
Op : /
Int : 6
Var : bcd
Unknown : =
Int : 4
Op : %
Int : 9
Op : -
Int : 333

到此Lex用法会有个直观的了解:

1.定义Lex描述文件
2.通过lex,flex工具解析成lex.yy.c文件
3.使用cc编译lex.yy.c生成可执行程序


再来看一个比较完整的Lex描述文件 exsec.l :


%{
#include "stdio.h"
int linenum;
%}
%%
title showtitle();
[\n] linenum++;
[0-9]+ printf("Int : %s\n",yytext);
[0-9]*\.[0-9]+ printf("Float : %s\n",yytext);
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);
[\+\-\*\/\%] printf("Op : %s\n",yytext);
. printf("Unknown : %c\n",yytext[0]);
%%
showtitle()
{
printf("----- Lex Example -----\n");
}

int main()
{
linenum=0;
yylex(); /* 进行分析 */
printf("\nLine Count: %d\n",linenum);
return 0;
}
int yywrap()
{
return 1;
}

进行解析编译:
[root@localhost liweitest]flex exsec.l
[root@localhost liweitest]cc -o parser lex.yy.c
[root@localhost liweitest]./parser < file.txt

----- Lex Example -----
Var : i
Unknown : =
Int : 1
Op : +
Float : 3.9
Unknown : ;
Var : a3
Unknown : =
Int : 909
Op : /
Int : 6
Var : bcd
Unknown : =
Int : 4
Op : %
Int : 9
Op : -
Int : 333

Line Count: 4

这里就没有加-ll选项,但是可以编译通过。下面开始着重整理下Lex描述文件.l。


二.Lex(Lexical Analyzar) 描述文件的结构介绍

Lex工具是一种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识
别程序,由该程序识别出输入文本中的各个单词。 一般可以分为<定义部分><规则部
分><用户子程序部分>。其中规则部分是必须的,定义和用户子程序部分是任选的。


(1)定义部分
定义部分起始于 %{ 符号,终止于 %} 符号,其间可以是包括include语句、声明语句
在内的C语句。这部分跟普通C程序开头没什么区别。
%{
#include "stdio.h"
int linenum;
%}

(2) 规则部分
规则部分起始于"%%"符号,终止于"%%"符号,其间则是词法规则。词法规则由模式和
动作两部分组成。模式部分可以由任意的正则表达式组成,动作部分是由C语言语句组
成,这些语句用来对所匹配的模式进行相应处理。需要注意的是,lex将识别出来的单
词存放在yytext[]字符数据中,因此该数组的内容就代表了所识别出来的单词的内容。
类似yytext这些预定义的变量函数会随着后面内容展开一一介绍。动作部分如果有多
行执行语句,也可以用{}括起来。

%%
title showtitle();
[\n] linenum++;
[0-9]+ printf("Int : %s\n",yytext);
[0-9]*\.[0-9]+ printf("Float : %s\n",yytext);
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);
[\+\-\*\/\%] printf("Op : %s\n",yytext);
. printf("Unknown : %c\n",yytext[0]);
%%

A.规则部分的正则表达式

规则部分是Lex描述文件中最为复杂的一部分,下面列出一些模式部分的正则表达式字
符含义:

A-Z, 0-9, a-z 构成模式部分的字符和数字。

- 指定范围。例如:a-z 指从 a 到 z 之间的所有字符。

\ 转义元字符。用来覆盖字符在此表达式中定义的特殊意义,
只取字符的本身。

[] 表示一个字符集合。匹配括号内的任意字符。如果第一个字
符是^那么它表示否定模式。例如: [abC] 匹配 a, b, 和C
的任何一个。

^ 表示否定。

* 匹配0个或者多个上述模式。
+ 匹配1个或者多个上述模式。
? 匹配0个或1个上述模式。

$ 作为模式的最后一个字符时匹配一行的结尾。

{ } 表示一个模式可能出现的次数。 例如: A{1,3} 表示 A 可
能出现1次或3次。[a-z]{5} 表示长度为5的,由a-z组成的
字符。此外,还可以表示预定义的变量。

. 匹配任意字符,除了 \n。

( ) 将一系列常规表达式分组。如:{Letter}({Letter}|{Digit})*
| 表达式间的逻辑或。

"一些符号" 字符的字面含义。元字符具有。如:"*" 相当于 [\*]。

/ 向前匹配。如果在匹配的模式中的"/"后跟有后续表达式,
只匹配模版中"/"前面的部分。如:模式为 ABC/D 输入 ABCD,
时ABC会匹配ABC/D,而D会匹配相应的模式。输入ABCE的话,
ABCE就不会去匹配ABC/D。


B.规则部分的优先级


规则部分具有优先级的概念,先举个简单的例子:


%{
#include "stdio.h"
%}
%%
[\n] ;
A {printf("ONE\n");};
AA {printf("TWO\n");};
AAAA {printf("THREE\n");};
%%

此时,如果输入内容:

[root@localhost liweitest]# cat file1.txt
AAAAAAA

[root@localhost liweitest]# ./parser < file1.txt
THREE
TWO
ONE

Lex分析词法时,是逐个字符进行读取,自上而下进行规则匹配的,读取到第一个A字符
时,遍历后发现三个规则皆匹配成功,Lex会继续分析下去,读至第五个字符时,发现
"AAAA"只有一个规则可用,即按行为进行处理,以此类推。可见Lex会选择最长的字符
匹配规则。

如果将规则
AAAA {printf("THREE\n");};
改为
AAAAA {printf("THREE\n");};

./parser < file1.txt 输出结果为:
THREE
TWO


再来一个特殊的例子:

%%
title showtitle();
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);
%%

并输入title,Lex解析完后发现,仍然存在两个规则,这时Lex只会选择第一个规则,下面
的则被忽略的。这里就体现了Lex的顺序优先级。把这个例子稍微改一下:

%%
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);
title showtitle();
%%

Lex编译时会提示:warning, rule cannot be matched.这时处理title字符时,匹配
到第一个规则后,第二个规则就无效了。

再把刚才第一个例子修改下,加深下印象!

%{
#include "stdio.h"
%}
%%
[\n] ;
A {printf("ONE\n");};
AA {printf("TWO\n");};
AAAA {printf("THREE\n");};
AAAA {printf("Cannot be executed!");};

./parser < file1.txt 显示效果是一样的,最后一项规则肯定是会忽略掉的。



C.规则部分的使用变量

且看下面示例:

%{
#include "stdio.h"
int linenum;
%}
int [0-9]+
float [0-9]*\.[0-9]+
%%
{int} printf("Int : %s\n",yytext);
{float} printf("Float : %s\n",yytext);
. printf("Unknown : %c\n",yytext[0]);
%%

在%}和%%之间,加入了一些类似变量的东西,注意是没有;的,这表示int,float分
别代指特定的含义,在两个%%之间,可以通过{int}{float}进行直接引用,简化模
式定义。


(3) 用户子程序部分

最后一个%%后面的内容是用户子程序部分,可以包含用C语言编写的子程序,而这些子
程序可以用在前面的动作中,这样就可以达到简化编程的目的。这里需要注意的是,
当编译时不带-ll选项时,是必须加入main函数和yywrap(yywrap将下后面说明)。如:

...
%%
showtitle()
{
printf("----- Lex Example -----\n");
}

int main()
{
linenum=0;
yylex(); /* 进行Lex分析 */
printf("\nLine Count: %d\n",linenum);
return 0;
}
int yywrap()
{
return 1;
}


三.Lex(Lexical Analyzar) 一些的内部变量和函数

内部预定义变量:

yytext char * 当前匹配的字符串
yyleng int 当前匹配的字符串长度
yyin FILE * lex当前的解析文件,默认为标准输出
yyout FILE * lex解析后的输出文件,默认为标准输入
yylineno int 当前的行数信息

内部预定义宏:

ECHO #define ECHO fwrite(yytext, yyleng, 1, yyout) 也是未匹配字符的
默认动作


内部预定义的函数:

int yylex(void) 调用Lex进行词法分析
int yywrap(void) 在文件(或输入)的末尾调用。如果函数的返回值是1,就停止解
析。 因此它可以用来解析多个文件。代码可以写在第三段,这
样可以解析多个文件。 方法是使用 yyin 文件指针指向不同的
文件,直到所有的文件都被解析。最后,yywrap() 可以返回1
来表示解析的结束。


lex和flex都是解析Lex文件的工具,用法相近,flex意为fast lexical analyzer generator。
可以看成lex的升级版本。


相关更多内容就需要参考flex的man手册了,十分详尽。



四.关于Lex的一些综述

Lex其实就是词法分析器,通过配置文件*.l,依据正则表达式逐字符去顺序解析文件,
并动态更新内存的数据解析状态。不过Lex只有状态和状态转换能力。因为它没有堆栈,
它不适合用于剖析外壳结构。而yacc增加了一个堆栈,并且能够轻易处理像括号这样的
结构。Lex善长于模式匹配,如果有更多的运算要求就需要yacc了。

re: In function `_start': 聂文龙 2007-05-10 01:33
[root@localhost spcacat]# make
/usr/local/arm/2.95.3/bin/arm-linux-gcc -Wall -o spcacat -lm -lpthread

/usr/local/arm/2.95.3/arm-linux/lib/crt1.o: In function `_start':

/usr/local/arm/2.95.3/arm-linux/lib/crt1.o(.text+0x2c):
undefined reference to `main'
collect2: ld returned 1 exit status

make: *** [spcacat] Error 1


好像原因是这样的,_start不是一个函数,找不到main函数的入口。
看到网上说加个选项:-no三tartfiles。没有了错误,可下载到arm版上运行的时候说:
no symbol version information.
不知怎么解决?




问题已解决,原因在我的makefile文件里一个宏写错了。

re: 在Linux下安装和使用MySQL 聂文龙 2007-05-10 01:16
mysql安装
编译源代码并安装。


groupadd mysql
useradd mysql
cd mysql_src_home
./configure --prefix=/usr/local/mysql
make
make install
scripts/mysql_install_db
chown -R root:mysql /usr/local/mysql
chown -R mysql:mysql /usr/local/mysql/var
chgrp -R mysql /usr/local/mysql
cp support-files/my-medium.cnf /etc/my.cnf
cp /usr/local/mysql/share/mysql/mysql.server /usr/local/mysql/share/mysql/mysqld
chmod a+x /usr/local/mysql/share/mysql/mysqld
启动服务方法
/usr/local/mysql/bin/safe_mysqld --user=mysql &
或者
/usr/local/mysql/share/mysql/mysqld start
停止服务方法
/usr/local/mysql/bin/mysqladmin shutdown
re: smpp的超长wappush格式 聂文龙 2007-04-28 15:25
00 ’SMSC Len。用手机上设置短信中心号码

51 ’submit type

00 ’SMS_TP_Message_Reference type

0B ’对方电话的长度

A1 ’Number type

13166416588F8 ’电话号码:13661456888

00 ’SMS_TP_PID

F5 ’SMS DCS

A744 ’SMS available date

0B05040B8423F00003030101 ’Wap Push Header 1

29060603AE81EA8DCA 'Wap Push header 2

02

05 '-//WAPFORUM//DTD SI 1.0//EN

6A 'UTF-8

00

45 '<si>

C6 '<indication

08 '<action=signal-high>

0C 'href="http://

03 '字符串开始

687474703A2F2F696D732E6E656173652E6E6574 'URL: http://ims.nease.net

00 'URL 字符串结束

01 '>

03 '内容描述字符串开始

'这里就是显示给用户的内容,用utf-8编码。

E796AFE78B82E79FADE4BFA1 '内容描述:疯狂短信

00 '内容描述字符串结束

01 '</indication>"

01 '</si>
共5页: 1 2 3 4 5