Reputation: 446
I have a simple project setup for an OpenGL-project for University.
An API project where every library I want to use (GLEW, GLFW, GLM) is linked statically. These libraries should be combined with my own API code into one single DLL file.
The other project should only have one dependency, the DLL. Throw that DLL it should get access to the API code and all libraries linked inside the API.
My problem is that inside the API I have access to all functions of all libraries I linked. But inside the actual project which has the API as a dependency, I can call the functions and the compiler throws out no error (of cause) because the function declaration is in the linked header files but the linker does not find the function definition inside the DLL, which mean the build of the API does not export the linked libraries into the DLL.
In the API project, I also defined the necessary preprocessor definitions:
I defined _GLFW_BUILD_DLL:
from "glfw3.h" l. 233-245
/* GLFWAPI is used to declare public API functions for export
* from the DLL / shared library / dynamic library.
*/
#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)
/* We are building GLFW as a Win32 DLL */
#define GLFWAPI __declspec(dllexport) <----- this one is active
#elif defined(_WIN32) && defined(GLFW_DLL)
/* We are calling GLFW as a Win32 DLL */
#define GLFWAPI __declspec(dllimport)
#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
/* We are building GLFW as a shared / dynamic library */
#define GLFWAPI __attribute__((visibility("default")))
#else
/* We are building or calling GLFW as a static library */
#define GLFWAPI
#endif
I defined GLEW_BUILD:
from "glew.h" l. 200-208
#ifdef GLEW_STATIC
#define GLEWAPI extern
#else
#ifdef GLEW_BUILD
#define GLEWAPI extern __declspec(dllexport) <---- this one is active
#else
#define GLEWAPI extern __declspec(dllimport)
#endif
#endif
Any help?
EDIT:
The linker options:
/OUT:"D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.dll" /MANIFEST /NXCOMPAT /PDB:"D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.pdb" /DYNAMICBASE "glew32s.lib" "glfw3.lib" "opengl32.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.lib" /DEBUG /DLL /MACHINE:X86 /INCREMENTAL /PGD:"D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:NO /ManifestFile:"D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin-int\Debug\Win32\CGAPI.dll.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"D:\Programmierung\C++-Projekte\CG-Project\Dependencies\GLFW\Win32\lib-vc2019\" /LIBPATH:"D:\Programmierung\C++-Projekte\CG-Project\Dependencies\GLEW\lib\Release\Win32\" /TLBID:1
The one I added:
/WHOLEARCHIVE:glew32s.lib
/WHOLEARCHIVE:glfw3.lib
/WHOLEARCHIVE:opengl32.lib
EDIT 2:
So I had to download the source code from glew and build it myself and also I had to remove the .res
file inside the option of my own glew build. Now the API builds successfully but the methods aren't part of the DLL. So nothing changed.
Upvotes: 1
Views: 1038
Reputation: 41116
I don't fully understand your motivation for doing things this way. The common approach (that I'd also use) is shipping the OpenGL .dlls (I'm not aware of the licensing implications) along with yours.
However, even if this looks like an XY Problem, in order to achieve your goal, you could pass [MS.Docs]: /WHOLEARCHIVE (Include All Library Object Files) to the linker. In order to differentiate which .libs to include and which not, specify the flag once per each target library: /wholearchive:glew32.lib /wholearchive:glfw3.lib /wholearchive:glm.lib
.
Check [SO]: Exporting symbols in static library that is linked to dynamic library (@CristiFati's answer) for more details.
As a note: the .libs must have been built with exportable symbols. If not, you'll have to export them "manually", using one of the other choices:
/EXPORT linker option
Module definition (.def) files
or rebuild the .lib as static but with exportable symbols. However, there's high chance it won't work OOTB (you'll probably need to modify a file or 2 or manually pass a compile flag), as it's not a normal way (most of the people would agree that's a NO-NO, especially for someone without a fairly deep know-how) of doing things.
Upvotes: 1