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

У меня много исходных файлов в исходном каталоге. Например, 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.

Спасибо.


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


Ответы (1)


Используйте 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 где угодно в ваших исходных файлах.

person Sergei Nikulov    schedule 16.11.2011