Native: Nested library dependencies aren't recognised by install tasks


(Phil McArdle) #1

In summary, in the first example below, the install task for Exe1, below, does not copy the output of Lib2 - only Lib1, despite that our exe will ultimately require both dll’s.

We found this in a much larger project, but we’re not sure what, if there is one, the correct way to solve this in Gradle is, or whether it’s a bug.

It would seem that Gradle should understand the nested dependencies and copy the respective outputs, but it’s not doing so.

The only way we can get Lib2 in the install folder for the exe is to reference it in the exe’s component, which seems like inappropriate coupling for the configuration, from the point of view of consumers of a shared library having to know the dependencies of every shared library they consume - a much larger issue in a larger project.

Full source code here. Will compile under MSVC 2013.

Nested Project Dependency

apply plugin: 'cpp'

model {

    components {

        Lib2(NativeLibrarySpec) {
            sources {
                cpp{
                    source{
                        srcDirs "Lib2"
                        include "**/*.cpp"
                    }
                }
            }
        }

        Lib1(NativeLibrarySpec) {
            sources {
                cpp{
                    lib library: 'Lib2', linkage: 'shared'
                    source{
                        srcDirs "Lib1"
                        include "**/*.cpp"
                    }
                }
            }
        }

        Exe1(NativeExecutableSpec) {
            sources {
                cpp{
                    lib library: 'Lib1', linkage: 'shared'
                    source{
                        srcDirs "Exe1"
                        include "**/*.cpp"
                    }
                }
            }
        }
    }

}

And the same issue manifests if the second library is a PrebuiltSharedLibrary.

Nested Prebuilt Dependency

apply plugin: 'cpp'

model {

    repositories {
        libs(PrebuiltLibraries) {
            PrebuiltLib {
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("PrebuiltLib/PrebuiltLib.dll")
                    sharedLibraryLinkFile = file("PrebuiltLib/PrebuiltLib.lib")
                }
            }
        }
    }    

    components {

        Lib1(NativeLibrarySpec) {
            sources {
                cpp{
                    lib library: "PrebuiltLib", linkage: "shared"
                    source{
                        srcDirs "Lib1"
                        include "**/*.cpp"
                    }
                }
            }
        }

        Exe1(NativeExecutableSpec) {
            sources {
                cpp{
                    lib library: 'Lib1', linkage: 'shared'

                    source{
                        srcDirs "Exe1"
                        include "**/*.cpp"
                    }
                }
            }
        }

    }
}

Is there a Gradle way of solving this, or is this a bug?

Is the behaviour different for an equivalent example in Java? (I don’t know Java well enough to try)

Environment: Gradle 3.1, Windows 10 1607, MSVC 2013

Best Regards,

Phil


(Daniel Lacasse) #2

Hi Phil,

This post slip by me. Just for completeness, this limitation is documented on this issue.

Daniel


(Phil McArdle) #3

Thanks, we figured that one would solve it once we entered the issue :slight_smile:

Phil