nothings / stb

stb single-file public domain libraries for C/C++
https://twitter.com/nothings
Other
26.84k stars 7.72k forks source link

Move includes into include/stb folder #1209

Open mdeforge opened 3 years ago

mdeforge commented 3 years ago

I get frustrated when I try to make a CMakeLists.txt for this project because I can't use target_include_directories on the root folder without adding ALL the files and folders (code or not) to the include list.

If the headers could be moved into an include/stb folder, the following would work really well.

add_library(stb INTERFACE)
target_include_directories(stb
    INTERFACE
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> # Used for working with a 'build tree'
        $<INSTALL_INTERFACE:include> # Used for working with an 'install tree'
)

(Note for readers: You may want to consider a STATIC library given there is a source file or two, but the same problem persists in that case as well.)

Including a file would look like #include "stb/stb_image.h", for example.

However, because they are not, when I do this now I get folders such as "deprecated" and files such ".travis.yml" showing up in intellisense when I type #include, which really pollutes what I'm looking for.

intellisense

Plus, it can't be good for the build system to be aware of these extra files and folders. I'm sure there's another impact beyond my intellisense complaint. Like maybe a rebuild is triggered if it senses one of these non-source files have changed.

I considered suggesting adding a CMakeLists.txt of your own, but I understand being build system agnostic. I just wish the includes were in a folder of their own. If you make this change, you might as well throw the source files into a src/ folder.

nothings commented 3 years ago

So your build system (or IDE, I don't know how the two are linked) has no ability to reference a directory WITHOUT recursively going through its subdirectories?

mdeforge commented 3 years ago

When it comes to picking which files are a part of the public interface (i.e, the headers) of a library, CMake users have to specify a directory. Under the hood, I think all target_include_directories is doing is specifying the /I flag for "additional include directories". AFAIK, we can't target specific files individually unless we're using something like target_sources, which is something different. That's used (often in conjunction with target_include_directories) to specify which sources to use when building the library itself. I think this limitation exists for /I as well?

To state it another way, target_include_directories is for the headers you want exposed to both the project using this library and the IDE (BUILD_INTERFACE), and also which headers will be installed (INSTALL_INTERFACE) when you build the install target. Building the install target generates the binaries and installs them to /usr/bin or Program Files (or another specified location). Right now, if I ran the install target I would get all the non-source files as well. In contrast, target_sources is what files you want the library itself to have access to when compiling itself.

I think in any project, regardless of CMake, it's best practice to have the includes in an include folder -- probably for similar reasons. It's just easier for people to grab.

If you're interested in adding a CMakeLists to this project, I can help with that. I could clone this, reorg, add a CMake, and you could take a look and see if it's something you want to do?

nothings commented 3 years ago

I'm not interested in having a CMakeLists, I'm just trying to understand the true nature of the problem. As far as I can see, the problem is that if you specify the stb directory, something is picking up stuff recursively in subdirectories. Which is what I asked, and which you didn't address.

Because that's my point. All the headers are in a directory. They're in the top-level directory. It's a perfectly fine directory. So apparently for you the problem is not that they're not in a directory, but the fact that the directory they're in has subdirectories which contain things that are not header files.

And to be clear, I am very unlikely to change things so they live in a different location, as that would be very disruptive to all the other users.

ghidosoft commented 3 years ago

I'm using CMake too and I tackled the problem differently:

target_include_directories(stb SYSTEM PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" )

target_include_directories(stb INTERFACE SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}" )

* I created the `<your-library-subdir>/stb/stb.cpp` file with the various implementations that I need. E.g.
```c++
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_JPEG
#define STBI_ONLY_PNG
#include "stb/stb_image.h"

...

With this setup I just add target_link_libraries(your-target stb) where I need it and include with #include <stb/stb_image.h>.