2016-09-27 6 views
0

У меня есть намного больше, мне нужно разобраться с CMake, а не только следующей проблемой, но это первый и самый простой, который я до сих пор не могу пройти. Я прочесывал interwebs и даже заимствовал книгу «Mastering CMake» от друга, но мне все еще тяжело ... Много вещей существует в Интернете в отношении CMake, Fortran и MinGW, и даже комбинации по два за раз. Но все три вместе кажутся почти несуществующими.Как создать/скомпилировать Fortran с помощью MinGW gfortran через CMake?

Все, что я хочу сделать (на данном этапе), - это простая программа Fortran, созданная и компилирующая с использованием CMake в Windows с использованием компилятора MinGW gfortran.

... И я CMake n00b.

Это то, что я работаю с до сих пор:

CMakeLists.txt:

project(cmake_test Fortran) 
add_executable(testf test.f90) 

test.f90:

 program test 
     write(*,*)"hello world" 
     endprogram test 

У меня есть версия MSYS2 MinGW, так как это единственная версия, которую код, который я собираюсь собирать, будет компилировать w в Windows. (Т.е. когда я скомпилирую его со своим собственным Makefile в оболочке MSYS2, он компилируется.)

У меня есть мой путь к Windows с добавлением ;C:\msys64\mingw64\bin. (Я также попытался ;C:\msys64\usr\bin, но он жалуется на sh.exe быть в том же каталоге, среди других вопросов.)

Тогда я поп открыть CMake-GUI, нагрузки в вышеуказанных CMakeLists, нажмите Настроить, задайте генератор для проект будет «MinGW Makefiles», выберите «Использовать по умолчанию родной компиляторы», и получить следующий вывод:

The Fortran compiler identification is GNU 5.4.0 
Check for working Fortran compiler: C:/msys64/mingw64/bin/gfortran.exe 
Check for working Fortran compiler: C:/msys64/mingw64/bin/gfortran.exe -- works 
Detecting Fortran compiler ABI info 
Detecting Fortran compiler ABI info - done 
Checking whether C:/msys64/mingw64/bin/gfortran.exe supports Fortran 90 
Checking whether C:/msys64/mingw64/bin/gfortran.exe supports Fortran 90 -- yes 
Configuring done 

Затем я снова нажмите кнопку Настроить и получить:

Configuring done 

Затем Сформировать:

Generating done 

В моем каталоге сборки есть файл Makefile и ряд других файлов и каталогов.

Я стараюсь работаю сделать в MSYS2 оболочке, и я получаю это:

[email protected] MSYS /c/users/myself/desktop/dll_test/with_fortran_cmake/build 
$ make 
Microsoft Windows [Version 6.1.7601] 
Copyright (c) 2009 Microsoft Corporation. All rights reserved. 

C:\users\myself\desktop\dll_test\with_fortran_cmake\build> 

Это последняя строка подсказки. Если я набираю такие вещи, как make, кажется, он снова запускает его, и он снова выводит подсказку снова в подсказке. Если я нажму Ctrl + C, он убьет его и вернется в обычную подсказку MSYS2.

Так что я не могу понять, как это сделать, предполагая, что я даже делаю часть CMake правильно.

Вопрос: Как получить этот примерный код для сборки/компиляции/выполнения с учетом ограничений, перечисленных мной?

(Что бы я на самом деле делал, как только я получу эту часть, я получаю его для работы с Visual Studio 13, так как у меня есть проект на C++, созданный с помощью CMake (написанный в основном кем-то другим, которому я имеют ограниченный доступ для вопросов и помощи), из которых я хочу иметь возможность называть мой Fortran. Как только я получаю Fortran в библиотеку какого-либо типа, которая может быть вызвана C++ из Visual Studio, Fortran может в значительной степени просто остаться в покое как предварительно построенная библиотека. Я знаю, что редактирование Fortran от VS не очень много о возможности, и я не заинтересован в этом его.)

Вот содержимое генерируемого Makefile (обратите внимание на моем редактор заменил вкладки с помощью пробела эс, когда я скопировал его здесь): информация

# CMAKE generated file: DO NOT EDIT! 
# Generated by "MinGW Makefiles" Generator, CMake Version 3.5 

# Default target executed when no arguments are given to make. 
default_target: all 

.PHONY : default_target 

# Allow only one "make -f Makefile2" at a time, but pass parallelism. 
.NOTPARALLEL: 


#============================================================================= 
# Special targets provided by cmake. 

# Disable implicit rules so canonical targets will work. 
.SUFFIXES: 


