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

Add support for non-system usb library on Linux #36

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jlmuir
Copy link

@jlmuir jlmuir commented Jan 29, 2025

Add support for building against a usb library on Linux that is not a system library.

@MarkRivers
Copy link
Member

I have the same comment about this as I did about your asyn PR for tirpc. It is a slippery slope. There are lots of other EPICS modules that use libusb or libusb-1.0. Why do you have a PR for usb here, but not in asyn?

What is the reason for not installing usb as a system library?

Your PR has many instances like this:

ifdef USB_DIR
  test_measCompDiscover_LIBS_Linux += usb-1.0
else
  test_measCompDiscover_SYS_LIBS_Linux += usb-1.0
endif

That usually won't work if STATIC_BUILD=YES because the EPICS build system will look for a .a file, but often only a .so file exists. This can be worked around by always using SYS_LIBS. If USB_DIR is defined it will search there for SYS_LIBS and will correctly use the .so file. See the documented example here: https://github.com/areaDetector/ADSpinnaker/blob/0decb23f6602c88e775c11e67082b81535cd306c/iocs/spinnakerIOC/spinnakerApp/src/Makefile#L28

@jlmuir
Copy link
Author

jlmuir commented Feb 12, 2025

I have the same comment about this as I did about your asyn PR for tirpc. It is a slippery slope. There are lots of other EPICS modules that use libusb or libusb-1.0. Why do you have a PR for usb here, but not in asyn?

Hmm, because it wasn't revealed when I compiled asyn, so I didn't realize that asyn had a dependency on that.

What is the reason for not installing usb as a system library?

Same as for the asyn PR for tirpc.

Your PR has many instances like this:

ifdef USB_DIR
  test_measCompDiscover_LIBS_Linux += usb-1.0
else
  test_measCompDiscover_SYS_LIBS_Linux += usb-1.0
endif

That usually won't work if STATIC_BUILD=YES because the EPICS build system will look for a .a file, but often only a .so file exists. This can be worked around by always using SYS_LIBS. If USB_DIR is defined it will search there for SYS_LIBS and will correctly use the .so file. See the documented example here: https://github.com/areaDetector/ADSpinnaker/blob/0decb23f6602c88e775c11e67082b81535cd306c/iocs/spinnakerIOC/spinnakerApp/src/Makefile#L28

Interesting. I would say that that's a bug for the .a file to not exist when you're doing a static build. But I accept that doing what you describe is a workaround that's needed, so I can update this PR to do that. Are you likely to accept the PR if I do that?

@MarkRivers
Copy link
Member

Hmm, because it wasn't revealed when I compiled asyn, so I didn't realize that asyn had a dependency on that.

That is because by default when linking a library on Linux it does not actually check the dependent libraries to make sure the symbols exist. So on Linux you can omit the LIB_LIBS libraries and not get an error. But on Windows you will get an error, because it does check when linking DLLs.

Interesting. I would say that that's a bug for the .a file to not exist when you're doing a static build.

.a files no longer exist for system libraries on Linux, but we can still build static binaries that use them. Similarly, many vendors distribute Linux libraries for their devices, but typically only .so files, not .a files. When building a static executable those need to be listed in SYS_LIBS, not _LIBS.

@MarkRivers
Copy link
Member

Are you likely to accept the PR if I do that?

Yes, I understand the rationale. There are lots of places where those comments in Makefiles (and CONFIG_SITE files) will be needed if you want to be consistent. The user still needs to edit files to enable non-system locations, but at least they are just removing comment characters.

@jlmuir
Copy link
Author

jlmuir commented Feb 13, 2025

Re using SYS_LIBS instead of LIBS so that a static build will work, I tried it, but it didn't work on RHEL 9. The -L$(USB_LIB) doesn't get added to the /usr/bin/g++ -o measCompApp [...] command, so it fails with the following:

/usr/bin/ld: cannot find -lusb-1.0
collect2: error: ld returned 1 exit status

@jlmuir jlmuir force-pushed the add-non-system-usb-library-support branch from 6307599 to a331eda Compare February 13, 2025 00:22
@jlmuir
Copy link
Author

