RejectedSoftware Forums

Sign up

Dependency on a package which uses a local library

Hey there,

(warning) I'm not all too experienced in programming. So here's my intention:

  • Build an interface for a C-library that I can use in my project
  • Put this interface in a separate package so that I can use it in other projects (e.g. in a subpackage of my project) per dependency

The problem I'm having is the following:

  • I am writing my own c library file that interfaces with the actual library (this is since I did not get a translation of the original c library header -> d module running)
  • my c library file is in my package's "lib" folder

When I now set the dependency on the package in my project with

"dependencies": { "path": "../<package>" }

I often get that the library is not found or that the function name symbol can't be found.

I'm wildly trying out things, but probably I'm doing a lot wrong. Is my idea feasible at all? Or is this "bs" and I should install my own library into "usr/local/lib"?

So I guess this is also a general question of how local libraries can be dealt with in dependencies...

Please let me know if my mind is shooting too far off.

Bests!

Re: Dependency on a package which uses a local library

On 11/22/16 8:30 AM, Timoses wrote:

Hey there,

(warning) I'm not all too experienced in programming. So here's my intention:

  • Build an interface for a C-library that I can use in my project
  • Put this interface in a separate package so that I can use it in other projects (e.g. in a subpackage of my project) per dependency

The problem I'm having is the following:

  • I am writing my own c library file that interfaces with the actual library (this is since I did not get a translation of the original c library header -> d module running)
  • my c library file is in my package's "lib" folder

When I now set the dependency on the package in my project with

"dependencies": { "path": "../<package>" }

I often get that the library is not found or that the function name symbol can't be found.

I'm wildly trying out things, but probably I'm doing a lot wrong. Is my idea feasible at all? Or is this "bs" and I should install my own library into "usr/local/lib"?

Definitely possible.

I'd experiment with dub -v to see what commands dub is actually calling.
Most likely your library is not being found by the linker.

-Steve

Re: Dependency on a package which uses a local library

On Tue, 22 Nov 2016 10:59:36 -0500, Steven Schveighoffer wrote:

Definitely possible.

I'd experiment with dub -v to see what commands dub is actually calling.
Most likely your library is not being found by the linker.

-Steve

Thanks Steve! Super happy that you're letting me know it should be possible.

What I have is the following.

Interface

My interface package dub.json:

{
    "name": "dneo4j",
	
    "targetType": "library",

    "libs": ["neo4jCon"],

    "configurations": [
        {
            "name": "osx",
            "targetType": "library",
            "platforms": ["osx"],
            "lflags" : ["-Llib"]
        },
        {
            "name": "unix",
            "targetType": "library",
            "lflags" : ["-Llib", "-rpath=./lib"]
        },
        {
            "name": "unittest",
            "targetType": "executable",
            "lflags" : ["-Llib"]
        }
    ]
}

dneo4j.d:

module dneo4j;

extern(C) {
    int neo4jConTest();
}
int testfunc()
{
    return 3;
}

Project using the interface

dub.json:

{
    "name": "projectname",

    "dependencies": {
        "dneo4j": {"path": "../dneo4j/"}
    },

    "configurations": [
        {
            "name": "osx",
            "targetType": "executable",
            "platforms": ["osx"],
            "lflags": ["-Llib"]
        },
        {
            "name": "unix",
            "targetType": "executable",
            "lflags" : ["-Llib", "-rpath=./lib"]
        }
    ]
}

app.d:

import std.stdio;
import dneo4j;

void main()
{
    writeln(neo4jConTest());
    writeln(testfunc());
}

Result - Scenario 1

If I now run the project with "dub" it yields:

Generate target projectname (executable /Users/Timoses/programs/projectname/projectname projectname)
Generate target dneo4j (staticLibrary /Users/Timoses/programs/projectname/dneo4j dneo4j)
Performing "debug" build using dmd for x86_64.
dneo4j ~master: target for configuration "osx" is up to date.
Using existing build in /Users/Timoses/programs/projectname/dneo4j/.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-CA8448A996762CE52501F2A7E2480226/.
Copying target from /Users/Timoses/programs/projectname/dneo4j/.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-CA8448A996762CE52501F2A7E2480226/libdneo4j.a to /Users/Timoses/programs/projectname/dneo4j
Target '/Users/Timoses/programs/projectname/projectname/.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname' doesn't exist, need rebuild.
projectname ~master: building configuration "osx"...
Using direct -l... flags for neo4jCon.
dmd -c -of.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname.o -debug -g -w -version=Have_projectname -version=Have_dneo4j -Isource/ -I../dneo4j/source/ source/app.d -vcolumns
Linking...
dmd -of.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname .dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname.o ../dneo4j/libdneo4j.a -L-Llib -L-Llib -L-lneo4jCon -g
ld: library not found for -lneo4jCon
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: linker exited with status 1
FAIL .dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/ projectname executable
dmd failed with exit code 1.

What I find weird about this is that it is linking with -L-Llib -L-Llib -L-lneo4jCon as if it takes the linker options from the dneo4j package dub.json and adds it.

Result - Scenario 2

When I leave out the line "libs": ["neo4jCon"], from dneo4j dub.json I get:

