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

Build error: undefined reference to `std::filesystem::status(std::filesystem::__cxx11::path const&)' #842

Closed
rfalke opened this issue Aug 20, 2020 · 13 comments · Fixed by #846

Comments

@rfalke
Copy link

rfalke commented Aug 20, 2020

cmake output

-- Capstone: using remote Capstone revision.
-- LLVM: using remote LLVM revision.
-- YARA: using remote YARA revision.
-- YaraMod: using remote YaraMod revision.
-- -- Library stdc++fs NOT FOUND -> linking utils without stdc++fs library
-- Configuring done
-- Generating done
-- Build files have been written to: ....

make output

$ make
[  1%] Built target capstone-project
[  2%] Built target llvm-project
[  2%] Built target tinyxml2
[  3%] Built target yara
[  4%] Built target yaramod-project
[  6%] Built target utils
[  6%] Built target ar-extractor
[  6%] Linking CXX executable retdec-ar-extractor
/usr/bin/ld: CMakeFiles/ar-extractortool.dir/ar_extractor.cpp.o: in function `processArguments(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)':
ar_extractor.cpp:(.text+0x135c): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
/usr/bin/ld: ar_extractor.cpp:(.text+0x1369): undefined reference to `std::filesystem::status(std::filesystem::__cxx11::path const&)'
/usr/bin/ld: ../ar-extractor/libretdec-ar-extractor.a(archive_wrapper.cpp.o): in function `retdec::ar_extractor::ArchiveWrapper::extract(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const':
archive_wrapper.cpp:(.text+0x3a92): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
/usr/bin/ld: archive_wrapper.cpp:(.text+0x3a9a): undefined reference to `std::filesystem::status(std::filesystem::__cxx11::path const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [src/ar-extractortool/CMakeFiles/ar-extractortool.dir/build.make:123: src/ar-extractortool/retdec-ar-extractor] Error 1
make[1]: *** [CMakeFiles/Makefile2:631: src/ar-extractortool/CMakeFiles/ar-extractortool.dir/all] Error 2
make: *** [Makefile:130: all] Error 2
$
@miz2019
Copy link

miz2019 commented Aug 21, 2020

try this, it save me from similar error.
in src/utils/CMakeLists.txt

 # We may need to link filesystem library manually.      
 find_library(STD_CPP_FS stdc++fs)                       
-if (STD_CPP_FS)                                         
+if (STD_CPP_FS OR true)                                 
        message("-- Linking with ${STD_CPP_FS} library") 
        target_link_libraries(utils                      
                PRIVATE                                

@s3rvac
Copy link
Member

s3rvac commented Aug 21, 2020

Thank you for the report. Could you please provide more details about the platform on which the reported error occurs? We would like to be able to reproduce the issue. Based on the output, it seems to be Linux. Which distribution and version do you run?

@rfalke
Copy link
Author

rfalke commented Aug 21, 2020

The linux is "Fedora release 29 (Twenty Nine)". Yeah it is a bit older. But cmake didn't complain. So it should build.

g++ (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)

@rfalke
Copy link
Author

rfalke commented Aug 21, 2020

try this, it save me from similar error.
in src/utils/CMakeLists.txt

 # We may need to link filesystem library manually.      
 find_library(STD_CPP_FS stdc++fs)                       
-if (STD_CPP_FS)                                         
+if (STD_CPP_FS OR true)                                 
        message("-- Linking with ${STD_CPP_FS} library") 
        target_link_libraries(utils                      
                PRIVATE                                

I can confirm that this works. Thanks.

Maybe this can be included in master?!

@xkubov
Copy link
Contributor

xkubov commented Aug 21, 2020

Hi, this works only because you have forced linking with stdc++fs by making condition always true. This is, however, not a good solution as it would break compilation with GCC version >= 9 and clang. Is it possible that on fedora is stdc++fs included in the non-standard directory?

For example, this is a case for GCC 7 on ubuntu and so that's why we included a notice in README.md.

Note: RetDec requires a filesystem library. CMake will try to find the library in the system but on GCC 7 it might fail to do so. In that case, you must specify a path to the library:

-DCMAKE_LIBRARY_PATH=${PATH_TO_FILESTSTEM_DIR}, e.g. on GCC 7 stdc++fs is in -DCMAKE_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/.

Can you check the directory in which is stdc++fs located on your system?

@rfalke
Copy link
Author

rfalke commented Aug 21, 2020

I'm not sure how cmake detects stuff. By trying include or by linking against it or running?.

Anyway I did the following:

# locate stdc++fs
/usr/lib/gcc/x86_64-redhat-linux/8/libstdc++fs.a
/usr/lib/gcc/x86_64-redhat-linux/8/32/libstdc++fs.a
# rpm -qf /usr/lib/gcc/x86_64-redhat-linux/8/libstdc++fs.a
libstdc++-devel-8.3.1-2.fc29.x86_64
# rpm -ql libstdc++-devel-8.3.1-2.fc29.x86_64 | grep -i fs
/usr/include/c++/8/bits/fs_dir.h
/usr/include/c++/8/bits/fs_fwd.h
/usr/include/c++/8/bits/fs_ops.h
/usr/include/c++/8/bits/fs_path.h
/usr/include/c++/8/bits/fstream.tcc
/usr/include/c++/8/experimental/bits/fs_dir.h
/usr/include/c++/8/experimental/bits/fs_fwd.h
/usr/include/c++/8/experimental/bits/fs_ops.h
/usr/include/c++/8/experimental/bits/fs_path.h
/usr/include/c++/8/fstream
/usr/lib/gcc/x86_64-redhat-linux/8/libstdc++fs.a
# ls -F /usr/lib/gcc/x86_64-redhat-linux/8
32/
crtbegin.o
crtbeginS.o
crtbeginT.o
crtend.o
crtendS.o
crtfastmath.o
crtoffloadbegin.o
crtoffloadend.o
crtoffloadtable.o
crtprec32.o
crtprec64.o
crtprec80.o
include/
libasan_preinit.o
libasan.so
libatomic.so
libgcc.a
libgcc_eh.a
libgcc_s.so@
libgcov.a
libgomp.a
libgomp.so@
libgomp.spec
libitm.spec
liblsan_preinit.o
liblsan.so
libmpx.so
libmpx.spec
libmpxwrappers.so
libquadmath.so
libsanitizer.spec
libstdc++fs.a
libstdc++.so@
libtsan_preinit.o
libtsan.so
libubsan.so
plugin/
rpmver
#

From https://stackoverflow.com/questions/9922949/how-to-print-the-ldlinker-search-path:

# g++ -Xlinker --verbose  2>/dev/null | grep SEARCH | sed 's/SEARCH_DIR("=\?\([^"]\+\)"); */\1\n/g'  | grep -vE '^$'
/usr/x86_64-redhat-linux/lib64
/usr/lib64
/usr/local/lib64
/lib64
/usr/x86_64-redhat-linux/lib
/usr/local/lib
/lib
/usr/lib
#

I hope this helps.

@xkubov
Copy link
Contributor

xkubov commented Aug 21, 2020

Can you verify that the current master builds if you add -DCMAKE_LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/8/ as a parameter to the cmake?

The problem seems to be the same as on Ubuntu Bionic. GCC can locate the stdc++fs library but cmake not because it is located in a non-standard path (or at least non-standard to cmake).

@rfalke
Copy link
Author

rfalke commented Aug 22, 2020

I can confirm it builds.

I'm still confused about
-- -- Library stdc++fs NOT FOUND -> linking utils without stdc++fs library from the top of the issue. Either the library is not found in the standard place and the code can work without it somehow (a version in bundled with retdec or whatever) OR the library is required and if not found cmake should fail early (not not make later). In the later case a helpful error message about non-standard places and CMAKE_LIBRARY_PATH would be nice.

@xkubov
Copy link
Contributor

xkubov commented Aug 24, 2020

Well, Retdec requires <filesystem> from c++17. The problem, however, is in the implementation of this feature in compilers.

On macOS and Windows, there is no problem. If you provide a compiler on those systems with -std=c++17, then executable is linked with all filesystem functions if required. Note, that library stdc++fs is not present on these systems.

With GCC, however, things are different. GCC included experimental implementation with version 7. To use the filesystem feature, you had to link executable with -lstdc++fs. In version 8 GCC, they included the full implementation of filesystem but still required linking with stdc++fs. GCC has dropped the requirement to link with stdc++fs since version 9. This means that GCC now behaves as compilers on macOS and Windows.

I didn't find anything about the future presence of this library on GCC websites, so that is why I decided that we should try to find the library in the system first and use it only if cmake finds it. This, however, seems not to work because cmake does not appear to be searching all the paths from which GCC loads libraries. At least on Ubuntu Bionic with GCC 7 and on Fedora 29 with GCC 8.

So I leave @PeterMatula to decide, but I think that the best solution now should be to check the system for stdc++fs and if not found and on Linux compiling with GCC, enforce cmake to link stdc++fs.

@rfalke
Copy link
Author

rfalke commented Aug 24, 2020

IMHO:

  • either do a version test for compiler==gcc and version is 7 or 8 OR
  • do a test (compile a small source file which uses some filesystem function, link, run) with and without -lstdc++fs. Fail if neither succeeds. This is the configure way.

But I will shut up now since retdec isn't my project and C++ is not my area of expertise.

@xkubov
Copy link
Contributor

xkubov commented Aug 24, 2020

  • either do a version test for compiler==gcc and version is 7 or 8 OR
  • do a test (compile a small source file which uses some filesystem function, link, run) with and without -lstdc++fs. Fail if neither succeeds. This is the configure way.

Hm, this is precisely what I wanted to avoid but If nothing better comes up I thing that we can implement something similiar to what you suggest. Thanks for your input on this matter. We will fix this ASAP.

@xkubov
Copy link
Contributor

xkubov commented Sep 1, 2020

This should be now fixed. In case of the error still occurring you can reopen this issue.

@rfalke
Copy link
Author

rfalke commented Sep 3, 2020

I can confirm that the fix in master works.

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

Successfully merging a pull request may close this issue.

5 participants