CMake fails to link nested library - c++

im trying to build my first CMake project and it fails on CXX executable NeuralNetLibrary.
I get the undefined reference to FFLayer::test() error when building.
The full project is in here
https://github.com/JRazek/ConvolutionalNetLib.
Please help me how can I solve this issue.

The reason is that you're missing dependencies between the different library projects. For example, the Net library uses a function defined in FFLayer in Net.cpp, but the corresponding target_link_libraries(Net PRIVATE FFLayer) is missing.
This causes CMake to link against the static libraries in the wrong order, as it assumes that there are no order constraints.
If you fix that you'll find that you still get a missing symbol error for the destructor of Layer, which isn't implemented. You can add a .cpp file with the definition or just add = default; to the existing declaration, in both cases it will build.

Related

How to avoid "LNK2005 Already Defined error" in case of two static libraries that use same another static library?

Situation:
Static library LIB1, compiled from source and linked as lib1.lib (with /MD).
Uses library LIB2 and has inside objects from lib2.lib
Static library LIB2, also compiled with /MD.
EXE that (not directly) depends on both libraries.
Result of linking this EXE on MSVC 15.9.19: a lot of LNK2005 errors like
lib2.lib: error LNK2005: "function <funcsig> already defined in lib1.lib"
Also I get a lot of warnings like
lib1.lib: warning LNK4099: PDB 'lib2.pdb' was not found with 'lib1.lib' or at '<path>'; linking object as if no debug info
The question: why didn't the linker merge duplicate definitions? How do I diagnose the exact reason for this problem?
Thanks!
UPDATE:
The errors are NOT about the standard library. They are about the Google Protobuf functions. LIB2 is Google's libprotobuf.lib. LIB1 is also Google's OR-Tools library that uses Protobuf. But we also use Protobuf, hence the conflict!
This link to MSDN will almost certainly help.
As you say these are not standard C/C++ functions, you can ignore the sections about the mixing Debug and Release code. Unfortunately this still leaves you with plenty of possible causes. This one is a good one to rule out.
This error can occur if you mix use of static and dynamic libraries when you use the /clr option.
If you view the command line options as you compile, either by switching on verbose mode or examining the properties of each file.
Once this is ruled out, all the other causes are that you literally declaring the same thing (function/variable) twice. The most likely way for this to happen is to put something (like a function) in a header file, which is included by more than one module file. Diagnosing this without seeing the code is hard. You must pick one of the errors, and select part of the name that is not mangled, basically the human readable bit. You then need to examine where it is declared, and see if is in a header. If it is not, you must be including a non-header from a source file. A quick (and dirty) way to find where a file is included from is to add a #pragma message to the file, then recompile one file at a time to see when it is printed. To understand why it is included use show includes.
If the symbol is declared from a header file, you must fix it, by making it a forward declare.
If you don't know how to do this, I would suggest starting a new question, along the lines of, "how do I forward declare this?". It should get you answers pretty quickly.
Hope this helps.

Linking error with cmake

