Giter Site home page Giter Site logo

cmrc's Introduction

CMakeRC - A Standalone CMake-Based C++ Resource Compiler

CMakeRC is a resource compiler provided in a single CMake script that can easily be included in another project.

What is a "Resource Compiler"?

For the purpose of this project, a resource compiler is a tool that will compile arbitrary data into a program. The program can then read this data from without needing to store that data on disk external to the program.

Examples use cases:

  • Storing a web page tree for serving over HTTP to clients. Compiling the web page into the executable means that the program is all that is required to run the HTTP server, without keeping the site files on disk separately.
  • Storing embedded scripts and/or shaders that support the program, rather than writing them in the code as string literals.
  • Storing images and graphics for GUIs.

These things are all about aiding in the ease of portability and distribution of the program, as it is no longer required to ship a plethora of support files with a binary to your users.

What is Special About CMakeRC?

CMakeRC is implemented as a single CMake module, CMakeRC.cmake. No additional libraries or headers are required.

This project was initially written as a "literate programming" experiment. The process for the pre-2.0 version can be read about here.

2.0.0+ is slightly different from what was written in the post, but a lot of it still applies.

Installing

Installing CMakeRC is designed to be as simple as possible. The only thing required is the CMakeRC.cmake script. You can copy it into your project directory (recommended) or install it as a package and get all the features you need.

For vcpkg users there is a cmakerc port that can be installed via vcpkg install cmakerc or by adding it to dependencies section of your vcpkg.json file.

Usage

  1. Once installed, simply import the CMakeRC.cmake script. If you placed the module in your project directory (recommended), simply use include(CMakeRC) to import the module. If you installed it as a package, use find_package(CMakeRC).

  2. Once included, create a new resource library using cmrc_add_resource_library, like this:

    cmrc_add_resource_library(foo-resources ...)

    Where ... is simply a list of files that you wish to compile into the resource library.

You can use the ALIAS argument to immediately generate an alias target for the resource library (recommended):

cmrc_add_resource_library(foo-resources ALIAS foo::rc ...)

Note: If the name of the library target is not a valid C++ namespace identifier, you will need to provide the NAMESPACE argument. Otherwise, the name of the library will be used as the resource library's namespace.

cmrc_add_resource_library(foo-resources ALIAS foo::rc NAMESPACE foo  ...)
  1. To use the resource library, link the resource library target into a binary using target_link_libraries():

    add_executable(my-program main.cpp)
    target_link_libraries(my-program PRIVATE foo::rc)
  2. Inside of the source files, any time you wish to use the library, include the cmrc/cmrc.hpp header, which will automatically become available to any target that links to a generated resource library target, as my-program does above:

    #include <cmrc/cmrc.hpp>
    
    int main() {
        // ...
    }
  3. At global scope within the .cpp file, place the CMRC_DECLARE(<my-lib-ns>) macro using the namespace that was designated with cmrc_add_resource_library (or the library name if no namespace was specified):

    #include <cmrc/cmrc.hpp>
    
    CMRC_DECLARE(foo);
    
    int main() {
        // ...
    }
  4. Obtain a handle to the embedded resource filesystem by calling the get_filesystem() function in the generated namespace. It will be generated at cmrc::<my-lib-ns>::get_filesystem().

    int main() {
        auto fs = cmrc::foo::get_filesystem();
    }

    (This function was declared by the CMRC_DECLARE() macro from the previous step.)

    You're now ready to work with the files in your resource library! See the section on cmrc::embedded_filesystem.

The cmrc::embedded_filesystem API

All resource libraries have their own cmrc::embedded_filesystem that can be accessed with the get_filesystem() function declared by CMRC_DECLARE().

This class is trivially copyable and destructible, and acts as a handle to the statically allocated resource library data.

