linux下c程序如何包含头文件
刚学linux下的c编程,写了一个简单的程序,如下:
#include <stdio.h>
#include <math.h>
int main()
{
int i;
for(i=0;i<10;i++)
{
printf("%f\n",sin(i));
}
}
编译时如下:
# cc first.c
出现如下提示:
first.o(.text+0x30):In function 'main';
: undefined reference to 'sin'
collect2: Id returned 1 exit status
不知道这是为什么,他提示说没有包含数学库文件,但是我程序里
已经有#include <math.h>,为何不行呢?
如果编译时用 #cc first.c -lm 就可以.
如果包含的文件都得在编译行里面加进去,那代码行里面的include有什么用呢?
请各位高手指点一下,忙了几天也没弄明白.
------解决方案--------------------lm是共享库.类似于windows的静态库或者动态链接库
------解决方案--------------------楼上说的对,编多线程时要-lpthread
------解决方案--------------------#include <math.h>
math.h有sin函数的声明. sin函数的代码在libm.so/libm.a里. 链接时需要sin函数的代码所以要加-lm
一个不恰当的比喻. math.h就象你们公司的程序员名单. libm.a/libm.so就像公司的程序员们.
在做软件开发计划的时候看名单就可以了,真正开发软件的时候就需要程序员了.
------解决方案--------------------你这个过程实际上包含了编译和链接两个过程
第一个过程是
cc -c first.c -o first.o
这个是编译过程,include头文件在这里起作用,声明math库中的常量和函数
第二个过程是连接
cc first.o -o first -lm
这里将编译出的目标文件first.o和math函数库做链接,生成可执行文件,-lm是告诉编译器与哪个库进行连接
------解决方案--------------------C标准库的函数,类型和宏标准头文件里声明:
<assert.h> <float.h> <math.h> <stdarg.h> <stdlib.h>
<ctype.h> <limits.h> <setjmp.h> <stddef.h> <string.h>
<errno.h> <locale.h> <signal.h> <stdio.h> <time.h>
使用math.h里的函数需要-lm, 其他的函数需要-lc.
用gcc编译和链接时,到了链接阶段gcc会加上-lc参数取调用ld(链接编辑程序).
可以传--verbose参数给ld查看链接的详细步骤.
gcc -Wl,--verbose -o hello hello.c
GNU ld version 2.15 [FreeBSD] 2004-05-23
Supported emulations:
elf_i386_fbsd
elf_x86_64_fbsd
using internal linker script:
==================================================
/* Script for -z combreloc: combine and sort reloc sections */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = 0x400000); . = 0x400000 + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.dyn :
{
*(.rel.init)
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
*(.rel.fini)
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
*(.rel.ctors)
*(.rel.dtors)
*(.rel.got)
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
}
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)