You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CMakeLists INSTALL DESTINATION and INSTALL_INTERFACE are inconsistent #384
Previously, I had been grabbing concurrentqueue with cmake's FetchContent and it worked great. Recently, I switched to using it as a bitbake recipe in an embedded system, where concurrentqueue gets installed as a system-level dependency. I suddenly had to change my includes to #include <moodycamel/concurrentqueue.h>. And of course this fails when I want to build without the system-level install for local debugging without the embedded sysroot.
I propose removing the trailing moodycamel from the install destination.
That way, all the include statements in the source code will be the same (#include <concurrentqueue.h>) whether someone grabs concurrentqueue with FetchContent or they install concurrentqueue to the system and use find_package(concurrentqueue) followed by target_link_libraries(${PROJECT_NAME} concurrentqueue::concurrentqueue).
Currently, I'm patching concurrentqueue on fetch with this exact change and it's working well for me.
I regret accepting PRs for CMake support, it seems to cause no end of issues for what is a header-only library.
It seems like if I change this, it would break code currently including <moodycamel/concurrentqueue.h>? Also, what if there is another concurrentqueue.h from some other project? Shouldn't the moodycamel be present for both in order to avoid conflicts?
I regret accepting PRs for CMake support, it seems to cause no end of issues for what is a header-only library.
I appreciate it being there. It has proven itself useful for me in a couple projects already. Nothing that I probably couldn't do with some custom CMake code but when I'm pulling in 5+ 3rd party dependencies, it's nice when most of them just need a FetchContent statement and nothing else custom.
Also, what if there is another concurrentqueue.h from some other project?
Are you concerned about overwriting in the system /usr/include?
That isn't an issue with this change. The 3 header files get installed into /usr/include/concurrentqueue/ instead of /usr/include/concurrentqueue/moodycamel where they are installed in the current version of the code. IMO, the current format is pretty strange that the org comes after the project name.
Or are you concerned about shadowing #include <concurrentqueue.h> statements?
All the examples use #include "concurrentqueue.h" so that might already be an issue.
For cmake-installed workflow users, concurrentqueue isn't available to #include unless the target project cmake config does target_link_libraries(..., so conflicts seem unlikely.
I'm hoping we can achieve syntax parity among the CMake-installed workflow and the clone-and-include workflow. With the proposed changes, the syntax for including concurrentqueue for CMake-installed users is aligned with the non-cmake workflow.
I'd also be happy with #include <concurrentqueue/concurrentqueue.h> syntax.
This can be achieved for CMake users by dropping ${PROJECT_NAME}/ from INSTALL_INTERFACE above.
However, the only way to get syntax parity for clone-and-include workflows would be to instruct users to -I path/to/concurrentqueue/.. or to nest it within the repo itself. Even though I think nesting it within a subfolder in the repo is a good idea, I also recognize that would be more of a disturbance to users than the other approaches.
@cameron314 , I'd be happy to put forth a PR, but I'm hoping you can help me decide on the preferred approach, if any.
I realize the issue itself as described thus far is confusing so I'll try to refocus it.
AFAIK, there are 3 main workflows to use concurrentqueue in a project:
Clone and include the cloned folder.
CMake FetchContent
Clone and Install via cmake
Admittedly, the first workflow is far more common than the others, and that is totally appropriate because it's a header-only library (except C-API users). I would like to use the 3rd workflow for a specific project where automated auditing of dependencies is important and is much easier to do by installing it (as a yocto layer, in case you are curious).
Unfortunately, the 3rd workflow requires different include statements to the others, which is a bit tricky for documentation and for people like me who want to share any concurrentqueue-using code between build workflows.
The different include statements are:
#include "concurrentqueue.h"
or #include <concurrentqueue.h>, depending on how you add the cloned folder.
#include <moodycamel/concurrentqueue.h>
Is it desirable to you to unify the include statements across these different workflows?
If yes, what is the preferred include statement?
#include <concurrentqueue.h>
#include <moodycamel/concurrentqueue.h>
#include <concurrentqueue/concurrentqueue.h>
My preferred is the last or 2nd-last, but that would require that the header files are placed one folder deeper in the repository (e.g., <repo_root>/concurrentqueue/concurrentqueue.h). But I realize this is unlikely because, even with a version bump and an update to the documentation, this would cause a lot of pain for people who are fetching concurrentqueue master in their builds. That's why in my first message, the suggested change unified on the first include statement.
For now, I can solve my problem by patching concurrentqueue when I pull it, or manually adding the /usr/local/include/concurrentqueue/moodycamel path to my includes.
I agree that the include paths should be consistent.
Are you concerned about overwriting in the system /usr/include?
Installing into non-namespaced directories can create conflicts. What if someone else writes a foobar::ConcurrentQueue also installed under concurrentqueue/concurrentqueue.h?
Hence, my preferred installation structure would be moodycamel/concurrentqueue/concurrentqueue.h. However, I'm okay with any of the proposed options, since I recognize that minimizing friction for existing workflows is probably more important than hypothetical clashes.
Thanks for taking the time to look into this, and for bearing with me through my slow response times.
edit:
there are some falut in the cmake script. the try_compile only works for imported target (i.e. the moodycamel/concurrentqueue.h case)
temporary user side solution:
use cmake's try_compile command to auto detect the possible include flavor.
cmake file:
if(NOTTARGET concurrentqueue::concurrentqueue)
add_library(concurrentqueue::concurrentqueueALIASconcurrentqueue)
endif()
# after cmake 3.29: Alias targets to imported libraries are also supported in try_compile.# add these code to compatible with cmake<3.29get_property(aliased_target TARGET concurrentqueue::concurrentqueue PROPERTY ALIASED_TARGET)
if(aliased_target)
set(concurrentqueue_link_name concurrentqueue)
else()
set(concurrentqueue_link_name concurrentqueue::concurrentqueue)
endif()
try_compile(
include_moodycamel_concurrentqueueSOURCES${PROJECT_SOURCE_DIR}/src/try_compile/test_include_moodycamel_concurrentqueue.ccLINK_LIBRARIES${concurrentqueue_link_name})
# since `try_compile` only works for imported target, if the target is added by `add_library` or `add_subdirectory`,# the `try_compile` will always fail. since the `concurrentqueue` target always exists, we just assume the header # is included as `#include <concurrentqueue.h>`if(NOT include_moodycamel_concurrentqueue)
set(include_concurrentqueue true)
endif()
configure_file("include_concurrentqueue.h.in""${CMAKE_BINARY_DIR}/configured_files/include/internal_use_only/include_concurrentqueue.h"ESCAPE_QUOTES)
include_concurrentqueue.h.in
#pragma once
// clang-format off
#cmakedefine include_concurrentqueue
#cmakedefine include_moodycamel_concurrentqueue
// clang-format on
#ifdef include_concurrentqueue
#include<concurrentqueue.h>
#elifdef include_moodycamel_concurrentqueue
#include<moodycamel/concurrentqueue.h>
#else
#include<concurrentqueue/concurrentqueue.h>
#warning "try to include system concurrentqueue"
#endif
then add $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/configured_files/include> into the target's PUBLIC include directories. then you can use #include <internal_use_only/include_concurrentqueue.h> to include concurrentqueue everywhere.
Activity
cameron314 commentedon May 19, 2024
I regret accepting PRs for CMake support, it seems to cause no end of issues for what is a header-only library.
It seems like if I change this, it would break code currently including
<moodycamel/concurrentqueue.h>? Also, what if there is anotherconcurrentqueue.hfrom some other project? Shouldn't themoodycamelbe present for both in order to avoid conflicts?cboulay commentedon May 20, 2024
I appreciate it being there. It has proven itself useful for me in a couple projects already. Nothing that I probably couldn't do with some custom CMake code but when I'm pulling in 5+ 3rd party dependencies, it's nice when most of them just need a
FetchContentstatement and nothing else custom.Are you concerned about overwriting in the system
/usr/include?That isn't an issue with this change. The 3 header files get installed into
/usr/include/concurrentqueue/instead of/usr/include/concurrentqueue/moodycamelwhere they are installed in the current version of the code. IMO, the current format is pretty strange that the org comes after the project name.Or are you concerned about shadowing
#include <concurrentqueue.h>statements?All the examples use
#include "concurrentqueue.h"so that might already be an issue.For cmake-installed workflow users, concurrentqueue isn't available to
#includeunless the target project cmake config doestarget_link_libraries(..., so conflicts seem unlikely.I'm hoping we can achieve syntax parity among the CMake-installed workflow and the clone-and-include workflow. With the proposed changes, the syntax for including concurrentqueue for CMake-installed users is aligned with the non-cmake workflow.
I'd also be happy with
#include <concurrentqueue/concurrentqueue.h>syntax.This can be achieved for CMake users by dropping
${PROJECT_NAME}/fromINSTALL_INTERFACEabove.However, the only way to get syntax parity for clone-and-include workflows would be to instruct users to
-I path/to/concurrentqueue/..or to nest it within the repo itself. Even though I think nesting it within a subfolder in the repo is a good idea, I also recognize that would be more of a disturbance to users than the other approaches.cboulay commentedon May 30, 2024
@cameron314 , I'd be happy to put forth a PR, but I'm hoping you can help me decide on the preferred approach, if any.
I realize the issue itself as described thus far is confusing so I'll try to refocus it.
AFAIK, there are 3 main workflows to use concurrentqueue in a project:
Admittedly, the first workflow is far more common than the others, and that is totally appropriate because it's a header-only library (except C-API users). I would like to use the 3rd workflow for a specific project where automated auditing of dependencies is important and is much easier to do by installing it (as a yocto layer, in case you are curious).
Unfortunately, the 3rd workflow requires different include statements to the others, which is a bit tricky for documentation and for people like me who want to share any concurrentqueue-using code between build workflows.
The different include statements are:
#include "concurrentqueue.h"#include <concurrentqueue.h>, depending on how you add the cloned folder.#include <moodycamel/concurrentqueue.h>Is it desirable to you to unify the include statements across these different workflows?
If yes, what is the preferred include statement?
#include <concurrentqueue.h>#include <moodycamel/concurrentqueue.h>#include <concurrentqueue/concurrentqueue.h>My preferred is the last or 2nd-last, but that would require that the header files are placed one folder deeper in the repository (e.g.,
<repo_root>/concurrentqueue/concurrentqueue.h). But I realize this is unlikely because, even with a version bump and an update to the documentation, this would cause a lot of pain for people who are fetching concurrentqueue master in their builds. That's why in my first message, the suggested change unified on the first include statement.For now, I can solve my problem by patching concurrentqueue when I pull it, or manually adding the
/usr/local/include/concurrentqueue/moodycamelpath to my includes.cameron314 commentedon Jun 2, 2024
I agree that the include paths should be consistent.
Installing into non-namespaced directories can create conflicts. What if someone else writes a
foobar::ConcurrentQueuealso installed underconcurrentqueue/concurrentqueue.h?Hence, my preferred installation structure would be
moodycamel/concurrentqueue/concurrentqueue.h. However, I'm okay with any of the proposed options, since I recognize that minimizing friction for existing workflows is probably more important than hypothetical clashes.Thanks for taking the time to look into this, and for bearing with me through my slow response times.
handle cameron314/concurrentqueue#384
LXYan2333 commentedon Sep 16, 2024
edit:
there are some falut in the cmake script. the try_compile only works for imported target (i.e. the moodycamel/concurrentqueue.h case)
temporary user side solution:
use cmake's
try_compilecommand to auto detect the possible include flavor.cmake file:
include_concurrentqueue.h.in
test_include_moodycamel_concurrentqueue.cc
then add
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/configured_files/include>into the target's PUBLIC include directories. then you can use#include <internal_use_only/include_concurrentqueue.h>to include concurrentqueue everywhere.LXYan2333 commentedon Oct 25, 2024
ok seems
__has_includepreprocessor instruction should be the simplest solution.https://en.cppreference.com/w/cpp/preprocessor/include
dg0yt commentedon Aug 3, 2025
Related: #249 (comment)
Fix CMake install destination include path (fixes cameron314#384, cam…