# Remove some rules from gmake that .SUFFIXES does not remove. 
SUFFIXES = 

.SUFFIXES: .hpux_make_needs_suffix_list 


# Suppress display of executed commands. 
$(VERBOSE).SILENT: 


# A target that is always out of date. 
cmake_force: 

.PHONY : cmake_force 

#============================================================================= 
# Set environment variables for the build. 

SHELL = cmd.exe 

# The CMake executable. 
CMAKE_COMMAND = "C:\Program Files (x86)\CMake\bin\cmake.exe" 

# The command to remove a file. 
RM = "C:\Program Files (x86)\CMake\bin\cmake.exe" -E remove -f 

# Escaping for special characters. 
EQUALS = = 

# The top-level source directory on which CMake was run. 
CMAKE_SOURCE_DIR = C:\Users\myself\Desktop\dll_test\with_fortran_cmake 

# The top-level build directory on which CMake was run. 
CMAKE_BINARY_DIR = C:\Users\myself\Desktop\dll_test\with_fortran_cmake\build 

#============================================================================= 
# Targets provided globally by CMake. 

# Special rule for the target edit_cache 
edit_cache: 
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..." 
    "C:\Program Files (x86)\CMake\bin\cmake-gui.exe" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) 
.PHONY : edit_cache 

# Special rule for the target edit_cache 
edit_cache/fast: edit_cache 

.PHONY : edit_cache/fast 

# Special rule for the target rebuild_cache 
rebuild_cache: 
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." 
    "C:\Program Files (x86)\CMake\bin\cmake.exe" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) 
.PHONY : rebuild_cache 

# Special rule for the target rebuild_cache 
rebuild_cache/fast: rebuild_cache 

.PHONY : rebuild_cache/fast 

# The main all target 
all: cmake_check_build_system 
    $(CMAKE_COMMAND) -E cmake_progress_start C:\Users\myself\Desktop\dll_test\with_fortran_cmake\build\CMakeFiles C:\Users\myself\Desktop\dll_test\with_fortran_cmake\build\CMakeFiles\progress.marks 
    $(MAKE) -f CMakeFiles\Makefile2 all 
    $(CMAKE_COMMAND) -E cmake_progress_start C:\Users\myself\Desktop\dll_test\with_fortran_cmake\build\CMakeFiles 0 
.PHONY : all 

# The main clean target 
clean: 
    $(MAKE) -f CMakeFiles\Makefile2 clean 
.PHONY : clean 

# The main clean target 
clean/fast: clean 

.PHONY : clean/fast 

# Prepare targets for installation. 
preinstall: all 
    $(MAKE) -f CMakeFiles\Makefile2 preinstall 
.PHONY : preinstall 

# Prepare targets for installation. 
preinstall/fast: 
    $(MAKE) -f CMakeFiles\Makefile2 preinstall 
.PHONY : preinstall/fast 

# clear depends 
depend: 
    $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles\Makefile.cmake 1 
.PHONY : depend 

#============================================================================= 
# Target rules for targets named testf 

# Build rule for target. 
testf: cmake_check_build_system 
    $(MAKE) -f CMakeFiles\Makefile2 testf 
.PHONY : testf 

# fast build rule for target. 
testf/fast: 
    $(MAKE) -f CMakeFiles\testf.dir\build.make CMakeFiles/testf.dir/build 
.PHONY : testf/fast 

test.obj: test.f90.obj 

.PHONY : test.obj 

# target to build an object file 
test.f90.obj: 
    $(MAKE) -f CMakeFiles\testf.dir\build.make CMakeFiles/testf.dir/test.f90.obj 
.PHONY : test.f90.obj 

test.i: test.f90.i 

.PHONY : test.i 

# target to preprocess a source file 
test.f90.i: 
    $(MAKE) -f CMakeFiles\testf.dir\build.make CMakeFiles/testf.dir/test.f90.i 
.PHONY : test.f90.i 

test.s: test.f90.s 

.PHONY : test.s 

# target to generate assembly for a file 
test.f90.s: 
    $(MAKE) -f CMakeFiles\testf.dir\build.make CMakeFiles/testf.dir/test.f90.s 
.PHONY : test.f90.s 

# Help Target 
help: 
    @echo The following are some of the valid targets for this Makefile: 
    @echo ... all (the default if no target is provided) 
    @echo ... clean 
    @echo ... depend 
    @echo ... testf 
    @echo ... edit_cache 
    @echo ... rebuild_cache 
    @echo ... test.obj 
    @echo ... test.i 
    @echo ... test.s 
