在Ubuntu下编译 C++与Fortran

ephesians 2012-03-29

GCC是GNU编译器集合(GNUCompilerCollection)的首字母缩写词。GNU编译器集合包含C,C++,Objective-C,Fortran,Java和Ada的前端以及这些语言对应的库(libstdc++,libgcj,……)。

前面我们只涉及到C语言,那么如何用gcc编译其他语言呢?本节将简单介绍C++和Fortran编译的例子。

首先我们尝试编译简单的C++的经典程序Helloworld:

#include<iostream>

intmain(intargc,char*argv[])

{

std::cout<<"hello,world"<<std::endl;

return0;

}

将文件保存为‘hello.cpp’,用gcc编译,结果如下:

$gcc-Wallhello.cpp-ohello/tmp/cch6oUy9.o:Infunction`__static_initialization_and_destruction_0(int,int)':hello.cpp:(.text+0x23):undefinedreferenceto`std::ios_base::Init::Init()'/tmp/cch6oUy9.o:Infunction`__tcf_0':hello.cpp:(.text+0x6c):undefinedreferenceto`std::ios_base::Init::~Init()'/tmp/cch6oUy9.o:Infunction`main':hello.cpp:(.text+0x8e):undefinedreferenceto`std::cout'hello.cpp:(.text+0x93):undefinedreferenceto`std::basic_ostream<char,std::char_traits<char>>&std::operator<<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>>&,charconst*)'/tmp/cch6oUy9.o:(.eh_frame+0x11):undefinedreferenceto`__gxx_personality_v0'collect2:ldreturned1exitstatus

出错了!!而且错误还很多,很难看懂,这可怎么办呢?在解释之前,我们先试试下面的命令:

$gcc-Wallhello.cpp-ohello-lstdc++

噫,加上-lstdc++选项后,编译竟然通过了,而且没有任何警告。运行程序,结果如下:

$./hellohello,world

通过上节,我们可以知道,-lstdc++选项用来通知链接器链接静态库libstdc++.a。而从字面上可以看出,libstdc++.a是C++的标准库,这样一来,上面的问题我们就不难理解了──编译C++程序,需要链接C++的函数库libstdc++.a。

编译C的时候我们不需要指定C的函数库,为什么C++要指定呢?这是由于早期gcc是指GNU的C语言编译器(GNUCCompiler),随着C++,Fortran等语言的加入,gcc的含义才变化成了GNU编译器集合(GNUCompilerCollection)。C作为gcc的原生语言,故编译时不需额外的选项。

不过幸运的是,GCC包含专门为C++、Fortran等语言的编译器前端。于是,上面的例子,我们可以直接用如下命令编译:

$g++-Wallhello.cpp-ohello

GCC的C++前端是g++,而Fortran的情况则有点复杂:在gcc-4.0版本之前,Fortran前端是g77,而gcc-4.0之后的版本对应的Fortran前端则改为gfortran。下面我们先写一个简单的Fortran示例程序:

CFortran示例程序

PROGRAMHELLOWORLD

WRITE(*,10)

10FORMAT('hello,world')

ENDPROGRAMHELLOWORLD

将文件保存‘hello.f’,用GCC的Fortran前端编译运行该文件

$gfortran-Wallhello.f-ohello$./hellohello,world

我们已经知道,直接用gcc来编译C++时,需要链接C++标准库,那么用gcc编译Fortran时,命令该怎么写呢?

$gcc-Wallhello.f-ohelloworld-lgfortran-lgfortranbegin

注意:上面这条命令与gfortran前端是等价的(g77与此稍有不同)。其中库文件libgfortranbegin.a(通过命令行选项-lgfortranbegin被调用)包含运行和终止一个Fortran程序所必须的开始和退出代码。库文件libgfortran.a包含Fortran底层的输入输出等所需要的运行函数。

对于g77来说,下面两条命令是等价的(注意到g77对应的gcc是4.0之前的版本):

$g77-Wallhello.f-ohello$gcc-3.4-Wallhello.f-ohello-lfrtbegin-lg2c

命令行中的两个库文件分别包含Fortran的开始和退出代码以及Fortran底层的运行函数。

相关推荐