Skip to content

zenny-chen/Linux-based-Development

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 

Repository files navigation

Linux-based Development

Linux(主要基于Debian系)系统下的开发资料


Contents


Resource List

export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
/**
NAME
       sendfile - transfer data between file descriptors

SYNOPSIS
       #include <sys/sendfile.h>
*/
       ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
        int connectSock = socket(AF_INET, SOCK_STREAM, 0);
        if (connectSock < 0)
        {
            fprintf(stderr, "socket failed with error: %d\n", errno);
            return;
        }
        // setting for 7 seconds timeout
        const struct timeval timeout { .tv_sec = 7, .tv_usec = 0 };

        // Set receive timeout
        int result = setsockopt(connectSock, SOL_SOCKET, SO_RCVTIMEO, &timeout, (socklen_t)sizeof(timeout));
        if (result < 0)
        {
            fprintf(stderr, "setsockopt for receive timeout failed with error: %d\n", errno);
            break;
        }

        // Set send timeout
        result = setsockopt(connectSock, SOL_SOCKET, SO_SNDTIMEO, &timeout, (socklen_t)sizeof(timeout));
        if (result < 0)
        {
            fprintf(stderr, "setsockopt for send timeout failed with error: %d\n", errno);
            break;
        }
  • Linux 使用 getaddrinfo 获取IP地址:
#include <stdio.h>
#include <errno.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>

static const char* const IP_ADDRESS = "127.0.0.1";
static const char* const PORT_NUMBER = "5678";

static void ClientTest(void)
{
    struct addrinfo hints { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP };
    struct addrinfo *resAddrInfo = NULL;
    int result = getaddrinfo(IP_ADDRESS, PORT_NUMBER, &hints, &resAddrInfo);
    if(result != 0)
    {
        fprintf(stderr, "getaddrinfo failed with error: %s\n", gai_strerror(result));
        return;
    }

    // TODO: Insert client socket connection code here...
    int connectSock = socket(AF_INET, SOCK_STREAM, 0);
    if (connectSock < 0)
    {
        fprintf(stderr, "socket failed with error: %d\n", errno);
        return;
    }

    result = connect(connectSock, resAddrInfo->ai_addr, resAddrInfo->ai_addrlen);
    if (result < 0)
    {
        fprintf(stderr, "connect failed with error: %d\n", errno);
        if(errno == EINPROGRESS) {
            fprintf(stderr, "The connection request has been initialized but is still in progress!\n");
        }
        return;
    }

    // Release the IP address info object
    if(resAddrInfo != NULL) {
        freeaddrinfo(resAddrInfo);
    }
}
  • Linux系统下获取当前机器 IPv4 地址的 shell 命令:
ip addr show | grep 'inet ' | awk '{print $2}' | cut -d/ -f1 | grep -v "127.0.0.1"
  • Linux系统下获取当前机器 Multicast IPv4 地址的 shell 命令:
ip maddr show | grep 'inet ' | awk '{print $2}' | cut -d/ -f1 | grep -v "224.0.0.1"
#include <cpuid.h>

// Return highest supported input value for cpuid instruction.
// @param ext can be either 0x0 or 0x8000000 to return highest supported value for basic or extended cpuid information.
// Function returns 0 if cpuid is not supported or whatever cpuid returns in eax register.
// @sig If sig pointer is non-null, then first four bytes of the signature (as found in ebx register) are returned in location pointed by sig.
unsigned int __get_cpuid_max (unsigned int __ext, unsigned int *__sig);

// Return cpuid data for requested cpuid level, as found in returned eax, ebx, ecx and edx registers.
// The function checks if cpuid is supported and returns 1 for valid cpuid information, or 0 for unsupported cpuid level.
// All pointers are required to be non-null.
int __get_cpuid (unsigned int __level,
    unsigned int *__eax, unsigned int *__ebx,
    unsigned int *__ecx, unsigned int *__edx);
[[ clang::optnone ]] void foo(void) {  }
  • GCC编译器指定结构体对齐:-fpack-struct=n
  • GCC与Clang使用打包的结构体:
#if __clang__
    struct [[gnu::packed]]
#else
    struct __attribute__((packed))
#endif
    SS { long long a; int b; long long c; };

    static_assert(sizeof(SS) == 20);
#include <sys/time.h>

