编程世界的多元语言与C源文件编译指南
在编程的广阔天地里,有着各种各样的脚本语言和编译型语言,它们各自有着独特的用途和特点。下面我们将为大家介绍一些常见的脚本语言,以及Java语言的相关特性,最后深入探讨C源文件的编译过程。
常见脚本语言介绍
- PHP :有些人会使用PHP编写独立脚本。其官方网站为http://www.php.net/ 。
- Ruby :面向对象编程的爱好者和许多Web开发者喜欢用这种语言进行编程。更多信息可访问http://www.ruby-lang.org/ 。
- JavaScript :主要用于浏览器中处理动态内容。虽然经验丰富的程序员常因其缺陷而拒绝将其作为独立脚本语言,但在Web编程中几乎无法避免使用它。还可以找到名为Node.js的实现,系统中有可执行文件node。
- Emacs Lisp :是文本编辑器Emacs使用的Lisp编程语言的一种变体。
- Matlab和Octave :Matlab是用于矩阵和数学运算的商业编程语言和库。有一个非常相似的免费软件项目Octave。
- R :是一种流行的免费统计分析语言。访问http://www.r-project.org/ ,并查看Norman Matloff所著的《The Art of R Programming》(No Starch Press,2011年)可获取更多信息。
- Mathematica :是另一种带有库的商业数学编程语言。
- m4 :是一种宏处理语言,通常仅在GNU autotools中出现。
- Tcl :即工具命令语言,是一种简单的脚本语言,通常与图形用户界面工具包Tk和自动化实用程序Expect相关联。虽然它的使用不如以前广泛,但不要低估其有效性。许多资深开发者更喜欢Tk,特别是因为它包含的功能。访问http://www.tcl.tk/ 可获取有关Tk的更多信息。
Java语言特性
Java是一种像C一样的编译型语言,语法更简单,对面向对象编程有有效的支持。它在Unix系统中有特定的应用场景,常被用作Web应用环境,在专业应用中也很受欢迎,例如Android应用通常用Java编写。
Java有两种类型的编译器:
-
本地编译器
:为系统生成机器代码(类似于C编译器)。
-
字节码编译器
:供字节码解释器(有时称为虚拟机,与第17章中描述的虚拟机管理程序提供的虚拟机不同)使用。在Linux中,通常会遇到字节码。
Java字节码文件以.class结尾,Java运行时环境(JRE)包含执行Java字节码所需的所有程序。执行字节码文件的命令如下:
$ java arquivo.class
也会遇到以.jar结尾的字节码文件,它们是多个.class文件的集合。执行.jar文件的语法如下:
$ java -jar arquivo.jar
有时需要设置环境变量
JAVA_HOME
为Java安装的前缀。如果运气不好,可能需要使用
CLASSPATH
来包含程序所需的所有类所在的目录,这是一个用冒号分隔的目录集合,类似于可执行文件的
PATH
变量。
如果需要编译.java文件并生成字节码,需要有Java开发工具包(JDK)。JDK的
javac
编译器可用于创建.class文件:
$ javac arquivo.java
JDK还带有
jar
程序,可用于创建和分离.jar文件,其工作方式类似于
tar
。
C源文件编译的背景与原因
大多数非专有Unix第三方软件包以可编译和安装的源代码形式提供。原因主要有两点:
- Unix(包括Linux)有众多变体和架构,难以分发适用于所有平台组合的二进制包。
- 通过Unix社区广泛分发源代码,鼓励用户为软件贡献错误修复和新功能,体现了开源的意义。
虽然可以从源代码安装几乎所有Linux系统中的软件,包括内核、C库和Web浏览器等,但不建议全部通过源代码安装来更新计算机,除非你喜欢这个过程或有其他特殊原因。Linux发行版通常提供更简单的方式来更新系统的关键部分,并且能快速修复安全问题。不过,你可能想自己安装某些软件包,原因如下:
- 控制配置选项。
- 可以将软件安装到你想要的位置,甚至可以安装同一软件包的不同版本。
- 控制要安装的版本,因为发行版并不总是能及时更新所有软件包的最新版本,特别是软件包的附加组件(如Python库)。
- 更好地理解软件包的工作原理。
C源文件编译的基本步骤
使用GNU autotools生成的配置脚本来编译和安装C源代码包,通常包括以下步骤:
1. 解压缩源代码文件。
2. 配置软件包。
3. 执行
make
命令生成程序。
4. 执行
make install
或特定发行版的安装命令来安装软件包。
解压缩C源代码包
源代码包通常以.tar.gz、.tar.bz2或.tar.xz文件形式提供。在解压缩之前,使用
tar tvf
或
tar ztvf
检查文件内容,因为有些软件包不会在提取目录中创建自己的子目录。
如果输出类似如下内容,说明解压缩可能没有问题:
package-1.23/Makefile.in
package-1.23/README
package-1.23/main.c
package-1.23/bar.c
但如果发现并非所有文件都在一个公共目录中,例如:
Makefile
README
main.c
直接提取这样的文件可能会导致当前目录混乱。为避免这种情况,在提取文件内容之前,创建一个新目录并使用
cd
命令进入该目录。
此外,要注意包含绝对路径名文件的软件包,如
/etc/passwd
、
/etc/inetd.conf
,如果遇到这种情况,应从系统中删除该文件,因为它可能包含特洛伊木马或其他恶意代码。
开始编译前的准备
提取源代码文件内容后,要对软件包有一个大致的了解。特别要查找
README
和
INSTALL
文件,总是先查看
README
文件,因为它通常包含软件包的描述、简易手册、安装提示和其他有用信息。许多软件包还带有
INSTALL
文件,其中包含编译和安装软件包的说明,要特别注意编译器的特殊选项和定义。
除了
README
和
INSTALL
文件,软件包中的其他文件通常可分为以下三类:
-
与make系统相关的文件
:如
Makefile
、
Makefile.in
、
configure
和
CMakeLists.txt
。一些非常古老的软件包带有可能需要修改的
Makefile
,但大多数使用GNU autoconf或CMake等配置实用程序。这些软件包带有脚本或配置文件(如
configure
或
CMakeLists.txt
),用于根据系统配置和配置选项从
Makefile.in
生成
Makefile
。
-
源代码文件
:以.c、.h或.cc结尾。C源代码文件可能出现在软件包目录的任何位置。C++源代码文件通常以.cc、.C或.cxx为后缀。
-
目标文件或二进制文件
:以.o结尾的目标文件或二进制文件。通常,源代码发行版中不会有目标文件,但在极少数情况下,软件包维护者可能没有权限分发某些源代码,需要特殊处理才能使用目标文件。在大多数情况下,源代码发行版中的目标文件(或二进制可执行文件)意味着软件包的组成方式不当,应执行
make clean
以确保进行新的编译。
GNU autoconf的原理与使用
由于C源代码通常具有较好的可移植性,但不同平台的差异使得用单一的
Makefile
编译大多数软件包变得不可能。最初的解决方案是为每个操作系统提供单独的
Makefile
或易于修改的
Makefile
,后来演变为使用根据生成软件包的系统分析来生成
Makefile
的脚本。
GNU autoconf是一种流行的自动生成
Makefile
的系统。使用该系统的软件包带有名为
configure
、
Makefile.in
和
config.h.in
的文件,.in文件是模板。执行
configure
脚本可以发现系统的特性,然后在.in文件中进行替换,创建真正的构建文件。对于最终用户来说很简单,要从
Makefile.in
生成
Makefile
,执行以下命令:
$ ./configure
执行过程中,脚本会检查系统的先决条件,并在输出中提供各种诊断数据。如果一切顺利,
configure
将创建一个或多个
Makefile
、一个
config.h
文件以及一个缓存文件(
config.cache
),这样就不需要再次执行某些测试。
现在可以执行
make
命令来编译软件包。
configure
执行成功并不一定意味着
make
步骤也会成功,但成功的可能性很大。
在进行操作之前,要确保系统中具备所有必要的构建工具。对于Debian和Ubuntu系统,最简单的方法是安装
build-essential
软件包;对于Fedora类型的系统,使用
groupinstall “Development Tools”
。
GNU autoconf的示例操作
以安装GNU coreutils软件包到自己的主目录为例,步骤如下:
1. 从http://ftp.gnu.org/gnu/coreutils/ 获取软件包(通常最新版本是最好的)。
2. 解压缩软件包,进入其目录并进行配置:
$ ./configure --prefix=$HOME/mycoreutils
执行过程中会输出各种检查信息,如:
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
配置完成后,会创建一些文件,如:
config.status: executing po-directories commands
config.status: creating po/POTFILES
config.status: creating po/Makefile
-
执行
make命令:
$ make
执行过程中会生成一些文件,如:
GEN lib/alloca.h
GEN lib/c++defs.h
-
可以尝试执行新创建的可执行文件,如
./src/ls,并执行make check对软件包进行一系列测试(这可能需要一些时间,但值得一看)。 -
在安装之前,先使用
make -n进行“预演”,查看make install将执行的操作:
$ make -n install
浏览输出,如果没有异常(如安装到非
mycoreutils
目录),则进行实际安装:
$ make install
安装完成后,主目录下会有一个名为
mycoreutils
的子目录,包含
bin
、
share
等子目录。可以查看
bin
中的一些程序,这些程序就是你刚刚生成的基本工具。由于
mycoreutils
目录被配置为独立于系统的其他部分,因此可以完全删除它而不用担心造成损害。
使用打包工具进行安装
在大多数发行版中,可以将新软件安装为一个软件包,以便后续使用发行版的打包工具进行管理。
-
基于Debian的发行版(如Ubuntu)
:可以使用
checkinstall
实用程序,而不是简单地执行
make install
,命令如下:
# checkinstall make install
可以使用
--pkgname=nome
选项为新软件包指定特定的名称。
-
创建RPM软件包
:稍微复杂一些,需要先使用
rpmdev-setuptree
命令创建目录树,完成后可以使用
rpmbuild
实用程序执行其余步骤。建议参考在线教程进行操作。
configure脚本的选项
configure
脚本有很多有用的选项,其中最常用的是
--prefix
,用于指定安装目录。默认情况下,由autoconf生成的
Makefile
的
install
目标使用的前缀是
/usr/local
,即二进制程序位于
/usr/local/bin
,库位于
/usr/local/lib
等。
常见的配置选项如下:
|选项|说明|
| ---- | ---- |
|
--prefix=novo_prefixo
|更改安装目录的前缀|
|
--bindir=diretório
|将可执行文件安装到指定目录|
|
--sbindir=diretório
|将系统可执行文件安装到指定目录|
|
--libdir=diretório
|将库安装到指定目录|
|
--disable-shared
|阻止软件包生成共享库,这可以避免后续的一些问题|
|
--with-pacote=diretório
|告知
configure
某个软件包所在的目录,当所需的库不在标准位置时很实用,但并非所有
configure
脚本都支持此选项,且确定确切的语法可能比较困难|
还可以创建单独的构建目录进行实验。创建一个新目录,从该目录执行原软件包源代码目录中的
configure
脚本。
configure
会在新的构建目录中创建一组符号链接,所有链接都指向原软件包源代码目录中的代码树。一些开发者更喜欢这种方式生成软件包,因为原代码树不会被修改,而且如果想使用同一源代码包为多个平台或一组配置选项生成软件包,这种方式也很有用。
环境变量对configure的影响
可以使用环境变量影响
configure
脚本,它会将这些环境变量传递给
make
变量。最重要的环境变量是
CPPFLAGS
、
CFLAGS
和
LDFLAGS
。但要注意,
configure
对环境变量的要求可能比较严格。例如,通常应该使用
CPPFLAGS
而不是
CFLAGS
来指定头文件目录,因为
configure
通常会独立于编译器执行预处理器。
在bash中,将环境变量传递给
configure
的最简单方法是在命令行中
./configure
之前设置变量。例如,为预处理器定义一个
DEBUG
宏:
$ CPPFLAGS=-DDEBUG ./configure
也可以将变量作为
configure
的选项传递:
$ ./configure CPPFLAGS=-DDEBUG
当
configure
不知道在哪里查找包含文件和第三方库时,环境变量特别有用。例如,让预处理器在
dir_include
目录中查找:
$ CPPFLAGS=-Idir_include ./configure
让链接器在
dir_lib
目录中查找:
$ LDFLAGS=-Ldir_lib ./configure
如果
dir_lib
目录中有共享库,上述命令可能不会定义运行时动态链接器的路径。在这种情况下,除了
-L
选项,还需要使用链接器的
-rpath
选项:
$ LDFLAGS="-Ldir_lib -Wl,-rpath=dir_lib" ./configure
定义变量时要小心,一个小错误可能会导致编译器出错,使
configure
失败。例如,忘记
-I
中的
-
:
$ CPPFLAGS=Idir_include ./configure
会导致如下错误:
configure: error: C compiler cannot create executables
See 'config.log' for more details
查看生成的
config.log
文件,会发现:
configure:5037: checking whether the C compiler works
configure:5059: gcc Idir_include conftest.c >&5
gcc: error: Idir_include: No such file or directory
configure:5063: $? = 1
configure:5101: result: no
autoconf的目标
configure
成功执行后,生成的
Makefile
除了标准的
all
和
install
目标外,还有其他有用的目标:
-
make clean
:如前文所述,此命令会删除所有目标文件、可执行文件和库。
-
make distclean
:类似于
make clean
,但会删除所有自动生成的文件,包括
Makefile
、
config.h
、
config.log
等。执行
make distclean
后,代码树看起来就像刚解压缩的发行版。
-
make check
:一些软件包带有一组测试,用于检查编译后的程序是否正常工作,
make check
命令会执行这些测试。
-
make install-strip
:类似于
make install
,但在安装时会删除可执行文件和库的符号表和其他调试信息,这样的二进制文件占用的空间会小很多。
autoconf的日志文件分析
如果
configure
过程中出现问题且原因不明显,可以分析
config.log
文件来确定问题所在。但
config.log
通常是一个很大的文件,很难找到问题的准确来源。
一般的查找方法是先到
config.log
的末尾(例如在
less
中按
G
键),然后逐页返回,直到找到问题。但末尾有很多数据,因为
configure
会在那里输出整个环境信息,包括输出变量、缓存变量和其他定义。因此,更好的方法是到末尾后进行反向搜索,查找“for more details”之类的字符串,或者查找
configure
失败输出附近的其他部分(在
less
中可以使用
?
命令开始反向搜索)。很有可能错误就在你搜索到的内容上方。
pkg-config的使用
由于有大量的第三方库,将它们都放在一个公共位置可能会很混乱。而每个库使用不同的前缀安装,在生成需要这些第三方库的软件包时可能会出现问题。例如,要编译OpenSSH,就需要OpenSSL库。那么如何告知OpenSSH配置过程OpenSSL库的位置和所需的库呢?
许多库现在使用
pkg-config
程序,它不仅可以公布其包含文件和库的位置,还可以指定编译和链接程序所需的确切标志。语法如下:
$ pkg-config opções pacote1 pacote2 ...
例如,查找OpenSSL所需的库,可以执行以下命令:
$ pkg-config --libs openssl
输出可能如下:
-lssl -lcrypto
要查看
pkg-config
已知的所有库,可以执行:
$ pkg-config --list-all
pkg-config
通过读取以
.pc
结尾的配置文件来查找软件包信息。例如,OpenSSL套接字库的
openssl.pc
文件就包含了相关信息。
综上所述,在编程的世界里,无论是脚本语言的灵活运用,还是Java语言的强大功能,再到C源文件编译的复杂过程,都有着各自的特点和技巧。希望通过本文的介绍,能帮助你更好地理解和掌握这些知识,在编程的道路上更加得心应手。
编程世界的多元语言与C源文件编译指南
不同脚本语言的应用场景总结
不同的脚本语言在编程领域有着各自独特的应用场景,下面通过表格进行总结:
| 脚本语言 | 应用场景 |
| ---- | ---- |
| PHP | 常用于编写独立脚本,在Web开发中也有广泛应用 |
| Ruby | 受面向对象编程爱好者和Web开发者青睐,用于各类Web项目开发 |
| JavaScript | 主要用于浏览器处理动态内容,是Web前端编程的核心语言 |
| Emacs Lisp | 作为Emacs文本编辑器的脚本语言,用于定制编辑器功能 |
| Matlab和Octave | 用于矩阵和数学运算,在科学计算、工程领域应用广泛 |
| R | 专注于统计分析,在数据分析、机器学习等领域使用频繁 |
| Mathematica | 商业数学编程,在科研、教育等领域有重要应用 |
| m4 | 主要在GNU autotools中用于宏处理 |
| Tcl | 与图形用户界面工具包Tk和自动化实用程序Expect相关,在特定自动化场景中发挥作用 |
编译型语言的对比分析
除了脚本语言,编译型语言如C和Java也各有特点。以下是C和Java的对比分析:
| 语言 | 编译方式 | 语法特点 | 应用场景 |
| ---- | ---- | ---- | ---- |
| C | 本地编译生成机器代码 | 语法相对复杂,对底层操作支持好 | 系统编程、嵌入式开发等 |
| Java | 可本地编译或生成字节码 | 语法简单,对面向对象编程支持好 | Web应用、Android应用开发等 |
C源文件编译的流程图
下面是C源文件编译的mermaid流程图:
graph TD;
A[获取源代码包] --> B[解压缩源代码文件];
B --> C{检查文件结构};
C -- 正常 --> D[查找README和INSTALL文件];
C -- 异常 --> E[创建新目录并提取];
D --> F[执行configure脚本];
E --> F;
F --> G[执行make命令生成程序];
G --> H[执行make check进行测试];
H -- 通过 --> I[执行make install安装软件包];
H -- 未通过 --> J[分析config.log查找问题];
J --> F;
不同发行版安装方式的选择建议
在不同的Linux发行版中,安装软件包的方式有所不同。以下是一些选择建议:
-
基于Debian的发行版(如Ubuntu)
:如果希望将软件包纳入系统的包管理体系,方便后续更新和管理,建议使用
checkinstall
实用程序。例如:
# checkinstall make install --pkgname=my_package
-
基于Fedora的发行版
:对于需要创建RPM软件包的情况,按照
rpmdev-setuptree和rpmbuild的步骤进行操作。但由于过程相对复杂,建议先参考在线教程。
环境变量使用的注意事项
在使用环境变量影响
configure
脚本时,有以下注意事项:
-
变量选择
:要根据具体需求选择合适的环境变量,如使用
CPPFLAGS
指定头文件目录,使用
LDFLAGS
指定库文件目录。
-
语法正确性
:定义变量时要确保语法正确,避免因小错误导致
configure
失败。例如,使用
-I
指定头文件目录时,不能遗漏
-
。
-
兼容性
:不同的
configure
脚本对环境变量的支持可能有所不同,在使用时要进行测试。
编译过程中的常见问题及解决方法
在C源文件编译过程中,可能会遇到各种问题,以下是一些常见问题及解决方法:
| 问题 | 现象 | 解决方法 |
| ---- | ---- | ---- |
|
configure
失败 | 输出错误信息,如“C compiler cannot create executables” | 分析
config.log
文件,查找错误原因,可能是缺少依赖库或环境变量设置错误 |
|
make
失败 | 编译过程中出现错误提示 | 检查源代码是否有语法错误,或者是否缺少必要的头文件和库文件 |
| 测试不通过 |
make check
命令执行后有测试用例失败 | 检查程序的逻辑是否正确,或者是否存在内存泄漏等问题 |
未来编程趋势与这些语言和编译技术的关联
随着科技的不断发展,编程领域也在不断变化。未来,脚本语言可能会在人工智能、大数据等领域发挥更重要的作用。例如,Python作为一种脚本语言,在机器学习和数据分析中已经占据主导地位。而Java和C等编译型语言将继续在系统开发、嵌入式设备等领域保持重要地位。
C源文件编译技术也将不断优化,以适应新的硬件架构和软件需求。例如,随着多核处理器的普及,编译技术可能会更加注重并行编译,提高编译效率。同时,软件包管理工具也将更加智能化,方便开发者管理和维护软件包。
总之,无论是脚本语言、编译型语言还是编译技术,都将随着时代的发展而不断演进。开发者需要不断学习和掌握新的知识和技能,才能在编程的道路上跟上时代的步伐。
希望本文能为你在编程学习和实践中提供有价值的参考,让你在面对各种编程任务时更加从容自信。
编程多元语言介绍与C源文件编译指南
超级会员免费看
1313

被折叠的 条评论
为什么被折叠?



