zoukankan      html  css  js  c++  java
  • 分析linux下的编译环境

      不论是windows下的程序,还是linux下的程序,开发环境都离不开三个目录:include、lib、bin,分别是头文件目录、库文件目录、运行文件目录。或许目录不叫这个名字,但却必不可少,除非你的程序是运行在虚拟机上或脚本文件如java、php、lua等。

      在windows下,可以不怎么关注这些东西,因为VS安装后默认了配置好了这些路径,如D:Program FilesMicrosoft SDKinclude,如果使用到一些开源的库,在VS下设置就好了。并且windows下程序运行时,如果在系统的dll(相当于lib了,只是封装为dll),目录下找不到相关dll,会查找当前目录下是否有相应的dll,所有很多windows下的程序把自己的dll放到当前程序目录下就OK了。

      然而linux并不这么容易。一个原因是linux下没有像VS一样统一的IDE(Qt creator、code::block不错,但很多人不习惯用),都用gcc、g++来编译,如果不熟悉linux下这三个目录,让程序跑起来可能有点困难。尤其是使用了许多开源库的时候。

      linux的include默认有两个(可能有我不知道的吧),分别是/usr/include、/usr/local/include,gcc中用参数 -I可以指定其他目录

      lib目录默认则有三个,分别是/lib、/usr/lib、/usr/local/lib,gcc中用-L可以指定其他目录

      bin目录默认也有三个,分别是/bin、、/usr/bin、usr/local/bin。当然你可以用包含路径的指令来运行程序。

      当你编译一个开源的库时,如libev,在make install时(编译过程见另一篇随笔),通常会告诉你一些信息,如:

    Libraries have been installed in:
       /usr/local/lib
    
    If you ever happen to want to link against installed libraries
    in a given directory, LIBDIR, you must either use libtool, and
    specify the full pathname of the library, or use the `-LLIBDIR'
    flag during linking and do at least one of the following:
       - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
         during execution
       - add LIBDIR to the `LD_RUN_PATH' environment variable
         during linking
       - use the `-Wl,-rpath -Wl,LIBDIR' linker flag
       - have your system administrator add LIBDIR to `/etc/ld.so.conf'
    
    See any operating system documentation about shared libraries for
    more information, such as the ld(1) and ld.so(8) manual pages.
    

      这就是告诉你,库文件安装到了/usr/local/lib文件夹里。可是当我编译链接下面的代码时,却发生了错误:

    #include <ev.h>
    #include <stdio.h>
    
    ev_io stdin_watcher;
    ev_timer timeout_watcher;
    
    static void stdin_cb(EV_P_ ev_io *w,int revents)
    {
        puts ("stdin ready");
        ev_io_stop(EV_A_ w);
        ev_break (EV_A_ EVBREAK_ALL);
    }
    
    static void timeout_cb (EV_P_ ev_timer *w,int revents)
    {
        puts ("timeout");
        ev_break( EV_A_ EVBREAK_ONE );
    }
    
    int main(int argc,char* argv[])
    {
        struct ev_loop *loop = EV_DEFAULT;
    
        ev_io_init(&stdin_watcher,stdin_cb,0,EV_READ);
        ev_io_start (loop,&stdin_watcher);
    
        ev_timer_init (&timeout_watcher,timeout_cb,5.5,0); // in document the last is 0. not 0,I don't know why yet 
        ev_timer_start (loop,&timeout_watcher);
    
        ev_run (loop,0);
    
        return 0;
    }
    
    output:
    root@debian:/home/xzc/cpp/test# gcc -o libev_hello libev_hello.c
    /tmp/ccNN2QkE.o: In function `stdin_cb':
    libev_hello.c:(.text+0x20): undefined reference to `ev_io_stop'
    libev_hello.c:(.text+0x33): undefined reference to `ev_break'
    /tmp/ccNN2QkE.o: In function `timeout_cb':
    libev_hello.c:(.text+0x5a): undefined reference to `ev_break'
    /tmp/ccNN2QkE.o: In function `main':
    libev_hello.c:(.text+0x71): undefined reference to `ev_default_loop'
    libev_hello.c:(.text+0xc9): undefined reference to `ev_io_start'
    libev_hello.c:(.text+0x11f): undefined reference to `ev_timer_start'
    libev_hello.c:(.text+0x133): undefined reference to `ev_run'
    collect2: ld returned 1 exit status

    正确的编译方法为gcc -o libev_hello libev_hello.c -lev,为什么要加-lev呢,参考gcc参数-llibrary,即需要指定ev库(就是libev)。这里我有点不明白,为什么我指定了头文件#include<ev.h>,链接时gcc没有自动去查找库libev.o,这个库已经被安装到/usr/local/lib里了。并且,我指定ev库,gcc怎么知道去哪个.o文件查找,难道根据名字,ev就是libev.o,如果是test,那就是libtest.o么。好吧,在没有找到答案之前,我就这样认为。

  • 相关阅读:
    实用硬件篇(一)
    iOS通讯录(纯纯的干货)
    iOS社会化分享(干货)
    静态库的打包及使用(干货)
    iOS地图集成示例:百度地图POI检索
    iOS开发之KVC全解
    网络干货
    输入一个字符串,按字典序打印出该字符串中字符的所有排列(剑指offer)
    序列化二叉树
    二叉树中和为某一值的路径
  • 原文地址:https://www.cnblogs.com/coding-my-life/p/3720595.html
Copyright © 2011-2022 走看看