Methods on cmrc::embedded_filesystem

  • open(const std::string& path) -> cmrc::file - Opens and returns a non-directory file object at path, or throws std::system_error() on error.
  • is_file(const std::string& path) -> bool - Returns true if the given path names a regular file, false otherwise.
  • is_directory(const std::string& path) -> bool - Returns true if the given path names a directory. false otherwise.
  • exists(const std::string& path) -> bool returns true if the given path names an existing file or directory, false otherwise.
  • iterate_directory(const std::string& path) -> cmrc::directory_iterator returns a directory iterator for iterating the contents of a directory. Throws if the given path does not identify a directory.

Members of cmrc::file

  • typename iterator and typename const_iterator - Just const char*.
  • begin()/cbegin() -> iterator - Return an iterator to the beginning of the resource.
  • end()/cend() -> iterator - Return an iterator past the end of the resource.
  • file() - Default constructor, refers to no resource.

Members of cmrc::directory_iterator

  • typename value_type - cmrc::directory_entry
  • iterator_category - std::input_iterator_tag
  • directory_iterator() - Default construct.
  • begin() -> directory_iterator - Returns *this.
  • end() -> directory_iterator - Returns a past-the-end iterator corresponding to this iterator.
  • operator*() -> value_type - Returns the directory_entry for which the iterator corresponds.
  • operator==, operator!=, and operator++ - Implement iterator semantics.

Members of cmrc::directory_entry

  • filename() -> std::string - The filename of the entry.
  • is_file() -> bool - true if the entry is a file.
  • is_directory() -> bool - true if the entry is a directory.

Additional Options

After calling cmrc_add_resource_library, you can add additional resources to the library using cmrc_add_resources with the name of the library and the paths to any additional resources that you wish to compile in. This way you can lazily add resources to the library as your configure script runs.

Both cmrc_add_resource_library and cmrc_add_resources take two additional keyword parameters:

  • WHENCE tells CMakeRC how to rewrite the filepaths to the resource files. The default value for WHENCE is the CMAKE_CURRENT_SOURCE_DIR, which is the source directory where cmrc_add_resources or cmrc_add_resource_library is called. For example, if you say cmrc_add_resources(foo images/flower.jpg), the resource will be accessible via cmrc::open("images/flower.jpg"), but if you say cmrc_add_resources(foo WHENCE images images/flower.jpg), then the resource will be accessible only using cmrc::open("flower.jpg"), because the images directory is used as the root where the resource will be compiled from.

    Because of the file transformation limitations, WHENCE is required when adding resources which exist outside of the source directory, since CMakeRC will not be able to automatically rewrite the file paths.

  • PREFIX tells CMakeRC to prepend a directory-style path to the resource filepath in the resulting binary. For example, cmrc_add_resources(foo PREFIX resources images/flower.jpg) will make the resource accessible using cmrc::open("resources/images/flower.jpg"). This is useful to prevent resource libraries from having conflicting filenames. The default PREFIX is to have no prefix.

The two options can be used together to rewrite the paths to your heart's content:

cmrc_add_resource_library(
    flower-images
    NAMESPACE flower
    WHENCE images
    PREFIX flowers
    images/rose.jpg
    images/tulip.jpg
    images/daisy.jpg
    images/sunflower.jpg
    )
int foo() {
    auto fs = cmrc::flower::get_filesystem();
    auto rose = fs.open("flowers/rose.jpg");
}

cmrc's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cmrc's Issues

Can you provide an install target on top level CMakelists.txt

Hello and well done on your excellent and hard work. I find this cmake module very usefull and I want to install it system-wide on my Gentoo with an ebuild. Perphaps pimp the ebuild into the Portage tree.

But the ebuild failed in install phase with this:

OUTPUT(tests/whence elf64-x86-64)
/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../x86_64-pc-linux-gnu/bin/ld: total time in link: 0.143828
>>> Source compiled.
>>> Test phase [not enabled]: dev-cpp/cmrc-2.0.1

