目录
- 软件环境
- Windows下CMake编译配置
- Command Line
- CMake GUI
- PreLoad.cmake
- 设置项目的generator
- 设置make
- 示例程序
- 设置Fortran语言的一个小问题
- CMake
- source/hello.cpp
- source/caller.cpp
- source/caller.f90
- 参考资料
软件环境
# 操作系统 = 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编译工具,并将添加到环境变量中。
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可以直接使用。
是因为在下,对应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 // #includeusing namespace std; int main() { cout << "Aloha!" << endl; return 0; }
source/caller.cpp
// name: caller.cpp // date: 2021/3/14 // #include#include#include#include#includeusing 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)