From 538c3452ad660a45c3d6ca32f8c09ee7c93a8b84 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Fri, 9 Dec 2011 18:04:19 -0500 Subject: Add CMakeAddFortranSubdirectory to use MinGW gfortran in VS This patch adds a new module that allows for easy integration of MinGW gfortran and the Visual Studio compiler. It is done in a function called cmake_add_fortran_subdirectory. The patch also includes a test for this feature. --- Modules/CMakeAddFortranSubdirectory.cmake | 167 +++++++++++++++++++++ .../build_mingw.cmake.in | 2 + .../config_mingw.cmake.in | 8 + Tests/CMakeLists.txt | 9 ++ Tests/VSGNUFortran/CMakeLists.txt | 39 +++++ Tests/VSGNUFortran/c_code/CMakeLists.txt | 2 + Tests/VSGNUFortran/c_code/main.c | 7 + Tests/VSGNUFortran/fortran/CMakeLists.txt | 12 ++ Tests/VSGNUFortran/fortran/hello.f | 7 + Tests/VSGNUFortran/fortran/world.f | 6 + Tests/VSGNUFortran/runtest.cmake.in | 23 +++ 11 files changed, 282 insertions(+) create mode 100644 Modules/CMakeAddFortranSubdirectory.cmake create mode 100644 Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in create mode 100644 Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in create mode 100644 Tests/VSGNUFortran/CMakeLists.txt create mode 100644 Tests/VSGNUFortran/c_code/CMakeLists.txt create mode 100644 Tests/VSGNUFortran/c_code/main.c create mode 100644 Tests/VSGNUFortran/fortran/CMakeLists.txt create mode 100644 Tests/VSGNUFortran/fortran/hello.f create mode 100644 Tests/VSGNUFortran/fortran/world.f create mode 100644 Tests/VSGNUFortran/runtest.cmake.in diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake new file mode 100644 index 0000000..4e351a6 --- /dev/null +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -0,0 +1,167 @@ +# - Use MinGW gfortran from VS if a fortran compiler is not found. +# The 'add_fortran_subdirectory' function adds a subdirectory +# to a project that contains a fortran only sub-project. The module +# will check the current compiler and see if it can support fortran. +# If no fortran compiler is found and the compiler is MSVC, then +# this module will find the MinGW gfortran. It will then use +# an external project to build with the MinGW tools. It will also +# create imported targets for the libraries created. This will only +# work if the fortran code is built into a dll, so BUILD_SHARED_LIBS +# is turned on in the project. In addition the GNUtoMS option is set +# to on, so that the MS .lib files are created. +# Usage is as follows: +# cmake_add_fortran_subdirectory( +# # name of subdirectory +# PROJECT # project name in sbudir toplevel CMakeLists.txt +# ARCHIVE_DIR # .lib location relative to root binary tree (lib) +# RUNTIME_DIR # .dll location relative to root binary tree (bin) +# LIBRARIES lib2 lib2 # names of libraries created and exported +# LINK_LIBRARIES # link interface libraries for LIBRARIES +# LINK_LIBS ... +# LINK_LIBS ... +# CMAKE_COMMAND_LINE # extra command line flags to pass to cmake +# ) +# + +#============================================================================= +# Copyright 2002-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + + +set(_MS_MINGW_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) +include(CheckLanguage) +include(ExternalProject) +include(CMakeParseArguments) + +function(_setup_mingw_config_and_build source_dir) + find_program(MINGW_GFORTRAN NAMES gfortran + HINTS + c:/MinGW/bin + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MinGW;InstallLocation]/bin" ) + if(NOT MINGW_GFORTRAN) + message(FATAL_ERROR + "gfortran not found, please install MinGW with the gfortran option." + "Or set the cache variable MINGW_GFORTRAN to the full path. " + " This is required to build") + endif() + execute_process(COMMAND ${MINGW_GFORTRAN} -v ERROR_VARIABLE out) + if(NOT "${out}" MATCHES "Target:.*mingw32") + message(FATAL_ERROR "Non-MinGW gfortran found: ${MINGW_GFORTRAN}\n" + "output from -v [${out}]\n" + "set MINGW_GFORTRAN to the path to MinGW fortran.") + endif() + get_filename_component(MINGW_PATH ${MINGW_GFORTRAN} PATH) + file(TO_NATIVE_PATH "${MINGW_PATH}" MINGW_PATH) + string(REPLACE "\\" "\\\\" MINGW_PATH "${MINGW_PATH}") + configure_file( + ${_MS_MINGW_SOURCE_DIR}/CMakeAddFortranSubdirectory/config_mingw.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/config_mingw.cmake + @ONLY) + configure_file( + ${_MS_MINGW_SOURCE_DIR}/CMakeAddFortranSubdirectory/build_mingw.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/build_mingw.cmake + @ONLY) +endfunction() + +function(_add_fortran_library_link_interface library depend_library) + set_target_properties(${library} PROPERTIES + IMPORTED_LINK_INTERFACE_LIBRARIES_NOCONFIG "${depend_library}") +endfunction() + + +function(cmake_add_fortran_subdirectory subdir) + # if we are not using MSVC without fortran support + # then just use the usual add_subdirectory to build + # the fortran library + check_language(Fortran) + if(NOT (MSVC AND (NOT CMAKE_Fortran_COMPILER))) + add_subdirectory(${subdir}) + return() + endif() + + # if we have MSVC without Intel fortran then setup + # external projects to build with mingw fortran + + # Parse arguments to function + set(oneValueArgs PROJECT ARCHIVE_DIR RUNTIME_DIR) + set(multiValueArgs LIBRARIES LINK_LIBRARIES CMAKE_COMMAND_LINE) + cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}") + set(project_name "${ARGS_PROJECT}") + set(library_dir "${ARGS_ARCHIVE_DIR}") + set(binary_dir "${ARGS_RUNTIME_DIR}") + set(libraries ${ARGS_LIBRARIES}) + # use the same directory that add_subdirectory would have used + set(build_dir "${CMAKE_CURRENT_BINARY_DIR}/${subdir}") + # create build and configure wrapper scripts + _setup_mingw_config_and_build(${source_dir}) + # create the external project + externalproject_add(${project_name}_build + SOURCE_DIR ${source_dir} + BINARY_DIR ${build_dir} + CONFIGURE_COMMAND ${CMAKE_COMMAND} + -P ${CMAKE_CURRENT_BINARY_DIR}/config_mingw.cmake + BUILD_COMMAND ${CMAKE_COMMAND} + -P ${CMAKE_CURRENT_BINARY_DIR}/build_mingw.cmake + INSTALL_COMMAND "" + ) + # make the external project always run make with each build + externalproject_add_step(${project_name}_build forcebuild + COMMAND ${CMAKE_COMMAND} + -E remove + ${CMAKE_CURRENT_BUILD_DIR}/${project_name}-prefix/src/${project_name}-stamp/${project_name}-build + DEPENDEES configure + DEPENDERS build + ALWAYS 1 + ) + # create imported targets for all libraries + foreach(lib ${libraries}) + add_library(${lib} SHARED IMPORTED) + set_property(TARGET ${lib} APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG) + set_target_properties(${lib} PROPERTIES + IMPORTED_IMPLIB_NOCONFIG + "${build_dir}/${library_dir}/lib${lib}.lib" + IMPORTED_LOCATION_NOCONFIG + "${build_dir}/${binary_dir}/lib${lib}.dll" + ) + add_dependencies(${lib} ${project_name}_build) + endforeach() + + # now setup link libraries for targets + set(start FALSE) + set(target) + foreach(lib ${ARGS_LINK_LIBRARIES}) + if("${lib}" STREQUAL "LINK_LIBS") + set(start TRUE) + else() + if(start) + if(DEFINED target) + # process current target and target_libs + _add_fortran_library_link_interface(${target} "${target_libs}") + # zero out target and target_libs + set(target) + set(target_libs) + endif() + # save the current target and set start to FALSE + set(target ${lib}) + set(start FALSE) + else() + # append the lib to target_libs + list(APPEND target_libs "${lib}") + endif() + endif() + endforeach() + # process anything that is left in target and target_libs + if(DEFINED target) + _add_fortran_library_link_interface(${target} "${target_libs}") + endif() +endfunction() diff --git a/Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in b/Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in new file mode 100644 index 0000000..55b271a --- /dev/null +++ b/Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in @@ -0,0 +1,2 @@ +set(ENV{PATH} "@MINGW_PATH@\;$ENV{PATH}") +execute_process(COMMAND "@CMAKE_COMMAND@" --build . ) diff --git a/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in b/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in new file mode 100644 index 0000000..96141da --- /dev/null +++ b/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in @@ -0,0 +1,8 @@ +set(ENV{PATH} "@MINGW_PATH@\;$ENV{PATH}") +execute_process( + COMMAND "@CMAKE_COMMAND@" "-GMinGW Makefiles" + -DCMAKE_Fortran_COMPILER:PATH=@MINGW_GFORTRAN@ + -DBUILD_SHARED_LIBS=ON + -DCMAKE_GNUtoMS=ON + @ARGS_CMAKE_COMMAND_LINE@ + "@source_dir@") diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 906b40d..e949887 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -163,6 +163,15 @@ IF(BUILD_TESTING) IF(CMAKE_Fortran_COMPILER) ADD_TEST_MACRO(FortranOnly FortranOnly) ENDIF() + # test Visual Studio GNU Fortran mixing with cmake_add_fortran_subdirectory + # run this project if we have a working fortran compiler or + # the test is enabled with CMAKE_TEST_CMAKE_ADD_FORTRAN cache variable. + # If you enable the test, CMake should find the MinGW fortran install, + # or in some cases you might need to set the PATH so that cmake can find + # the gfortran from mingw. + IF(CMAKE_Fortran_COMPILER OR CMAKE_TEST_CMAKE_ADD_FORTRAN) + ADD_TEST_MACRO(VSGNUFortran ${CMAKE_COMMAND} -P runtest.cmake) + ENDIF() ADD_TEST_MACRO(COnly COnly) ADD_TEST_MACRO(CxxOnly CxxOnly) ADD_TEST_MACRO(IPO COnly/COnly) diff --git a/Tests/VSGNUFortran/CMakeLists.txt b/Tests/VSGNUFortran/CMakeLists.txt new file mode 100644 index 0000000..2e527f9 --- /dev/null +++ b/Tests/VSGNUFortran/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 2.8) +project(VSGNUFortran) +# force the executable to be put out of Debug/Release dir +# because gmake build of fortran will not be in a config +# directory, and for easier testing we want the exe and .dll +# to be in the same directory. +if(CMAKE_CONFIGURATION_TYPES) + foreach(config ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${config}" config) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${config} + "${PROJECT_BINARY_DIR}/bin") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${config} + "${PROJECT_BINARY_DIR}/bin") + endforeach() +else() + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) +endif() + +include(CMakeAddFortranSubdirectory) +# add the fortran subdirectory as a fortran project +# the subdir is fortran, the project is FortranHello +cmake_add_fortran_subdirectory(fortran + PROJECT FortranHello # project name in toplevel CMakeLists.txt + ARCHIVE_DIR ../bin # .lib location relative to root binary tree + RUNTIME_DIR ../bin # .dll location relative to root binary tree + LIBRARIES hello world # target libraries created + CMAKE_COMMAND_LINE -DEXECUTABLE_OUTPUT_PATH=../bin + -DLIBRARY_OUTPUT_PATH=../bin + LINK_LIBRARIES # link interface libraries + LINK_LIBS hello world # hello needs world to link + ) + +include_directories(${VSGNUFortran_BINARY_DIR}/fortran) +add_subdirectory(c_code) +# use a cmake script to run the executable so that PATH +# can be set with the MinGW/bin in it, and the fortran +# runtime libraries can be found. +configure_file(runtest.cmake.in runtest.cmake @ONLY) diff --git a/Tests/VSGNUFortran/c_code/CMakeLists.txt b/Tests/VSGNUFortran/c_code/CMakeLists.txt new file mode 100644 index 0000000..27d22fd --- /dev/null +++ b/Tests/VSGNUFortran/c_code/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(c_using_fortran main.c) +target_link_libraries(c_using_fortran hello) diff --git a/Tests/VSGNUFortran/c_code/main.c b/Tests/VSGNUFortran/c_code/main.c new file mode 100644 index 0000000..391bf26 --- /dev/null +++ b/Tests/VSGNUFortran/c_code/main.c @@ -0,0 +1,7 @@ +#include // created by FortranCInterface +extern void FC_hello(void); +int main() +{ + FC_hello(); + return 0; +} diff --git a/Tests/VSGNUFortran/fortran/CMakeLists.txt b/Tests/VSGNUFortran/fortran/CMakeLists.txt new file mode 100644 index 0000000..ff22993 --- /dev/null +++ b/Tests/VSGNUFortran/fortran/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 2.8) +project(FortranHello Fortran C) + +include(FortranCInterface) +FortranCInterface_HEADER(HelloWorldFCMangle.h + MACRO_NAMESPACE "FC_" + SYMBOL_NAMESPACE "FC_" + SYMBOLS hello world) + +add_library(hello SHARED hello.f) +add_library(world SHARED world.f) +target_link_libraries(hello world) diff --git a/Tests/VSGNUFortran/fortran/hello.f b/Tests/VSGNUFortran/fortran/hello.f new file mode 100644 index 0000000..e52119a --- /dev/null +++ b/Tests/VSGNUFortran/fortran/hello.f @@ -0,0 +1,7 @@ +!DEC$ ATTRIBUTES DLLEXPORT :: HELLO + SUBROUTINE HELLO + + PRINT *, 'Hello' + CALL WORLD + + END diff --git a/Tests/VSGNUFortran/fortran/world.f b/Tests/VSGNUFortran/fortran/world.f new file mode 100644 index 0000000..0598eee --- /dev/null +++ b/Tests/VSGNUFortran/fortran/world.f @@ -0,0 +1,6 @@ +!DEC$ ATTRIBUTES DLLEXPORT :: WORLD + SUBROUTINE WORLD + + PRINT *, 'World!' + + END diff --git a/Tests/VSGNUFortran/runtest.cmake.in b/Tests/VSGNUFortran/runtest.cmake.in new file mode 100644 index 0000000..987207b --- /dev/null +++ b/Tests/VSGNUFortran/runtest.cmake.in @@ -0,0 +1,23 @@ +get_filename_component(MINGW_PATH "@MINGW_GFORTRAN@" PATH) +if(NOT EXISTS "${MINGW_PATH}") + set(test_exe + "@VSGNUFortran_BINARY_DIR@/bin/c_using_fortran@CMAKE_EXECUTABLE_SUFFIX@") + message("run: ${test_exe}") + execute_process(COMMAND "${test_exe}" + RESULT_VARIABLE res) + if(NOT "${res}" EQUAL 0) + message(FATAL_ERROR "${test_exe} returned a non 0 value") + endif() + return() +endif() +file(TO_NATIVE_PATH "${MINGW_PATH}" MINGW_PATH) +string(REPLACE "\\" "\\\\" MINGW_PATH "${MINGW_PATH}") +message("${MINGW_PATH}") +set(test_exe "@VSGNUFortran_BINARY_DIR@/bin/c_using_fortran.exe") +set(ENV{PATH} "${MINGW_PATH}";$ENV{PATH}) +message("run ${test_exe}") +execute_process(COMMAND "${test_exe}" + RESULT_VARIABLE res) +if(NOT "${res}" EQUAL 0) + message(FATAL_ERROR "${test_exe} returned a non 0 value") +endif() -- cgit v0.12 From e4ae038f5d9f0fa14d63f9eaea71e0466dc86619 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 15 Dec 2011 10:19:46 -0500 Subject: CMakeAddFortranSubdirectory: Allow full paths to directories Fix the implementation to allow full paths with spaces. Change the interpretation of relative paths to be with respect to the current binary directory. This matches the convention used in ExternalProject. Test both full and relative paths in the VSGNUFortran test. --- Modules/CMakeAddFortranSubdirectory.cmake | 19 +++++++++++++------ .../config_mingw.cmake.in | 3 ++- Tests/VSGNUFortran/CMakeLists.txt | 22 ++++++++++++---------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index 4e351a6..e92dcb4 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -13,14 +13,17 @@ # cmake_add_fortran_subdirectory( # # name of subdirectory # PROJECT # project name in sbudir toplevel CMakeLists.txt -# ARCHIVE_DIR # .lib location relative to root binary tree (lib) -# RUNTIME_DIR # .dll location relative to root binary tree (bin) +# ARCHIVE_DIR # dir where project places .lib files +# RUNTIME_DIR # dir where project places .dll files # LIBRARIES lib2 lib2 # names of libraries created and exported # LINK_LIBRARIES # link interface libraries for LIBRARIES # LINK_LIBS ... # LINK_LIBS ... # CMAKE_COMMAND_LINE # extra command line flags to pass to cmake # ) +# Relative paths in ARCHIVE_DIR and RUNTIME_DIR are interpreted with respect +# to the build directory corresponding to the source directory in which the +# function is invoked. # #============================================================================= @@ -102,6 +105,12 @@ function(cmake_add_fortran_subdirectory subdir) set(libraries ${ARGS_LIBRARIES}) # use the same directory that add_subdirectory would have used set(build_dir "${CMAKE_CURRENT_BINARY_DIR}/${subdir}") + foreach(dir_var library_dir binary_dir) + if(NOT IS_ABSOLUTE "${${dir_var}}") + get_filename_component(${dir_var} + "${CMAKE_CURRENT_BINARY_DIR}/${${dir_var}}" ABSOLUTE) + endif() + endforeach() # create build and configure wrapper scripts _setup_mingw_config_and_build(${source_dir}) # create the external project @@ -128,10 +137,8 @@ function(cmake_add_fortran_subdirectory subdir) add_library(${lib} SHARED IMPORTED) set_property(TARGET ${lib} APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG) set_target_properties(${lib} PROPERTIES - IMPORTED_IMPLIB_NOCONFIG - "${build_dir}/${library_dir}/lib${lib}.lib" - IMPORTED_LOCATION_NOCONFIG - "${build_dir}/${binary_dir}/lib${lib}.dll" + IMPORTED_IMPLIB_NOCONFIG "${library_dir}/lib${lib}.lib" + IMPORTED_LOCATION_NOCONFIG "${binary_dir}/lib${lib}.dll" ) add_dependencies(${lib} ${project_name}_build) endforeach() diff --git a/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in b/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in index 96141da..97f6769 100644 --- a/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in +++ b/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in @@ -1,8 +1,9 @@ set(ENV{PATH} "@MINGW_PATH@\;$ENV{PATH}") +set(CMAKE_COMMAND_LINE "@ARGS_CMAKE_COMMAND_LINE@") execute_process( COMMAND "@CMAKE_COMMAND@" "-GMinGW Makefiles" -DCMAKE_Fortran_COMPILER:PATH=@MINGW_GFORTRAN@ -DBUILD_SHARED_LIBS=ON -DCMAKE_GNUtoMS=ON - @ARGS_CMAKE_COMMAND_LINE@ + ${CMAKE_COMMAND_LINE} "@source_dir@") diff --git a/Tests/VSGNUFortran/CMakeLists.txt b/Tests/VSGNUFortran/CMakeLists.txt index 2e527f9..422350a 100644 --- a/Tests/VSGNUFortran/CMakeLists.txt +++ b/Tests/VSGNUFortran/CMakeLists.txt @@ -1,5 +1,10 @@ cmake_minimum_required(VERSION 2.8) project(VSGNUFortran) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") + # force the executable to be put out of Debug/Release dir # because gmake build of fortran will not be in a config # directory, and for easier testing we want the exe and .dll @@ -7,14 +12,9 @@ project(VSGNUFortran) if(CMAKE_CONFIGURATION_TYPES) foreach(config ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER "${config}" config) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${config} - "${PROJECT_BINARY_DIR}/bin") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${config} - "${PROJECT_BINARY_DIR}/bin") + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) endforeach() -else() - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) endif() include(CMakeAddFortranSubdirectory) @@ -22,11 +22,13 @@ include(CMakeAddFortranSubdirectory) # the subdir is fortran, the project is FortranHello cmake_add_fortran_subdirectory(fortran PROJECT FortranHello # project name in toplevel CMakeLists.txt - ARCHIVE_DIR ../bin # .lib location relative to root binary tree - RUNTIME_DIR ../bin # .dll location relative to root binary tree + ARCHIVE_DIR ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + RUNTIME_DIR bin # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} LIBRARIES hello world # target libraries created - CMAKE_COMMAND_LINE -DEXECUTABLE_OUTPUT_PATH=../bin - -DLIBRARY_OUTPUT_PATH=../bin + CMAKE_COMMAND_LINE + -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} LINK_LIBRARIES # link interface libraries LINK_LIBS hello world # hello needs world to link ) -- cgit v0.12 From d6b031283a686eaeff643a13f8368c7828850229 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 15 Dec 2011 10:48:33 -0500 Subject: CMakeAddFortranSubdirectory: Fix documentation format and typos Indent the function signature correctly. Fix some typos. Fix the copyright year. --- Modules/CMakeAddFortranSubdirectory.cmake | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index e92dcb4..10935a8 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -7,27 +7,25 @@ # an external project to build with the MinGW tools. It will also # create imported targets for the libraries created. This will only # work if the fortran code is built into a dll, so BUILD_SHARED_LIBS -# is turned on in the project. In addition the GNUtoMS option is set -# to on, so that the MS .lib files are created. +# is turned on in the project. In addition the CMAKE_GNUtoMS option +# is set to on, so that the MS .lib files are created. # Usage is as follows: -# cmake_add_fortran_subdirectory( -# # name of subdirectory -# PROJECT # project name in sbudir toplevel CMakeLists.txt -# ARCHIVE_DIR # dir where project places .lib files -# RUNTIME_DIR # dir where project places .dll files -# LIBRARIES lib2 lib2 # names of libraries created and exported -# LINK_LIBRARIES # link interface libraries for LIBRARIES -# LINK_LIBS ... -# LINK_LIBS ... -# CMAKE_COMMAND_LINE # extra command line flags to pass to cmake +# cmake_add_fortran_subdirectory( +# # name of subdirectory +# PROJECT # project name in subdir top CMakeLists.txt +# ARCHIVE_DIR # dir where project places .lib files +# RUNTIME_DIR # dir where project places .dll files +# LIBRARIES ... # names of library targets to import +# LINK_LIBRARIES # link interface libraries for LIBRARIES +# [LINK_LIBS ...]... +# CMAKE_COMMAND_LINE ... # extra command line flags to pass to cmake # ) # Relative paths in ARCHIVE_DIR and RUNTIME_DIR are interpreted with respect # to the build directory corresponding to the source directory in which the # function is invoked. -# #============================================================================= -# Copyright 2002-2009 Kitware, Inc. +# Copyright 2011 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. -- cgit v0.12 From 7e0d9f15d626c13b452bc213172cd54c24f5b41a Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 15 Dec 2011 10:50:55 -0500 Subject: CMakeAddFortranSubdirectory: Find gfortran in PATH In the find_program(MINGW_GFORTRAN) call use the PATHS option for hard-coded guesses instead of HINTS. This allows the user environment to override the guesses and corrects usage of the command options. --- Modules/CMakeAddFortranSubdirectory.cmake | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index 10935a8..d36738c 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -44,10 +44,13 @@ include(ExternalProject) include(CMakeParseArguments) function(_setup_mingw_config_and_build source_dir) - find_program(MINGW_GFORTRAN NAMES gfortran - HINTS - c:/MinGW/bin - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MinGW;InstallLocation]/bin" ) + # Look for a MinGW gfortran. + find_program(MINGW_GFORTRAN + NAMES gfortran + PATHS + c:/MinGW/bin + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MinGW;InstallLocation]/bin" + ) if(NOT MINGW_GFORTRAN) message(FATAL_ERROR "gfortran not found, please install MinGW with the gfortran option." -- cgit v0.12 From 414a780d1c22339e924ea3d880e54482f0d67898 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 15 Dec 2011 11:39:42 -0500 Subject: CMakeAddFortranSubdirectory: Validate gfortran architecture Verify that MINGW_GFORTRAN not only points to a MinGW gfortran but also one that compiles for the target architecture. This prevents using a 32-bit gfortran in a 64-bit MSVC build. --- Modules/CMakeAddFortranSubdirectory.cmake | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index d36738c..c846b55 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -57,12 +57,28 @@ function(_setup_mingw_config_and_build source_dir) "Or set the cache variable MINGW_GFORTRAN to the full path. " " This is required to build") endif() - execute_process(COMMAND ${MINGW_GFORTRAN} -v ERROR_VARIABLE out) - if(NOT "${out}" MATCHES "Target:.*mingw32") - message(FATAL_ERROR "Non-MinGW gfortran found: ${MINGW_GFORTRAN}\n" - "output from -v [${out}]\n" - "set MINGW_GFORTRAN to the path to MinGW fortran.") + + # Validate the MinGW gfortran we found. + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_mingw_target "Target:.*64.*mingw") + else() + set(_mingw_target "Target:.*mingw32") endif() + execute_process(COMMAND "${MINGW_GFORTRAN}" -v + ERROR_VARIABLE out ERROR_STRIP_TRAILING_WHITESPACE) + if(NOT "${out}" MATCHES "${_mingw_target}") + string(REPLACE "\n" "\n " out " ${out}") + message(FATAL_ERROR + "MINGW_GFORTRAN is set to\n" + " ${MINGW_GFORTRAN}\n" + "which is not a MinGW gfortran for this architecture. " + "The output from -v does not match \"${_mingw_target}\":\n" + "${out}\n" + "Set MINGW_GFORTRAN to a proper MinGW gfortran for this architecture." + ) + endif() + + # Configure scripts to run MinGW tools with the proper PATH. get_filename_component(MINGW_PATH ${MINGW_GFORTRAN} PATH) file(TO_NATIVE_PATH "${MINGW_PATH}" MINGW_PATH) string(REPLACE "\\" "\\\\" MINGW_PATH "${MINGW_PATH}") -- cgit v0.12 From bd69e1c567cc4fc1bf30d321d888dd2567d82e7a Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Fri, 16 Dec 2011 17:01:19 -0500 Subject: VSGNUFortran: Add special case for SunPro Fortran runtime library The SunPro compiler does not add the fortran runtime library when creating a shared fortran library. Link to the SunPro Fortran runtime libraries explicitly. --- Tests/VSGNUFortran/fortran/CMakeLists.txt | 36 ++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/Tests/VSGNUFortran/fortran/CMakeLists.txt b/Tests/VSGNUFortran/fortran/CMakeLists.txt index ff22993..3ee1855 100644 --- a/Tests/VSGNUFortran/fortran/CMakeLists.txt +++ b/Tests/VSGNUFortran/fortran/CMakeLists.txt @@ -1,12 +1,46 @@ cmake_minimum_required(VERSION 2.8) project(FortranHello Fortran C) +# add a function to test for -lsunquad on sunpro sun systems. +function(test_sunquad result) + set( TEST_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/sunq") + file(WRITE "${TEST_DIR}/testsunq.f" " + PROGRAM TEST + END + ") + file(WRITE ${TEST_DIR}/CMakeLists.txt " +project(sunq Fortran) +add_library(sunq SHARED testsunq.f) +target_link_libraries(sunq sunquad) +") + message(STATUS "looking for -lsunquad") + try_compile(RESULT "${TEST_DIR}" "${TEST_DIR}" sunq OUTPUT_VARIABLE OUT) + if("${RESULT}") + message(STATUS "-lsunquad found") + else() + message(STATUS "-lsunquad not found") + endif() + message(STATUS + "looking for sunquad:\nRESULT=[${RESULT}]\nOUTPUT=[\n${OUT}\n]") + set(${result} "${RESULT}" PARENT_SCOPE) +endfunction() + +# check for the fortran c interface mangling include(FortranCInterface) FortranCInterface_HEADER(HelloWorldFCMangle.h MACRO_NAMESPACE "FC_" SYMBOL_NAMESPACE "FC_" SYMBOLS hello world) - add_library(hello SHARED hello.f) add_library(world SHARED world.f) target_link_libraries(hello world) +if(CMAKE_Fortran_COMPILER_ID MATCHES SunPro) + target_link_libraries(hello fsu) + if(CMAKE_Fortran_PLATFORM_ID MATCHES SunOS) + target_link_libraries(hello sunmath m) + test_sunquad(CMAKE_HAS_SUNQUAD) + if(CMAKE_HAS_SUNQUAD) + target_link_libraries(hello sunquad) + endif() + endif() +endif() -- cgit v0.12 From 067c1f44a80ed8fb32e56918a57437142c64b049 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Fri, 16 Dec 2011 18:20:46 -0500 Subject: VSGNUFortran: Disable test in special cases The ifort compiler found on some test machines does not support Mac universal binaries or the Linux Standard Base. --- Tests/CMakeLists.txt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index e949887..9c97828 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -170,7 +170,24 @@ IF(BUILD_TESTING) # or in some cases you might need to set the PATH so that cmake can find # the gfortran from mingw. IF(CMAKE_Fortran_COMPILER OR CMAKE_TEST_CMAKE_ADD_FORTRAN) - ADD_TEST_MACRO(VSGNUFortran ${CMAKE_COMMAND} -P runtest.cmake) + SET(CMAKE_SKIP_VSGNUFortran FALSE) + # disable test for apple builds using ifort if they are building + # more than one architecture, as ifort does not support that. + IF(APPLE AND (CMAKE_Fortran_COMPILER MATCHES ifort)) + LIST(LENGTH CMAKE_OSX_ARCHITECTURES len) + IF("${len}" GREATER 1) + MESSAGE(STATUS "Skip VSGNUFortran for ifort dual cpu mac build") + SET(CMAKE_SKIP_VSGNUFortran TRUE) + ENDIF() + ENDIF() + IF((CMAKE_C_COMPILER MATCHES lsb) + AND (CMAKE_Fortran_COMPILER MATCHES ifort)) + MESSAGE(STATUS "Skip VSGNUFortran for ifort and lsb compilers") + SET(CMAKE_SKIP_VSGNUFortran TRUE) + ENDIF() + IF(NOT CMAKE_SKIP_VSGNUFortran) + ADD_TEST_MACRO(VSGNUFortran ${CMAKE_COMMAND} -P runtest.cmake) + ENDIF() ENDIF() ADD_TEST_MACRO(COnly COnly) ADD_TEST_MACRO(CxxOnly CxxOnly) -- cgit v0.12 From 48a09f82ccadf93eb2d60c9efe5da783327a8520 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Fri, 27 Jan 2012 11:14:00 -0500 Subject: CMakeAddFortranSubdirectory: Make IMPORTED targets GLOBAL cmake_add_fortran_directory uses imported targets when using the mingw fortran compiler. This change makes those targets global in scope so they act just like the real targets that exist when a fortran compiler exists and regular add_subdirectory is used. --- Modules/CMakeAddFortranSubdirectory.cmake | 4 +-- Tests/VSGNUFortran/CMakeLists.txt | 19 ++-------- Tests/VSGNUFortran/fortran/CMakeLists.txt | 46 ------------------------ Tests/VSGNUFortran/fortran/hello.f | 7 ---- Tests/VSGNUFortran/fortran/world.f | 6 ---- Tests/VSGNUFortran/subdir/CMakeLists.txt | 15 ++++++++ Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt | 46 ++++++++++++++++++++++++ Tests/VSGNUFortran/subdir/fortran/hello.f | 7 ++++ Tests/VSGNUFortran/subdir/fortran/world.f | 6 ++++ 9 files changed, 78 insertions(+), 78 deletions(-) delete mode 100644 Tests/VSGNUFortran/fortran/CMakeLists.txt delete mode 100644 Tests/VSGNUFortran/fortran/hello.f delete mode 100644 Tests/VSGNUFortran/fortran/world.f create mode 100644 Tests/VSGNUFortran/subdir/CMakeLists.txt create mode 100644 Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt create mode 100644 Tests/VSGNUFortran/subdir/fortran/hello.f create mode 100644 Tests/VSGNUFortran/subdir/fortran/world.f diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index c846b55..5c3e9a2 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -25,7 +25,7 @@ # function is invoked. #============================================================================= -# Copyright 2011 Kitware, Inc. +# Copyright 2011-2012 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -151,7 +151,7 @@ function(cmake_add_fortran_subdirectory subdir) ) # create imported targets for all libraries foreach(lib ${libraries}) - add_library(${lib} SHARED IMPORTED) + add_library(${lib} SHARED IMPORTED GLOBAL) set_property(TARGET ${lib} APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG) set_target_properties(${lib} PROPERTIES IMPORTED_IMPLIB_NOCONFIG "${library_dir}/lib${lib}.lib" diff --git a/Tests/VSGNUFortran/CMakeLists.txt b/Tests/VSGNUFortran/CMakeLists.txt index 422350a..229c315 100644 --- a/Tests/VSGNUFortran/CMakeLists.txt +++ b/Tests/VSGNUFortran/CMakeLists.txt @@ -17,23 +17,8 @@ if(CMAKE_CONFIGURATION_TYPES) endforeach() endif() -include(CMakeAddFortranSubdirectory) -# add the fortran subdirectory as a fortran project -# the subdir is fortran, the project is FortranHello -cmake_add_fortran_subdirectory(fortran - PROJECT FortranHello # project name in toplevel CMakeLists.txt - ARCHIVE_DIR ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - RUNTIME_DIR bin # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARIES hello world # target libraries created - CMAKE_COMMAND_LINE - -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - LINK_LIBRARIES # link interface libraries - LINK_LIBS hello world # hello needs world to link - ) - -include_directories(${VSGNUFortran_BINARY_DIR}/fortran) +add_subdirectory(subdir) +include_directories(${VSGNUFortran_BINARY_DIR}/subdir/fortran) add_subdirectory(c_code) # use a cmake script to run the executable so that PATH # can be set with the MinGW/bin in it, and the fortran diff --git a/Tests/VSGNUFortran/fortran/CMakeLists.txt b/Tests/VSGNUFortran/fortran/CMakeLists.txt deleted file mode 100644 index 3ee1855..0000000 --- a/Tests/VSGNUFortran/fortran/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -cmake_minimum_required(VERSION 2.8) -project(FortranHello Fortran C) - -# add a function to test for -lsunquad on sunpro sun systems. -function(test_sunquad result) - set( TEST_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/sunq") - file(WRITE "${TEST_DIR}/testsunq.f" " - PROGRAM TEST - END - ") - file(WRITE ${TEST_DIR}/CMakeLists.txt " -project(sunq Fortran) -add_library(sunq SHARED testsunq.f) -target_link_libraries(sunq sunquad) -") - message(STATUS "looking for -lsunquad") - try_compile(RESULT "${TEST_DIR}" "${TEST_DIR}" sunq OUTPUT_VARIABLE OUT) - if("${RESULT}") - message(STATUS "-lsunquad found") - else() - message(STATUS "-lsunquad not found") - endif() - message(STATUS - "looking for sunquad:\nRESULT=[${RESULT}]\nOUTPUT=[\n${OUT}\n]") - set(${result} "${RESULT}" PARENT_SCOPE) -endfunction() - -# check for the fortran c interface mangling -include(FortranCInterface) -FortranCInterface_HEADER(HelloWorldFCMangle.h - MACRO_NAMESPACE "FC_" - SYMBOL_NAMESPACE "FC_" - SYMBOLS hello world) -add_library(hello SHARED hello.f) -add_library(world SHARED world.f) -target_link_libraries(hello world) -if(CMAKE_Fortran_COMPILER_ID MATCHES SunPro) - target_link_libraries(hello fsu) - if(CMAKE_Fortran_PLATFORM_ID MATCHES SunOS) - target_link_libraries(hello sunmath m) - test_sunquad(CMAKE_HAS_SUNQUAD) - if(CMAKE_HAS_SUNQUAD) - target_link_libraries(hello sunquad) - endif() - endif() -endif() diff --git a/Tests/VSGNUFortran/fortran/hello.f b/Tests/VSGNUFortran/fortran/hello.f deleted file mode 100644 index e52119a..0000000 --- a/Tests/VSGNUFortran/fortran/hello.f +++ /dev/null @@ -1,7 +0,0 @@ -!DEC$ ATTRIBUTES DLLEXPORT :: HELLO - SUBROUTINE HELLO - - PRINT *, 'Hello' - CALL WORLD - - END diff --git a/Tests/VSGNUFortran/fortran/world.f b/Tests/VSGNUFortran/fortran/world.f deleted file mode 100644 index 0598eee..0000000 --- a/Tests/VSGNUFortran/fortran/world.f +++ /dev/null @@ -1,6 +0,0 @@ -!DEC$ ATTRIBUTES DLLEXPORT :: WORLD - SUBROUTINE WORLD - - PRINT *, 'World!' - - END diff --git a/Tests/VSGNUFortran/subdir/CMakeLists.txt b/Tests/VSGNUFortran/subdir/CMakeLists.txt new file mode 100644 index 0000000..df018b3 --- /dev/null +++ b/Tests/VSGNUFortran/subdir/CMakeLists.txt @@ -0,0 +1,15 @@ +include(CMakeAddFortranSubdirectory) +# add the fortran subdirectory as a fortran project +# the subdir is fortran, the project is FortranHello +cmake_add_fortran_subdirectory(fortran + PROJECT FortranHello # project name in toplevel CMakeLists.txt + ARCHIVE_DIR ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + RUNTIME_DIR bin # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARIES hello world # target libraries created + CMAKE_COMMAND_LINE + -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + LINK_LIBRARIES # link interface libraries + LINK_LIBS hello world # hello needs world to link + ) diff --git a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt new file mode 100644 index 0000000..3ee1855 --- /dev/null +++ b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 2.8) +project(FortranHello Fortran C) + +# add a function to test for -lsunquad on sunpro sun systems. +function(test_sunquad result) + set( TEST_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/sunq") + file(WRITE "${TEST_DIR}/testsunq.f" " + PROGRAM TEST + END + ") + file(WRITE ${TEST_DIR}/CMakeLists.txt " +project(sunq Fortran) +add_library(sunq SHARED testsunq.f) +target_link_libraries(sunq sunquad) +") + message(STATUS "looking for -lsunquad") + try_compile(RESULT "${TEST_DIR}" "${TEST_DIR}" sunq OUTPUT_VARIABLE OUT) + if("${RESULT}") + message(STATUS "-lsunquad found") + else() + message(STATUS "-lsunquad not found") + endif() + message(STATUS + "looking for sunquad:\nRESULT=[${RESULT}]\nOUTPUT=[\n${OUT}\n]") + set(${result} "${RESULT}" PARENT_SCOPE) +endfunction() + +# check for the fortran c interface mangling +include(FortranCInterface) +FortranCInterface_HEADER(HelloWorldFCMangle.h + MACRO_NAMESPACE "FC_" + SYMBOL_NAMESPACE "FC_" + SYMBOLS hello world) +add_library(hello SHARED hello.f) +add_library(world SHARED world.f) +target_link_libraries(hello world) +if(CMAKE_Fortran_COMPILER_ID MATCHES SunPro) + target_link_libraries(hello fsu) + if(CMAKE_Fortran_PLATFORM_ID MATCHES SunOS) + target_link_libraries(hello sunmath m) + test_sunquad(CMAKE_HAS_SUNQUAD) + if(CMAKE_HAS_SUNQUAD) + target_link_libraries(hello sunquad) + endif() + endif() +endif() diff --git a/Tests/VSGNUFortran/subdir/fortran/hello.f b/Tests/VSGNUFortran/subdir/fortran/hello.f new file mode 100644 index 0000000..e52119a --- /dev/null +++ b/Tests/VSGNUFortran/subdir/fortran/hello.f @@ -0,0 +1,7 @@ +!DEC$ ATTRIBUTES DLLEXPORT :: HELLO + SUBROUTINE HELLO + + PRINT *, 'Hello' + CALL WORLD + + END diff --git a/Tests/VSGNUFortran/subdir/fortran/world.f b/Tests/VSGNUFortran/subdir/fortran/world.f new file mode 100644 index 0000000..0598eee --- /dev/null +++ b/Tests/VSGNUFortran/subdir/fortran/world.f @@ -0,0 +1,6 @@ +!DEC$ ATTRIBUTES DLLEXPORT :: WORLD + SUBROUTINE WORLD + + PRINT *, 'World!' + + END -- cgit v0.12 From 6f6891b33736918f149279dc7d1e9ade50efd917 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Feb 2012 11:55:07 -0500 Subject: CMakeAddFortranSubdirectory: Always parse arguments Parse arguments even in add_subdirectory() mode to validate them. --- Modules/CMakeAddFortranSubdirectory.cmake | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index 5c3e9a2..681b09e 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -99,6 +99,11 @@ endfunction() function(cmake_add_fortran_subdirectory subdir) + # Parse arguments to function + set(oneValueArgs PROJECT ARCHIVE_DIR RUNTIME_DIR) + set(multiValueArgs LIBRARIES LINK_LIBRARIES CMAKE_COMMAND_LINE) + cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + # if we are not using MSVC without fortran support # then just use the usual add_subdirectory to build # the fortran library @@ -111,10 +116,6 @@ function(cmake_add_fortran_subdirectory subdir) # if we have MSVC without Intel fortran then setup # external projects to build with mingw fortran - # Parse arguments to function - set(oneValueArgs PROJECT ARCHIVE_DIR RUNTIME_DIR) - set(multiValueArgs LIBRARIES LINK_LIBRARIES CMAKE_COMMAND_LINE) - cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}") set(project_name "${ARGS_PROJECT}") set(library_dir "${ARGS_ARCHIVE_DIR}") -- cgit v0.12 From 1e16406dc9a8c5bdad7adbed8c3b6cee0a7020d0 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 8 Feb 2012 11:58:57 -0500 Subject: CMakeAddFortranSubdirectory: Add NO_EXTERNAL_INSTALL option We do not yet support "make install" in the external project case. Document this explicitly in the interface. Require the caller to use an option to "disable" the unsupported behavior. This will allow us to add the behavior by default in the future without clobbering existing projects that handle the installation themselves. --- Modules/CMakeAddFortranSubdirectory.cmake | 16 +++++++++++++++- Tests/VSGNUFortran/subdir/CMakeLists.txt | 3 ++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index 681b09e..ddb79fb 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -19,10 +19,17 @@ # LINK_LIBRARIES # link interface libraries for LIBRARIES # [LINK_LIBS ...]... # CMAKE_COMMAND_LINE ... # extra command line flags to pass to cmake +# NO_EXTERNAL_INSTALL # skip installation of external project # ) # Relative paths in ARCHIVE_DIR and RUNTIME_DIR are interpreted with respect # to the build directory corresponding to the source directory in which the # function is invoked. +# +# Limitations: +# +# NO_EXTERNAL_INSTALL is required for forward compatibility with a +# future version that supports installation of the external project +# binaries during "make install". #============================================================================= # Copyright 2011-2012 Kitware, Inc. @@ -100,9 +107,16 @@ endfunction() function(cmake_add_fortran_subdirectory subdir) # Parse arguments to function + set(options NO_EXTERNAL_INSTALL) set(oneValueArgs PROJECT ARCHIVE_DIR RUNTIME_DIR) set(multiValueArgs LIBRARIES LINK_LIBRARIES CMAKE_COMMAND_LINE) - cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(NOT ARGS_NO_EXTERNAL_INSTALL) + message(FATAL_ERROR + "Option NO_EXTERNAL_INSTALL is required (for forward compatibility) " + "but was not given." + ) + endif() # if we are not using MSVC without fortran support # then just use the usual add_subdirectory to build diff --git a/Tests/VSGNUFortran/subdir/CMakeLists.txt b/Tests/VSGNUFortran/subdir/CMakeLists.txt index df018b3..0b99199 100644 --- a/Tests/VSGNUFortran/subdir/CMakeLists.txt +++ b/Tests/VSGNUFortran/subdir/CMakeLists.txt @@ -12,4 +12,5 @@ cmake_add_fortran_subdirectory(fortran -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} LINK_LIBRARIES # link interface libraries LINK_LIBS hello world # hello needs world to link - ) + NO_EXTERNAL_INSTALL + ) -- cgit v0.12