如何手动禁用libstdc++在Cmake for Clang

发布于 2025-01-27 04:19:28 字数 6788 浏览 1 评论 0 原文

最近,我正在使用 cmake 和llvm clang 使用 Visual Studio Code 使用 clang clang clang clang clang clang clang >每个确切的对象或库会生成或取决于需要明确指定以进行或链接的需求。设计的程序应具有较高的RAM效率,对于未使用的数据段引起的最小漏洞和交叉兼容的安全性。

话虽如此,架构的配置库,应用程序二进制接口(又称ABI),C和C ++标准的标准库功能以及可执行的二进制二进制二进制需求手册设置用于工具链程序以适当的方式处理。

好吧,我认为,用libc ++库的libstdc ++替换是一个很好的“切入点”,但绝对不是直截了当的,您可能已经从其他地方有足够的痛苦实践中学到了足够多的东西,并认为这是一个糟糕的主意。 。但很抱歉,这已成为我的痴迷。我非常感谢您的帮助,然后它使我在这里发疯。

无论如何,以下是有关我本地计算机的信息列表:

  • ubuntu 20.04 @ v5.13.0-40基因内核,SMP,x86_64指令集
  • CMake 3.23.1,由源
  • GCC-10构建:AMD64
  • Clang-12: AMD64
  • LIBSTDC ++ -10-DEV:AMD64
  • LIBC ++ -12-DEV:AMD64

Clang可以从命令返回:

jacob.nielson@ubuntu~jul:clang ++ -12 -V -C -xc/dev/null

“

尽可能出乎意料且无关紧要的问题,我将项目目录布局尽可能简单,在制作cmakelists.txt:

https://s3.bmp.ovh/imgs/2022/05/05/06/3ebb5a1a1a1a1a08fa08fa08fa0274.4.plgng首先,我在Cmake的文档中查找了有关编译(预处理)或链接选项的文档:

-"-nostdinc"
-"-nostdinc++"
-"-nobuiltininc"
-"-nostdlib"
-"-nolibc"
-"-nostdlib++"
-"-nodefaultlibs"

中提出了一些简单的线条。

  cmake_minimum_required(VERSION 3.23.0)
  project(program VERSION 0.0.1)
  set(TARGET program)

  add_compile_options(-std=c++17)

  # I'm not sure about semantics of "-nostdinc++", "-nostdinc" and "-nobuiltininc". 
  # Should I add them all in case to substitute libstdc++ with libc++ or not in below?
  add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:-nobuiltininc>)
  add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:-nostdinc++>)
  add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:-nostdinc>)

  # Should I add path to system headers in "-isystem" option? 
  # Attention: cmake-generator-expression does not recognize white-space separated options group to be string. It is option "-isystem" where the path to directory as value follows without white-space in this example.
  add_compile_options(
      $<$<COMPILE_LANG_AND_ID:CXX,Clang>:-isystem/usr/include/x86_64-linux-gnu>
      $<$<COMPILE_LANG_AND_ID:CXX,Clang>:-isystem-after/usr/include>
      # "-cxx-isystem" option is legacy and is not appropriate for standard headers. Add path to the subdirectories where you put your own c++-only headers in your project.
      $<$<COMPILE_LANG_AND_ID:CXX,Clang>:-cxx-isystem ${...}>
  )

  # If C or/and C++ standard library is turned off like in above, Should I add path to libc++ headers in "-stdlib++-isystem" option?
  # Attention: cmake-generator-expression does not recognize white-space separated options group to be string. It is option "-stdlib++-isystem" where the path to directory as value follows without white-space in this example.
  add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:-stdlib++-isystem/usr/lib/llvm-12/include/c++/v1>) 

  # Replace default C++ standard with libc++.
  add_link_options(
      $<$<LINK_LANG_AND_ID:CXX,Clang>:-stdlib=libc++>
  )

  add_executable(${TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/source/${TARGET}.cpp")
  target_link_libraries(${TARGET} PRIVATE
      $<$<LINK_LANG_AND_ID:CXX,Clang>:c++> 
      $<$<LINK_LANG_AND_ID:CXX,Clang>:c++abi>
      $<$<LINK_LANG_AND_ID:CXX,Clang>:unwind>
      $<$<LINK_LANG_AND_ID:CXX,Clang>:ssl>
      $<$<LINK_LANG_AND_ID:CXX,Clang>:crypto>
      $<$<LINK_LANG_AND_ID:CXX,Clang>:pthread>
      )

然后我

在CMakelists =“ https://s3.bmp.ovh/imgs/2022/05/06/4e169b31361de09a.png” rel =“ nofollow noreferrer”> CMake Prompt

CMake parsed successfully:

” > cmakeccompiler.cmake 和 cmakecxxcompiler.cmake in ./ build> ./ build/cmakefiles/3.23.1/临时文件夹,后来包含几行:

    set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include/c++/10;/usr/include/x86_64-linux-gnu/c++/10;/usr/include/c++/10/backward;/usr/local/include;/usr/lib/llvm-12/lib/clang/12.0.0/include;/usr/include/x86_64-linux-gnu;/usr/include")
    set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;gcc_s;gcc;c;gcc_s;gcc")
    set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/10;/usr/lib/x86_64-linux-gnu;/usr/lib64;/lib/x86_64-linux-gnu;/lib64;/usr/lib;/usr/lib/llvm-12/lib;/lib")
    set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")

注意:clang:clang :clang:clang:clang使用启发式发现来搜索前端报告的目录中的标题。 这是不合适的,因为我只是不希望LIBSTDC ++的标题或库中隐式使用。

另外,它将编译命令导出到 compile_commands.json 如下:

/usr/bin/clang++-12 -DLIBCXXABI_USE_COMPILER_RT=YES -DLIBCXX_USE_COMPILER_RT=YES -I/data/solution/projects/program/include -std=c++17 -stdlib=libc++ -isystem /usr/include/x86_64-linux-gnu -stdlib++-isystem /usr/lib/llvm-12/include/c++/v1 -o CMakeFiles/program.dir/source/program.cpp.o -c /data/solution/projects/program/source/program.cpp

一切看起来都不错。但是当我使用LDD检查时:

jacob.nielson@ubuntu:/data/data/doady/projection/proginse/progress/build/debug $ ldd program

    linux-vdso.so.1 (0x00007ffee7190000)
    libc++.so.1 => /lib/x86_64-linux-gnu/libc++.so.1 (0x00007f69164a5000)
    libc++abi.so.1 => /lib/x86_64-linux-gnu/libc++abi.so.1 (0x00007f691646d000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f691628b000)     /* LIBSTDC++ in here! */
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f691613c000)               /* LIBM in here */
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f6916121000)       /* gcc startup file in here! */
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6915f2f000)               /* LIBC in here! */
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6915f0a000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f6915f00000)
    libatomic.so.1 => /lib/x86_64-linux-gnu/libatomic.so.1 (0x00007f6915ef6000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f691658d000)

看到所有libstdc ++,libc,libc,libm或libgcc_s仍然令人沮丧。我是否错过了静态链接它们的任何选择,例如gnu cc中的-Static -libc,还是我必须在此时早期放弃自己的野心?

Recently I'm configuring a new project in language C and C++ using both CMake and llvm Clang with Visual Studio Code for a program where EVERY exact object or library it generates or depends needs specifying explicitly to make or link against. The program by design should feature high RAM efficency, security for the least vulnerabilities induced by the unused data segments and cross-compilation.

That being said, the provision libraries for architecture, application binary interface (aka ABIs), standard libraries functions from C and C++ standard and executable binary need manual setup for toolchain program to process in appropriate manner.

Well, the libstdc++ substitution with libc++ library is what I think a good "entry point" to kick-off, but definitely not straight forward, which you might have learned enough from documented painful practices elsewhere and think of that as a bad idea...but I'm sorry, this has become my obsession. I really appreciate your help before it drives me nuts here.

Anyway, here is a list of information about my local machine in below:

  • Ubuntu 20.04 @ v5.13.0-40-generic kernel, SMP, x86_64 instruction-set
  • CMake 3.23.1, built from source
  • gcc-10:amd64
  • clang-12:amd64
  • libstdc++-10-dev:amd64
  • libc++-12-dev:amd64

Clang works fine to return from command:

jacob.nielson@ubuntu~$: clang++-12 -v -c -xc /dev/null

CLANG

to keep the new project from any future unexpected and irrelevant issue as much as possible, I leave the project directory layout as simple as it could be before making a CMakeLists.txt:

CLANG

To begin with, I looked up in CMake's document about either compiling (preprocessing) or linking options:

-"-nostdinc"
-"-nostdinc++"
-"-nobuiltininc"
-"-nostdlib"
-"-nolibc"
-"-nostdlib++"
-"-nodefaultlibs"

Then I come up with a few simple lines in the CMakeLists.txt:

  cmake_minimum_required(VERSION 3.23.0)
  project(program VERSION 0.0.1)
  set(TARGET program)

  add_compile_options(-std=c++17)

  # I'm not sure about semantics of "-nostdinc++", "-nostdinc" and "-nobuiltininc". 
  # Should I add them all in case to substitute libstdc++ with libc++ or not in below?
  add_compile_options(
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:-nobuiltininc>)
  add_compile_options(
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:-nostdinc++>)
  add_compile_options(
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:-nostdinc>)

  # Should I add path to system headers in "-isystem" option? 
  # Attention: cmake-generator-expression does not recognize white-space separated options group to be string. It is option "-isystem" where the path to directory as value follows without white-space in this example.
  add_compile_options(
      
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:-isystem/usr/include/x86_64-linux-gnu>
      
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:-isystem-after/usr/include>
      # "-cxx-isystem" option is legacy and is not appropriate for standard headers. Add path to the subdirectories where you put your own c++-only headers in your project.
      
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:-cxx-isystem ${...}>
  )

  # If C or/and C++ standard library is turned off like in above, Should I add path to libc++ headers in "-stdlib++-isystem" option?
  # Attention: cmake-generator-expression does not recognize white-space separated options group to be string. It is option "-stdlib++-isystem" where the path to directory as value follows without white-space in this example.
  add_compile_options(
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:-stdlib++-isystem/usr/lib/llvm-12/include/c++/v1>) 

  # Replace default C++ standard with libc++.
  add_link_options(
      
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:-stdlib=libc++>
  )

  add_executable(${TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/source/${TARGET}.cpp")
  target_link_libraries(${TARGET} PRIVATE
      
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:c++> 
      
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:c++abi>
      
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:unwind>
      
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:ssl>
      
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:crypto>
      
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:pthread>
      )

Next, I tried to generate "Unix Makefiles" for project:

CMake Prompt

CMake parsed successfully:

CMake Output

Meanwhile it generates CMakeCCompiler.cmake and CMakeCXXCompiler.cmake in ./build/CMakeFiles/3.23.1/ temporary folder, the later contains a few lines:

    set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include/c++/10;/usr/include/x86_64-linux-gnu/c++/10;/usr/include/c++/10/backward;/usr/local/include;/usr/lib/llvm-12/lib/clang/12.0.0/include;/usr/include/x86_64-linux-gnu;/usr/include")
    set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;gcc_s;gcc;c;gcc_s;gcc")
    set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/10;/usr/lib/x86_64-linux-gnu;/usr/lib64;/lib/x86_64-linux-gnu;/lib64;/usr/lib;/usr/lib/llvm-12/lib;/lib")
    set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")

Note: Clang uses heuristic discovery to search headers in directories which are reported by front-end.
This is inappropriate because I just don't want either headers or libraries of libstdc++ to be implicitly used within the project.

Also, it exports compile commands into compile_commands.json as below:

/usr/bin/clang++-12 -DLIBCXXABI_USE_COMPILER_RT=YES -DLIBCXX_USE_COMPILER_RT=YES -I/data/solution/projects/program/include -std=c++17 -stdlib=libc++ -isystem /usr/include/x86_64-linux-gnu -stdlib++-isystem /usr/lib/llvm-12/include/c++/v1 -o CMakeFiles/program.dir/source/program.cpp.o -c /data/solution/projects/program/source/program.cpp

It all looks good. But when I use ldd to check:

jacob.nielson@ubuntu:/data/solution/projects/program/build/debug$ ldd program

    linux-vdso.so.1 (0x00007ffee7190000)
    libc++.so.1 => /lib/x86_64-linux-gnu/libc++.so.1 (0x00007f69164a5000)
    libc++abi.so.1 => /lib/x86_64-linux-gnu/libc++abi.so.1 (0x00007f691646d000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f691628b000)     /* LIBSTDC++ in here! */
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f691613c000)               /* LIBM in here */
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f6916121000)       /* gcc startup file in here! */
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6915f2f000)               /* LIBC in here! */
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6915f0a000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f6915f00000)
    libatomic.so.1 => /lib/x86_64-linux-gnu/libatomic.so.1 (0x00007f6915ef6000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f691658d000)

It is frustrating to see all libstdc++, libc, libm or libgcc_s remain. Is there any option I missed to link them statically such like -static-libc in GNU CC or do I have to give up my ambition early at this point?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

糖粟与秋泊 2025-02-03 04:19:28

特此指出了问题的答案。

关于缺少定义的错误,可以指示Clang使用 Compiler_rt 一旦我添加到相关选项,就可以解决问题。

为了用libc ++替换libstsdc ++,一个人不会忘记添加以下选项:

add_compile_definitions(
    
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:LLVM_ENABLE_RUNTIMES=libunwind>
    
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:LIBCXX_USE_COMPILER_RT=YES>
    
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:LIBCXXABI_USE_COMPILER_RT=YES>
    
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:LIBUNWIND_USE_COMPILER_RT=YES>
    )

add_link_options(
    
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:-stdlib=libc++>
    
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:-rtlib=compiler-rt>
    )

afak,上述定义有助于指示clang“不要链接默认库”,但也必须将它们与编译选项结合使用, libc ++”,尤其是 no“ -nostdlib” 以生效。文档的一部分涵盖以下内容:

编译器运行时

默认运行时库是特定于目标的。对于GCC的目标
是主要的编译器,目前默认用于使用libgcc_s。
在大多数其他目标上,默认情况下使用编译器RT。

但是,我还不清楚这里指的是什么是指的是什么,以及如何告诉编译器对于给定目标是主导的。

The answer to the question is hereby noted.

There is a mistake about missing definitions to instruct Clang to use compiler_rt. The problem is solved once I had add to relevant options.

As to replace libstsdc++ with libc++, one shall not forget to add the following options:

add_compile_definitions(
    
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:LLVM_ENABLE_RUNTIMES=libunwind>
    
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:LIBCXX_USE_COMPILER_RT=YES>
    
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:LIBCXXABI_USE_COMPILER_RT=YES>
    
lt;
lt;COMPILE_LANG_AND_ID:CXX,Clang>:LIBUNWIND_USE_COMPILER_RT=YES>
    )

add_link_options(
    
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:-stdlib=libc++>
    
lt;
lt;LINK_LANG_AND_ID:CXX,Clang>:-rtlib=compiler-rt>
    )

AFAK, definitions above help to instruct clang "not to link against default libraries", but one also has to use them in conjunction with compile option "-stdlib=libc++" and especially NO "-nostdlib" for the replace to take effect. Part of the document covers in below:

Compiler runtime

The default runtime library is target-specific. For targets where GCC
is the dominant compiler, Clang currently defaults to using libgcc_s.
On most other targets, compiler-rt is used by default.

However, it is much unclear to me what target refers to here and how comes to tell a compiler is dominant for a given target.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文