Discussion:
[eigen] Eigen in a namespace?
Robert Lupton the Good
2018-04-06 13:35:02 UTC
Permalink
We've been using eigen (at a lowish level) for quite a time in a large astronomical software project, the LSST, and now have the desire to include a semi-external package; both use eigen.

For packaging reasons the semi-external package would like to include its own copy of the eigen headers (probably as a sub-module from git), so we potentially have two copies of eigen in the same dynamically-loaded package (both imported into python). We're worried about ABI/API issues as eigen evolves in interesting ways.

One way to fix this would be to include eigen in different namespaces (maybe anonymous?) in the two packages, but I don't think that this is possible due to eigen's use of the STL. Is there any way to do this now? Or alternatively would it be crazy to restructure the eigen includes to allow us to include a header outside our namespace that pulls in the STL, and then the "real" eigen headers inside our namespace?

R
Mark Borgerding
2018-04-06 14:00:46 UTC
Permalink
Not directly an answer to your question, but a possible resolution (on a
linux or unix-like system anyway) ...


Would it help to build your shared object binaries with
-fvisibility=hidden, so the contained library is not visible outside the
.so? Thus no name collisions.

This might fail if you need the public interface to use the eigen ABI.


-- Mark
Post by Robert Lupton the Good
We've been using eigen (at a lowish level) for quite a time in a large astronomical software project, the LSST, and now have the desire to include a semi-external package; both use eigen.
For packaging reasons the semi-external package would like to include its own copy of the eigen headers (probably as a sub-module from git), so we potentially have two copies of eigen in the same dynamically-loaded package (both imported into python). We're worried about ABI/API issues as eigen evolves in interesting ways.
One way to fix this would be to include eigen in different namespaces (maybe anonymous?) in the two packages, but I don't think that this is possible due to eigen's use of the STL. Is there any way to do this now? Or alternatively would it be crazy to restructure the eigen includes to allow us to include a header outside our namespace that pulls in the STL, and then the "real" eigen headers inside our namespace?
R
Robert Lupton the Good
2018-04-06 14:05:52 UTC
Permalink
Thank you. We thought about that, but we'd have to get this working on multiple O/Ss and we are using a rather old-fashioned way of handling the multi-level namespaces on os/x. So I'd really rather solve this at source!

R
Not directly an answer to your question, but a possible resolution (on a linux or unix-like system anyway) ...
Would it help to build your shared object binaries with -fvisibility=hidden, so the contained library is not visible outside the .so? Thus no name collisions.
This might fail if you need the public interface to use the eigen ABI.
Vincent Vanhoucke
2018-04-06 15:30:08 UTC
Permalink
It's a terrible hack, and you didn't hear it from me, but if you only use
Eigen in a narrow scope, you can fake a namespace by compiling with:
-DEigen=EigenNotToBeLinkedAgainst
Post by Mark Borgerding
Not directly an answer to your question, but a possible resolution (on a
linux or unix-like system anyway) ...
Would it help to build your shared object binaries with
-fvisibility=hidden, so the contained library is not visible outside the
.so? Thus no name collisions.
This might fail if you need the public interface to use the eigen ABI.
-- Mark
Post by Robert Lupton the Good
We've been using eigen (at a lowish level) for quite a time in a large
astronomical software project, the LSST, and now have the desire to include
a semi-external package; both use eigen.
Post by Robert Lupton the Good
For packaging reasons the semi-external package would like to include
its own copy of the eigen headers (probably as a sub-module from git), so
we potentially have two copies of eigen in the same dynamically-loaded
package (both imported into python). We're worried about ABI/API issues as
eigen evolves in interesting ways.
Post by Robert Lupton the Good
One way to fix this would be to include eigen in different namespaces
(maybe anonymous?) in the two packages, but I don't think that this is
possible due to eigen's use of the STL. Is there any way to do this now?
Or alternatively would it be crazy to restructure the eigen includes to
allow us to include a header outside our namespace that pulls in the STL,
and then the "real" eigen headers inside our namespace?
Post by Robert Lupton the Good
R
Rasmus Munk Larsen
2018-04-06 15:33:23 UTC
Permalink
Yeah, who would do such a thing?!?!
Post by Vincent Vanhoucke
It's a terrible hack, and you didn't hear it from me, but if you only use
-DEigen=EigenNotToBeLinkedAgainst
Post by Mark Borgerding
Not directly an answer to your question, but a possible resolution (on a
linux or unix-like system anyway) ...
Would it help to build your shared object binaries with
-fvisibility=hidden, so the contained library is not visible outside the
.so? Thus no name collisions.
This might fail if you need the public interface to use the eigen ABI.
-- Mark
Post by Robert Lupton the Good
We've been using eigen (at a lowish level) for quite a time in a large
astronomical software project, the LSST, and now have the desire to include
a semi-external package; both use eigen.
Post by Robert Lupton the Good
For packaging reasons the semi-external package would like to include
its own copy of the eigen headers (probably as a sub-module from git), so
we potentially have two copies of eigen in the same dynamically-loaded
package (both imported into python). We're worried about ABI/API issues as
eigen evolves in interesting ways.
Post by Robert Lupton the Good
One way to fix this would be to include eigen in different namespaces
(maybe anonymous?) in the two packages, but I don't think that this is
possible due to eigen's use of the STL. Is there any way to do this now?
Or alternatively would it be crazy to restructure the eigen includes to
allow us to include a header outside our namespace that pulls in the STL,
and then the "real" eigen headers inside our namespace?
Post by Robert Lupton the Good
R
Gael Guennebaud
2018-04-06 20:33:18 UTC
Permalink
Post by Vincent Vanhoucke
It's a terrible hack, and you didn't hear it from me, but if you only use
-DEigen=EigenNotToBeLinkedAgainst
I was tempted to suggest the same hack ;)