Generate target projectname (executable /Users/Timoses/programs/projectname/projectname projectname)
Generate target dneo4j (staticLibrary /Users/Timoses/programs/projectname/dneo4j dneo4j)
Performing "debug" build using dmd for x86_64.
dneo4j ~master: target for configuration "osx" is up to date.
Using existing build in /Users/Timoses/programs/projectname/dneo4j/.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-CA8448A996762CE52501F2A7E2480226/.
Copying target from /Users/Timoses/programs/projectname/dneo4j/.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-CA8448A996762CE52501F2A7E2480226/libdneo4j.a to /Users/Timoses/programs/projectname/dneo4j
Target '/Users/Timoses/programs/projectname/projectname/.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname' doesn't exist, need rebuild.
projectname ~master: building configuration "osx"...
dmd -c -of.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname.o -debug -g -w -version=Have_projectname -version=Have_dneo4j -Isource/ -I../dneo4j/source/ source/app.d -vcolumns
Linking...
dmd -of.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname .dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname.o ../dneo4j/libdneo4j.a -L-Llib -L-Llib -g
Undefined symbols for architecture x86_64:
  "_neo4jConTest", referenced from:
      __Dmain in projectname.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: linker exited with status 1
FAIL .dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/ projectname executable
dmd failed with exit code 1.

which is understandable. dub test in dneo4j package yields the same result then.

What now does work is calling testfunc().

Conclusion

I would find using a "copyFiles": ["$DNEO4J_PACKAGE_DIR/libs/*"], command in the project's dub.json odd (didn't test it either).

So, what's wrong?

Hope this ain't too much input : P.

Re: Dependency on a package which uses a local library

On 11/22/16 12:47 PM, Timoses wrote:

Result - Scenario 1

If I now run the project with "dub" it yields:

Generate target projectname (executable /Users/Timoses/programs/projectname/projectname projectname)
Generate target dneo4j (staticLibrary /Users/Timoses/programs/projectname/dneo4j dneo4j)
Performing "debug" build using dmd for x86_64.
dneo4j ~master: target for configuration "osx" is up to date.
Using existing build in /Users/Timoses/programs/projectname/dneo4j/.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-CA8448A996762CE52501F2A7E2480226/.
Copying target from /Users/Timoses/programs/projectname/dneo4j/.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-CA8448A996762CE52501F2A7E2480226/libdneo4j.a to /Users/Timoses/programs/projectname/dneo4j
Target '/Users/Timoses/programs/projectname/projectname/.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname' doesn't exist, need rebuild.
projectname ~master: building configuration "osx"...
Using direct -l... flags for neo4jCon.
dmd -c -of.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname.o -debug -g -w -version=Have_projectname -version=Have_dneo4j -Isource/ -I../dneo4j/source/ source/app.d -vcolumns
Linking...
dmd -of.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname .dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname.o ../dneo4j/libdneo4j.a -L-Llib -L-Llib -L-lneo4jCon -g
ld: library not found for -lneo4jCon

This is the error right here. It's looking for libneo4jCon.a in the
library path, but cannot find it.

Note that generally the linker searches in the usual places (/usr/lib,
/lib, ...), and any location you pass via -L (e.g. the option -L-Llib in
your dub file).

Where is the lib file? Wherever it is, you need to add a linker search
path for it.

-Steve

Re: Dependency on a package which uses a local library

This is the error right here. It's looking for libneo4jCon.a in the
library path, but cannot find it.

Note that generally the linker searches in the usual places (/usr/lib,
/lib, ...), and any location you pass via -L (e.g. the option -L-Llib in
your dub file).

Where is the lib file? Wherever it is, you need to add a linker search
path for it.

-Steve

Thanks! I've "solved" it now by adding "lflags": ["-L$PACKAGE_DIR/lib"], to the dub.json of dneo4j.

Why is it that the linker flags of the library package are taken over by the project where I'm using the package? Just a kind of redundancy to be sure to get all library paths included (even though the ones from the dependency package include relative paths as well)?

Re: Dependency on a package which uses a local library

Just wondering whether it's intended behaviour.

Re: Dependency on a package which uses a local library

On Wed, 23 Nov 2016 15:25:53 GMT, Timoses wrote:

Thanks! I've "solved" it now by adding "lflags": ["-L$PACKAGE_DIR/lib"], to the dub.json of dneo4j.

Why is it that the linker flags of the library package are taken over by the project where I'm using the package? Just a kind of redundancy to be sure to get all library paths included (even though the ones from the dependency package include relative paths as well)?

Looking at the output of the first scenario:

dmd -of.dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname .dub/build/osx-debug-posix.osx-x86_64-dmd_2072-B74417139C39638134843B1B9E823EA2/projectname.o ../dneo4j/libdneo4j.a -L-Llib -L-Llib -L-lneo4jCon -g
ld: library not found for -lneo4jCon

With the flag -L-Llib, lib refers to the "lib" directory in the current directory. I'm guessing your library is instead in ../dneo4/lib. Another thing that is interesting is the following argument: ../dneo4j/libdneo4j.a. That should also link to the library, assuming the path is correct.

BTW, you can use DStep [1] to automatically generate bindings to C libraries.

[1] https://github.com/jacob-carlborg/dstep

/Jacob Carlborg