int main(void)
{
    struct timeval tBegin, tEnd;
    gettimeofday(&tBegin, NULL);

    int count = 0;
        
    for(int i = 0; i < 1000 * 1000; i++) {
        count += i;
    }
        
    gettimeofday(&tEnd, NULL);
        
    long deltaTime = 1000000L * (tEnd.tv_sec - tBegin.tv_sec ) + (tEnd.tv_usec - tBegin.tv_usec);

    printf("Time spent: %ldus\n", deltaTime);
}

gcc_option_order

cd /usr/local/cuda/bin/
sudo ./cuda-uninstaller

GCC内联汇编相关技巧(Clang编译器亦与之兼容)

以下为几个常用例子:

#include <stdbool.h>

// 常见的内联汇编方式
static inline int MyARM64Sub(int a, int b)
{
    int result;
    asm volatile ("sub    %w[dst], %w[src1], %w[src2]"
        : [dst] "=r" (result)
        : [src1] "r" (a), [src2] "r" (b));
    return result;
}

// 只有一个输出操作数
static inline unsigned MyGetFPCR(void)
{
    unsigned long long result;
    asm volatile ("mrs    %[result], fpcr" : [result] "=r" (result));
    return (unsigned)result;
}

// 只有一个输入操作数
static inline void MySetFPCR(unsigned fpcrValue)
{
    asm volatile ("msr    fpcr, %[fpcrValue]" : : [fpcrValue] "r" ((unsigned long long)fpcrValue));
}

// 参数expected在内联汇编中既作为输入操作数又作为输出操作数
static inline unsigned MyAtomicCAS_LSE(volatile void *dst, unsigned expected, unsigned newValue)
{
    asm volatile ("cas    %w[expected], %w[newValue], [%[dst]]"
        : [expected] "+r" (expected)
        : [newValue] "r" (newValue), [dst] "r" (dst));

    return expected;
}

static inline unsigned MyLDXR(const volatile void *ptr)
{
    unsigned result;
    asm volatile ("ldxr   %w[result], [%[ptr]]"
        : [result] "=r" (result)
        : [ptr] "r" (ptr));
    return result;
}

// 这里为了避免对不同变量使用相同的寄存器名,而特意指定相应的寄存器
static inline bool MySTXR(volatile void *dst, unsigned value)
{
    register volatile void *pDst asm("x2") = dst;
    register unsigned srcValue asm ("w1") = value;
    register bool result asm ("w0");

    asm volatile ("stxr   %w[result], %w[src], [%[dst]]"
        : [result] "=r" (result)
        : [src] "r" (srcValue), [dst] "r" (pDst));
    return result;
}

// 以上内联汇编的C函数在Android NDK平台下的测试:
const int result = MyARM64Sub(7, 3);
syslog(LOG_INFO, "The subtraction result: %d\n", result);

volatile unsigned data = 100;
unsigned expected = data;
expected = MyAtomicCAS_LSE(&data, expected, expected + 10);
syslog(LOG_INFO, "expected = %u\n", expected);
syslog(LOG_INFO, "now data = %u\n", data);

expected = MyLDXR(&data);
expected += 1000U;
const bool bRes = MySTXR(&data, expected);
syslog(LOG_INFO, "bRes = %d, expected = %u\n", bRes, expected);
syslog(LOG_INFO, "now data = %u\n", data);

MySetFPCR(0x07000000U);
expected = MyGetFPCR();
syslog(LOG_INFO, "Current FPCR: 0x%08X\n", expected);

GCC使用 naked-fomit-frame-pointer 优化属性来生成不依赖编译器的纯内联汇编函数

#include <stdio.h>

static int s_var = 0;

static void __attribute__((naked, optimize("-fomit-frame-pointer")))
ExecInc(int *pValue,  const void *pExitAddr)
{
    asm(".intel_syntax noprefix \n"
        "inc dword ptr [rdi]  \n"
        "jmp rsi     \n"
        ".att_syntax");
}

static void __attribute__((naked, optimize("-fomit-frame-pointer")))
CallEntry(int *pValue, const void *pExitAddr, const void *pExecAddr)
{
    asm(".intel_syntax noprefix \n"
        "jmp rdx     \n"
        ".att_syntax");
}

static void __attribute__((naked, optimize("-fomit-frame-pointer")))
CallExit(void)
{
    asm(".intel_syntax noprefix \n"
        "ret    \n"
        ".att_syntax");
}

int main(int argc, const char* argv[])
{
    while(s_var < 10)
        CallEntry(&s_var, (void*)CallExit, (void*)ExecInc);

    printf("s_var = %d\n", s_var);
}

Linux 系统下获取当前机器的 IPv4 地址

