-1

-- Updates --

  1. Adding the source file settings.cpp directly to the project via Add -> Existing Item resolved the LNK2019 (as I suspected it couldnt find it).

-- Updated Question--

  1. How to specify a source file directory without having to add all the files within it manually as described in the update above? This is clearly achievable for the header files (as described below by adding the directory to the settings, is this not the same for source files?

-- Original Question --

I'm working on replicating a project from CPython into C++ as a challenge to learn more C++ but I can't seem to get the environment established so that I can compile a test run. When I build the solution, it throws a LNK2019 which I know has something to do with the Linker unable to locate the symbols. I have read through numerous solutions on SO that say to updated the properties with the directories of the files, but they do not resolve the issue.

The issues currently stand at:

  1. Some of the headers from other directories show in the explorer, but some do not, why?
  2. The source files are not found and therefore LNK2019 is thrown, cannot resolve, how to?

Here is the layout of my project:

/root
    /proj-cmd
        /src/main/cpp
            /proj/cmd
                -> main.cpp
    /proj-core
        /src/main/cpp/
            /proj/cmd
                -> command.h
                -> base_command.h
                -> base_command.cpp
            /proj/utils
                -> settings.h
                -> settings.cpp
 

The content of main.cpp for testing of environment:

// astro
#include <astro/core/util/settings.h>

// stdlib
#include <exception>
#include <string>
#include <iostream>
    
using namespace std;

// astro entry point
int 
main(int argc, char *argv[])
{   

    if (conf().hasKey("APP_CWD"))
    {
        cout << "APP_CWD is: " << conf().getKey("APP_CWD") << endl;
    }
    else
    {
        cout << "APP_CWD was not found" << endl;
    }

}

In order for #include <astro/core/util/settings.h> to work, I updated the include directories in the properties:

Project Settings

However, in the explorer only command.h and settings.h are shown, not base_command.h:

Explorer

Additionally, the base_command.cpp and settings.cpp do not display in the source files either, so I updated (similar to the include directories) the source directories:

ProjectSettings2

That takes care of the first issue I am noticing, but now onto LNK2019. I believe this is a related result of the former problem, in that the source files are unknown:

Errors

So following many other SO posts, I tried to update the Linker settings without success:

LinkerSettings

I'm not very familiar with the Visual Studio 2017 environment, so if somebody could provide input as to how to configure these settings so that I can compile I'd appreciate this.

pstatix
  • 3,611
  • 4
  • 18
  • 40
  • Problem seems to be the linker can't resolve the library that contains the Settings class; are you sure the additional library directories contain that library? – paisanco Mar 26 '22 at 18:38
  • @paisanco Inside the `main.cpp` the path for the `settings.h` has `settings.cpp` in it which defines that class. So inside that top path in the last pic in my post (ending in `..\core\util`) the `settings.cpp` file resides. I have noticed most LNK2019 posts refer to `.lib` files though, so I am wondering if this is because the project does not see the `settings.cpp` as a source file? – pstatix Mar 26 '22 at 18:40
  • If you are wanting to compile settings.cpp and main.cpp into the same executable (and not build a .lib containing settings.cpp) check your C/C++ settings to make sure all the files are specified to be part of the build. – paisanco Mar 26 '22 at 18:53
  • Hi ,glad to know you've found the solution to resolve this issue! Please consider answering it and accepting it as an answer to change its status to Answered. See [can I answer my own question..](https://stackoverflow.com/help/self-answer), Just a reminder :) – Minxin Yu - MSFT Mar 29 '22 at 07:23

1 Answers1

3

You need to add all .cpp files to your project as Existing Items. Just being in a directory is not sufficient for the IDE to know to compile those files. Headers are found by directory via #include, but you should still add them to your project as Existing Items to make it easier to navigate them in the tree view.

This is why you are getting linker errors: the code in settings.cpp and base_command.cpp are never getting built.

See Microsoft Docs

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • Does Visual Studio not have a way to add a source directory that says "find all .cpp from here and any sub directories and include them"? I have to manually add them all to the project (which obviously doesn't move them from their physical directories). As you note, headers are identifiable (because we can set the directories for inclusions to check in), I would have though the "Source Directories" property allowed for this feature as well, no? – pstatix Mar 26 '22 at 18:58
  • In C/C++ make systems, you always list each build file manually. The same is true for CMake, Nmake, etc.. The 'filters' system in VS will place them under a 'folder' based on the file extension as you add them to the project. For new source files, use "New File" and it will automatically add it to your project. – Chuck Walbourn Mar 26 '22 at 18:58
  • So in C/C++ make systems, when specifying files, each file is explicitly listed for compilation/linking? I assume there is an automated system somewhere, that allows a user to simply specify a wildcard in a directory rather than creating a makefile with potential thousands of paths? – pstatix Mar 26 '22 at 19:05
  • In C/C++, the 'unit' of compilation is a single source file. The ``#include`` will search directories to make a copy of all the header content into that source file, and the compiler generates a single ``.obj`` file from that invocation of the compiler. The build systems are all designed to take a list of source .cpp files and then invoke the compiler on each one, then link the full list of .obj files together – Chuck Walbourn Mar 26 '22 at 19:07
  • 1
    It is technically possible to 'glob' in CMake and do the equivalent in MSBuild, but this is not good practice for C/C++ development and pretty quirky. The explicit list of source files is super-useful for iteration time as it lets the make system quickly determine *which* source file was changed since the last build and invoke the compiler on only those files. In scripting languages (like Python) the mere existence of the file is sufficient and the invocation is when you *run* the program. In compiled languages, it's a multi-pass process. – Chuck Walbourn Mar 26 '22 at 19:09
  • I should note that for large codebases, C/C++ programmers will use multiple projects so you don't have a single make/project file with thousands of files. Usually it's a few dozen source files in each one, and the larger project can have many dozens or even 100s of individual projects. Each individual project creates a ``.lib`` file and then the main project will link against all those individual library files to generate the final result which is an ``EXE`` and usually one or more ``DLL`` files. – Chuck Walbourn Mar 26 '22 at 19:11
  • I see, how is it they combine the projects together so that say a class from one project need be referenced in another? Clearly I have some reading to do on the build systems of C++, but if you dont mind me picking your brain while youre here... – pstatix Mar 26 '22 at 19:13
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/243353/discussion-between-chuck-walbourn-and-pstatix). – Chuck Walbourn Mar 26 '22 at 19:13