我有一个CMake 3.5.2项目,该项目创建一个库:libtest.a,然后通过可执行文件链接到该库。
源代码为Fortran,libtest.a生成一个模块文件:“ main.mod”
可执行文件还需要包含这个main.mod文件,以便使main.mod可以访问,在构建项目时,我将变量CMAKE_Fortran_MODULE_DIRECTORY设置到一个已知位置,并将其添加到相关的include路径。
这在构建整个项目时非常有用,main.mod是在已知位置构建的,并且无论需要什么代码,它都可以在该位置。但是,根据我的用法,有必要仅自行构建libtest.a,而有时让可执行文件由下游用户构建。
我遇到的问题是,当我进入libtest源并将其视为自己的CMake项目时,该库将生成并安装,但是main.mod文件始终保留在BINARY_DIR中,并且未内置libtest中CMakeList.txt中的CMAKE_Fortran_MODULE_DIRECTORY设置。
仅在调用add_executable()时才兑现Fortran_MODULE_DIRECTORY吗?只是因为库构建而被忽略了吗?还是我错过了什么?
感谢您的帮助。
编辑:这将重现我的问题。
test_mod.f90:
module main
implicit none
real, parameter :: pi=3.2
end module main
tt.f90:
program test
use main
implicit none
real :: a, area
a =10
area = a * 100
end program test
CMakeList.txt:
CMAKE_minimum_required( VERSION 3.5 )
enable_language( Fortran )
project( tt )
file( GLOB test_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.f90 )
add_library( tt STATIC ${test_SOURCES} )
set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Mod )
install( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/Lib/ )
如果我构建并安装以上代码,我将在Lib目录中安装libtt.a库,但是我的main.mod将保留在我的构建目录中,而不是在Mod文件夹中构建。
答案 0 :(得分:1)
在这里,我假设“用户”使用cmake来构建项目,同时可以访问项目的源代码。
构建可用的步骤。
CMakeLists.txt
的libtest文件。这足以使CMAKE_Fortran_MODULE_DIRECTORY
出现在这里。main.mod
文件,用于构建“客户端”程序。该文件应包含带有CMakeLists.txt
的libtest项目。add_subdirectory
。这仅需要库的链接,而对于客户端程序已知的模块而言(无论如何对于下面的解决方案B而言)是不够的。现在,进行自己的冒险:
解决方案A:在libtest target_link_libraries(NAME_OF_PROGRAM NAME_OF_LIBRARY)
中,将模块放置在“所有模块都将运行”的位置,例如CMakeLists.txt
(您还需要对“客户端” set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules)
执行此操作)。变量CMakeLists.txt
由“客户端” cmake调用设置,并且对于所有包含的cmake项目都是相同的。此目录将在Fortran程序的构建命令中列出。
解决方案B:在libtest ${CMAKE_BINARY_DIR}
中,将该库的模块放置在专用目录中。例如,您可以使用CMakeLists.txt
来实现。然后,您需要使用客户端set(CMAKE_Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/modules)
中的include_directories(PATH_THAT_DEPENDS_ON_THE_NAME_OF_THE_SUBPROJECT)
手动指定此位置。
如果希望该库是可安装的,则需要指定安装库和的路径。使用Fortran,您应该考虑目标操作系统,编译器和体系结构。
链接到CMake文档:
在添加示例代码之后,应进行以下修改:
CMakeLists.txt
CMAKE_minimum_required( VERSION 3.5 )
enable_language( Fortran )
project( tt )
set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Mod )
file( GLOB test_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.f90 )
add_library( tt STATIC ${test_SOURCES} )
install( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/Lib/ )
install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
出现在任何set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Mod )
行之前。add_library
以实际安装install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
文件。除了库文件之外,还必须安装模块文件(作为C中的头文件)。您创建的设置有点不寻常,因为您可以找到源代码版本中的所有内容,而“通常”的安装位置是相对于CMAKE_INSTALL_PREFIX