项目中有fortran和c代码混编,以前不用cmake,现在想切到cmake,发现项目中用的老编译器,VS不认,不能同时编c和fortran。
于是有了本文,网上找的方法,创建两个工程,A和AFortran,A依赖AFortran,AFortran生成所有fortran的obj,A把自己的c和AFortran生成的obj混合在一起产生动态库。
function(add_neue_dyn_target)
file(GLOB
SOURCES "*.c" "*.cxx"
"*.cpp" "*.f")
add_library(${my_lib_name} SHARED
${SOURCES})
if(UNIX)
if(NOT ARGN)
set_target_properties(${my_lib_name}
PROPERTIES
LINK_FLAGS
"${LINK_FLAGS} -Wl,--no-undefined
-Wl,--whole-archive
${IDEAS_ROOT}/../olb/z${purelib_name}.a
-Wl,--no-whole-archive")
endif()
endfunction(add_neue_dyn_target)
function(neue_use_safeseh my_lib_name)
target_link_options(${my_lib_name} PRIVATE
"/SAFESEH:NO")
endfunction(neue_use_safeseh)
function(neue_build_fortran_from_source
my_lib_name)
if(WIN32)
file(GLOB F_SOURCES
"*.f")
foreach(F_SOURCE_FILE
${F_SOURCES})
get_filename_component(FILENAME
"${F_SOURCE_FILE}"
NAME_WE)
add_custom_command(
OUTPUT
"${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.o"
COMMAND
"${CMAKE_Fortran_COMPILER}"
/DWINNT /D_X86_ /DWIN32 /DNONXP /D_AFXDLL ... -IXXX /c
/Fo"${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.o"
"${F_SOURCE_FILE}"
DEPENDS
"${F_SOURCE_FILE}"
COMMENT "Building Fortran file with custom
command: ${FILENAME}.f"
)
endforeach(F_SOURCE_FILE)
set(OBJECTS_FILES "")
foreach(F_SOURCE_FILE
${F_SOURCES})
get_filename_component(FILENAME
"${F_SOURCE_FILE}"
NAME_WE)
list(APPEND OBJECT_FILES
"${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.o")
endforeach()
target_sources(${my_lib_name}
PRIVATE ${OBJECT_FILES})
neue_use_safeseh(${my_lib_name})
add_custom_target(${my_lib_name}Fortran
ALL DEPENDS ${OBJECT_FILES})
add_dependencies(${my_lib_name}
${my_lib_name}FORTRAN)
endif()
CMake编译Fortran77的方法
项目中有fortran和c代码混编,以前不用cmake,现在想切到cmake,发现项目中用的老编译器,VS不认,不能同时编c和fortran。
于是有了本文,网上找的方法,创建两个工程,A和AFortran,A依赖AFortran,AFortran生成所有fortran的obj,A把自己的c和AFortran生成的obj混合在一起产生动态库。
function(add_neue_dyn_target)
file(GLOB SOURCES "*.c" "*.cxx" "*.cpp" "*.f")
add_library(${my_lib_name} SHARED ${SOURCES})
if(UNIX)
if(NOT ARGN)
set_target_properties(${my_lib_name} PROPERTIES
LINK_FLAGS "${LINK_FLAGS} -Wl,--no-undefined -Wl,--whole-archive ${IDEAS_ROOT}/../olb/z${purelib_name}.a -Wl,--no-whole-archive")
endif()
endfunction(add_neue_dyn_target)
function(neue_use_safeseh my_lib_name)
target_link_options(${my_lib_name} PRIVATE "/SAFESEH:NO")
endfunction(neue_use_safeseh)
function(neue_build_fortran_from_source my_lib_name)
if(WIN32)
file(GLOB F_SOURCES "*.f")
foreach(F_SOURCE_FILE ${F_SOURCES})
get_filename_component(FILENAME "${F_SOURCE_FILE}" NAME_WE)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.o"
COMMAND "${CMAKE_Fortran_COMPILER}" /DWINNT /D_X86_ /DWIN32 /DNONXP /D_AFXDLL ... -IXXX /c /Fo"${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.o" "${F_SOURCE_FILE}"
DEPENDS "${F_SOURCE_FILE}"
COMMENT "Building Fortran file with custom command: ${FILENAME}.f"
)
endforeach(F_SOURCE_FILE)
set(OBJECTS_FILES "")
foreach(F_SOURCE_FILE ${F_SOURCES})
get_filename_component(FILENAME "${F_SOURCE_FILE}" NAME_WE)
list(APPEND OBJECT_FILES "${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.o")
endforeach()
target_sources(${my_lib_name} PRIVATE ${OBJECT_FILES})
neue_use_safeseh(${my_lib_name})
add_custom_target(${my_lib_name}Fortran ALL DEPENDS ${OBJECT_FILES})
add_dependencies(${my_lib_name} ${my_lib_name}FORTRAN)
endif()