.PHONY : help 



#============================================================================= 
# Special targets to cleanup operation of make. 

# Special rule to run CMake to check the build system integrity. 
# No rule that depends on this can have commands that come from listfiles 
# because they might be regenerated. 
cmake_check_build_system: 
    $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles\Makefile.cmake 0 
.PHONY : cmake_check_build_system 

Версия:

  • GNU Fortran (GCC) 5.3.0
  • Windows 7 Enterprise
  • Cmake 3.5.2
  • MSYS2 - я не уверен, как найти версию для этого
  • MinGW - Я не уверен, как найти versio n для этого

В ходе поиска я просматривал множество разных страниц в сети, и я не беспокоился о том, чтобы отслеживать их всех, но это, в частности, тот, который я постоянно встречаю, потому что кажется как это очень родственные из названия, но реальная проблема и решение совершенно не так:

+0

Вместо этого следует попытаться использовать генератор «MSYS Makefiles»; это то, что я всегда использую, когда я использую CMake и MSYS2. Дайте мне знать, если это не сработает. –

+0

Doh! Я пропустил этот вариант! ... Однако, когда я пытаюсь это сделать и нажимаю Configure: –

+0

'Ошибка CMake: CMake не смог найти программу сборки, соответствующую« MSYS Makefiles ». CMAKE_MAKE_PROGRAM не установлен. Вероятно, вам нужно выбрать другой инструмент построения. ' ' Ошибка CMake: CMake не удалось найти программу сборки, соответствующую «MSYS Makefiles». CMAKE_MAKE_PROGRAM не установлен. Вероятно, вам нужно выбрать другой инструмент построения. ' ' Ошибка CMake: CMAKE_Fortran_COMPILER не установлен после EnableLanguage' 'Ошибка CMake: CMAKE_AR не был найден, пожалуйста, установите в архивную программу. Ошибка при настройке! ' –

ответ

1

Вот краткий сеанс оболочки, показывающий, как я смог построить свой Фортран с помощью MSYS2, cmake, make и gfortran. Вы должны попробовать выполнить те же команды, что и я, и посмотреть, дают ли они разные результаты, а затем исследуют причину.

Переменная MSYSTEM особенно важна; он определяется тем, на какой ярлык вы нажимаете при запуске MSYS2.

$ echo $MSYSTEM 
MINGW64 

$ which cmake 
/mingw64/bin/cmake 

$ which gfortran 
/mingw64/bin/gfortran 

$ which make 
/usr/bin/make 

$ ls 
CMakeLists.txt test.f90 

$ cat CMakeLists.txt 
project(cmake_test Fortran) 
add_executable(testf test.f90) 

$ cat test.f90 
     program test 
     write(*,*)"hello world" 
     endprogram test 

$ mkdir build && cd build 

$ cmake -G"MSYS Makefiles" .. 
-- The Fortran compiler identification is GNU 6.2.0 
-- Check for working Fortran compiler: D:/msys64/mingw64/bin/gfortran.exe 
-- Check for working Fortran compiler: D:/msys64/mingw64/bin/gfortran.exe -- works 
-- Detecting Fortran compiler ABI info 
-- Detecting Fortran compiler ABI info - done 
-- Checking whether D:/msys64/mingw64/bin/gfortran.exe supports Fortran 90 
-- Checking whether D:/msys64/mingw64/bin/gfortran.exe supports Fortran 90 -- yes 
-- Configuring done 
-- Generating done 
-- Build files have been written to: C:/Users/david/Documents/scraps/test_fortran/build 

$ make 
Scanning dependencies of target testf 
[ 50%] Building Fortran object CMakeFiles/testf.dir/test.f90.obj 
[100%] Linking Fortran executable testf.exe 
[100%] Built target testf 

$ ./testf.exe 
hello world 
+0

некоторые важные отличия ... '$ Эхо $ MSYSTEM' ' MSYS' и '$, который cmake' ' который: no cmake in (/ usr/local/bin:/usr/bin:/bin:/opt/bin:/c/Windows/System32:/c/Windows:/c/Windows/System32/Wbem: /c/Windows/System32/WindowsPowerShell/v1.0 /:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl) ' и ' $, которые gfortran' '/ usr/bin/gfortran' –

+0

Какой ярлык я должен нажимать? Обычно я запускаю 'C: \ msys64 \ msys2.exe' –

+0