I'm trying to understand why I get a linking error while compiling a project generated with CMake.
The CMakeFiles.txt builds a static library for each folder of the project and then link all of them together in the following way:
# root CMakeLists.txt
add_subdirectory(subfolder1)
add_subdirectory(subfolder2)
add_subdirectory(...)
add_executable(target ${SOURCES})
set(LIBRARIES
LIB_FOO
LIB_BAR
...
)
target_link_libraries(target
${LIBRARIES}
)
then in each subfolder I have a simple CMakeLists.txt like
file(GLOB FOO_SOURCE *.cpp)
add_library(LIB_FOO ${FOO_SOURCE})
Now this works and compiles everything fine but I get an undefined reference while linking, so I tried to investigate if everything was available at the end and it looks like so. The actual error is the following:
libLIB_WORLD.a(World.cpp.o): In function `World::generate(WorldGenOptions)':
World.cpp:(.text+0x803): undefined reference to `MapGenerator::MapGenerator(BlockMap*)'
World.cpp:(.text+0x837): undefined reference to `MapGenerator::generate(bool, WorldGenOptions)'
Now, MapGenerator.cpp is part of LIB_MAP, so I checked if the file exists and contains the symbols:
:~$ nm libLIB_MAP.a | grep generate
....
00000000000044dc T _ZN12MapGenerator8generateEb15WorldGenOptions
:~$ nm CMakeFiles/LIB_MAP.dir/MapGenerator.cpp.o | grep generate
....
00000000000044dc T _ZN12MapGenerator8generateEb15WorldGenOptions
So the symbol is present, at this point I checked if it was correctly linked by ld:
:~$ make VERBOSE=1
/usr/bin/g++ ... libLIB_MAP.a libLIB_WORLD.a ...
So it is actually present in linking phase together with the other library that is not able to find the symbol.
Is there something trivial I'm missing? I'm quite new to CMake so I'm out of ideas.
This is a problem of a library dependency that was not modeled correctly in CMake.
Your LIB_WORLD references methods from LIB_MAP. This dependency is not modeled in your CMake scripts. As both of those are static libraries, they will still build fine on their own. (Remember that static libraries are essentially a bunch of object files packed together, but they never pass through the linker.)
However, as soon as you link them to an executable or a shared library, you will get the problem. Even though your executable links against both LIB_WORLD and LIB_MAP, it does so in the wrong order. So when the linker is trying to resolve the missing symbols for LIB_WORLD, it does not know yet about the symbols exported by LIB_MAP, hence the error message you experienced.
The proper fix is to introduce the dependency on LIB_WORLD:
add_library(LIB_WORLD [...])
target_link_libraries(LIB_WORLD LIB_MAP)
Now whenever you link something against LIB_WORLD you will always also link against LIB_MAP and CMake will take care that the order is right. (In particular, if your executable does not make direct use of methods from LIB_MAP you might want to remove it from its target_link_libraries altogether.)
As an additional benefit, it now allows you to build LIB_WORLD as a shared library, which would have failed with a linker error before.

Mysterious "unresolved symbols" linker errors when compiling against large static lib

I am receiving a lot of strange LNK2001 and LNK2019 errors when attempting to compile and link against a somewhat large static library (developed in-house). Here are the facts:
There are several static libs (most built in-house) all compiled into one large wrapper static lib for public consumption ("Pimpl" idiom). Essentially, we have libs A, B, and C all compiled into an internal/private lib called D. Then, we have an external/public lib that wraps around D called E.
The final product is not an executable, but a plug-in for Adobe Illustrator. Plug-ins are essentially just a DLL with a couple special resources and a special entry point (PluginMain() function). Compiling and linking works just great until I use the /INCLUDE option to specify that PluginMain should always be exported.
Creating a plug-in and linking against lib D works fine (no errors whatsoever). Creating a plug-in and linking against lib E gives over 100 unresolved symbol errors (symbols that should be present in E).
When I run DUMPBIN on the E.lib file, it appears to have all the symbols that the linker is complaining about when trying to create a plug-in. However, I'm not entirely certain I understand all the output syntax from DUMPBIN...
The libs are all cross-platform and compile and link just fine with GCC/LLVM on Mac.
Most of the functions that the linker complains about are either plain functions or static member functions. Most of those look suspiciously like functions that the compiler might try to inline. I have tried disabling optimization and/or automatic inlining, but the same link errors are still present.
Can anyone point me in the direction of some compile and/or link settings that might resolve the issue? Settings that are commonly misconfigured in situations like this?
Perhaps there is a setting I missed that is causing the linker not to export these symbols when linking E? Perhaps there is a setting that forces the linker to export ALL symbols when linking E that I can try? Maybe a utility exists to help me inspect the lib symbols myself for a clue?
I feel like I've tried everything, but it never hurts to ask. Thanks all.
EDIT 1: snowdude requested an actual link error:
E.lib(PathArt.cpp.obj) : error LNK2001: unresolved external symbol "private: __thiscall E::PathSegPoint::PathSegPoint(struct D::PathSegPoint const &)" (??0PathSegPoint#E##AAE#ABU0D###Z)
I should add that E::PathSegPoint::PathSegPoint(const D::PathSegPoint&) is a private constructor for constructing an external/public consumable E::PathSegPoint object from an internal/private D::PathSegPoint object. Again, this is the "Pimpl" idiom. Some classes/functions are friends of E::PathSegPoint to enable this sort of construction.
I thought I'd post an answer in case anyone shows up to this page in the future.
For several reasons a few years ago, we started compiling these libraries with the Intel C++ compiler inside Visual Studio. Some of these reasons have changed, and we needed to switch back to the MSVC compiler. Upon switching to the MSVC compiler, these linker errors disappeared!
I don't know why or how the Intel C++ compiler developed these link problems, but it's entirely possible that this is a bug.

link static library in c++ visual studio

can someone please help me to understand the process.
in c++ visual studio 2010
i have a visual studio solution (lets call it mysol)
i have a project built as a static library (let's call it staticprj)
staticprj needs to use a library from outside (lets call it ext.lib)
in the body of the source code of staticprj i include outside library header file with
# include extlib.h and make calls to some of its functions (let call them extfunctions())
i also include the the path to the header files location of the ext.lib.
the staticprj compiles okay without errors
the mysol also has another project which is a dynamic library (dynprj) and which depends on the staticprj.
also in the source files of the dynprj uses functions from outside library.
i have included #include extlib.h in the source code of dynprj.
i have included the path of the header files
i have attached extlib.h directly to the dynprj
i have also added ext.lib to the linker input (along with the path where the ext.lib resides).
i still get a lnk2001 error stating that extfunctions() where not found.
the whole structure (the mysol solution) compiles okay if i do not use ext.lib at all.
my question is how does the linking process works and what can i do to correct this linking error.
(note that without the presence of ext.lib my linking of the staticprj and dynprj is fine. my compilation works okay and my code works. i only get the linking error when i try to link another ext.lib to staticprj and dynprj and use functions from ext.lib)
thanks in advance.
I'm not quite sure it will work, but try putting the .dll inside your "mysol" debug folder. I had a similar problem couple of weeks ago when I had library compiled as .dll. I just placed that .dll within my debug folder and worked lovely.

Getting undefined reference error at adding simple class to library

I am working with a rather sizeable library which uses CMake for compilation/linking. I need to add some functionality, thus I need to add some classes to the library. The problem is that when I add even a simple helloWorld class to the library, and try to call it from some main function, I get undefined reference problem at link time. When I looked into the built code ("CMakeFiles" within the library folder), my class hasn't been compiled by CMake (and thus, for instance, there is no HelloWorld.o file in there).
Can somebody point out where I am going wrong? Do I need to explicitely tell CMake to compile this class? (if yes, how?). I am novice in CMake, so don't know how to tackle this problem.
I call the function like this.
``
GSROrdinary sord;
The error message, I get, is something like this.
undefined reference to beep::GSROrdinary::GSROrdinary()
undefined reference to beep::GSROrdinary::~GSROrdinary()
Yes, you need to tell CMake to compile your class. I suggest that you check out some CMake tutorials that can be found online. Here is a nice one: http://www.cs.swarthmore.edu/~adanner/tips/cmake.php - pay particular attention to the CMakeLists.txt file and syntax. You will have to modify your lib's CMakeLists.txt in order to add a new class.
You have to explicitly add your new file to the CMake file so that they get compiled and linked.
This commented sample could give you a start (basically you have to look for a add_library (LIBNAME files) directive in one of your CMakeLists.txt files and add your new file there, but you should also possibly read the documentation.