gael
Post by Vincent Vanhoucke
Post by Mark Borgerding
Not directly an answer to your question, but a possible resolution (on a
linux or unix-like system anyway) ...
Would it help to build your shared object binaries with
-fvisibility=hidden, so the contained library is not visible outside the
.so? Thus no name collisions.
This might fail if you need the public interface to use the eigen ABI.
-- Mark
Post by Robert Lupton the Good
We've been using eigen (at a lowish level) for quite a time in a large
astronomical software project, the LSST, and now have the desire to include
a semi-external package; both use eigen.
Post by Robert Lupton the Good
For packaging reasons the semi-external package would like to include
its own copy of the eigen headers (probably as a sub-module from git), so
we potentially have two copies of eigen in the same dynamically-loaded
package (both imported into python). We're worried about ABI/API issues as
eigen evolves in interesting ways.
Post by Robert Lupton the Good
One way to fix this would be to include eigen in different namespaces
(maybe anonymous?) in the two packages, but I don't think that this is
possible due to eigen's use of the STL. Is there any way to do this now?
Or alternatively would it be crazy to restructure the eigen includes to
allow us to include a header outside our namespace that pulls in the STL,
and then the "real" eigen headers inside our namespace?
Post by Robert Lupton the Good
R
Stephen McDowell
2018-04-06 14:23:27 UTC
Permalink
Hi Robert,

I believe others will have better suggestions, but in my experience you should seek to have only one copy of Eigen if you can. For this external project you are bringing in, you can patch their build system so you can specify it manually. For example, if project Foo is doing something like

target_include_directories(foo PUBLIC hardcoded/path/to/internal/Eigen)

You can add a simple change that lets your parent project specify it instead:

if (NOT FOO_EIGEN_INCLUDE_DIRS)
target_include_directories(foo PUBLIC hardcoded/path/to/internal/Eigen)
else()
target_include_idrectories(foo PUBLIC ${FOO_EIGEN_INCLUDE_DIRS})
endif()

Then in your parent CMakeLists.txt you can

set(FOO_EIGEN_INCLUDE_DIRS “the/path/you/need” CACHE STRING “ “ FORCE)

I’d be willing to bet this patch would be accepted by project Foo, since it also lets users explicitly specify from the command line `cmake .. -DFOO_EIGEIN_INCLUDE_DIRS=“/their/desired/path”`.

For the same reason, adding the same bypass for your LSST project might be a good idea (?)

Hope that is useful!

-Stephen
Loading...