Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Location vs Link-Location issues #34

Open
dcbaker opened this issue Feb 21, 2024 · 7 comments
Open

Location vs Link-Location issues #34

dcbaker opened this issue Feb 21, 2024 · 7 comments
Labels
documentation This issue describes a problem which can be addressed by documentation rather than a schema change. scheduled The maintainers have flagged this issue as something to be addressed.

Comments

@dcbaker
Copy link
Collaborator

dcbaker commented Feb 21, 2024

The current state is that the tool doing the lookup needs to know what platform it is running for to know if it needs to point at Link-Location or Location, since on Windows you do not link with the .dll, but with the interface library, pointed at by Link-Location. On all other platforms you will link with the .so or .dylib, pointed at by by Location. This is especially burdensome when cross compiling, since now the tool needs to know what platform it going to be running for, not just on.

We can avoid all of this ambiguity by doing one of two things:

  1. Location should point to the library you will ink with, the implementation library on Windows, the shared object elsewhere
  2. whenever Location is provided Link-Location should also be provided, and point to the actual thing to link to, as above
@dcbaker
Copy link
Collaborator Author

dcbaker commented Feb 21, 2024

Actually, thinking about this more and looking at the sample, it has this:

    "sample-shared": {
      "Type": "dylib",
      "Requires": [ ":sample-core" ],
      "Configurations": {
        "Optimized": {
          "Location": "@prefix@/lib64/libsample.so.1.2.0"
        },
        "Debug": {
          "Location": "@prefix@/lib64/libsample_d.so.1.2.0"
        }
      }
    }

Which isn't correct. We don't want to link with the .so.1.2.0, we want to link with the bare .so. So that makes me thing we should require the Link-Location to be set always. On !Windows it should point the bare .so or .dylib

@mwoehlke
Copy link
Member

I think you're over-complicating things. The way this works is actually relatively simple:

  • Are you dynamically loading the artifact? Use location, always.
  • Are you linking the artifact? Use link_location if set, otherwise use location.

If that's unclear in the specification, we can fix that, but note that nothing in the above cares what platform you're on, or targeting. The idea with the current implementation is that you don't need to specify both if they have the same value.

We don't want to link with the .so.1.2.0, we want to link with the bare .so. So that makes me thing we should require the Link-Location to be set always.

I am perhaps less savvy with respect to when you use the unversioned symlinks, but that sounds plausible if "require" is replaced with "specify as best practice for".

@dcbaker
Copy link
Collaborator Author

dcbaker commented Feb 27, 2024

I'm not an expert on Windows, but you never link to the .dll, only the .lib, right?. If so there would never be a reason to specify the .dll, since you never pass it as a linking argument?

You should always link with the unversioned .so, the elf header in the .so will contain version requirement information, and at runtime ld.so will find a library that meets those requirements.

So, I guess the requirement for Linux should be either: Location points to the bare .so, or if it doesn't then Link-Location must be set.

@mwoehlke
Copy link
Member

I'm not an expert on Windows, but you never link to the .dll, only the .lib, right?

Link, yes, but you load the .dll. There are instances in which you want to know both paths. (For one, if something is trying to do automatic PATH mangling. I'm pretty sure there are also cases where some projects' build systems do things like taking a target — that is, a component in CPS parlance — location and passing it as a command-line argument.)

So, I guess the requirement for Linux should be either: Location points to the bare .so, or if it doesn't then Link-Location must be set.

That sounds reasonable, except, again, I'm not sure it belongs in the CPS specification. Not as a stronger than a recommendation, in any case.

@dcbaker
Copy link
Collaborator Author

dcbaker commented Feb 28, 2024

Link, yes, but you load the .dll. There are instances in which you want to know both paths. (For one, if something is trying to do automatic PATH mangling. I'm pretty sure there are also cases where some projects' build systems do things like taking a target — that is, a component in CPS parlance — location and passing it as a command-line argument.)

This makes me feel like we're specing backwards then. Link-Location should always be set, and must point at the thing you link to, and Location may be set, and point at a loaded component. But I'm not going to die on that hill

That sounds reasonable, except, again, I'm not sure it belongs in the CPS specification. Not as a stronger than a recommendation, in any case.

I think it does make sense to follow the standard for the OS. On *nix pointing at a versioned .so will surprise people, and it will break because there is no guarantee that a particular versioned .so will be on the system even though a dependency might be there. In fact, on systems like debian and fedora the versioned so's are part of the runtime package and the unversioned are in the dev package, along with the .cps files, and it is sometimes possible to install the -dev package without the runtime pacakge. It's also not how any current dependency system works because almost all of those (including pkg-config) give -lfoo, which the compiler will interpret as {path}/libfoo.so, not libfoo.so.X.Y.Z. It also runs up against issues of the portability of X.Y.Z extensions, as some *nix OSes have X.Y.Z, some have X.Y and some only have .X. It also breaks the intention of those versioned .so's, which are for the runtime loader, not for the compiler/linker, we should not be pointing the toolchain at them.

@mwoehlke
Copy link
Member

This makes me feel like we're specing backwards then.

Perhaps. I'll concede that there is historical "baggage" present. OTOH, from a human-language point of view, it seems (to me, at least) more natural that you always have a location, but may or may not have a distinct link-location. Regardless, our options are to either require both attributes when they might have identical values, or pick one to be optional, which will fall back to the other if not set.

I think it does make sense to follow the standard...

Again, I'm mostly not disagreeing, I just feel that what you're describing is best practice and not something that should be expressed as a strict requirement. (Not at the specification level, anyway; the specification generally tries to avoid getting into the weeds of platform-specific details. A "how to use CPS on ELF platforms" document might be a different matter.) That said, if a CPS is present and mentions a specific versioned .so, that does imply that said artifact is present. Otherwise you have a stray .cps file without the relevant artifacts.

it is sometimes possible to install the -dev package without the runtime pacakge

Since the unversioned .so is normally a symlink to the versioned .so, I don't see how that would be possible that wouldn't constitute being "broken".

For that matter, it's not entirely clear what difference this makes, since the linker is going to see the same bytes, regardless.

@dcbaker
Copy link
Collaborator Author

dcbaker commented Feb 28, 2024

Okay, then I would settle from "must" to "should" language like: "A compliant Link-Location must point to a location to be passed to the linker, this location should conform to the standards of the OS the CPS file is for". would something like that be acceptable?

@mwoehlke mwoehlke added scheduled The maintainers have flagged this issue as something to be addressed. documentation This issue describes a problem which can be addressed by documentation rather than a schema change. labels Feb 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation This issue describes a problem which can be addressed by documentation rather than a schema change. scheduled The maintainers have flagged this issue as something to be addressed.
Projects
None yet
Development

No branches or pull requests

2 participants