[CMake] How to use CMake with icc via configuration options when needing interprocedural optimization?

Michael Hertling mhertling at online.de
Fri Feb 10 18:04:49 EST 2012


On 02/10/2012 12:48 PM, janitor 048 wrote:
> Thank you so much for the hint. Setting the environment variable CXX from
> within my CMakeLists.txt via
> SET(ENV{CXX} "icpc")
> but before any call to project() or enable_language() seems indeed to do
> the trick.
> 
> Setting CMAKE_CXX_FLAGS_RELEASE or CMAKE_CXX_FLAGS_DEBUG at this stage
> however does not work. This apparently needs to go after the project()
> statement.

Sorry, my bad: CMAKE_CXX_FLAGS_<CONFIG> are typical cache variables,
i.e. they are meant to receive their values on the command line or
in the GUI, and their default fallback values are set when C++ is
enabled in Modules/CMakeCXXInformation.cmake by:

SET(CMAKE_CXX_FLAGS_... "${CMAKE_CXX_FLAGS_..._INIT}" CACHE STRING "...")

This SET() command overwrites the value in the current scope if there's
not already a value in the cache. Thus, in order to set these variables
along with the compiler in your IF()-ENDIF() block before PROJECT() or
ENABLE_LANGUAGE() - where there're placed well, IMO - just cache them:

IF (MY_COMPILER_OPTION STREQUAL "Intel")
  MESSAGE(STATUS "** Compiling with Intel settings **")
  SET(ENV{CXX} "icpc")
  SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w" CACHE STRING "...")
  SET(CMAKE_CXX_FLAGS_DEBUG "-g" CACHE STRING "...")
ENDIF ()

This will make the above-noted SET() command a no-op. Consider to use
the FORCE option if you want to modify/enhance/replace flags the user
might have already specified on the command line or in the GUI.

> I could of course set the environment cxx-flags in the same way as above.
> This would somewhat sacrifice the nice RELEASE / DEBUG distinction but
> maybe this can be done by some if-statements (there certainly is a way to
> query the CMAKE_BUILD_TYPE variable, right?).

Constructs like

IF(CMAKE_BUILD_TYPE STREQUAL Debug)
...
ENDIF()

or better

STRING(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE)
IF(CMAKE_BUILD_TYPE STREQUAL DEBUG)
...
ENDIF()

are possible, but only meaningful for single-configuration generators.
The CMAKE_CXX_FLAGS_<CONFIG> variables are definitely the way to go.

Regards,

Michael

> 2012/2/9 Michael Hertling <mhertling at online.de>
> 
>> On 02/07/2012 02:43 PM, janitor 048 wrote:
>>> Hello,
>>>
>>> this is a question I recently asked on stackoverflow (
>>>
>> http://stackoverflow.com/questions/9129233/recommended-ways-to-use-cmake-with-icc-via-configuration-options
>> )
>>> but that has not received any response since then. Maybe this mailing
>> list
>>> is a better place to ask... Here goes
>>>
>>> I would like to use the Intel compiler icc (or icpc) with a CMake-based
>>> project (on Linux for what it's worth). I can of course export the CXX
>>> variable when calling cmake, e.g. like
>>>
>>> CXX=icpc cmake ../
>>>
>>> and this works fine. I would however like to make this choice available
>> via
>>> a custom option. For this I parse custom option, e.g.
>>>
>>> cmake -DMY_COMPILER_OPTION=Intel ..
>>>
>>> as
>>>
>>> IF (MY_COMPILER_OPTION STREQUAL "Intel")
>>>   MESSAGE(STATUS "** Compiling with Intel settings **")
>>>   SET(CMAKE_CXX_COMPILER "icpc")
>>>   SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w")
>>>   SET(CMAKE_CXX_FLAGS_DEBUG "-g")
>>> ENDIF ()
>>>
>>> and set CMAKE_CXX_COMPILER together with some compiler flags. This also
>>> works, however there is an important "but".
>>>
>>> I would also like to use the option -ipo (interprocedural optimization)
>> for
>>> my code when compiling with icc plus I need to compile a static library
>>> within the build process. For this to work, I need to use Intel's xiar
>> (and
>>> also xilink I guess).
>>>
>>> cmake actually offers a special property for this
>>>
>>> set_property(TARGET mytarget PROPERTY INTERPROCEDURAL_OPTIMIZATION 1)
>>>
>>> however this only seems to works properly when the compiler has been set
>>> via the environment variable (then xiar is used). When setting the
>> compiler
>>> via CMAKE_CXX_COMPILER this property is ignored.
>>>
>>> Is there another way to do this?. Some recommended way? Or at least a
>>> work-around?
>>
>> If it actually works well when the compiler is specified via the
>> respective environment variable, you might try the following:
>>
>> IF (MY_COMPILER_OPTION STREQUAL "Intel")
>>  MESSAGE(STATUS "** Compiling with Intel settings **")
>>   SET(ENV{CXX} "icpc")
>>   SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w")
>>  SET(CMAKE_CXX_FLAGS_DEBUG "-g")
>> ENDIF ()
>>
>> However, note that you must do this *before* the language is enabled,
>> i.e. before the PROJECT() or ENABLE_LANGUAGE() commands. Note further
>> that this can be done only for the *initial* configuration of a build
>> tree; afterwards, the compiler can't be changed anymore. In order to
>> make that approach more robust, you might consider some refinements:
>>
>> IF (MY_COMPILER_OPTION STREQUAL "Intel")
>>   FIND_PROGRAM(ICPC_PROGRAM icpc ...)
>>  IF(ICPC_PROGRAM)
>>     MESSAGE(STATUS "** Compiling with Intel settings **")
>>     IF(ENV{CXX})
>>      MESSAGE(WARNING "Overwriting CXX envvar")
>>    ENDIF()
>>    SET(ENV{CXX} "${ICPC_PROGRAM}")
>>     SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w")
>>    SET(CMAKE_CXX_FLAGS_DEBUG "-g")
>>   ELSE()
>>    MESSAGE(FATAL_ERROR "Intel compiler not found")
>>  ENDIF()
>> ENDIF ()
>>
>> Regards,
>>
>> Michael


More information about the CMake mailing list