exiv2 icon indicating copy to clipboard operation
exiv2 copied to clipboard

Exiv2 compatibility 32-bit Debian 10 GCC 8.3 (undefined reference to std::filesystem)

Open QuietLullaby opened this issue 3 years ago • 6 comments

Hi,

Another issue came up after installing exiv2 on Debian 10 with GCC 8.3 (even if tests failed on #2134, I can still install and link up to the lib).

When compiling against libexiv2.so, following errors occurred :

path/to/libexiv2.so: undefined reference to std::filesystem::current_pathabi:cxx11 path/to/libexiv2.so: undefined reference to std::filesystem::__cxx11::path::_M_split_cmpts() path/to/libexiv2.so: undefined reference to std::filesystem::__cxx11::path::has_root_directory() const path/to/libexiv2.so: undefined reference to std::filesystem::__cxx11::path::has_filename() const path/to/libexiv2.so: undefined reference to std::filesystem::remove(std::filesystem::__cxx11::path const&) path/to/libexiv2.so: undefined reference to std::filesystem::status(std::filesystem::__cxx11::path const&) path/to/libexiv2.so: undefined reference to std::filesystem::rename(std::filesystem::__cxx11::path const&, std::filesystem::__cxx11::path

As stated in #2101 by @piponazo :

I forgot to mention one thing. On 32-bit OS, GCC 8.3 has a bug where std::filesystem does not work with larger than 2GB files. This was fixed with 8.4 I don't know if that's relevant. Debian 10 comes with GCC 8.3.

Definitely it is good to know. I'm adding this link for future reference in case this bites us in the future: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91947 Originally posted by @piponazo in https://github.com/Exiv2/exiv2/issues/2101#issuecomment-1042667647

Can it be handled ?

Thanks for your time and the incredible job you're doing

Regards, Jérémy

QuietLullaby avatar Mar 09 '22 10:03 QuietLullaby

missing link to lstdc++fs.

edit: on a sidenote, I tried everything possible with Debian 10 to get 64-bit std::filesystem working on a 32-bit system. Even swapping out libstdc++ for libc++. No luck. I suggest switching to a 64-bit OS. Or Debian 11 which fixes this bug.

neheb avatar Mar 10 '22 02:03 neheb

Hi @QuietLullaby , could you give more details about how you are consuming Exiv2? Are you trying to compile the project from scratch? Are you trying to consume the exvi2 library in other project?

With the work we did in #2101 , the new CMake file should add the needed INTERACE_LINK_LIBRARIES to link against the needed libraries when you consume exiv2 via CMake. However, I just noticed that we are adding:

target_link_libraries(exiv2 PRIVATE std::filesystem)

For the application target and maybe we should also do it for the library target:

target_link_libraries(exiv2lib PUBLIC std::filesystem)

piponazo avatar Mar 10 '22 08:03 piponazo

Hi,

I am building the project from sources with cmake (should I use the source archive available on exiv2.org ?). I followed these instructions :

git clone https://github.com/Exiv2/exiv2.git                  # i.e. main branch
cd exiv2
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
ctest --verbose
cmake --install .

After this, i am compiling my app with make (not cmake) so I added reference to the lib while compiling (compiling like $ g++ -std=c++17 myprog.cpp -o myprog -I/usr/local/include -L/usr/local/lib -lexiv2

NB : As a side note, the last command in README to install on unix-like system might be wrong. I think this should target current build directory : cmake --install . and not cmake --install

QuietLullaby avatar Mar 10 '22 08:03 QuietLullaby

Alright, then you are able to compile exiv2 with our CMake code but you have a problem when trying to link against the exvi2 library. As @neheb pointed out, you are missing the linking againt lstdc++fs (probably you just need to add -llstdc++fs to your compilation call.

Anyways, I would like to keep your issue open and check somehow that other projects can consume Exiv2 properly via CMake.

piponazo avatar Mar 10 '22 09:03 piponazo

In fact, I was already linking to lstdc++fs with -lstdc++fs but I am using a cross compiler that is based on gcc 7.4.1 and doesn't know of std::filesystem but std::experimental::filesystem 🤦‍♂️ I should have seen it from the very beginning of this problem ... I am now trying to get a new cross compiler on gcc-8 because I can't install a new gcc on my device ...

Thanks for the help and sorry for the time you took to answer a not really related exiv2 issue

QuietLullaby avatar Mar 10 '22 09:03 QuietLullaby

Ah right. std::filesystem support begins with GCC 8.

neheb avatar Mar 10 '22 09:03 neheb

@piponazo you think there's any point in adding std::experimental::filesystem support?

neheb avatar Jan 27 '23 23:01 neheb

I think the point is to avoid this situations in which some compilers versions have partial C++17 support but they do not bring the "standard" filesystem support. cmake/FindFilesystem.cmake is taking care of checking if std::filesystem or std::experimental::filesystem needs to be used on your system. From my point of view, that will help Exiv2 users with old gcc versions to be able to compile the project with CMake without issues (if the old gcc versions still support the rest of C++17 features we are using in the project)

piponazo avatar Jan 29 '23 07:01 piponazo

I think the point is to avoid this situations in which some compilers versions have partial C++17 support but they do not bring the "standard" filesystem support. cmake/FindFilesystem.cmake is taking care of checking if std::filesystem or std::experimental::filesystem needs to be used on your system. From my point of view, that will help Exiv2 users with old gcc versions to be able to compile the project with CMake without issues (if the old gcc versions still support the rest of C++17 features we are using in the project)

It does not seem to be doing a great job. Built just broke with 0.28 using GCC 7.5.0 on Ubuntu.

$ build/test/exiv2-0.28.0-Source/build# cmake ..
CMake Error at cmake/FindFilesystem.cmake:246 (message):
  Cannot run simple program using std::filesystem
Call Stack (most recent call first):
  cmake/findDependencies.cmake:38 (find_package)
  CMakeLists.txt:81 (include)


-- Configuring incomplete, errors occurred!

The culprit seems to be https://github.com/Exiv2/exiv2/blob/main/cmake/findDependencies.cmake#L38 thus, making the following a temporary hack which works:


--- a/cmake/findDependencies.cmake
+++ b/cmake/findDependencies.cmake
@@ -35,7 +35,7 @@ if (NOT Python3_Interpreter_FOUND)
     message(WARNING "Python3 was not found. Python tests under the 'tests' folder will not be executed")
 endif()

-find_package(Filesystem REQUIRED)
+find_package(Filesystem COMPONENTS Experimental REQUIRED)

kamiccolo avatar Jul 04 '23 08:07 kamiccolo

Yeah needs to be fixed in PR. Current CI does not test CMake with GCC7

neheb avatar Jul 04 '23 11:07 neheb

Fixed and backported

neheb avatar Jul 19 '23 18:07 neheb