Lori A. Pritchett-Sheats Los Alamos National Laboratory CCS-2, Computational Physics 505-665-6675
________________________________________ From: Andreas Mohr [a...@lisas.de] Sent: Tuesday, May 14, 2013 1:14 AM To: cmake@cmake.org Cc: Pritchett-Sheats, Lori Subject: Re: Compiling Fortran Modules And Hi, On Mon, May 13, 2013 at 09:31:46PM -0400, cmake-requ...@cmake.org wrote: > I'm converting a Fortran package that was using GNU make to build to CMake, > but I've run into a problem compiling F90 module code where the source code > is stored under many directories. > > The package has a directory structure > > src/ > src/dir1 > src/dir2 > : > : Ooook... > Each dir* has *.F files that must be preprocessed to *.f90 files and then > compiled. In the original build system, the package had an empty 'build' > directory under src. The processed files were created there and then the > library was built from these files was also generated there. I tried to do > something similar with CMake but I see errors from make about 'No rules to > make target ' pointing to files that do not exist under the CMakeFiles > directories, however the object file and the *.mod files are there, so I know > I'm compiling correctly. The semi-famous "No rules to make target" error, hinting at wrong-directory issues. > Here's my CMakeLists.txt snippet in the src directory > > > set(DIR1_FILES dir1/file1_module.F dir2/file2_module.F) > set(DIR2_FILES dir2/file3_module.F dir2/file4_module.F) > set(F_PREPROCESS_FILES ${DIR1_FILES} ${DIR2_FILES}) Hmm. Files with directory specification. But then... > set(F90Library_SOURCE_FILES) > foreach (src_file ${F_PREPROCESS_FILES}) > > get_filename_component(filename "${src_file}" NAME_WE) > set(F_file ${CMAKE_CURRENT_SOURCE_DIR}/${src_file}) ...using filename-only prepended with a questionably precise *current source dir* (if that was a function/macro invoked from somewhere else, then I'd buy that argument since CMAKE_CURRENT_SOURCE_DIR likely *would* be meaningful each, but since it seems it's processing over that F_PREPROCESS_FILES loop open-coded right there, the dir does seem out-of-place versus each of the input file dirs). I've replaced CMAKE_CURRENT_SOURCE_DIR with <PROJECT_NAME>_SOURCE_DIR where PROJECT_NAME is my current project name. Did not change the behavior of the error. CMake still can not find rules to make the files I listed below. > set(new_file_f90 ${CMAKE_CURRENT_BINARY_DIR}/${filename}.f90) > message(STATUS "new_file_f90=${new_file_f90}") > > add_custom_command(OUTPUT "${new_file_f90}" > COMMAND ${CMAKE_C_COMPILER} -E ${CMAKE_CPP_FLAGS} ${F_file} > ${grep_filter} | grep -v \\!\\!CPP\\!\\! | grep -v ^\# > ${new_file_f90} > IMPLICIT_DEPENDS Fortran "${F_file}" > COMMENT "\tPreprocessing ${src_file}" > VERBATIM) > list(APPEND PGSLibIface_SOURCE_FILES ${new_file_f90}) > endforeach() > > > # --- Library > add_library(mylib ${F90Library_SOURCE_FILES}) > > > When I try to build, the error I see is the following > > Preprocessing dir1/file1_module.F > Preprocessing dir1/file2_module.F > Preprocessing dir2/file3_module.F > Preprocessing dir2/file4_module.F > Scanning dependencies of target mylib > Building Fortran object src/CMakeFiles/mylib.dir/file1_module.f90.o > make[2]: *** No rule to make target `src/file1_module.f90.provides', needed > by `src/CMakeFiles/mylib.dir/file1_module.mod.proxy'. Stop. > make[1]: *** [src/CMakeFiles/mylib.dir/all] Error 2 > make: *** [all] Error 2 A frequent CMake pattern is to have one CMakeLists.txt per each files directory (to always have processing symmetrically going from foo_SOURCE_DIR to foo_BINARY_DIR, such as configure_file() etc.). I'm aware that this is a frequent usage pattern. However, in this case I have numerous directories, Fortran module dependencies across these directories and at the end instead of a single library to install, I would have over 20 libraries. If I can not maintain the old directory structure, I would rather flatten the entire src tree. Creating a CMakeLists.txt file for each directory Thus without even analyzing the problem (apologies!), I'd suggest having CMakeLists.txt per dir which then calls into a common macro/helper (to be implemented by a module) which will do that per-file processing, *with* *correct* *directory* *arguments* *each* (implicitly!). As I mentioned above, I have already tried explicit project name variables and it did not change the behavior. HTH, Andreas Mohr -- GNU/Linux. It's not the software that's free, it's you. -- Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://www.cmake.org/mailman/listinfo/cmake