libpcap icon indicating copy to clipboard operation
libpcap copied to clipboard

VERSION file causes an error when building software that includes <version> and searches libpcap source directory for headers with a case-insensitive file system

Open KrawMire opened this issue 1 year ago • 16 comments

I suppose this error only happens on MacOS. When I use libpcap in my project and link it and try to compile it using CMake, it fails with error:

lib/third_party/libpcap/version:1:1: error: expected unqualified-id

As I understood, MacOS compiler is trying to use this file as simple code file because the problem is caused by this:

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk/usr/include/c++/v1/iostream:38:.

Also, I can say that this could be fixed by renaming VERSION file to VERSION.txt and changing line 552 in CMakeLists.txt from this:

file(STRINGS ${pcap_SOURCE_DIR}/VERSION

to this

file(STRINGS ${pcap_SOURCE_DIR}/VERSION.txt

KrawMire avatar Jul 06 '24 20:07 KrawMire

It does not happen when building libpcap by itself with CMake, using the Ninja generator and the Ninja build tool. Perhaps there's something in the way you're including it. What generator are you using? Make, Ninja, or Xcode?

guyharris avatar Jul 06 '24 21:07 guyharris

It does not happen when building libpcap by itself with CMake, using the Ninja generator and the Ninja build tool. Perhaps there's something in the way you're including it. What generator are you using? Make, Ninja, or Xcode?

Thanks for advice! I am using Ninja, so I will check my CMakeLists again

KrawMire avatar Jul 07 '24 11:07 KrawMire

As I understood, it is a common bug for case-insensitive OS. Compiler tries to find version header file and takes VERSION. If you change VERSION file to VERSION.txt or something else, it will search this header file in another place.

For example, I found such discussions: https://github.com/nmap/nmap/issues/2747 https://groups.google.com/g/tesseract-ocr/c/MpCZe5wRYQE

So, the only workaround is to rename this file if you use case-insensitive OS, such as MacOS

KrawMire avatar Jul 07 '24 16:07 KrawMire

This is not a problem when trying to build libpcap.

It's a problem when trying to build other software that has #include <version> and that, for some reason, heppens to have the libpcap source directory in the include path.

Is there some reason why whatever software you're trying to build has the libpcap source directory in its include path?

guyharris avatar Jul 07 '24 18:07 guyharris

https://github.com/nmap/nmap/issues/2747

Nmap, for some unknown reason, has its own version of libpcap in its source code, and searches in the libpcap source directory for headers. That should be cleaned up by the Nmap developers.

guyharris avatar Jul 07 '24 22:07 guyharris

https://groups.google.com/g/tesseract-ocr/c/MpCZe5wRYQE

For some unknown reason, the build process is looking for header files in the top-level source directory. They need to fix it not to do so.

guyharris avatar Jul 07 '24 22:07 guyharris

Honestly, I am new to C++ and currently I and trying to learn it. I am really sorry for some misunderstanding. But I followed other developers' "best practices" and saw that they often include sources of external libraries into their own projects. How can you suggest to add a library to a project?

KrawMire avatar Jul 07 '24 22:07 KrawMire

In what fashion does your project use libpcap?

If it just compiles and links with libpcap, there's no reason to include the entire libpcap project source into your own project - you don't need libpcap source for your project, you just need to have libpcap's include file and libraries available.

guyharris avatar Jul 07 '24 22:07 guyharris

I have created git submodule inside my repository to copy all of libpcap source files. Thank you for your advice, I will try it!

KrawMire avatar Jul 07 '24 22:07 KrawMire

@KrawMire

I suppose this error only happens on MacOS.

On Windows too. I reported the same issue back in 2021.

gvanem avatar Jul 08 '24 16:07 gvanem

@gvanem oh, really, didn't notice your issue, sorry. As I see, there is no updates related to it, right?

KrawMire avatar Jul 08 '24 16:07 KrawMire

As that issue says:

The complication seems to be caused by providing the full libpcap source tree to a 3rd-party build process.

I suggested restructuring the source directory for libpcap to put all include files in a separate directory, so that those who, for whatever reason, insist on pointing their source tree at a libpcap source tree rather than installed headers, can do so without being at risk of picking up files that aren't public headers.

That's not going to happen in a 1.10.x release, however.

guyharris avatar Jul 08 '24 18:07 guyharris

In most use cases the best practice is to link, either dynamically or statically, with libpcap, but not to depend on libpcap source other than the public headers. If the build dependency is correctly satisfied this way, the VERSION and similar files are not present.

In less common use cases that genuinely demand a full copy of libpcap source (with or without modifications) the expectation is that the project developers know very well what they are doing and arrange the include paths in a way that does not trigger side effects on case-insensitive file systems.

This way, the current behaviour sometimes serves as an indicator that a project that uses libpcap may be not structured correctly, so keeping the tree source could the way it is now seems a sound alternative to restructuring.

infrastation avatar Jul 22 '24 22:07 infrastation

In less common use cases that genuinely demand a full copy of libpcap source (with or without modifications) the expectation is that the project developers know very well what they are doing and arrange the include paths in a way that does not trigger side effects on case-insensitive file systems.

The first project that should fix this is a project called "tcpdump". :-)

If you're building against an installed libpcap, no problem, but if you're building against a libpcap downloaded into a directory at the same level as the tcpdump directory, it tries searching in the libpcap source directory before searching in system source directories (so that it gets the downloaded-and-built libpcap rather than the system libpcap).

Fortunately, it's not written in C++ and doesn't include anything that tries including <version>, so it doesn't have a problem, but if we want tell uses to arrange the include paths in that fashion, we should figure out how to allow a program to build against a private libpcap build directory without getting the wrong <version>.

guyharris avatar Jul 23 '24 06:07 guyharris

It seems to me that #include (no .h) is the part that's broken.

mcr avatar Jul 23 '24 16:07 mcr

It seems to me that #include (no .h) is the part that's broken.

The ".h" in header file names is a convention, rather than an absolute requirement. In C code, header files all seem to be given .h names; for some reason, some header files for C++ aren't given extensions, and LLVM's libcpp, which Apple's SDKs use as the C++ library, has a header file named just "version".

guyharris avatar Jul 23 '24 18:07 guyharris

#1043 is an earlier discussion of the same problem.

infrastation avatar Nov 10 '24 23:11 infrastation