1

I am trying to use libraries for the first time with Visual Studio Code (not Visual Studio). I've been having trouble linking the SFML library using my tasks.json and my c_cpp_properties.json files. They hold include paths for the library and compiler flags used to build my .cpp and .hpp files. My research shows that the error might be due to the linker, and the -l compiler flag might be needed. I found few resources that detail what that flag actually does and how I should go about implementing it when building my project.

My project folder structure looks like this:

Test_Project (Root Folder)
     ﹂ build (main.exe compile location)
     ﹂ include (personal .hpp files)
     ﹂ src (main.cpp)
     ﹂ lib (only has SFML library)
         ﹂ SFML-2.5.1
             ﹂ bin (has a bunch of .dll files)
             ﹂ include (folder)
                 ﹂ SFML (has library specific .hpp files)
             ﹂ lib (has a bunch of .lib files)

My tasks.json file is below. I've commented the parts that might be useful. ${workspaceFolder} refers to the Root Folder, aka Test_Project.

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++.exe build active file",
            "command": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe",
            "args": [
                "-std=c++17",                                  //specify c++17
                "-g",                                          //give debug info
                "-I${workspaceFolder}/include",                //include personal .hpp files
                "-I${workspaceFolder}/lib/SFML-2.5.1/include", //include library .hpp files
                "-L${workspaceFolder}/lib/SFML-2.5.1/lib",     //add .lib files from library
                "${workspaceFolder}/src/*.cpp",                //builds with all .cpp files
                "-o",                                          //-l flag should go before here???
                "${workspaceFolder}/build/main.exe" 
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "compiler: \"C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe\""
        }
    ]
}

My c_cpp_properties.json is below. I don't really understand why I need to specify the include path here and in tasks.json but I read this Stack Overflow post that places the include from the library in the include path as well.

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "${workspaceFolder}/lib/SFML-2.5.1/include" // <---
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "compilerPath": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\gcc.exe",
            "cStandard": "gnu17",
            "intelliSenseMode": "windows-gcc-x64"
        }
    ],
    "version": 4
}

I've tried building with a different compiler version (MinGW 7.3.0) because SFML recommends it but still got my error. My error is below.

C:/.../Test_Project/src/main.cpp:15: undefined reference to `__imp__ZNK2sf6Window6isOpenEv'
C:/.../Test_Project/src/main.cpp:18: undefined reference to `__imp__ZN2sf6Window9pollEventERNS_5EventE'
C:/.../Test_Project/src/main.cpp:22: undefined reference to `__imp__ZN2sf6Window5closeEv'
C:/.../Test_Project/src/main.cpp:26: undefined reference to `__imp__ZN2sf5ColorC1Ehhhh'

etc...

The test code I'm running is a simple hello world script that should display a red circle.

#include <SFML/Graphics.hpp>

int main() {
    auto dimension = sf::VideoMode(1280u, 720u);
    auto title = "hello world";
    sf::RenderWindow window;
    window.create(dimension, title);

    sf::CircleShape circle;
    circle.setRadius(100);
    circle.setPosition(200, 200);
    circle.setFillColor(sf::Color::Red);

    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }
        }

        window.clear();
        window.draw(circle);
        window.display();
    }
}

I know Visual Studio has ways to easily add those linker dependencies, but the tutorials I'm following don't really describe why they work, and I'm more comfortable with VSCode. Any further reading for VSCode would be fantastic, as the main page for C++ on VSCode is not really descriptive with library implementation. Any info on how to proceed would also be great. Thanks! :)

K Bazan
  • 53
  • 1
  • 5
  • 2
    Why aren't you using Cmake or make ? – Aditya Singh Rathore Jun 20 '21 at 05:02
  • 1
    with multiple C++ files you need a build tool like Aditya suggests – rioV8 Jun 20 '21 at 05:36
  • `-L` doesn't add lib files. It adds a search path. A search path is useless without things to search for, – n. m. could be an AI Jun 20 '21 at 05:37
  • @AdityaSinghRathore Haven't learned it yet. I was wondering if compilation is possible without it. – K Bazan Jun 20 '21 at 13:16
  • 1
    @KBazan If you plan on using cpp, You MUST use make system. Start [here](https://cmake.org/examples/). If you want to explore VScode, you should try what you are doing. But if goal is to learn how multiple files are managed in cpp, you sh ok uld use make or cmake – Aditya Singh Rathore Jun 20 '21 at 14:51
  • @KBazan compilation is possible. Simple make files are just GCC commands. Here is an [example](https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_C_libraries.html). The point is it is error prone. I have done `gcc main.c -o main.c` just before a deadline in my university once and learned it hard way. – Aditya Singh Rathore Jun 20 '21 at 14:55

1 Answers1

1

You need to specify the search path with the -L flag and then the name of the library file with -l. I'd recommend looking at the compiler documentation rather than the information on vscode.