[CMake] Wrong flags in fortran project when use c library

Kelly (KT) Thompson kt at transpireinc.com
Fri Oct 9 18:05:11 EDT 2009


On Fri, Oct 9, 2009 at 12:49 PM, Bill Hoffman <bill.hoffman at kitware.com>wrote:

> Kelly (KT) Thompson wrote:
>
>  On Fri, Oct 9, 2009 at 6:15 AM, Sebas <spaseba at gmail.com <mailto:
>> spaseba at gmail.com>> wrote:
>>
>>    I send a example where happen explained before ( I have similar
>>    struct in my Program). I include too the VS2008 project generate by
>>    cmake. In the Fortran Project be can seen that use /W3 /Zm1000 /GR
>>    /RTC1 /TP Flags that don't work with ifort.
>>    I use CMake 2.8 rc2 (but happen same in 2.6 and 2.7)
>>
>>    Thanks.
>>
>>    Sebastian
>>
>>
>> Sebastian,
>>
>> You are mixing C, C++ and Fortran sources in a single project.  This does
>> not work well in general and particularly in CMake.  I was able to
>> restructure your sample code so that it will build with NMake Makefile
>> (Visual Studio 2008 SP1 and Intel Visual Fortran 11).
>>
>> Key points:
>>
>> 1. all C++ code goes into a single directory and produces a single
>> library.  The CMakeLists.txt has the project name CPPLibrary2.
>>
>> 2. each C library is built only from C sources. The CMakeLists.txt files
>> are given the project name CLibrary and CLibrary2.
>>
>> 3. the Fortran is also isolated into a single directory and the local
>> CMakeLists.txt file only deals with the Fortran.
>>
>> 4. CMake needs help knowing how to build mixed language targets that must
>> be compiled with the Fortran compiler.  In the Fortran CMakeLists.txt I had
>> to set_target properties for LINKER_LANGUAGE.
>>
>> 5. When mixing C and Fortran on the Windows platform you must use the same
>> type of runtime libraries (/MT or /MD).  The default Fortran build uses /MT,
>> so I had to set these to /MD (Fortran_FLAGS)
>>
>> 6. When interfacing C++ and Fortran code, you must mark the C++ function
>> as extern "C" to avoid name mangling issues.  The Fortran also expects the
>> C++ symbol name to be all caps.  You can use Fortran's ISO_C_BINDING to get
>> around this platform issue.
>>
>> There are many changes required to your sample build so I decided that a
>> zip file would be the best way to return the project to you.
>>
>>  Thanks for the work around.  However, this should work a bit smoother,
> Sebastian can you create a bug report and attach your example?
>
> Thanks.
>
> -Bill
>
>
Bill,

It is my understanding that each CMake target must be 'language pure"  The
following example will work (and is less complex).  This example assumes
that all sources are in a single directory (see below).  Because Sebastian
had separate directories for each language, I assumed that was important for
his build setup and tried to be faithful to that layout.

I think the key feature that was missing from his original setup was:

  set_target_properties( FortranProgram PROPERTIES LINKER_LANGUAGE Fortran )

Without that that statement, CMake will build FortranProgram.obj correctly,
but then try to generate the .exe by calling the MSVC linker (using the link
flags for C).

-kt

## Single directory equivalent CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT( FortranProgram C CXX Fortran )

# Find local headers
INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR} )

# Library CLibrary2
ADD_LIBRARY( CLibrary2 CLibrary2.c )

# Library CPPLibrary
ADD_LIBRARY( CPPLibrary2 CPPLibrary2.cpp )

# Library: CLibrary
ADD_LIBRARY( CLibrary CLibrary.c )
TARGET_LINK_LIBRARIES( CLibrary CLibrary2 CPPLibrary2 )

# Fortran
ADD_EXECUTABLE( FortranProgramExe FortranProgram.f90 )
TARGET_LINK_LIBRARIES( FortranProgramExe CLibrary CLibrary2 CPPLibrary2 )

set(CMAKE_Fortran_FLAGS_DEBUG   "/Od /DDEBUG /MDd" )
set(CMAKE_Fortran_FLAGS_RELEASE "/O2 /Ob2 /DNDEBUG /MD" )
set(CMAKE_Fortran_FLAGS_MINSIZEREL "/Os /DNDEBUG /MD" )
set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO "/O2 /Ob2 /DDEBUG /MD" )

IF( MSVC_IDE )
  set_target_properties( FortranProgramExe
    PROPERTIES
      LINKER_LANGUAGE Fortran
      LINK_FLAGS "/SUBSYSTEM:CONSOLE"
      OUTPUT_NAME FortranProgram
  )
ELSEIF( WIN32 )
  set_target_properties( FortranProgramExe
    PROPERTIES
      LINKER_LANGUAGE Fortran
      OUTPUT_NAME FortranProgram
  )
ENDIF()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20091009/f6a3949d/attachment.htm>


More information about the CMake mailing list