C++ 코드 실행을 위한 vscode 환경설정

Trouble shooting

자료구조와 알고리즘에서 cpp 파일을 빌드를 해야하는데 링커가 작동하지 않는다는 오류가 계속 발생하였다.

cd "/Users/syk25/studies/hong_dsa/HongLabDataStructures/Ex0303_SparsePolynomial/" && g++ -std=c++17 -fcolor-diagnostics -fansi-escape-codes Ex0303_SparsePolynomial.cpp -o Ex0303_SparsePolynomial && "/Users/syk25/studies/hong_dsa/HongLabDataStructures/Ex0303_SparsePolynomial/"Ex0303_SparsePolynomial Undefined symbols for architecture arm64: "SparsePolynomial::Add(SparsePolynomial const&)", referenced from: _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o "SparsePolynomial::Eval(float)", referenced from: _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o "SparsePolynomial::Print()", referenced from: _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o ... "SparsePolynomial::NewTerm(float, int)", referenced from: _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o _main in Ex0303_SparsePolynomial-429d5d.o ... ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

 

해결과정

문제분석

cd "/Users/syk25/studies/hong_dsa/HongLabDataStructures/Ex0303_SparsePolynomial/" && g++ -std=c++17 -fcolor-diagnostics -fansi-escape-codes Ex0303_SparsePolynomial.cpp -o Ex0303_SparsePolynomial && "/Users/syk25/studies/hong_dsa/HongLabDataStructures/Ex0303_SparsePolynomial/"Ex0303_SparsePolynomial Undefined symbols for architecture arm64

프롬프트를 분석했다. 나는 여러개의 소스코드를 링킹을 하는 게 목적인데 프롬프트는 main 함수가 들어가 있는 파일만 컴파일을 했다.

 

시도1

내 vscode 설정 오류인 줄 알고 tasks.json 파일을 수정하려고 했다. 하지만 tasks.json 파일은 오히려 제대로 설정되었고 프롬프트가 제대로 입력되지 않은 것이 문제였다.

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: clang++ build active file",
            "command": "/usr/bin/clang++",
            "args": [
                "-std=c++17",
                "-fcolor-diagnostics",
                "-fansi-escape-codes",
                "-g",
                "${fileDirname}/*.cpp",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "Task generated by Debugger."
        }
    ],
    "version": "2.0.0"
}

 

시도2

확인을 해보니 run code와 run c/c++ file이 동작하는 과정이 달랐다. 후자의 경우, 위에서 언급한 json 설정대로 작동을 했다. 하지만 소스코드를 쉽게 빌드하고 실행하는 것이 목적이었기 때문에 run code로 빌드, 실행이 되게끔하고 싶었다.

code runner의 json 설정을 바꾸면 되는 문제였다.

"code-runner.executorMap": {
    
      ...
        "cpp": "cd $dir && g++ -std=c++17 -fcolor-diagnostics -fansi-escape-codes -g *.cpp -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
     ...
    },

code runner 의 settings.json에 접근하면 code-runner.executorMap에 cpp 설정이 있다. *.cpp 으로 설정을 하면 cpp 확장자를 가진 소스코드를 모두 컴파일 후 링킹을 한다.

 

회고

  • 오류를 찾기 위해 프로그램의 빌드과정을 다시 학습했다. 소스코드는 프로그래밍 언어로서 작성 된 것으로 사람이 이해할 수 있는 반면에 컴퓨터는 이해할 수 없다. 따라서 소스코드를 기계어로 바꾸는 컴파일링이 필요한다.
  • 어떤 소스코드의 경우에는 라이브러리나 다른 소스코드에 있는 코드들을 의존하는 경우가 있다. 따라서 프로그램에 관련 된 소스코드들은 모두 컴파일되어야한다.
  • 컴파일 된 소스코드들은 객체파일이 된다. 프로그램이 제대로 실행되기 위해서는 객체 파일들을 서로 링크하여 실행파일이 만들어져야한다.
  • 컴파일부터 링킹까지의 과정을 거쳐 프로그램을 실행가능한 파일로 만드는 과정을 빌드라고 한다.
  • 이론과 실습은 상호보완적이다. 빌드과정을 이해해야만 어떤 부분을 고쳐야 프로그램이 실행될 수 있는지를 파악할 수 있다. 컴파일, 링킹 등이 프롬프트에서 어떻게 나타나는지, 즉, 어떻게 구현되는지를 봐야한다.