Linking Windows .res files with CMake - 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.

Related

Build gtest as shared library (dll) in CMake

I have never worked with CMake before, so please forgive any rookie mistakes. Most of the following working frame has been given to me by my project group.
The goal is to build GoogleTest into a .dll, to be used in different, indepentent parts of our project. I'm having troubles setting up CMake the right way.
The work-flow so far has been:
Clone gtest from git --> also downloads a CMake List file
Alter variables in CMakeCache.txt to have it produce a Code::Blocks project file
Compile the project file in Code::Blocks
So far, it produces a static library (.a files) that can be used in our project. I'm having troubles genereating .dll files.
Variables I have tried changing:
BUILD_SHARED_LIBS:BOOL=ON --> the files generated by Code::Blocks now have a .dll.a double extension
CMAKE_C_FLAGS and all the corresponding C++ flags where set to -DGTEST_CREATE_SHARED_LIBRARY=1 as given here
CMAKE_EXE_LINKER_FLAGS has been set to -shared to make the linker produce .dll files
I have worked my way through the GoogleTest documentation here and here but in both, building it into a .dll is merely a 2-sentence-topic.
As #Tsyvarev pointed out, the .dll files were created in a (very) different folder.

Compile .o files with Clion [duplicate]

This question already has answers here:
how to add prebuilt object files to executable in cmake
(4 answers)
Closed 3 years ago.
We have been given a C++ group project, and we've been given the completed project in .o format too, so as we work over the break we can test the individual parts we are working on.
I'm using CLion and I'd like to firstl compile the whole project from the object files to see how it works and from there I should be able to remove the .o files I am working on and include my own .h/.cpp versions.
Can someone tell me how to write the CMakeLists.txt, or at least tell me what to read? I couldn't find any specific documentation, and I don't know where to start.
**edit
I had a look at the other solution mentioned in the duplicate, but implementing that didn't work, I still needed to set the target properties. Possibly down to the object files being created with a different piece of software?
Thanks to Some programmer dude I got it working. I'll write it out here for clarity.
First I added all the .o files in the add_executable.
After that I added the language in the project command but it didn't work, still had the
CMake Error: CMake can not determine linker language for target: myProject
CMake Error: Cannot determine link language for target "myProject"
so I added set_target_properties. First the project name, then PROPERTIES then the thing I wanted to set: LINKER_LANGUAGE, then the language.
My file ended up looking like this:
cmake_minimum_required(VERSION 3.12)
project(myProject)
set(CMAKE_CXX_STANDARD 14)
add_executable(myProject
first.o
second.o
third.o
fourth.o)
set_target_properties(myProject PROPERTIES LINKER_LANGUAGE CXX )

'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})

Run rake in project built with 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.

code::blocks, libxml2 / libxml/parser.h: No such file or directory

Hello
I'm trying to write some tool using code::blocks, wxWidgets and libxml2 on Windows platform.
Things I've done:
copied libxml2.a, libxml2.dll.a and
other libs to MinGW lib/ folder
Wrote some headers like this in my
source file:
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
Added -lxml2 to linker
And now, when I'm trying to build this project I'm getting this error:
error: libxml/xmlmemory.h: No such file or directory
Anyone here experienced this error?
I believe that I misconfigured something but don't really know what.
Thanks for your ideas.
In general, it's better to not move things into the mingw directories, but to leave them in their own directories, and add search paths to the project properties so it knows where to look for them.
If you go into your project properties in Code::Blocks, hit the Project build options button, then inside the Linker Settings tab, add the two libraries you're linking against. Then In the Search directories tab, add the /include to compiler search locations, and optionally, add the /lib directory to Linker locations (This isn't necessary if you gave the full path to the .a in the linker settings.
Ok, I found the solution!
<libxml2/libxml/parser.h>
works perfectly