Попробуйте запустить mingw32.exe или mingw64.exe, в зависимости от того, хотите ли вы выполнить 32-разрядный или 64-разрядный исполняемый файл. Или найдите ярлыки «MinGW-w64 Win32 Shell» или «MinGW-w64 Win64 Shell» в меню «Пуск». Поскольку вы пытаетесь интегрироваться с Visual Studio, вам почти наверняка не нужна оболочка MSYS2 (msys2.exe); вместо этого вы хотите создать собственный исполняемый файл Windows. –

0

Редактировать: Здесь есть рабочее решение - читайте до конца!

Благодаря комментарию Дэвида Грейсона по первому вопросу, я нашел частичное решение. «Частичный», потому что вместо gfortran он использует f95. Я отправляю его, потому что он может работать для кого-то другого, и если я смогу понять, как заставить его работать с gfortran, я просто его обновлю.

Оказывается, основная проблема была довольно простой ошибкой: я использовал «MinGW Makefiles» instad из «MSYS Makefiles».

Когда я только изменил это, однако, я получил следующий вывод в CMake-GUI, когда я нажал Конфигурация:

CMake Error: CMake was unable to find a build program corresponding to "MSYS Makefiles". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool. 
CMake Error: CMake was unable to find a build program corresponding to "MSYS Makefiles". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool. 
CMake Error: CMAKE_Fortran_COMPILER not set, after EnableLanguage 
CMake Error: CMAKE_AR was not found, please set to archive program. Configuring incomplete, errors occurred! 

Чтобы это исправить, я снова изменил свой путь Windows. Я использовал ;C:\msys64\mingw64\bin, поэтому я переключил его на ;C:\msys64\usr\bin.

Это тогда работал (я нажал Configure во второй раз, нажал Генерировать, а затем побежал make через терминал MSYS2 в каталоге /build), но, как вы можете увидеть в следующих выходных, он использовал F95 вместо gfortran:

The Fortran compiler identification is GNU 5.3.0 
Check for working Fortran compiler: C:/msys64/usr/bin/f95.exe 
Check for working Fortran compiler: C:/msys64/usr/bin/f95.exe -- works 
Detecting Fortran compiler ABI info 
Detecting Fortran compiler ABI info - done 
Checking whether C:/msys64/usr/bin/f95.exe supports Fortran 90 
Checking whether C:/msys64/usr/bin/f95.exe supports Fortran 90 -- yes 
Configuring done 

Я все еще работаю, чтобы заставить его использовать gfortran, и я обновлю это решение, если выясню это.

Edit:

Хорошо, это, очевидно, больше рубить, и я уверен, что есть лучшее решение. Я переименовал C:\msys64\usr\bin\f95.exe в нечто другое (чтобы MSYS2 не нашел его другим компилятором Fortran, прежде чем найти gfortran). Я также должен был очистить кэш CMake и перезапустить его. Но теперь это работает:

The Fortran compiler identification is GNU 5.3.0 
Check for working Fortran compiler: C:/msys64/usr/bin/gfortran.exe 
Check for working Fortran compiler: C:/msys64/usr/bin/gfortran.exe -- works 
Detecting Fortran compiler ABI info 
Detecting Fortran compiler ABI info - done 
Checking whether C:/msys64/usr/bin/gfortran.exe supports Fortran 90 
Checking whether C:/msys64/usr/bin/gfortran.exe supports Fortran 90 -- yes 
Configuring done 

Работая над выяснением, как это сделать, «правильный» способ.

Edit:

Хорошо, я предполагаю, что это более правильный способ сделать это, как я предполагаю, что это по существу делает то же самое, что и установка переменных среды в командной строке при вызове CMake оттуда.

В CMake-GUI я задал все, как описано ранее, но прежде чем нажимать «Настроить» в первый раз, я нажал кнопку «Добавить запись» с символом «маленький плюс». Затем я установил два новых записей кэша - хотя только один действительно необходимо:

Name: CMAKE_Fortran_COMPILER 
Type: FILEPATH 
Value: C:\msys64\usr\bin\gfortran.exe 

Я также установил следующее, но это было только проверить, что она звала gfortran должным образом, как вы увидите в выводе ниже:

Name: CMAKE_VERBOSE_MAKEFILE 
Type: BOOL 
Value: [True] 

Затем выполняется make в терминале MSYS2, я получил следующее:

$ make 
"/C/Program Files (x86)/CMake/bin/cmake.exe" -H/C/Users/myself/Desktop/dll_test/with_fortran_cmake -B/C/Users/myself/Desktop/dll_test/with_fortran_cmake/build --check-build-system CMakeFiles/Makefile.cmake 0 
"/C/Program Files (x86)/CMake/bin/cmake.exe" -E cmake_progress_start /C/Users/myself/Desktop/dll_test/with_fortran_cmake/build/CMakeFiles /C/Users/myself/Desktop/dll_test/with_fortran_cmake/build/CMakeFiles/progress.marks 
make -f CMakeFiles/Makefile2 all 
make[1]: Entering directory '/c/Users/myself/Desktop/dll_test/with_fortran_cmake/build' 
make -f CMakeFiles/testf.dir/build.make CMakeFiles/testf.dir/depend 
make[2]: Entering directory '/c/Users/myself/Desktop/dll_test/with_fortran_cmake/build' 
"/C/Program Files (x86)/CMake/bin/cmake.exe" -E cmake_depends "MSYS Makefiles" /C/Users/myself/Desktop/dll_test/with_fortran_cmake /C/Users/myself/Desktop/dll_test/with_fortran_cmake /C/Users/myself/Desktop/dll_test/with_fortran_cmake/build /C/Users/myself/Desktop/dll_test/with_fortran_cmake/build /C/Users/myself/Desktop/dll_test/with_fortran_cmake/build/CMakeFiles/testf.dir/DependInfo.cmake --color= 
Scanning dependencies of target testf 
make[2]: Leaving directory '/c/Users/myself/Desktop/dll_test/with_fortran_cmake/build' 
make -f CMakeFiles/testf.dir/build.make CMakeFiles/testf.dir/requires 
make[2]: Entering directory '/c/Users/myself/Desktop/dll_test/with_fortran_cmake/build' 
make[2]: Nothing to be done for 'CMakeFiles/testf.dir/requires'. 
make[2]: Leaving directory '/c/Users/myself/Desktop/dll_test/with_fortran_cmake/build' 
make -f CMakeFiles/testf.dir/build.make CMakeFiles/testf.dir/build 
make[2]: Entering directory '/c/Users/myself/Desktop/dll_test/with_fortran_cmake/build' 
[ 50%] Building Fortran object CMakeFiles/testf.dir/test.f90.obj 
/C/msys64/usr/bin/gfortran.exe  -c /C/Users/myself/Desktop/dll_test/with_fortran_cmake/test.f90 -o CMakeFiles/testf.dir/test.f90.obj 
[100%] Linking Fortran executable testf.exe 
"/C/Program Files (x86)/CMake/bin/cmake.exe" -E remove -f CMakeFiles/testf.dir/objects.a 
/C/msys64/usr/bin/ar.exe cr CMakeFiles/testf.dir/objects.a @CMakeFiles/testf.dir/objects1.rsp 
/C/msys64/usr/bin/gfortran.exe  -Wl,--whole-archive CMakeFiles/testf.dir/objects.a -Wl,--no-whole-archive -o testf.exe -Wl,--out-implib,libtestf.dll.a -Wl,--major-image-version,0,--minor-image-version,0 
make[2]: Leaving directory '/c/Users/myself/Desktop/dll_test/with_fortran_cmake/build' 
[100%] Built target testf 
make[1]: Leaving directory '/c/Users/myself/Desktop/dll_test/with_fortran_cmake/build' 
"/C/Program Files (x86)/CMake/bin/cmake.exe" -E cmake_progress_start /C/Users/myself/Desktop/dll_test/with_fortran_cmake/build/CMakeFiles 0 

и результирующая программа работает как через терминал MSYS2 и окна s командной строки.

... Теперь мне нужно выяснить, как получить все это вместе с C++ в Visual Studio. Оставайтесь с нами для более вопросов! : D

+0

Если вы запустите cmake-gui, Я бы предложил запустить cmake-gui из оболочки MSYS2/MinGW, поэтому у него есть уже установленная PATH; нет необходимости редактировать переменные среды Windows с помощью интерфейса Microsoft. –

+0

Кроме того, поскольку вы скомпилировали исполняемый файл, который зависит от уровня эмуляции msys-2.0.dll POSIX, я скептически отношусь к его интеграции с Visual Studio, который использует среду Microsoft Visual C (msvcrt * .dll). –

+0

Получил. Я запускаю cmake-gui из контекстного меню «Пуск», потому что именно так работает код C++, на который я нацелен интегрироваться. Я не могу сказать людям «Когда вы создаете эту часть, вам нужно сначала открыть командную строку ...» У вас есть предложение о том, как лучше интегрировать ее с Visual Studio? –

 Смежные вопросы

  • Нет связанных вопросов^_^