[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