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

Reply via email to