Skip to content

Compile

C/C++ compile

GCC and G++

docs

  • -x : 設定文件使用的語言(副檔名)

  • -c : 只compile並將assembly輸出目標檔至.obj, 沒有link

  • -s : 只compile並輸出成assembly

  • -o <file>: compile, assembly跟linking完成後輸出目標檔至file

  • -v : 印出編譯的資訊

  • -### : 與-v類似,但只輸出跟文數字有關的資訊

  • -l -L < library > 在linking階段尋找library

  • -I <header>: 在compile階段增加標頭檔

  • -e entry 指定程式從entry作為輸入點

  • -pthread link POSIX內的thread library (只支援GNU/Linux系統) gtest的default必須要加,否則在compile gtest的sample code時就必須要更改環境變數

  • -static 在支援動態linking的系統上,指定靜態連結

  • -shared 輸出能夠被其他object動態linking的share object

CMake

gcc/g++ 太麻煩且不好管理,用CMakeLists一次建立build environment

範例框架

cmake_minimum_required(VERSION 3.16) # CMake_最低版本_需求

project("Hello World") # 建立一個CMake專案,並給予專案名稱

add_executable(hello-world) # 建立一個CMake目標,目標為可執行檔

target_sources(hello-world PRIVATE "main.cpp") # 指定建置該CMake目標時所使用的來源檔案

執行

add_executable() : 建立可執行檔
target_source() : 指定CMake使用的來源檔案,不需包含標頭檔

target_sources(project_name, 
PRIVATE
    "main.cpp"
    "func1.cpp"
    "fun2.cpp")


靜態函式庫連結

target_include_directories() : 新增目標的include目錄
target_link_libraries() : 新增目標的靜態函式庫
add_subdirectory() : 將指定資料夾內的CMake專案一起加入建置

# 新增目標 project-02 的 Include 目錄
target_include_directories(project-02
    PRIVATE
        "libstatic1/"
)

# 將指定資料夾的 CMake 專案(含有 CMakeLists.txt)一起加入建置。
add_subdirectory("libstatic1/")

# 新增目標 project-02 所連結的函式庫。函式庫名稱為其他 CMake 專案的目標名稱。通常來自
# find_package 或 add_subdirectory。以這個範例來說,libstatic1 函式庫是來自
# add_subdirectory 指令所加入的 CMake 專案。
target_link_libraries(project-02
    PRIVATE
        libstatic1
)
libstatic1/CMakeLists.txt
# 新增一個 CMake 目標,目標型態為靜態函式庫。
add_library(libstatic1 STATIC)

target_sources(libstatic1
    PRIVATE
        "f1.cpp"
        "f2.cpp"
)


動態函式庫連結

add_library() : 由路徑搜索函式庫

add_library(mylibrary SHARED src/mylibrary.cpp): 
# 指定生成名為 mylibrary 的共享庫(動態函式庫),並包含源文件 src/mylibrary.cpp#。

#-----------------------
#若是已經編譯好的.so或.dll

# 設置外部庫的包含路徑
include_directories(${CMAKE_SOURCE_DIR}/include)

# 指定外部庫的位置
set(EXTERNAL_LIB_PATH ${CMAKE_SOURCE_DIR}/lib)

# 查找動態庫
find_library(EXTERNAL_LIB NAMES external PATHS ${EXTERNAL_LIB_PATH})

# 連結外部動態函式庫
target_link_libraries(MyExecutable ${EXTERNAL_LIB})

Debug in vscode

使用gdb編譯單個文件時,可以使用以下configuration 參考資料 docs task.json

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "shell",
      "label": "C/C++: g++ build active file",
      "command": "/usr/bin/g++",
      "args": ["-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}"],
      "options": {
        "cwd": "/usr/bin"
      },
      "problemMatcher": ["$gcc"],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "Task generated by Debugger."
    }
  ]
}

launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "C/C++: g++ build and debug active file",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}/${fileBasenameNoExtension}",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "/usr/bin/gdb",
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ],
      "preLaunchTask": "C/C++: g++ build active file"
    }
  ]
}
* #### CmakeList.txt 將launch.json內的configuratiion以cppdbg與gdb就能利用cmake去設斷點Debug了,參考此文件:here
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            // Resolved by CMake Tools:
            "program": "${command:cmake.launchTargetPath}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [
                {
                    // add the directory where our target was built to the PATHs
                    // it gets resolved by CMake Tools:
                    "name": "PATH",
                    "value": "${env:PATH}:${command:cmake.getLaunchTargetDirectory}"
                },
                {
                    "name": "OTHER_VALUE",
                    "value": "Something something"
                }
            ],
            "externalConsole": true,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

若想要傳遞參數至cmake, 需要在task.json內增加configuration的code block

{
    "label": "configure",
    "type": "shell",
    "command": "cmake",
    "args": [
        "-S", ".",   // 指定源目录
        "-B", "build", // 指定构建目录
        "-DUNIT_TESTS=1",
    ],
    "group": {
        "kind": "build",
        "isDefault": true,
    },
    "problemMatcher": ["$gcc"],
    "detail": "configure cmake project."
}
{
    // in build section, add this line
    "dependsOn": [ "configure" ],
}
task.json的詳細設定可以在這裡找到 : link

Makefile

common compile method in GNU/Linux, a common makefile will look like this, every command line should started with a tab

TARGET : PREREQUISITES
    COMMAND
    ...
    ...

Example simple

#sample Makefile
edit : main.o kdb.o  command.o display.o \
    insert.o search.o 
main.o : main.c defs.h
    cc -c main.c

kbd.o : kbd.c defs.h command.h
    cc -c kbd.c

command.o : command.c defs.h command.h
    cc -c command.o
.
.
.