#include <stdio.h>
#include <stdbool.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <poll.h>

static bool FetchCurrentIPv4Address(char dstIPAddr[16])
{
    char buffer[256] = { };
    int fds[2];
    pipe(fds);
    int backupFD = dup(STDOUT_FILENO);
    dup2(fds[1], STDOUT_FILENO);

    system("ip addr show | grep 'inet ' | awk '{print $2}' | cut -d/ -f1 | grep -v \"127.0.0.1\"");

    read(fds[0], buffer, sizeof(buffer));

    dup2(backupFD, STDOUT_FILENO);

    const size_t ipAddrLen = strlen(buffer);
    for(size_t i = 0; i < ipAddrLen; ++i)
    {
        if((buffer[i] < '0' || buffer[i] > '9') && buffer[i] != '.')
        {
            buffer[i] = '\0';
            break;
        }
    }

    strcpy(dstIPAddr, buffer);

    return true;
}

Linux 系统下获取当前机器的 Multicast IPv4 地址

#include <stdio.h>
#include <stdbool.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <poll.h>

static bool FetchCurrentMulticastIPv4Address(char dstIPAddr[16])
{
    char buffer[256] = { };
    int fds[2];
    pipe(fds);
    int backupFD = dup(STDOUT_FILENO);
    dup2(fds[1], STDOUT_FILENO);

    system("ip maddr show | grep 'inet ' | awk '{print $2}' | cut -d/ -f1 | grep -v \"224.0.0.1\"");

    read(fds[0], buffer, sizeof(buffer));

    dup2(backupFD, STDOUT_FILENO);

    const size_t ipAddrLen = strlen(buffer);
    for(size_t i = 0; i < ipAddrLen; ++i)
    {
        if((buffer[i] < '0' || buffer[i] > '9') && buffer[i] != '.')
        {
            buffer[i] = '\0';
            break;
        }
    }

    strcpy(dstIPAddr, buffer);

    return true;
}

Raspbian系统下所需要安装的开发工具

sudo apt-get update

sudo apt-get install build-essential

# 如果在Ubuntu上安装GCC或使用`sudo apt-get install build-essential`失败,则需要先执行一下`sudo apt-get update`,更新之后再执行安装命令。

# 安装用于Objective-C的GNUstep
sudo apt-get install gnustep
sudo apt-get install gnustep-devel

# 安装GTK+3
sudo apt-get install libgtk-3-dev

# 安装asound2库
sudo apt-get install libasound2-dev

# 安装alsa-utils
sudo apt-get install alsa-utils

# 安装蓝牙相关工具
sudo apt-get install blueman

# 安装bluetooth开发库
sudo apt-get install libbluetooth-dev

# 安装 autoconf
sudo apt install autoconf

# 安装 automake
sudo apt install automake

# 安装 M4
sudo apt install m4

# 安装 libtool
sudo apt install libtool

# 安装 makeinfo 相关工具
sudo apt install texinfo

Ubuntu下安装CUDA以及其自带驱动

以下文档文档可供参考:

  1. 先在Ubuntu上卸载原始自带的nVidia驱动,它通常为Linux开源驱动:
sudo apt-get remove --purge nvidia*
sudo apt autoremove
sudo apt-get --purge remove "*nvidia*"

# 查看系统中安装了哪些nVidia驱动,如果全都删除的话应该不会有任何库出现
sudo dpkg --list | grep nvidia-*
  1. 由于安装NV显卡驱动过程中不能使用X Window界面,因此我们必须进入命令行,关闭图形窗口界面。 首先按下Ctrl + Alt + F1进入命令行模式,然后分别输入用户名和密码。
  2. 然后关闭X Server服务:sudo stop lightdm
  3. sudo init 3
  4. 重新输入用户名和密码。
  5. 运行CUDA安装run文件:sudo bash NVIDIA-Linux-x86_64-xxx.yy.zz.run
  6. 最后重启:sudo reboot

CentOS下安装CUDA驱动

  1. 准备环境设置:
chmod -R 777 /home/;chmod -R 777 /opt/;yum -y install gcc kernel-devel kernel-headers;mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak;dracut /boot/initramfs-$(uname -r).img $(uname -r);echo blacklist nouveau >>/usr/lib/modprobe.d/dist-blacklist.conf;echo options nouveau modeset=0 >>/usr/lib/modprobe.d/dist-blacklist.conf
  1. 退出GUI桌面:
systemctl stop gdm.service
  1. 运行安装文件(run文件):
