C++ linkage "shared"


(Dror Smolarsky) #1

I have the following build.gradle file:

apply plugin: “cpp”

model {
components {
mylib(NativeLibrarySpec) {
sources {
cpp {
exportedHeaders {
srcDirs “mylib/include”
}
source {
srcDir “mylib/src”
}
} // end of cpp
} // end of sources
} // end mylib(NativeLibrarySpec)
myexe(NativeExecutableSpec) {
sources {
cpp {
lib library: ‘mylib’, linkage: "shared"
source {
srcDir “myexe/src”
}
}
} // end of sources
} // end of mylib(NativeExecutableSpec)
} // end of components
} // end of model

When trying to compile on windows I get the following link error:

LINK : fatal error LNK1181: cannot open input file ‘<path_to_project>\build\binaries\mylibS
haredLibrary\x64Debug\mylib.lib’

What am I missing?

Thanks


(Julien K) #2

I am having the problem here.

EDIT:
In my project I’ve got the same problems. However, when I am trying to build with linkage:“static”, then it’s building as supposed.

I checked the samples and tried them as well with linkage:“shared” in order to exclude any gradle related bugs.
It worked like a charm. It must be something with our projects.

P.S.: To the CPP Team -> please copy the dlls when someone is using them.


(Dror Smolarsky) #3

Julilen, I create a plugin that will copy shared libs dependencies as part of an install executable task, see:
https://plugins.gradle.org/plugin/com.xykivo.nativeextension

It add pre/post compile/link/install tasks and tasks to copy shared library dependencies to the install executable output dir.

Still no solution to the original problem, however I changed my project to use api linkage, and use dynamic loading (this was the end goal in any case).


(Julien K) #4

@xykivo ,wow, that’s great!
Meanwhile, I have found a solution to our problem.

The error you provided in the initial post suggests, that you’re using Visual Studio.
And Visual Studio comes with interesting behaviour, when building shared libraries.
When the library doesn’t export anything, then no “.lib” file will be build. But how do we export something?

Well, VSC++ expects it like this:

__declspec(dllexport) // Exports the interface
__declspec(dllimport) // Imports the interface

However, you can utilize some macros for this:

#if defined(DLL_EXPORT)
    #define API __declspec(dllexport)
#else
    #define API __declspec(dllimport)
#endif

Now use it like this:

class API Application1337DafuqAmIDoing{
};

Now the complete class is being exported and a “.lib” file is being built.


(Dror Smolarsky) #5

Thanks Julien,
I was just running a simple test, which was why i didn’t use export.

I’m working on something else, right now, but I’ll try the moment I get a chance.


(George) #6

[All of the following comments assume that we are on Windows 10, using the MSVC toolchain for C/C++/VSC++ compilation]

TL;DR: Make sure something is being exported.

  • If Gradle is using the toolchian(s) for VS as specified, they most likely are expecting the implicit .lib to be generated-- By default some MS compiler component seems to properly generate the .lib, .DLL and properly link, in may build systems (CMake in particular), when objects are properly exported.

This is a very late reply, however, I think this is mild oversight in the development of Gradle for the MSVS and MFC ecosystems, for VC++. One thing is that Gradle does not seem to notice when implicit or explicit linking should be used or stated for VisualCpp library creation/linking.

The default behavior of generating a shared library under Gradle, clearly assumes standard implicit linking under VisualCpp. However, this seems to directly counter-act the Gradle X-platform development environment they have set up. Being able to support native cpp builds for x-platform development usually indicate explicit linking, as this follows the Unix flavor .so build chain.

The build system should identify whether the .dll has any exposed symbols that can be linked via a .lib, and tailor the linker for explicit/implicit linking.