GCC 多个 lib 同名函数链接冲突问题

问题描述

  • 用 gcc 编译两个动态库 lib1.so lib2.so, 程序 app 链接到这两个动态库
  • lib1.so 中定义了全局变量 var=1 , lib2.so 中定义全局变量 var=2 。即相同变量 var 在不同 lib 中定义值不同。
  • lib1.so 中定义了函数 fun1() { print(var); }
  • lib2.so 中定义了函数 fun2() { func1(); print(var); } , 即 lib2.so 依赖 lib1.so
  • 运行 app,调用 fun1fun2 ,输出 var 的值是相同的。

问题分析

  • gcc 链接时,有个默认规则:当一个符号需要被加入全局符号表时,如果相同的符号名已经存在,则后加入的符号被忽略
  • 用 VC 编译链接这个程序, fun1fun2 会输出不同值: VC 在发现多个依赖库中有同名符号时, 会符号重定义, 而不是默认的选择一个

问题解决

  • 使用编译参数 -fvisibility=hidden ,使所有符号默认不导出
  • 将 fun1 和 fun2 声明为导出符号

    #define MY_API __attribute__((visibility("default")))
    void MY_API fun1();
    void MY_API fun2();
    
  • fun1fun2 可以输出各自 lib 中定义的值。

ubuntu 批量编码转换

  • 查询编码

    find . \( -name "*.cpp" -or -name "*.c" -or -name "*.h" \) -type f -exec file -i {} \; > /tmp/a
    
    
  • 转换

    find . -name "*" -type f -exec iconv -f GBK -t UTF-8 {} -o /home/share/jni/{} \;
    
    
  • 转换脚本

    #!/bin/sh
    FILES=$(find . -type f -name '*.*')
    for f in $FILES
    do
        if test -f $f; then
            CHARSET="$( file -bi "$f"|awk -F "=" '{print $2}')"
            echo $CHARSET
            if [ "$CHARSET" = iso-8859-1 ]; then
                echo "Converting $f from $CHARSET to utf-8"
                # iconv -f "$CHARSET" -t utf-8 "$f" -o "$f.temp"
                iconv -f GBK -t UTF-8 "$f" -o "$f.temp"
                mv -f "$f.temp" $f
            fi
        else
            echo "Skipping $f - it's a regular file";
        fi
    done
    
  • 参考链接

ubuntu server 上安装 xfce 并远程访问

  • 安装 xfce

    apt install xfce4
    
  • 安装 vncserver

    apt install vnc4server
    
  • 设置 vncserver 密码

    vncserver :1
    vncserver -kill :1
    
  • 修改 vncserver 启动文件

    vim ~/.vnc/xstartup
    
    #x-window-manager &
    sesion-manager & xfdesktop & xfce4-panel &
    xfce4-menu-plugin &
    xfsettingsd &
    xfconfd &
    xfwm4 & 
    scim -d &
    fcitx &
    
  • 启动 vncserver

    vncserver -geometry 1920x1080
    
  • 从 window vnc 连接连接名称为 IP:1
  • 创建 clion 菜单项

    vim ~/.local/share/applications/.desktop
    
    [Desktop Entry]
    Version=1.0
    Type=Application
    Name=clion
    Exec=/home/share/clion-2017.1.1/bin/clion.sh
    Icon=/home/share/clion-2017.1.1/bin/clion.svg
    Categories=Development
    
  • 隐藏 panel
    • Applications -> Settings -> Settings Manager -> Panel
    • panel1, panel2 都设置为自动隐藏
  • 安装字体
    • 安装思源黑体

      curl -O https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKsc-hinted.zip
      unzip NotoSansCJKsc-hinted.zip -d noto
      cd noto
      mkdir -p /usr/share/fonts/opentype/noto
      cp *otf /usr/share/fonts/opentype/noto
      fc-cache -f -v
      
    • 安装文泉驿字体

      apt install fonts-wqy-microhei fonts-wqy-zenhei
      
  • 终端 tab 不能补全问题

    vim ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml
    
    <!-- <property name="&lt;Super&gt;Tab" type="string" value="switch_window_key"/> -->
    <property name="&lt;Super&gt;Tab" type="empty"/>
    
  • 安装 sublime-text3

    add-apt-repository ppa:webupd8team/sublime-text-3
    apt update
    apt install sublime-text-installer
    
    • 打开 Settings -> MIME Type Editor,修改文本文件的默认打开方式
  • 安装 7z, rar 解压

    apt install p7zip-full
    7z x archive.7z
    
  • 安装其它软件

    apt install firefox
    apt install gnome-commander
    apt install terminator
    
  • vnc4server 下使用中文输入法

    apt install fcitx fcitx-frontend-all fcitx-tools fcitx-config-gtk2 fcitx-table-wbpy im-switch scim
    e ~/.xprofile #append
    
    export XMODIFIERS=@im=fcitx
    export XIM=fcitx
    export XIM_PROGRAM=fcitx
    export GTK_IM_MODULE=fcitx
    export QT_IM_MODULE=fcitx
    
    e ~/.vnc/xstartup  #append
    
    scim -d &
    fcitx &
    
    • 修改切换输入法快捷键为 Ctrl-Alt-SPC
  • 快捷键冲突
    • Settings -> Windows Manager -> Clear 所有冲突快捷键
  • oh-my-zsh

    apt install zsh autojump thefuck silversearcher-ag
    chsh -s $(which zsh)
    sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
    
    vim ~/.zshrc #modify
    
    ZSH_THEME="ys"
    . /usr/share/autojump/autojump.sh
    

在 ubuntu server 上搭建 C++ 远程开发环境

  • 安装开发软件

    apt install build-essential
    apt install clang
    apt install cmake
    apt install git
    apt install subversion
    apt install ninja ninja-build
    apt install gcc-multilib g++-multilib lib32z1-dev
    
  • 安装并配置 samba

    apt install samba
    apt install smbclient
    cp /etc/samba/smb.conf /etc/samba/smb.conf.bak
    
    emacs /etc/samba/smb.conf
    
    [share]
      comment = Share Folder require password
      browseable = yes
      path = /home/share
      create mask = 0777
      directory mask = 0777
      valid users = share
      force user = nobody
      force group = nogroup
      public = yes
      writable = yes
      available = yes
    
    groupadd share -g 6000
    useradd share -u 6000 -g 6000 -s /sbin/nologin -d /dev/null
    smbpasswd -a share
    
    mkdir /home/share
    chmod 777 /home/share
    /etc/init.d/smbd restart