bash /mnt/andy/soft-all-for-linux/2xianka-install/NVIDIA-Linux-x86_64-390.48.run 
  1. 卸载驱动:
bash /mnt/andy/soft-all-for-linux/2xianka-install/NVIDIA-Linux-x86_64-390.48.run  --uninstall

GNUstep编译选项

我们通过执行以下命令来观察Objective-C编译时所需要的编译选项:gnustep-config --objc-flags
执行以下命令查看Objective-C连接时所需要的加载选项:gnustep-config --objc-libs

整理之后:

export GCC_PATH=/usr/lib/gcc/arm-linux-gnueabihf/8/
gcc test.m -std=gnu11 -Os  -MMD -MP -DGNUSTEP -DGNUSTEP_BASE_LIBRARY=1 -DGNU_RUNTIME=1 -DGNUSTEP_BASE_LIBRARY=1 -fno-strict-aliasing -pthread -fPIC -Wall -DGSWARN -DGSDIAGNOSE -Wno-import -fgnu-runtime -fconstant-string-class=NSConstantString  -I. -I/usr/local/include/GNUstep -I/usr/include/GNUstep -I${GCC_PATH}include/  -rdynamic -L/root/GNUstep/Library/Libraries -L/usr/local/lib -L/usr/lib -lobjc -lm -lgnustep-base -o test

GTK+下载安装及编程指南资料汇总

在Ubuntu下要下载安装GTK+执行以下步骤:

  1. sudo apt-get install gnome-core-devel
  2. sudo apt-get install libgtk*

如果 gnome-core-devel 命令由于Linux版本问题无法执行,可直接运行 install libgtk*,这个会将 pkg-config 在内的所有与 gtk 相关的库安装进去。 然后,我们可以在控制台输入:pkg-config --cflags --libs gtk+-3.0 来查看gtk+3.0所需要包含的所有头文件以及库的路径。

基于Eclipse的IDE来开发GTK+3.0需要设置头文件路径和库的路径:

头文件路径需要以下这些:
  • /usr/include/glib-2.0/
  • /usr/include/atk-1.0/
  • /usr/include/gdk-pixbuf-2.0/
  • /usr/include/cairo/
  • /usr/include/pango-1.0/
  • (64位)/usr/lib/x86_64-linux-gnu/glib-2.0/include/
  • (32位)/usr/lib/i386-linux-gnu/glib-2.0/include/
  • /usr/include/gtk-3.0/
库路径需要包含:

-(64位)/usr/lib/x86_64-linux-gnu/

  • (32位)/usr/lib/i386-linux-gnu/
所需要的库有:
  • gtk-3
  • gobject-2.0
  • pangocairo-1.0
  • gio-2.0
  • atk-1.0
  • gdk-3
  • glib-2.0

注意,Linux下的库文件名是前缀加lib然后再跟库名,再是 .a.so 结尾。

GTK+ 3编译选项

查看当前环境的GTK+ 3编译选项:pkg-config --cflags --libs gtk+-3.0

整理之后:

export ABI_NAME=${HOSTTYPE}-${OSTYPE}
gcc main.c -std=gnu11 -I/usr/include/glib-2.0/ -I/usr/include/atk-1.0/ -I/usr/include/gdk-pixbuf-2.0/ -I/usr/include/cairo/ -I/usr/include/pango-1.0/ -I/usr/lib/${ABI_NAME}/glib-2.0/include/ -I/usr/include/gtk-3.0/ -L/usr/lib/${ABI_NAME}/ -lgtk-3 -lgobject-2.0 -lpangocairo-1.0 -lgio-2.0 -latk-1.0 -lgdk-3 -lglib-2.0    -o gtk-test

C# mono的使用

先创建一个csharp文件名,比如:CSTest.cs。然后输入以下代码:

using System;

class CSTest
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello, C#");
    }
}

最后在命令行进入到该源文件所在目录,然后输入:mcs CSTest.cs,最后就会生成CSTest.exe可执行文件。


安装LLVM-Clang

sudo apt-get install llvm

sudo apt-get install clang

sudo apt-get install libdispatch-dev

从GCC 8起,Clang 6起可以使用-std=gnu17标准。


vim常用命令

  • ESC: 进入命令状态
  • a: 从命令状态进入编辑状态

命令状态下:

  • :q 退出,不保存
  • :wq 退出,且保存
  • 强制退出并保存::wq!

FreeBSD相关

About

Linux(主要基于Debian系)系统下的开发资料

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published