Hi,
On Mon, May 13, 2013 at 09:31:46PM -0400, [email protected] 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).
> 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.).
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!).
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