>>> Install dev-cpp/cmrc-2.0.1 into /mnt/Volume_3/Gentoo/temp/portage/dev-cpp/cmrc-2.0.1/image
>>> Working in BUILD_DIR: "/mnt/Volume_3/Gentoo/temp/portage/dev-cpp/cmrc-2.0.1/work/cmrc-2.0.1_build"
ninja: error: unknown target 'install'
 * ERROR: dev-cpp/cmrc-2.0.1::testing failed (install phase):
 *   died running ninja install
 * 
 * Call stack:
 *     ebuild.sh, line  125:  Called src_install
 *   environment, line 2183:  Called cmake-utils_src_install
 *   environment, line  974:  Called die
 * The specific snippet of code:
 *       DESTDIR="${D}" ${CMAKE_MAKEFILE_GENERATOR} install "$@" || die "died running ${CMAKE_MAKEFILE_GENERATOR} install";
 * 

So, could you provide an install target for the module and/or the examples?
Thank you very much.

How do I embed my file into an executable and how do I retrieve my resources from it?

Hi, I hope you are doing well.

What I don't understand is how it's possible to embed arbitrary files into my executable. Would you mind explaining that to me? Of course I followed the exact method that was in the README.md file. However, the size of my executable didn't change no matter how large my resources were.

There is my project structure:

-CMakeLists.txt
-CMakeRC.cmake
-resources/
Photo.jpg

My configuration for CMake:

cmake_minimum_required(VERSION 3.10)


project(AddResource)#========== Global Configurations 
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_VERBOSE_MAKEFILE ON)set(CMAKE_CXX_EXTENSIONS OFF)
include(CMakeRC.cmake)



cmrc_add_resource_library(    app1-resources
ALIAS app1::rc    NAMESPACE app1    resources/archive.zip    resources/photo.jpg )
add_executable(MyExe code.cpp)
target_link_libraries(MyExe app1::rc)

My code is:

#include <stdio.h>
#include <cmrc/cmrc.hpp>

CMRC_DECLARE(app1);

int main()

{

    getchar();

    return 0;

}

Using CMakeRC file objects with std::istream

I am trying to pass a cmrc resource file to a function that takes a std::istream object as input. In order to do that, I create a std::streambuf object from the cmrc data, which I can then pass to std::istream. There are two issues I've encountered:

  • streambuf uses char*, whereas cmrc's begin() and end() return const char*. This isn't such a big deal, as I've found a few workarounds.
  • The real issue is that istream::seekg seeks way past the end of the data. You can see this happen in the example below, which I created from the 'simple' test. The data_size value is enormous!

Is there some way to make this work? I could probably create a string from the data and then pass it to a std:istringstream, but I am trying to avoid the copy, as my data files could be very large. This is all rather new territory for me, so I wouldn't be surprised if I just overlooked something obvious.

include <cmrc/cmrc.hpp>

#include <cstddef>
#include <iostream>
#include <streambuf>

CMRC_DECLARE(simple);

struct membuf : std::streambuf {
    membuf(char *begin, char *end) { this->setg(begin, begin, end); }
};

int main() {
    auto fs = cmrc::simple::get_filesystem();
    auto data = fs.open("hello.txt");
    // Instead of const_cast, Krzysztof Tomaszewski at The Art of Code provides 
    // a solution to use const char* with streambuf.
    // https://artofcode.wordpress.com/2010/12/12/deriving-from-stdstreambuf/
    // However, I wanted to keep things simple for this example.
    membuf data_buf(const_cast<char*>(data.begin()),
                    const_cast<char*>(data.end()));
    std::istream data_stream(&data_buf);
    data_stream.seekg(0, data_stream.end);
    size_t data_size = data_stream.tellg();
    std::cout << data_size << '\n'; // This prints 18446744073709551615 on my computer.
}

linking cmrc with a shared library

Linker error when I try to link with cmrc generated library with a SHARED library.

