Higigig
Higigig

Reputation: 1265

Resource Folder In Cmake

I have a project like this:

- root/
    - main/
        - include/
            - *.h
        - res/
            - *.txt
        - src/
            - *.c
        CMakeListst.txt
    - CMakeLists.txt

The res folder is the folder with a bunch of text files which my application reads.

This is how my root/CMakeLists.txt looks like:

// Configuration stuff

add_subdirectory(main)

Then root/main/CMakeLists.txt looks like:

include_directories(include)

file(GLOB_RECURSE SOURCES *.c)
file(GLOB_RECURSE RESOURCES *.txt)
add_executable(${PROJECT_NAME} ${RESOURCES} ${SOURCES})

I thought I could add all the resources to the add_executable statement, but then I debugged my program and I found out it crashed when I tried to open the file. Lets say I have a file called foo.txt in the res/ folder, then when I do fopen("foo.txt", "r"); it returns null. How can I add custom resources?

Upvotes: 2

Views: 5611

Answers (1)

lionkor
lionkor

Reputation: 799

I believe you misunderstand what add_executable does. It will generally just pass the files specified in it to the compiler.

As the compiler presumably doesn't know how to process your foo.txt, it ignores it (i'm actually surprised that it does not complain). What happens in your CMakeLists file is roughly equivalent to something like

gcc src/*.c res/*.txt 

... which might make clear why it didn't do what you wanted it to (if you're familiar with gcc, not sure about your platform).

So, how can you "add" resources? Well, there are multiple ways:

  • If you run your executable from the root/main directory, you can just open it like:
FILE* my_file = fopen("res/foo.txt", "r");

or otherwise provide a relative or full path to your file. This is probably the best way.

  • You can make cmake copy your "foo.txt" to the build directory (and then do what I said in the previous point). That way it's always in the same spot relative to your executable. Here's a link I found that explains this fairly well

  • You can embed the resources in your binary directly. I personally wouldn't do this unless there was a very good reason why the others can't be used. Generally this should also only be done for very small resources. I'm just putting this here for completeness. A library that can do this is hexembed.

Upvotes: 3

Related Questions