2022年5月16日 星期一

[Linux] Makefile

 一般我們在linux下編譯程式碼變為執行檔
是透過gcc的指令透過參數來產生
gcc -o hello.out -Wall -I./ main.c

由於在複雜的多個程式碼裡只利用gcc指令會變很複雜
所以就有了Makefile的檔案來協助我們來做編譯
以下是二個簡單的Makefile範例
包含了一個執行檔
和另一個執行檔呼叫函式庫Makefile範例

1. 程式的Makefile

main.c
#include "stdio.h"

int main(int argc, char *argv[])
{
    printf("Hello World!\n");
    return 0;
}
Makefile
CC = gcc
INCLUDE = ./
CFLAG = -Wall
SRC = main.c
EXEC_FILE = hello.out

make_api:
    $(CC) -o $(EXEC_FILE) $(CFLAG) -I$(INCLUDE) $(SRC)

clean:
    rm -f *.o $(EXEC_FILE)

要注意的是$(CC)前是Tab鍵而非空格


2. Shared Library函式庫的Makefile
libtest.h
extern void ShowHelloWorld();
void ShowHelloWorld();
libtest.c
#include "libtest.h"
#include "stdio.h"

void ShowHelloWorld()
{
        printf("Hello World!\n");
}
main.c
#include "libtest.h"

int main(int argc, char *argv[])
{
    ShowHelloWorld();
    return 0;
}
Makefile
CC = gcc
SRC = ./main.c
INCLUDE = -I./
CFLAG = -Wall -ltest -L./
EXEC_FILE = ./hello.out

LIB = ./libtest.c
LIB_CFLAG = -Wall -fPIC -shared
LIB_NAME = ./libtest.so

all:make_lib make_api

make_api:$(SRC)
        $(CC) -o $(EXEC_FILE) $(CFLAG) $(INCLUDE) $(LIB_NAME) $(SRC)

make_lib:$(LIB)
        $(CC) -o $(LIB_NAME) $(LIB_CFLAG) $(LIB)

clean:
        rm -f *.so $(EXEC_FILE)

因為要編譯函式庫,所以CFLAG參數要多一個-shared
另外執行檔要連結函式庫,所以要用到大小寫L的參數
大寫L是表示到時候執行連結函式庫的路徑 (大部分程式的連結都是在/lib下)
小寫l則是lib之後去除.so的檔案名稱, 例如libtest.so就是取test


範例下載
我自己有寫一個簡單產生程式碼的程式
讓我一開始就可以產生一個簡單的範例讓我可以直接修改
如果有興趣的話也可以下載使用
git clone https://github.com/awaysu/newc

 產生一個執行檔範例
newc -p test

產生一個函式庫+執行檔範例
newc -l test


沒有留言:

張貼留言