Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Cmake и gcc объединяются

Автор вопроса: Igor PetushkovОтветов: 1

У меня много исходных файлов в исходном каталоге. Например, a.c, b.c, c.c и хотите скомпилировать его с помощью gcc с параметром -combine.

set(CMAKE_C_FLAGS "-combine")
set(SRC a.c b.c c.c)
add_executable(a.out ${SRC})

Cmake компилирует каждый файл * .c в объектный файл, но я хочу скомпилировать все источники в один объект. Как я могу это получить.

С точки зрения gcc:

gcc -combine a.c b.c c.c -o module.o
ar rcs library.a module.o

Но cmake использует помодульный перевод источников.

gcc a.c -o a.o
gcc b.c -o b.o
gcc c.c -o c.o
ar rcs library.a a.o b.o c.o

Перевод с помощью комбайна может ускорить выполнение программы. Я не мог использовать LTO, который мог бы решить ту же проблему в cmake из-за старой версии gcc.

Спасибо.

  • Вы уверены, что опция -combine существует? У меня такое чувство, что вы пытаетесь сделать не это. Возможно, вы имеете в виду -fwhole-program, что морально эквивалентно объединению всех ваших исходных файлов вместе. Но более вероятно, что вы просто пытаетесь создать многоразовую библиотеку. Используйте -shared, чтобы создать динамическую библиотеку, или просто используйте программу ar, чтобы объединить множество .o файлов в статическую библиотеку. CMake может автоматизировать и то, и другое за вас. Kerrek SB 14.06.2011
  • Да, я уверен. Эта опция существует в gcc версии 4.4 / 4.5 Igor Petushkov 16.06.2011
  • Интересно, пропало оно в 4.6! :-) Какова его цель? Чего вы не можете достичь с -fwhole-program? Kerrek SB 16.06.2011
  • Да, в 4.6 нет -combine, но наша команда использует gcc-4.3 и 4.4. С -fwhole-program возникает та же проблема, что и с comb, потому что для создания 1 объектного файла необходимо скомпилировать все исходные файлы в одну единицу компиляции. Igor Petushkov 17.06.2011
  • Я тоже хотел бы узнать ответ на этот вопрос. В настоящее время я использую собственную систему Makefile вместо CMake, но я бы хотел переключиться. Но производительность за счет межмодульной оптимизации важнее, чем CMake. Zan Lynx 07.09.2011
  • Кстати, любой, кто хочет объединить исходные файлы без -combine или хочет объединить для c ++, может проверить это: pastebin.com/fRa4MnPC Zan Lynx 07.09.2011

gcccmake

Ответы

Ответ 1 · рейтинг 1 · Sergei Nikulov

Используйте add_custom_target / add_custom_command.

В любом случае это непереносимая конструкция, поэтому вот простой пример

[корень проекта] с двумя папками в нем [src] - здесь N файлов, [build] для двоичного файла и CMakeLists.txt

cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)
set(TARGET_NAME whole)
project(${TARGET_NAME} C)

file(GLOB SRC_FILES src/*.c)

add_custom_target(${TARGET_NAME} ${CMAKE_C_COMPILER} -flto -fwhole-program ${SRC_FILES} -o ${TARGET_NAME})

В папке сборки запустите cmake ..; make VERBOSE = 1 целое

Это сделает работу за вас.

Но -fwhole-program работает только с исполняемым файлом, как указано в документации.

-fwhole-program Предположить, что текущая единица компиляции представляет всю компилируемую программу. Все общедоступные функции и переменные, за исключением main и тех, которые объединены атрибутом external_visible, становятся статическими функциями и, по сути, более агрессивно оптимизируются межпроцедурными оптимизаторами.

Итак, вы должны определить main где угодно в ваших исходных файлах.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы