Run rake in project built with cmake - cmake

I'm trying to build a fortran project that uses Fruit for unit tests. Essentially, I have a fortran module source file which contains some subroutines named test_something, and then I want to run a Rakefile which calls Fruit to generate a fortran program source file which will run all the tests. Fruit uses rake for this purpose, so not using rake isn't really an option for me.
I've included these commands to tell cmake to expect these files to be generated:
set_source_files_properties(fruit_driver_gen.f90 PROPERTIES GENERATED true)
set_source_files_properties(fruit_basket_gen.f90 PROPERTIES GENERATED true)
Then I have a custom command to run rake:
add_custom_command(
OUTPUT fruit_driver_gen.f90 fruit_basket_gen.f90
COMMAND rake gen
DEPENDS Rakefile)
The Rakefile is just a file that needs to be copied over to the folder where the custom command is executed, but whith DEPENDS it's registered as a target, so I try adding it as a custom target like this:
add_custom_target(Rakefile SOURCES "${PROJECT_SOURCE_DIR}/Rakefile}")
When I run cmake, I get the following error:
CMake Error at tests/CMakeLists.txt:20 (add_custom_target):
Cannot find source file:
~/Fruit_example/tests/Rakefile}
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
Am I doing something completely wrong? Is there a more elegant way to achive what I want? I'm essentially trying to make cmake copy and run a script to generate some output, and I guess I can't be the only one trying to do that, even if using Fortran and Fruit is perhaps not that common.

Related

Linking Windows .res files with CMake

I'm looking into switching my C++ building workflow from use of VisualStudio sln/vcxproj files and Makefiles to using CMake. Compilation is fine, but I'm running into issues when trying to link .res files for our Windows dialogs.
Our project is structured as you would expect a VS project to be structured: it has a solution with a core project, and it relies symbols from other projects. One of the 'libraries' I need for building on Windows is our base dialog .res file, which has been pre-compiled and is available in a directory, but when I try to link that file I get an error stating that it can't link "BaseResource.res.lib".
So of course I've done some Googling on this, and have spent more than a few hours looking for something. The closest I've found is this StackOverflow question on the subject, and I've tried its suggestion which apparently worked for the original ask-er, but it doesn't seem to be working on my end. Currently within my CMakeLists I have:
project(my_project CXX)
...
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
ENABLE_LANGUAGE(RC)
file(TO_CMAKE_PATH "${RES_SOURCE_ROOT}/Source/Resources/Dialogs/Resource.rc"
BASE_RESOURCE_RC)
add_executable( BaseResource ${BASE_RESOURCE_RC})
target_link_libraries(BaseResource "BaseResource.res")
set(BASE_RESOURCE_LINK_FLAGS
"${RES_SOURCE_ROOT}/Lib/${PLATFORM_DIR}/BaseResource.res")
set_target_properties(BaseResource PROPERTIES LINK_FLAGS
${BASE_RESOURCE_LINK_FLAGS})
...
else()
# Do *Nix things.
endif()
Where BaseResource is the previously-undeclared project which is different from this one, and PLATFORM_DIR is the platform-based directory where we keep our binaries, e.g. "windows/v140/32bit". However, when I attempt this, loading the project tells me:
Cannot find source file:
D:/Path/To/Resource/Root/Source/Resources/Dialogs/Resource.rc
Tried extensions .c .C .c++ .cc .cpp .cxx .cu .m .M .mm .h .hh .h++ .hm
.hpp .hxx .in .txx
No SOURCES given to target: BaseResource
To be clear, this project should not care about the sources of other projects - it is specifically meant to compile just this project and to use the libraries from other projects to do so. The use of the above workaround was solely in the hope that it might allow me to use the resource.
I'm honestly at a loss; it's using the MSVC compiler so there really should be no issues in doing this linking, which goes off without a hitch using the VisualStudio solution. Any help on this subject would be hugely appreciated.
Thanks,
~Jon
EDIT: To clarify further, the original error is when I attempt to use:
link_libraries("${RES_SOURCE_ROOT}/Lib/${PLATFORM_DIR}/BaseResource.res")
The original error I get is:
LINK : fatal error LNK1104: cannot open file 'BaseResource.res.lib'
The error with the .rc file is coming from a workaround, in the event that it was the right direction but lacking some other things.

cmake, how to add project to a solution?

I have the jpeglib library, built with cmake and visual studio 2005. And I also have a separate program that uses this library. How can I compile that program so that I can debug both program and library code?
My first attempt was by just including the main program's project into the libjpeg solution, changing include paths and specifying the path to libjpeg .lib. This worked, but when I rerun cmake, I have to redo that. I described it here: https://board.flatassembler.net/topic.php?p=203834#203834
How can I compile those two programs using cmake itself? I tried adding this in the libjpeg CMakeList.txt :
add_executable(_main--ddraw main.cpp)
set_property(TARGET _main--ddraw PROPERTY RUNTIME_OUTPUT_DIRECTORY "c:/_src/_main--ddraw3")
target_link_libraries(_main--ddraw jpeg-static)
But it only resulted in this:
1>CMake Error at CMakeLists.txt:369 (add_executable):
1> Cannot find source file:
1> main.cpp
1> Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
1> .hxx .in .txx
1>CMake Error: CMake can not determine linker language for target: _main--ddraw

How to add a dependency to an object file in cmake

So I'm trying to convert a make-based project to cmake, and having trouble wrapping my head around how it works. I've figured out how to get custom commands to generate a header file, and how to compile source file for the target executable, but I can't seem to link them together -- I can't figure out how to trigger the custom command to generate the header file. Here's a trivial example of what I'm trying to do:
CMakeLists.txt:
add_executable(test test.c)
add_custom_command(OUTPUT foo.h
COMMAND echo "/* test */" > foo.h
)
test.c:
#include "foo.h"
int main() { return 0; }
However, when I run cmake and make, it gives me:
/home/cdodd/test/test.c:1:17: fatal error: foo.h: No such file or directory
compilation terminated.
It can't seem to figure out that it needs to create foo.h first before compiling test.c. With make I'd just add a dependency; how do I do that with cmake?
Add the generated file foo.h to the executable target as a dependency:
add_executable(testexe test.c foo.h)
This will make CMake add a file level dependency of the target testexe to the file foo.h in the generated build system.

cmake, fortran 2008, and .f08 file extension

I am trying to configure a Fortran 2008 project to use CMake; the files in the project have the ".f08" extension. However, I cannot get CMake to work even with a "hello world" example. Here are the relevant parts of my CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8)
project (hello)
enable_language (Fortran)
set (CMAKE_Fortran_SOURCE_FILE_EXTENSIONS ${CMAKE_Fortran_SOURCE_FILE_EXTENSIONS} "f08;F08")
add_executable ("hello-world" "hello-world.f08")
set_target_properties (hello-world PROPERTIES LINKER_LANGUAGE Fortran)
Three notes:
The Makefile generated does not compile "hello-world.f08" into an object file.
The "set_target_properties" is needed. Otherwise, CMake reports that it "can not determine linker language for target:hello-world".
Renaming the file to "hello-world.f95" along with the corresponding change in CMakeLists.txt makes things work. Even the "set_target_properties" command is no longer needed.
If you need to specify Fortran files with unrecognized extensions, you can set the source file's LANGUAGE property, e.g.:
set_source_files_properties(hello-world.f08 PROPERTIES LANGUAGE Fortran)

'Cannot determine link language for target...' issue in sub directory

In the main folder of my project, I have a CMakeLists.txt file. Inside this file, I include (using add_subdirectory) another CMakeLists.txt file located in my header file directory. The responsibility of this second file is to add all of my header files to the project:
file(GLOB gl_nbody_HEADERS "*.h")
add_executable(gl_nbody ${gl_nbody_HEADERS})
However, this files causes an error:
CMake Error: CMake can not determine linker language for target:gl_nbody
CMake Error: Cannot determine link language for target "gl_nbody".
What is strange is that when I include the two lines causing this error in my main CMakeLists.txt file (modified to work correctly for the change in directory), it works fine.
What is going wrong here?
add_executable causes the creation of an executable target, meaning the compilation of a list of source code files into an executable binary.
In order for this to work, and have CMake select a suitable compiler, the list of source files must contain at least one file with a "compilable" extension, ie. .c, or .cpp, or .cxx....
I don't see why you are trying to compile an executable here, since you only seem to try to list header files for inclusion into a project (which only makes sense for IDE-based generators, such as Visual Studio).
Also, it is not recommended to use globbing of files in CMake, because if you add more files to your project, CMake cannot detect them automatically, and will not regenerate build files. Please list all files explicitely.
The proper solution here is to list the header files in the proper add_executable command call where you list the actual source files that you want to compile.
You might also want to use the source_group() command, that allows you to group files into folders in the generated Visual Studio solution, for example:
source_group(header_files ${gl_nbody_HEADERS})