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

Unable to remove linkage to xml, mDNS etc #921

Open
N0YKG opened this issue Dec 6, 2022 · 7 comments
Open

Unable to remove linkage to xml, mDNS etc #921

N0YKG opened this issue Dec 6, 2022 · 7 comments

Comments

@N0YKG
Copy link

N0YKG commented Dec 6, 2022

I am working in a very limited embedded system, and need libIIO to ONLY access local hardware. The development environment does not have some of the libraries, like XML or mDNS, so I need to build a version of libIIO that does not pull those libraries in.
However, it is not possible to do so, as it stands, due to the way the code is using the variables defined by CMake.

Right now, the code checks for the variables with a runtime test, e.g.
if (WITH_XML_BACKEND && strncmp(uri, "xml:", sizeof("xml:") - 1) == 0)
return iio_create_xml_context(uri + sizeof("xml:") - 1);

While this may prevent the RUNTIME call to iio_create_xml_context, this does NOT prevent linkage of the function, and thus the library will still be required to build and run.

The test really should be a compile time test, e.g.

+#if WITH_XML_BACKEND
if (strncmp(uri, "xml:", sizeof("xml:") - 1) == 0)
return iio_create_xml_context(uri + sizeof("xml:") - 1);

+#endif
So that if the function is disabled at compile time, the call to iio_create_xml_context won't exist, and won't be pulled in, so the libraries don't need to be there.

@pcercuei
Copy link
Contributor

pcercuei commented Dec 6, 2022

@N0YKG It does prevent linkage of the function, as long as your compiler is not stupid.

GCC, Visual Studio, Clang will remove the dead branch and the iio_create_xml_context function won't be linked.

@N0YKG
Copy link
Author

N0YKG commented Dec 6, 2022

I am using GCC, and it does NOT remove the call, hence why I am making the post. There is no reason to use a run time check - it will always be false or it will always be true. Optionality like this is one of the few places in modern C++ where using the preprocessor is still a good idea.

@pcercuei
Copy link
Contributor

pcercuei commented Dec 6, 2022

It does remove the call unless you compile with -O0 I think. If you compile with CMAKE_BUILD_TYPE=Debug, try RelWithDebInfo instead.

And no, these are not run-time checks, they are compile-time checks. Instead of hiding parts of the code with preprocessor guards we leave it to the compiler to remove the disabled code. The compiler then "sees" the whole code independently of the current configuration and bugs and build errors are subsequently much easier to catch.

@N0YKG
Copy link
Author

N0YKG commented Dec 7, 2022

No, I am compiling at -O2 and it is not removing the call.

It's a little annoying that you are assuming that I am not having a real problem, and dismissing my concerns out of hand. Believe me, I did exhaustive checks to try to find out why I could not remove the linkage to the libraries I didn't have before changing the code, as I have enough code to be responsible for without adding your code to that.

Using #if for compile time optionality and "if" for runtime optionality is a well established programming paradigm that is immediately understood by programmers, and immediately conveys to them the optionality of the code.

You should keep in mind that the goal of libIIO is to be used in embedded systems, where you a) cannot always have every library in the world available to use and b) cannot always choose to use the latest spiffiest compiler. That's the case I am in - an embedded system that has a vendor supplied toolset that I am not getting paid to replace with a custom built environment. I am presenting a simple change, one that follows standard programming paradigms, that solves a problem.
I am reaching the point where I really don't have a very good impression of this project, and really don't have the desire to continue. If you want to ignore valid feedback about the design patterns of your code, I really don't care - I'll just fork the code and note that we need to make the source available under the license terms.

@pcercuei
Copy link
Contributor

pcercuei commented Dec 7, 2022

Get off your high horse, you are not helping your case.

Libiio is used on hundreds of different product lines out there, most of which are embedded systems. Generally all of these only compile the local backend and never had your problem.

If you can't use a newer toolchain, then fork it and use preprocessor guards, like you said, because we're not going to do that. Using compile-time dead code removal like we do in Libiio is not uncommon in C programs, you just don't know about it. The Linux kernel uses it extensively, for instance, so if your toolchain can compile Linux, it should be able to compile Libiio.

@rgetz
Copy link
Contributor

rgetz commented Feb 24, 2023

@N0YKG what version of gcc are you using, and for what architecture?

I'm using gcc 10.2.1 for ARM (32-bit and 64-bit) and it does dead code reduction like Paul indicates.

@rgetz
Copy link
Contributor

rgetz commented Mar 12, 2023

If I build for x86:

mkdir wusb; cd wusb; cmake ../ && make

and then check for libusb:

objdump -x libiio.so.0 | grep usb | wc -l
48

There are 48 references to libusb (as expected).

When I turn USB off:

mkdir wusb; cd wusb; cmake ../ -DWITH_USB_BACKEND=0 && make

and check for references to libusb:

objdump -x libiio.so.0 | grep usb | wc -l
0

there are zero. This is the way that modern compilers work, and what we expect in a modern toolchain.
Mine is:

gcc --version
gcc (Debian 10.2.1-6) 10.2.1 20210110

Until we something different (what toolchain are you using?) - this is the way it's going to stay.

I think this can be closed for now.

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

No branches or pull requests

3 participants