軟件環境
# 操作系統 = Windows10
# 編譯鏈工具 =
# gcc, g++, GNU Fortran (MinGW.org GCC Build-2) 9.2.0
# GNU Make 3.82.90 Built for i686-pc-mingw32
# GNU ld (GNU Binutils) 2.32
# CMake version 3.18.1
本機安裝了MinGW編譯工具,並將<安裝路徑>\MinGW\bin
添加到環境變量中。
Windows下CMake編譯配置
設置項目的generator
在本機使用CMake過程中發現,默認使用NMake Makefiles
作為generator,因為沒有安裝因此配置失敗。
希望設置generator為已安裝的MinGW Makefiles
。
Command Line
cmake .. -G "MinGW Makefiles"
CMake GUI
初次Configure
時指定項目的generator。
選用MinGW Makefiles
,使用默認編譯器。
如果已經指定generator后,需要修改。可以清除CMake Cache
后再次Configure
,File->Delete Cache
。
PreLoad.cmake
CMake設置generator是在處理CMakeLists.txt之前的,因此不能通過在CMakeLists.txt中設置CMAKE_GENERATOR
達到修改默認generator的作用。
可以在項目根目錄添加PreLoad.cmake
這樣的文件實現預先修改配置,內容如下。
set(CMAKE_GENERATOR "MinGW Makefiles" CACHE INTERNAL "" FORCE)
設置make
即使已為MinGW添加了環境變量,但是不能在命令行中直接使用make。gcc、g++、gfortran可以直接使用。
是因為在<安裝路徑>\MinGW\bin
下,對應make的可執行程序名字為mingw32-make
,在同目錄下拷貝一份,重命名為make即可使用。
示例程序
CMake
以下為CMakeLists.txt文件內容,
# name: exe_test
# date: 2021/3/14
#
cmake_minimum_required(VERSION 3.3)
project(exe_test CXX Fortran)
add_executable(hello source/hello.cpp)
add_executable(caller_cpp source/caller.cpp)
add_executable(caller_fort source/caller.f90)
設置Fortran語言的一個小問題
-->$ cmake ..
-- The CXX compiler identification is GNU 9.3.0
CMake Error: Could not find cmake module file: CMakeDetermineFORTRANCompiler.cmake
CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
Missing variable is:
CMAKE_FORTRAN_COMPILER_ENV_VAR
CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
Missing variable is:
CMAKE_FORTRAN_COMPILER
...
這個問題的原因在CMakeLists.txt
中,是大小寫敏感的,Fortran
只應該使用首字母大寫的形式。
# project(exe_test CXX FORTRAN)
project(exe_test CXX Fortran)
source/hello.cpp
// name: hello.cpp
// date: 2021/3/14
//
#include <iostream>
using namespace std;
int main()
{
cout << "Aloha!" << endl;
return 0;
}
source/caller.cpp
// name: caller.cpp
// date: 2021/3/14
//
#include <iostream>
#include <string>
#include <Windows.h>
#include <tlhelp32.h>
#include <process.h>
using namespace std;
void Launch(LPCTSTR lpApplicationName)
{
// additional information
STARTUPINFO si;
PROCESS_INFORMATION pi;
// set the size of the structures
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// start the program up
CreateProcess( lpApplicationName, // the path
(char*)"", // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
);
cout << "process id: " << pi.dwProcessId << ", thread id: " << pi.dwThreadId << endl;
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
int main(int argv, char* args[])
{
cout << "caller_cpp:" << endl;
// 1.
// 可以加路徑,路徑中應使用\\而非/
// WinExec("hello.exe", SW_SHOW);
// 2.
// SHELLEXECUTEINFO shell = { sizeof(shell) };
// shell.fMask = SEE_MASK_FLAG_DDEWAIT;
// shell.lpVerb = "open";
// shell.lpFile = "hello.exe";
// shell.nShow = SW_SHOWNORMAL;
// BOOL ret = ShellExecuteEx(&shell);
// 3.
// ShellExecuteA
// ShellExecute(NULL, "open", "hello.exe", NULL, NULL, SW_SHOWDEFAULT);
// 4.
// system("hello.exe");
// 5.
Launch("hello.exe");
// 6.
// _execv("hello.exe", args);
return 0;
}
收集了多種方式,建議使用CreateProcess()
,詳細內容查閱Microsoft Docs。
source/caller.f90
! name: caller.f90
! date: 2021/3/14
!
PROGRAM Caller_fort
PRINT *, "Caller_fort"
! Fortran 2008
call execute_command_line ("hello.exe", wait=.false.)
!
call system("hello.exe")
END
execute_command_line
是Fortran2008
標准開始支持的函數。
參考資料
- cmake_ Selecting a generator within CMakeLists.txt - Stack Overflow
- Using cmake with fortran - Stack Overflow
- windows C_C++ 在一個程序中打開,關閉和監視其它的exe程序_lumanman_的博客-CSDN博客
- C++ 打開exe文件的方法(VS2008) - work hard work smart - 博客園
- C++ 中打開 exe 文件_楠木大哥的博客-CSDN博客
- C++程序中調用exe可執行文件_積累點滴,保持自我-CSDN博客_c++調用exe文件
- ShellExecuteA function (shellapi.h) - Win32 apps _ Microsoft Docs
- Creating Processes - Win32 apps _ Microsoft Docs
- _exec, _wexec Functions _ Microsoft Docs
- EXECUTE_COMMAND_LINE (The GNU Fortran Compiler)
- SYSTEM (The GNU Fortran Compiler)