jlmuir commented Feb 13, 2025

I force-pushed to this PR the change that I thought was what you were suggesting that doesn't work to make sure we're on the same page.

@MarkRivers
Copy link
Member

When you build usb-1.0 locally does it produce both a .so and a .a file? If you go back to _LIBS rather than _SYS_LIBS does a static build work?

@jlmuir
Copy link
Author

jlmuir commented Feb 13, 2025

When you build usb-1.0 locally does it produce both a .so and a .a file?

Yes:

$ cd /opt/pkg-2024Q4/lib
$ ls -l libusb-*
-rw-r--r-- 1 root root 214132 Jan 29 08:12 libusb-1.0.a
-rwxr-xr-x 1 root root    976 Jan 29 08:12 libusb-1.0.la
lrwxrwxrwx 1 root root     19 Jan 29 08:12 libusb-1.0.so -> libusb-1.0.so.0.4.0
lrwxrwxrwx 1 root root     19 Jan 29 08:12 libusb-1.0.so.0 -> libusb-1.0.so.0.4.0
-rwxr-xr-x 1 root root 145280 Jan 29 08:12 libusb-1.0.so.0.4.0

If you go back to _LIBS rather than _SYS_LIBS does a static build work?

I added STATIC_BUILD=YES to configure/CONFIG_SITE.local and ran make. The build completes successfully, but I have very little experience with static builds, and file reports that the binaries are dynamically linked, not statically linked, so I think I must be doing something wrong:

$ file bin/linux-x86_64/*
bin/linux-x86_64/measCompApp:           ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=fc18e8b120509b5d506672bafe8560269231c79a, for GNU/Linux 3.2.0, with debug_info, not stripped
bin/linux-x86_64/testDualEthDevice:     ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f1b6089fe69ce36c9f8a5a08ce6067cd8779a3ae, for GNU/Linux 3.2.0, with debug_info, not stripped
bin/linux-x86_64/test_measCompDiscover: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9dcc2c3e46e404744d9682c241e5014c0873806c, for GNU/Linux 3.2.0, with debug_info, not stripped

@MarkRivers
Copy link
Member

Run ldd on both dynamically and statically built versions and see what libraries they depend on.

@jlmuir
Copy link
Author

jlmuir commented Feb 13, 2025

With STATIC_BUILD=YES:

$ ldd bin/linux-x86_64/*
bin/linux-x86_64/measCompApp:
        linux-vdso.so.1 (0x00007ffc6affe000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fcd59e00000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fcd59d25000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fcd5a0d5000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fcd59a00000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fcd5a0f9000)
bin/linux-x86_64/testDualEthDevice:
        linux-vdso.so.1 (0x00007fffa4db7000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f5ba8600000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f5ba88e9000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f5ba88ce000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f5ba8200000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f5ba89cd000)
bin/linux-x86_64/test_measCompDiscover:
        linux-vdso.so.1 (0x00007ffd37ee4000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f2e23000000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f2e22f25000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f2e2326d000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f2e22c00000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f2e23291000)

Without STATIC_BUILD=YES:

$ ldd bin/linux-x86_64/*
bin/linux-x86_64/measCompApp:
        linux-vdso.so.1 (0x00007ffd2e169000)
        libmeasComp.so => /opt/epics-meascomp-4.3/lib/linux-x86_64/libmeasComp.so (0x00007fc21cb78000)
        libscaler.so => /opt/epics-scaler-4.1/lib/linux-x86_64/libscaler.so (0x00007fc21cb67000)
        libbusy.so => /opt/epics-busy-1.7.4/lib/linux-x86_64/libbusy.so (0x00007fc21cb5b000)
        libcalc.so => /opt/epics-calc-3.7.5/lib/linux-x86_64/libcalc.so (0x00007fc21cb13000)
        libmca.so => /opt/epics-mca-7.10/lib/linux-x86_64/libmca.so (0x00007fc21cb03000)
        libsscan.so => /opt/epics-sscan-2.11.6/lib/linux-x86_64/libsscan.so (0x00007fc21cad0000)
        libautosave.so => /opt/epics-autosave-5.11/lib/linux-x86_64/libautosave.so (0x00007fc21caa7000)
        libasyn.so => /opt/epics-asyn-4.45/lib/linux-x86_64/libasyn.so (0x00007fc21c9e8000)
        libseq.so => /opt/epics-sequencer-2.2.9/lib/linux-x86_64/libseq.so (0x00007fc21c9d6000)
        libpv.so => /opt/epics-sequencer-2.2.9/lib/linux-x86_64/libpv.so (0x00007fc21c9cf000)
        libdbRecStd.so.3.23.1 => /opt/epics-7.0.8.1/lib/linux-x86_64/libdbRecStd.so.3.23.1 (0x00007fc21c987000)
        libdbCore.so.3.23.1 => /opt/epics-7.0.8.1/lib/linux-x86_64/libdbCore.so.3.23.1 (0x00007fc21c8ec000)
        libca.so.4.14.4 => /opt/epics-7.0.8.1/lib/linux-x86_64/libca.so.4.14.4 (0x00007fc21c888000)
        libCom.so.3.23.1 => /opt/epics-7.0.8.1/lib/linux-x86_64/libCom.so.3.23.1 (0x00007fc21c80a000)
        libuldaq.so.1 => /opt/uldaq-1.2.1/lib/libuldaq.so.1 (0x00007fc21c400000)
        libusb-1.0.so.0 => /opt/pkg-2024Q4/lib/libusb-1.0.so.0 (0x00007fc21c7e9000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fc21c000000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fc21c325000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fc21c7c7000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fc21bc00000)
        libtirpc.so.3 => /opt/pkg-2024Q4/lib/libtirpc.so.3 (0x00007fc21c794000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fc21cba9000)
        libgssapi.so.3 => /opt/pkg-2024Q4/lib/libgssapi.so.3 (0x00007fc21c2e2000)
        libheimntlm.so.0 => /opt/pkg-2024Q4/lib/libheimntlm.so.0 (0x00007fc21c789000)
        libkrb5.so.26 => /opt/pkg-2024Q4/lib/libkrb5.so.26 (0x00007fc21c24b000)
        libhx509.so.5 => /opt/pkg-2024Q4/lib/libhx509.so.5 (0x00007fc21bfb1000)
        libwind.so.0 => /opt/pkg-2024Q4/lib/libwind.so.0 (0x00007fc21bf87000)
        libsqlite3.so.0 => /opt/pkg-2024Q4/lib/libsqlite3.so.0 (0x00007fc21be23000)
        libz.so.1 => /opt/pkg-2024Q4/lib/libz.so.1 (0x00007fc21c231000)
        libhcrypto.so.4 => /opt/pkg-2024Q4/lib/libhcrypto.so.4 (0x00007fc21bbc3000)
        libasn1.so.8 => /opt/pkg-2024Q4/lib/libasn1.so.8 (0x00007fc21bb15000)
        libcom_err.so.1 => /opt/pkg-2024Q4/lib/libcom_err.so.1 (0x00007fc21c781000)
        libheimbase.so.1 => /opt/pkg-2024Q4/lib/libheimbase.so.1 (0x00007fc21be11000)
        libcrypto.so.3 => /opt/pkg-2024Q4/lib/libcrypto.so.3 (0x00007fc21b400000)
        libroken.so.18 => /opt/pkg-2024Q4/lib/libroken.so.18 (0x00007fc21bafd000)
        libcrypt.so.2 => /lib64/libcrypt.so.2 (0x00007fc21bac3000)
bin/linux-x86_64/testDualEthDevice:
        linux-vdso.so.1 (0x00007ffd87762000)
        libuldaq.so.1 => /opt/uldaq-1.2.1/lib/libuldaq.so.1 (0x00007f6728c00000)
        libusb-1.0.so.0 => /opt/pkg-2024Q4/lib/libusb-1.0.so.0 (0x00007f67290bc000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f6728800000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f6728fda000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f6728fbf000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f6728400000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f67290dd000)
bin/linux-x86_64/test_measCompDiscover:
        linux-vdso.so.1 (0x00007ffd99ee7000)
        libmeasComp.so => /opt/epics-meascomp-4.3/lib/linux-x86_64/libmeasComp.so (0x00007fe4f6d1f000)
        libdbRecStd.so.3.23.1 => /opt/epics-7.0.8.1/lib/linux-x86_64/libdbRecStd.so.3.23.1 (0x00007fe4f6cd7000)
        libdbCore.so.3.23.1 => /opt/epics-7.0.8.1/lib/linux-x86_64/libdbCore.so.3.23.1 (0x00007fe4f6c3c000)
        libca.so.4.14.4 => /opt/epics-7.0.8.1/lib/linux-x86_64/libca.so.4.14.4 (0x00007fe4f6bd8000)
        libCom.so.3.23.1 => /opt/epics-7.0.8.1/lib/linux-x86_64/libCom.so.3.23.1 (0x00007fe4f6b58000)
        libuldaq.so.1 => /opt/uldaq-1.2.1/lib/libuldaq.so.1 (0x00007fe4f6600000)
        libusb-1.0.so.0 => /opt/pkg-2024Q4/lib/libusb-1.0.so.0 (0x00007fe4f6b39000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fe4f6200000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fe4f6a57000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe4f6a3c000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fe4f5e00000)
        libasyn.so => /opt/epics-asyn-4.45/lib/linux-x86_64/libasyn.so (0x00007fe4f6541000)
        libseq.so => /opt/epics-sequencer-2.2.9/lib/linux-x86_64/libseq.so (0x00007fe4f6a28000)
        libpv.so => /opt/epics-sequencer-2.2.9/lib/linux-x86_64/libpv.so (0x00007fe4f6a23000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fe4f6d50000)
        libtirpc.so.3 => /opt/pkg-2024Q4/lib/libtirpc.so.3 (0x00007fe4f69f0000)
        libgssapi.so.3 => /opt/pkg-2024Q4/lib/libgssapi.so.3 (0x00007fe4f69ad000)
        libheimntlm.so.0 => /opt/pkg-2024Q4/lib/libheimntlm.so.0 (0x00007fe4f69a2000)
        libkrb5.so.26 => /opt/pkg-2024Q4/lib/libkrb5.so.26 (0x00007fe4f64aa000)
        libhx509.so.5 => /opt/pkg-2024Q4/lib/libhx509.so.5 (0x00007fe4f645b000)
        libwind.so.0 => /opt/pkg-2024Q4/lib/libwind.so.0 (0x00007fe4f6431000)
        libsqlite3.so.0 => /opt/pkg-2024Q4/lib/libsqlite3.so.0 (0x00007fe4f609c000)
        libz.so.1 => /opt/pkg-2024Q4/lib/libz.so.1 (0x00007fe4f6986000)
        libhcrypto.so.4 => /opt/pkg-2024Q4/lib/libhcrypto.so.4 (0x00007fe4f605f000)
        libasn1.so.8 => /opt/pkg-2024Q4/lib/libasn1.so.8 (0x00007fe4f5d52000)
        libcom_err.so.1 => /opt/pkg-2024Q4/lib/libcom_err.so.1 (0x00007fe4f6980000)
        libheimbase.so.1 => /opt/pkg-2024Q4/lib/libheimbase.so.1 (0x00007fe4f604d000)
        libcrypto.so.3 => /opt/pkg-2024Q4/lib/libcrypto.so.3 (0x00007fe4f5800000)
        libroken.so.18 => /opt/pkg-2024Q4/lib/libroken.so.18 (0x00007fe4f6035000)
        libcrypt.so.2 => /lib64/libcrypt.so.2 (0x00007fe4f57c6000)

@jlmuir jlmuir force-pushed the add-non-system-usb-library-support branch from a331eda to 0bd3815 Compare February 16, 2025 22:19
@jlmuir
Copy link
Author

jlmuir commented Feb 16, 2025

Force-pushed to get back to what was tested last and what produced the with and without STATIC_BUILD=YES results reported above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants