首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过使用gcc而不是g++,输出二进制文件的大小更小

通过使用gcc而不是g++,输出二进制文件的大小更小
EN

Stack Overflow用户
提问于 2020-05-14 04:21:24
回答 1查看 187关注 0票数 0

我正在将我的项目从C迁移到C++,今天我注意到了一些奇怪的事情。我有两个几乎相同的主文件(唯一的区别是.cpp中的外部关键字)(为编译测试目的而创建的)。第一个是main.c,第二个是main.cpp。

你可以在下面找到这些文件的源代码。我使用的是libopencm3,它被编译成静态库,然后可以链接到任何需要它的地方。那么问题出在哪里呢?在我使用main.c (使用gcc)编译我的项目的场景中,输出二进制文件比使用main.cpp (使用g++)编译产生的输出二进制文件要小得多。我不知道是什么导致了这个问题?

为STM32F1C8T6目标编译代码。

//main.c

代码语言:javascript
复制
#include <libopencm3/stm32/rcc.h>

static void rcc_setup()
{
  //Clock setup
  rcc_clock_setup_in_hse_8mhz_out_72mhz();

  //Peripherals clock
  rcc_periph_clock_enable(RCC_GPIOA);
  rcc_periph_clock_enable(RCC_GPIOB); 
}

int main()
{
  rcc_setup();

  while(1)
  {

  }
}

//main.cpp

代码语言:javascript
复制
extern "C" { 
  #include <libopencm3/stm32/rcc.h>
}

static void rcc_setup()
{
  //Clock setup
  rcc_clock_setup_in_hse_8mhz_out_72mhz();

  //Peripherals clock
  rcc_periph_clock_enable(RCC_GPIOA);
  rcc_periph_clock_enable(RCC_GPIOB); 
}

int main()
{
  rcc_setup();

  while(1)
  {

  }
}

我的项目的结构看起来基本如下:

代码语言:javascript
复制
- root
  CMakeLists.txt
  - lib
    - libopencm3
  - src 
    - app
      CMakeLists.txt
      - inc 
      - src
        - main.c
        - main.cpp

这是我的根CMakeFile.txt。我认为它是最重要的,因为它包含编译标志等。它还包含其他一些东西,如端口目录、port.cmake等,但在这种情况下这些并不重要,所以请忽略它们。

代码语言:javascript
复制
cmake_minimum_required(VERSION 3.16)
project(stm32-template)

# COMPILER JUST TEMPORARY TODO: REMOVE!!!
set(CMAKE_ASM_COMPILER "/usr/bin/arm-none-eabi-gcc")
set(CMAKE_C_COMPILER "/usr/bin/arm-none-eabi-gcc")
set(CMAKE_CXX_COMPILER "/usr/bin/arm-none-eabi-g++")

# CMAKE MODULES
include(${CMAKE_ROOT}/Modules/ExternalProject.cmake)

# GENERAL PATHS 
set(PORT_DIR ${PROJECT_SOURCE_DIR}/src/port/${PORT})

# PORT CONFIGURATIOM 
include(${PORT_DIR}/port.cmake)

# COMPILER CONFIGURATION
set(COMPILER_CXX_FLAGS "-fno-use-cxa-atexit -Os")
set(COMPILER_FLAGS "-fdata-sections -ffunction-sections -O0 -DNDEBUG -Werror")
set(LINKER_FLAGS "-nostartfiles -specs=nano.specs -specs=nosys.specs --static -ggdb3 -Wl,--gc-sections -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group -Wl,-Map=output.map -T ${LD_SCRIPT}")
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

set(CMAKE_C_FLAGS "${COMPILER_FLAGS} ")
set(CMAKE_CXX_FLAGS "${COMPILER_CXX_FLAGS} ${COMPILER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${LINKER_FLAGS}")

# LIBRARIES 
set(LIBOPENCM3_PATH ${PROJECT_SOURCE_DIR}/lib/libopencm3)
set(LIBOPENCM3_INCLUDE ${LIBOPENCM3_PATH}/include)
set(LIBOPENCM3_BIN ${LIBOPENCM3_PATH}/lib/libopencm3_${MCU_FAMILY}.a)
ExternalProject_Add(libopencm3
    SOURCE_DIR "${LIBOPENCM3_PATH}"
    BUILD_IN_SOURCE true
    DOWNLOAD_COMMAND ""
    CONFIGURE_COMMAND ""
    INSTALL_COMMAND ""
    BUILD_COMMAND make
)

# ADD LIBRARY INCLUDES 
include_directories(${LIBOPENCM3_INCLUDE})

# SUBDIRECTORIS 
add_subdirectory(src)

# CUSTOM COMMANDS 
add_custom_target(flash
  COMMAND JLinkExe -device STM32F103C8 -If SWD -Speed 1000 -CommandFile tools/jlink/FlashCommand.jlink
  COMMENT "asd"

  #DEPENDS {EXE_NAME}
)
EN

回答 1

Stack Overflow用户

发布于 2020-05-14 05:03:06

C++语言的运行时比C语言大得多(因为异常、RTTI、<iostream><thread>等)。

当您静态链接应用程序时,您将链接到整个语言运行时,或者至少是代码中引用的那些部分,包括在您拉入的头中的静态和线程本地存储持续时间的对象(例如。std::cout)。大多数桌面应用程序看不到这一点,因为它往往在DSO中。

由于语言互操作,您会发现C++运行时的很大一部分实际上位于您的系统libc中。这包括异常处理和解开。如果你看到像__cxa_*和Unwind*这样的符号,那就是发生的事情。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61784112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档