/usr/bin/ld: thelibx-resources.a(lib.cpp.o): relocation R_X86_64_PC32 against symbol `_ZN4cmrc6detail9directoryD1Ev' can not be used when making a shared object; recompile with -fPIC

I want the shared library to be statically linked with the cmrc_add_resource_library generated target thelibx-resources.

add_library(thelibx SHARED ${THE_LIBX_SOURCES})
target_link_libraries(thelibx ${Boost_PROGRAM_OPTIONS_LIBRARY} thelibx-resources)

If I remove that SHARED then everything works fine.

MSVC doesn't compile directory, since it contains a deque of itself

Currently, directory contains a std::deque<directory> _dirs. This std::deque is instantiated with the incomplete type directory.

class directory {
    std::deque<directory> _dirs;

As far as I can tell, this isn't allowed by the standard, and MSVC rejects it.

The cppreference entry on std::deque seems to imply that it doesn't allow incomplete types, especially when juxtaposed with std::vector. It's not just cppreference, n4659 does the same:

[vector]:

An incomplete type T may be used when instantiating vector if the allocator satisfies the allocator completeness requirements. T shall be complete before any member of the resulting specialization of vector is referenced.

[deque] has no such mention.

Generate `OBJECT` library instead of `STATIC`

When installing a STATIC library that includes files using cmrc_add_resource_library, it is necessary to export and install the library generated by CMakeRC as well. This shouldn't be necessary.
An option would be to generate an OBJECT library instead of a STATIC library, and to use it with target_sources and target_include_directories instead of linking it with target_link_libraries

#include <cmrc/cmrc.hpp> never finds the include file

CMakeLists.txt:

include(CMakeRC.cmake)

cmrc_add_resource_library(my_files data/foo.bin)

add_executable(
    MyApp
    main.cpp
)
target_link_libraries(
    MyApp
    PRIVATE
    my_files 
    ...
)

However for some reason #include <cmrc/cmrc.hpp> always says the include file cannot be found. When I look at the compiler command, I don't see the include path anywhere (there's no -I<...>/cmrc anywhere).

Any idea what might be going on?

CMake version 3.23.

Failure to compile long strings on MSVC

Building the current repository with Visual Studio 2017 fails:

$ mkdir build
$ cd build
$ cmake "Visual Studio 15 2017 Win64" ..
$ cmake --build .

Gives:

Microsoft (R) Build Engine version 15.7.177.53362 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 18/05/2018 9:02:30 AM.
Project "C:\work\cmrc\build\ALL_BUILD.vcxproj" on node 1 (default targets).
Project "C:\work\cmrc\build\ALL_BUILD.vcxproj" (1) is building "C:\work\cmrc\build\ZERO_CHECK.vcxproj" (2) on node 1 (d
efault targets).
PrepareForBuild:
  Creating directory "x64\Debug\ZERO_CHECK\".
  Creating directory "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\".
InitializeBuildStatus:
  Creating "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
CustomBuild:
  Checking Build System
  CMake does not need to re-run because C:/work/cmrc/build/CMakeFiles/generate.stamp is up-to-date.
FinalizeBuildStatus:
  Deleting file "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\unsuccessfulbuild".
  Touching "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\ZERO_CHECK.lastbuildstate".
Done Building Project "C:\work\cmrc\build\ZERO_CHECK.vcxproj" (default targets).

Project "C:\work\cmrc\build\ALL_BUILD.vcxproj" (1) is building "C:\work\cmrc\build\flower.vcxproj" (3) on node 1 (defau
lt targets).
Project "C:\work\cmrc\build\flower.vcxproj" (3) is building "C:\work\cmrc\build\hello.vcxproj" (4) on node 1 (default t
argets).
PrepareForBuild:
  Creating directory "hello.dir\Debug\".
  Creating directory "C:\work\cmrc\build\Debug\".
  Creating directory "hello.dir\Debug\hello.tlog\".
InitializeBuildStatus:
  Creating "hello.dir\Debug\hello.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
ComputeCustomBuildOutput:
  Creating directory "C:\work\cmrc\build\hello\intermediate\".
CustomBuild:
  Generating hello resource loader
  Generating intermediate file for C:/work/cmrc/hello.txt
  Generating intermediate file for C:/work/cmrc/flower.jpg
  Building Custom Rule C:/work/cmrc/CMakeLists.txt
  CMake does not need to re-run because C:/work/cmrc/build/CMakeFiles/generate.stamp is up-to-date.
ClCompile:
  C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\HostX86\x64\CL.exe /c /IC
  :\work\cmrc\build\_cmrc\include /Zi /nologo /W3 /WX- /diagnostics:classic /Od /Ob0 /D WIN32 /D _WINDOWS /D "CMAKE_INT
  DIR=\"Debug\"" /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /Fo"hello.dir\D
  ebug\\" /Fd"hello.dir\Debug\hello.pdb" /Gd /TP /FC /errorReport:queue C:\work\cmrc\build\hello\lib.cpp C:\work\cmrc\b
  uild\hello\intermediate\hello.txt.cpp C:\work\cmrc\build\hello\intermediate\flower.jpg.cpp
  lib.cpp
  hello.txt.cpp
  flower.jpg.cpp
c:\work\cmrc\build\hello\intermediate\flower.jpg.cpp(1): error C2026: string too big, trailing characters truncated [C:
\work\cmrc\build\hello.vcxproj]
  Generating Code...
Done Building Project "C:\work\cmrc\build\hello.vcxproj" (default targets) -- FAILED.

Done Building Project "C:\work\cmrc\build\flower.vcxproj" (default targets) -- FAILED.

Done Building Project "C:\work\cmrc\build\ALL_BUILD.vcxproj" (default targets) -- FAILED.


Build FAILED.

"C:\work\cmrc\build\ALL_BUILD.vcxproj" (default target) (1) ->
"C:\work\cmrc\build\flower.vcxproj" (default target) (3) ->
"C:\work\cmrc\build\hello.vcxproj" (default target) (4) ->
(ClCompile target) ->
  c:\work\cmrc\build\hello\intermediate\flower.jpg.cpp(1): error C2026: string too big, trailing characters truncated [
C:\work\cmrc\build\hello.vcxproj]

    0 Warning(s)
    1 Error(s)

Time Elapsed 00:00:04.11

We can fix this by reverting back to an array of chars in the intermediate representation rather than using a string literal.

Split C++ source from CMake files

Is it possible to split the C++ source embedded in the CMake file into its own files? It would make following the project much easier.

std::string_view API on file

Please provide one.

My current workaround is: std::string_view data(file.begin(), file.end() - file.begin());

empty resources in android project

I'm currently writing a C++ app for android and accessing assets from native code is far from trivial in Android.
On my search for alternatives I stumbled upon your resource compiler. It looks fantastic and would solve a lot of problems for me. However when I try to access resources it just returns null pointers as iterators.
Have a look at the following:
Inside CMakeLists.txt:

cmrc_add_resource_library(shaderFiles src/main/assets/shader/standard.fs src/main/assets/shader/standard.vs)

Inside C++:

CMRC_INIT(shaderFiles);
auto stdVertexShader = cmrc::open("src/main/assets/shader/standard.vs");
auto stdFragShader = cmrc::open("src/main/assets/shader/standard.fs");
LOGI("%d", stdVertexShader.end()-stdVertexShader.begin()); // prints "0"
LOGI("%d", (int)stdVertexShader.begin()); // prints "0"

The code compiles without errors and prints two zeros when executed. However the vertex shader file definitely contains data.
In order to get behind this I added the following line to the cmake script:

function(_cmrc_generate_intermediate_cpp libname symbol outfile infile)
    message(STATUS "infile: ${infile}")  # <--
    add_custom_command(

This prints "infile: /home/<...>/ProjectPath/app/src/main/assets/shader/standard.vs" (and respectively "*.fs") which are the valid paths to my files I want to include. (Tested using "cat")
The table entries in "/home/<...>/ProjectPath/app/shaderFiles/lib_.cpp" are the following:

// Table entry for src/main/assets/shader/standard.fs
table.emplace("src/main/assets/shader/standard.fs", resource{res_chars::f_be11_src_main_assets_shader_standard_fs_begin, res_chars::f_be11_src_main_assets_shader_standard_fs_end});
// Table entry for src/main/assets/shader/standard.vs
table.emplace("src/main/assets/shader/standard.vs", resource{res_chars::f_6947_src_main_assets_shader_standard_vs_begin, res_chars::f_6947_src_main_assets_shader_standard_vs_end});

So I'm using the correct keys and the script uses the correct file paths. What could have gone wrong? How can I further investigate this problem? I'm not exactly a CMake expert...

[Wishlist] Allow nested namespaces

On most compilers (gcc, clang) you can actually have a nested namespace. This bit me, because MSVC doesn't let you do that by default. Maybe there's a way that a nested namespace can be detected and expanded in the generated code.

To reproduce, simply try following the instructions with

cmrc_add_resource_library(foo-resources ALIAS foo::rc NAMESPACE foo::bar  ...)

And then keep going. In the generated lib.cpp file you'll see

namespace foo::bar {

....which I think is legal C++17. I'm surprised that my gcc didn't choke (it was set to C++14), but MSVC for sure didn't like it. If this can be autoexpanded to

namespace foo { namespace bar {

(and then again on the closing braces), this will work just fine.

Adding ouputs of other targets as the inputs to a resource libary target

Right now it seems that cmrc only supports adding files from the sourcetree.
I have an application where I have to add some build outputs to the resource library, but there seems to be a configure time check for the existence of the file. The actual conversion of the file is performed at build time, so I can ensure that the target generating the file is executed before and the file is present.

As a workaround I've added a file(TOUCH ...) command before the cmrc calls. This works but looks a bit funny.

Is there a better way to do this right now? Is it a valid usecase?
Possible improvements to cmrc in this regard:

  • remove the check (probably not good for the majority of users)
  • move the check to build-time
  • add a flag to skip the test
  • add a new command variant which accepts a target as a dependency and does not perform the test for build artifacts.

I'd be happy to contribute a PR but I wanted to make sure that this isn't already supported or going into the wrong direction.

My usecase is to compile a webasembly client in a cmake ExternalProject_add call and then add the .wasm/.html files as resources to the server component which will serve them next to the api endpoint.

Undefined reference to get_filesystem()

I seem to have an issue with linking a library that uses cmrc. For example I have a file called foo.cpp in my src dir which has code that calls cmrc::resource_name::filesystem(). When I build this library I have no issues but when I link this library to its respective test file I have linkage issues where there is an error of undefined reference to cmrc::resource_name::filesystem().

Constexpr

Would it be possible/worthwhile to have a version of this library that provides the file data in a constexpr context instead of hiding the data in a cpp file?

This library feels dangerously close to a std::embed equivalent/workaround, and having access to some file contents from a constexpr context would be very handy.

Call "cmrc_add_resources" in sub directory

Hi, thanks for nice work. I am having trouble with a setup like this. Use "cmrc_add_resource_library" at top level source directory and "add_subdirectory" some sub directory. Each sub directory with a "cmrc_add_resources" command for resource files in that sub directory.
CMake always complain about that it can not find source file (intermediate cpp file) at configuring (cmake) step.
CMake Error at cmake/CMakeRC.cmake:498 (add_library):
Cannot find source file:
/home/nvidia/DeepStream/release/__cmrc_vinbigdata_deepstream-resources/intermediate/rc.jpg.cpp

I'd love to here your ideas or minimal example supporting such case.

clangd-lsp does not recognize header files

First of all, to use Clangd's LSP feature, I set set(CMAKE_EXPORT_COMPILE_COMMANDS ON) in CMakeLists.txt. This makes the compile commands to be written to the compile_commands.json file, which helps the language server understand the project structure.

However, using cmrc_add_resource_library() in CMakeLists.txt causes some header files to not recognize other header files. For example, the project structure is as follows

│  CMakeLists.txt
│  CMakeRC.cmake
├─build
├─include1
│      header1.h
├─include2
│      header2.h
├─resources
│      kitty.png
└─src
        main.cpp

in this case, if header1.h imports header2.h, LSP says it could not find the file. (However, it will compile and build normally!)

Failing to compile with GLSL shaders

Hi!

I am currently trying to use this tool to compile shader into our shared library, but I get the following error during compile:

make[3]: *** No rule to make target '../src/shaders/debug_fragment.glsl', needed by '__cmrc_foo-shaders/intermediate/debug_fragment.glsl.cpp'. Stop.

I am using the following function to include the files:
cmrc_add_resource_library(foo-shaders ALIAS shaders::rc NAMESPACE shaders WHENCE src/shaders ...)

Build failed(Error C1060) with big resource files.

I have a few resource files around 155 MB.
In the building process, the following error occurred:
(I used msvc tool set.)

~~~resourceFileName.cpp(1): fatal error C1060: compiler is out of heap space

(And overloads memory and disk. My computer almost died...)

How to solve this problem?

Making the cmrc-generated resource libraries install-friendly

Hi,

When using CMakeRC in a project, one has to add all of the resource libraries to the export target. Like this:

cmrc_add_resource_library(foo-resources ALIAS foo::rc NAMESPACE foo data/test.txt)
target_link_libraries(sample_project PRIVATE foo::rc)
install(TARGETS sample_project foo-resources ... EXPORT sample_projectTargets ...)

foo-resources is of course a STATIC library, but it requires the cmrc::base as an INTERFACE dependency here:

target_link_libraries(${name} PUBLIC cmrc::base)

Thus, CMake complains that cmrc-base is not in any export target. According to this, this, and this, the most simple fix would be to change that line to:

target_link_libraries(${name} PUBLIC "$<BUILD_INTERFACE:cmrc-base>")

What do you think? Is it a viable fix or it breaks something elsewhere?

Specify include directories as system includes

When using strict compiler warnings with clang, the header cmrc.hpp emits conversion warnings.
When building a project using cmrc, such a warning should not appear to the user, so I woud propose to specify the include directory as a system include to silence warnings:

target_include_directories(cmrc-base SYSTEM INTERFACE $<BUILD_INTERFACE:${CMRC_INCLUDE_DIR}>)

CMP0058: Ninja requires custom command byproducts to be explicit.

Running this with the Ninja generator results in the following warning:

[cmake] CMake Warning (dev):
[cmake]   Policy CMP0058 is not set: Ninja requires custom command byproducts to be
[cmake]   explicit.  Run "cmake --help-policy CMP0058" for policy details.  Use the
[cmake]   cmake_policy command to set the policy and suppress this warning.
[cmake] 
[cmake]   This project specifies custom command DEPENDS on files in the build tree
[cmake]   that are not specified as the OUTPUT or BYPRODUCTS of any
[cmake]   add_custom_command or add_custom_target:
[cmake] 
[cmake]    _cmrc/include/cmrc/cmrc.hpp
[cmake] 
[cmake]   For compatibility with versions of CMake that did not have the BYPRODUCTS
[cmake]   option, CMake is generating phony rules for such files to convince 'ninja'
[cmake]   to build.
[cmake] 
[cmake]   Project authors should add the missing BYPRODUCTS or OUTPUT options to the
[cmake]   custom commands that produce these files.
[cmake] This warning is for project developers.  Use -Wno-dev to suppress it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.